1b97bf3fdSPer Liden /* 2b97bf3fdSPer Liden * net/tipc/netlink.c: TIPC configuration handling 3b97bf3fdSPer Liden * 40655f6a8SRichard Alpe * Copyright (c) 2005-2006, 2014, Ericsson AB 559f0c452SAllan Stephens * Copyright (c) 2005-2007, Wind River Systems 6b97bf3fdSPer Liden * All rights reserved. 7b97bf3fdSPer Liden * 8b97bf3fdSPer Liden * Redistribution and use in source and binary forms, with or without 9b97bf3fdSPer Liden * modification, are permitted provided that the following conditions are met: 10b97bf3fdSPer Liden * 119ea1fd3cSPer Liden * 1. Redistributions of source code must retain the above copyright 129ea1fd3cSPer Liden * notice, this list of conditions and the following disclaimer. 139ea1fd3cSPer Liden * 2. Redistributions in binary form must reproduce the above copyright 149ea1fd3cSPer Liden * notice, this list of conditions and the following disclaimer in the 159ea1fd3cSPer Liden * documentation and/or other materials provided with the distribution. 169ea1fd3cSPer Liden * 3. Neither the names of the copyright holders nor the names of its 179ea1fd3cSPer Liden * contributors may be used to endorse or promote products derived from 189ea1fd3cSPer Liden * this software without specific prior written permission. 199ea1fd3cSPer Liden * 209ea1fd3cSPer Liden * Alternatively, this software may be distributed under the terms of the 219ea1fd3cSPer Liden * GNU General Public License ("GPL") version 2 as published by the Free 229ea1fd3cSPer Liden * Software Foundation. 23b97bf3fdSPer Liden * 24b97bf3fdSPer Liden * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25b97bf3fdSPer Liden * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26b97bf3fdSPer Liden * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27b97bf3fdSPer Liden * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 28b97bf3fdSPer Liden * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29b97bf3fdSPer Liden * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30b97bf3fdSPer Liden * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31b97bf3fdSPer Liden * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32b97bf3fdSPer Liden * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33b97bf3fdSPer Liden * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34b97bf3fdSPer Liden * POSSIBILITY OF SUCH DAMAGE. 35b97bf3fdSPer Liden */ 36b97bf3fdSPer Liden 37b97bf3fdSPer Liden #include "core.h" 3834b78a12SRichard Alpe #include "socket.h" 391593123aSRichard Alpe #include "name_table.h" 400655f6a8SRichard Alpe #include "bearer.h" 417be57fc6SRichard Alpe #include "link.h" 423e4b6ab5SRichard Alpe #include "node.h" 43fd3cf2adSRichard Alpe #include "net.h" 44b97bf3fdSPer Liden #include <net/genetlink.h> 45b97bf3fdSPer Liden 460655f6a8SRichard Alpe static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { 470655f6a8SRichard Alpe [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, 480655f6a8SRichard Alpe [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, 4934b78a12SRichard Alpe [TIPC_NLA_SOCK] = { .type = NLA_NESTED, }, 507be57fc6SRichard Alpe [TIPC_NLA_PUBL] = { .type = NLA_NESTED, }, 517be57fc6SRichard Alpe [TIPC_NLA_LINK] = { .type = NLA_NESTED, }, 5246f15c67SRichard Alpe [TIPC_NLA_MEDIA] = { .type = NLA_NESTED, }, 53fd3cf2adSRichard Alpe [TIPC_NLA_NODE] = { .type = NLA_NESTED, }, 541593123aSRichard Alpe [TIPC_NLA_NET] = { .type = NLA_NESTED, }, 557b3f5229SParthasarathy Bhuvaragan [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, }, 567b3f5229SParthasarathy Bhuvaragan [TIPC_NLA_MON] = { .type = NLA_NESTED, }, 570655f6a8SRichard Alpe }; 580655f6a8SRichard Alpe 5949cc66eaSRichard Alpe const struct nla_policy 6049cc66eaSRichard Alpe tipc_nl_name_table_policy[TIPC_NLA_NAME_TABLE_MAX + 1] = { 6149cc66eaSRichard Alpe [TIPC_NLA_NAME_TABLE_UNSPEC] = { .type = NLA_UNSPEC }, 6249cc66eaSRichard Alpe [TIPC_NLA_NAME_TABLE_PUBL] = { .type = NLA_NESTED } 6349cc66eaSRichard Alpe }; 6449cc66eaSRichard Alpe 657b3f5229SParthasarathy Bhuvaragan const struct nla_policy tipc_nl_monitor_policy[TIPC_NLA_MON_MAX + 1] = { 667b3f5229SParthasarathy Bhuvaragan [TIPC_NLA_MON_UNSPEC] = { .type = NLA_UNSPEC }, 677b3f5229SParthasarathy Bhuvaragan [TIPC_NLA_MON_ACTIVATION_THRESHOLD] = { .type = NLA_U32 }, 687b3f5229SParthasarathy Bhuvaragan }; 697b3f5229SParthasarathy Bhuvaragan 7049cc66eaSRichard Alpe const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = { 7149cc66eaSRichard Alpe [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC }, 7249cc66eaSRichard Alpe [TIPC_NLA_SOCK_ADDR] = { .type = NLA_U32 }, 7349cc66eaSRichard Alpe [TIPC_NLA_SOCK_REF] = { .type = NLA_U32 }, 7449cc66eaSRichard Alpe [TIPC_NLA_SOCK_CON] = { .type = NLA_NESTED }, 7549cc66eaSRichard Alpe [TIPC_NLA_SOCK_HAS_PUBL] = { .type = NLA_FLAG } 7649cc66eaSRichard Alpe }; 7749cc66eaSRichard Alpe 7849cc66eaSRichard Alpe const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { 7949cc66eaSRichard Alpe [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC }, 8049cc66eaSRichard Alpe [TIPC_NLA_NET_ID] = { .type = NLA_U32 } 8149cc66eaSRichard Alpe }; 8249cc66eaSRichard Alpe 8349cc66eaSRichard Alpe const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = { 8449cc66eaSRichard Alpe [TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC }, 8549cc66eaSRichard Alpe [TIPC_NLA_LINK_NAME] = { .type = NLA_STRING, 8649cc66eaSRichard Alpe .len = TIPC_MAX_LINK_NAME }, 8749cc66eaSRichard Alpe [TIPC_NLA_LINK_MTU] = { .type = NLA_U32 }, 8849cc66eaSRichard Alpe [TIPC_NLA_LINK_BROADCAST] = { .type = NLA_FLAG }, 8949cc66eaSRichard Alpe [TIPC_NLA_LINK_UP] = { .type = NLA_FLAG }, 9049cc66eaSRichard Alpe [TIPC_NLA_LINK_ACTIVE] = { .type = NLA_FLAG }, 9149cc66eaSRichard Alpe [TIPC_NLA_LINK_PROP] = { .type = NLA_NESTED }, 9249cc66eaSRichard Alpe [TIPC_NLA_LINK_STATS] = { .type = NLA_NESTED }, 9349cc66eaSRichard Alpe [TIPC_NLA_LINK_RX] = { .type = NLA_U32 }, 9449cc66eaSRichard Alpe [TIPC_NLA_LINK_TX] = { .type = NLA_U32 } 9549cc66eaSRichard Alpe }; 9649cc66eaSRichard Alpe 9749cc66eaSRichard Alpe const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = { 9849cc66eaSRichard Alpe [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC }, 9949cc66eaSRichard Alpe [TIPC_NLA_NODE_ADDR] = { .type = NLA_U32 }, 10049cc66eaSRichard Alpe [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG } 10149cc66eaSRichard Alpe }; 10249cc66eaSRichard Alpe 10349cc66eaSRichard Alpe /* Properties valid for media, bearer and link */ 10449cc66eaSRichard Alpe const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = { 10549cc66eaSRichard Alpe [TIPC_NLA_PROP_UNSPEC] = { .type = NLA_UNSPEC }, 10649cc66eaSRichard Alpe [TIPC_NLA_PROP_PRIO] = { .type = NLA_U32 }, 10749cc66eaSRichard Alpe [TIPC_NLA_PROP_TOL] = { .type = NLA_U32 }, 10849cc66eaSRichard Alpe [TIPC_NLA_PROP_WIN] = { .type = NLA_U32 } 10949cc66eaSRichard Alpe }; 11049cc66eaSRichard Alpe 11149cc66eaSRichard Alpe const struct nla_policy tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = { 11249cc66eaSRichard Alpe [TIPC_NLA_BEARER_UNSPEC] = { .type = NLA_UNSPEC }, 11349cc66eaSRichard Alpe [TIPC_NLA_BEARER_NAME] = { .type = NLA_STRING, 11449cc66eaSRichard Alpe .len = TIPC_MAX_BEARER_NAME }, 11549cc66eaSRichard Alpe [TIPC_NLA_BEARER_PROP] = { .type = NLA_NESTED }, 11649cc66eaSRichard Alpe [TIPC_NLA_BEARER_DOMAIN] = { .type = NLA_U32 } 11749cc66eaSRichard Alpe }; 11849cc66eaSRichard Alpe 11949cc66eaSRichard Alpe const struct nla_policy tipc_nl_media_policy[TIPC_NLA_MEDIA_MAX + 1] = { 12049cc66eaSRichard Alpe [TIPC_NLA_MEDIA_UNSPEC] = { .type = NLA_UNSPEC }, 12149cc66eaSRichard Alpe [TIPC_NLA_MEDIA_NAME] = { .type = NLA_STRING }, 12249cc66eaSRichard Alpe [TIPC_NLA_MEDIA_PROP] = { .type = NLA_NESTED } 12349cc66eaSRichard Alpe }; 12449cc66eaSRichard Alpe 12549cc66eaSRichard Alpe const struct nla_policy tipc_nl_udp_policy[TIPC_NLA_UDP_MAX + 1] = { 12649cc66eaSRichard Alpe [TIPC_NLA_UDP_UNSPEC] = {.type = NLA_UNSPEC}, 12749cc66eaSRichard Alpe [TIPC_NLA_UDP_LOCAL] = {.type = NLA_BINARY, 12849cc66eaSRichard Alpe .len = sizeof(struct sockaddr_storage)}, 12949cc66eaSRichard Alpe [TIPC_NLA_UDP_REMOTE] = {.type = NLA_BINARY, 13049cc66eaSRichard Alpe .len = sizeof(struct sockaddr_storage)}, 13149cc66eaSRichard Alpe }; 13249cc66eaSRichard Alpe 1330655f6a8SRichard Alpe /* Users of the legacy API (tipc-config) can't handle that we add operations, 1340655f6a8SRichard Alpe * so we have a separate genl handling for the new API. 1350655f6a8SRichard Alpe */ 136bfb3e5ddSRichard Alpe struct genl_family tipc_genl_family = { 1370655f6a8SRichard Alpe .id = GENL_ID_GENERATE, 1380655f6a8SRichard Alpe .name = TIPC_GENL_V2_NAME, 1390655f6a8SRichard Alpe .version = TIPC_GENL_V2_VERSION, 1400655f6a8SRichard Alpe .hdrsize = 0, 1410655f6a8SRichard Alpe .maxattr = TIPC_NLA_MAX, 142d49e2041SYing Xue .netnsok = true, 1430655f6a8SRichard Alpe }; 1440655f6a8SRichard Alpe 1450655f6a8SRichard Alpe static const struct genl_ops tipc_genl_v2_ops[] = { 1460655f6a8SRichard Alpe { 1470655f6a8SRichard Alpe .cmd = TIPC_NL_BEARER_DISABLE, 1480655f6a8SRichard Alpe .doit = tipc_nl_bearer_disable, 1490655f6a8SRichard Alpe .policy = tipc_nl_policy, 1500655f6a8SRichard Alpe }, 1510655f6a8SRichard Alpe { 1520655f6a8SRichard Alpe .cmd = TIPC_NL_BEARER_ENABLE, 1530655f6a8SRichard Alpe .doit = tipc_nl_bearer_enable, 1540655f6a8SRichard Alpe .policy = tipc_nl_policy, 15535b9dd76SRichard Alpe }, 15635b9dd76SRichard Alpe { 15735b9dd76SRichard Alpe .cmd = TIPC_NL_BEARER_GET, 15835b9dd76SRichard Alpe .doit = tipc_nl_bearer_get, 15935b9dd76SRichard Alpe .dumpit = tipc_nl_bearer_dump, 16035b9dd76SRichard Alpe .policy = tipc_nl_policy, 161315c00bcSRichard Alpe }, 162315c00bcSRichard Alpe { 163315c00bcSRichard Alpe .cmd = TIPC_NL_BEARER_SET, 164315c00bcSRichard Alpe .doit = tipc_nl_bearer_set, 165315c00bcSRichard Alpe .policy = tipc_nl_policy, 16634b78a12SRichard Alpe }, 16734b78a12SRichard Alpe { 16834b78a12SRichard Alpe .cmd = TIPC_NL_SOCK_GET, 16934b78a12SRichard Alpe .dumpit = tipc_nl_sk_dump, 17034b78a12SRichard Alpe .policy = tipc_nl_policy, 1711a1a143dSRichard Alpe }, 1721a1a143dSRichard Alpe { 1731a1a143dSRichard Alpe .cmd = TIPC_NL_PUBL_GET, 1741a1a143dSRichard Alpe .dumpit = tipc_nl_publ_dump, 1751a1a143dSRichard Alpe .policy = tipc_nl_policy, 1767be57fc6SRichard Alpe }, 1777be57fc6SRichard Alpe { 1787be57fc6SRichard Alpe .cmd = TIPC_NL_LINK_GET, 1795be9c086SJon Paul Maloy .doit = tipc_nl_node_get_link, 18038206d59SJon Paul Maloy .dumpit = tipc_nl_node_dump_link, 1817be57fc6SRichard Alpe .policy = tipc_nl_policy, 182f96ce7a2SRichard Alpe }, 183f96ce7a2SRichard Alpe { 184f96ce7a2SRichard Alpe .cmd = TIPC_NL_LINK_SET, 1855be9c086SJon Paul Maloy .doit = tipc_nl_node_set_link, 186f96ce7a2SRichard Alpe .policy = tipc_nl_policy, 187ae36342bSRichard Alpe }, 188ae36342bSRichard Alpe { 189ae36342bSRichard Alpe .cmd = TIPC_NL_LINK_RESET_STATS, 1905be9c086SJon Paul Maloy .doit = tipc_nl_node_reset_link_stats, 191ae36342bSRichard Alpe .policy = tipc_nl_policy, 19246f15c67SRichard Alpe }, 19346f15c67SRichard Alpe { 19446f15c67SRichard Alpe .cmd = TIPC_NL_MEDIA_GET, 19546f15c67SRichard Alpe .doit = tipc_nl_media_get, 19646f15c67SRichard Alpe .dumpit = tipc_nl_media_dump, 19746f15c67SRichard Alpe .policy = tipc_nl_policy, 1981e55417dSRichard Alpe }, 1991e55417dSRichard Alpe { 2001e55417dSRichard Alpe .cmd = TIPC_NL_MEDIA_SET, 2011e55417dSRichard Alpe .doit = tipc_nl_media_set, 2021e55417dSRichard Alpe .policy = tipc_nl_policy, 2033e4b6ab5SRichard Alpe }, 2043e4b6ab5SRichard Alpe { 2053e4b6ab5SRichard Alpe .cmd = TIPC_NL_NODE_GET, 2063e4b6ab5SRichard Alpe .dumpit = tipc_nl_node_dump, 2073e4b6ab5SRichard Alpe .policy = tipc_nl_policy, 208fd3cf2adSRichard Alpe }, 209fd3cf2adSRichard Alpe { 210fd3cf2adSRichard Alpe .cmd = TIPC_NL_NET_GET, 211fd3cf2adSRichard Alpe .dumpit = tipc_nl_net_dump, 212fd3cf2adSRichard Alpe .policy = tipc_nl_policy, 21327c21416SRichard Alpe }, 21427c21416SRichard Alpe { 21527c21416SRichard Alpe .cmd = TIPC_NL_NET_SET, 21627c21416SRichard Alpe .doit = tipc_nl_net_set, 21727c21416SRichard Alpe .policy = tipc_nl_policy, 2181593123aSRichard Alpe }, 2191593123aSRichard Alpe { 2201593123aSRichard Alpe .cmd = TIPC_NL_NAME_TABLE_GET, 2211593123aSRichard Alpe .dumpit = tipc_nl_name_table_dump, 2221593123aSRichard Alpe .policy = tipc_nl_policy, 2237b3f5229SParthasarathy Bhuvaragan }, 2247b3f5229SParthasarathy Bhuvaragan { 2257b3f5229SParthasarathy Bhuvaragan .cmd = TIPC_NL_MON_SET, 2267b3f5229SParthasarathy Bhuvaragan .doit = tipc_nl_node_set_monitor, 2277b3f5229SParthasarathy Bhuvaragan .policy = tipc_nl_policy, 2287b3f5229SParthasarathy Bhuvaragan }, 229*bf1035b2SParthasarathy Bhuvaragan { 230*bf1035b2SParthasarathy Bhuvaragan .cmd = TIPC_NL_MON_GET, 231*bf1035b2SParthasarathy Bhuvaragan .doit = tipc_nl_node_get_monitor, 232*bf1035b2SParthasarathy Bhuvaragan .policy = tipc_nl_policy, 233*bf1035b2SParthasarathy Bhuvaragan }, 2340655f6a8SRichard Alpe }; 2350655f6a8SRichard Alpe 2361a1a143dSRichard Alpe int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr) 2371a1a143dSRichard Alpe { 238bfb3e5ddSRichard Alpe u32 maxattr = tipc_genl_family.maxattr; 2391a1a143dSRichard Alpe 240bfb3e5ddSRichard Alpe *attr = tipc_genl_family.attrbuf; 2411a1a143dSRichard Alpe if (!*attr) 2421a1a143dSRichard Alpe return -EOPNOTSUPP; 2431a1a143dSRichard Alpe 2441a1a143dSRichard Alpe return nlmsg_parse(nlh, GENL_HDRLEN, *attr, maxattr, tipc_nl_policy); 2451a1a143dSRichard Alpe } 2461a1a143dSRichard Alpe 2474323add6SPer Liden int tipc_netlink_start(void) 248b97bf3fdSPer Liden { 249acb0a200SMichał Mirosław int res; 250b70e4f45SJon Maloy 251bfb3e5ddSRichard Alpe res = genl_register_family_with_ops(&tipc_genl_family, 2520655f6a8SRichard Alpe tipc_genl_v2_ops); 2530655f6a8SRichard Alpe if (res) { 2542cf8aa19SErik Hugne pr_err("Failed to register netlink interface\n"); 255acb0a200SMichał Mirosław return res; 256acb0a200SMichał Mirosław } 257acb0a200SMichał Mirosław return 0; 258b97bf3fdSPer Liden } 259b97bf3fdSPer Liden 2604323add6SPer Liden void tipc_netlink_stop(void) 261b97bf3fdSPer Liden { 262acb0a200SMichał Mirosław genl_unregister_family(&tipc_genl_family); 263b97bf3fdSPer Liden } 264