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, }, 551593123aSRichard Alpe [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, } 560655f6a8SRichard Alpe }; 570655f6a8SRichard Alpe 58*49cc66eaSRichard Alpe const struct nla_policy 59*49cc66eaSRichard Alpe tipc_nl_name_table_policy[TIPC_NLA_NAME_TABLE_MAX + 1] = { 60*49cc66eaSRichard Alpe [TIPC_NLA_NAME_TABLE_UNSPEC] = { .type = NLA_UNSPEC }, 61*49cc66eaSRichard Alpe [TIPC_NLA_NAME_TABLE_PUBL] = { .type = NLA_NESTED } 62*49cc66eaSRichard Alpe }; 63*49cc66eaSRichard Alpe 64*49cc66eaSRichard Alpe const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = { 65*49cc66eaSRichard Alpe [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC }, 66*49cc66eaSRichard Alpe [TIPC_NLA_SOCK_ADDR] = { .type = NLA_U32 }, 67*49cc66eaSRichard Alpe [TIPC_NLA_SOCK_REF] = { .type = NLA_U32 }, 68*49cc66eaSRichard Alpe [TIPC_NLA_SOCK_CON] = { .type = NLA_NESTED }, 69*49cc66eaSRichard Alpe [TIPC_NLA_SOCK_HAS_PUBL] = { .type = NLA_FLAG } 70*49cc66eaSRichard Alpe }; 71*49cc66eaSRichard Alpe 72*49cc66eaSRichard Alpe const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { 73*49cc66eaSRichard Alpe [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC }, 74*49cc66eaSRichard Alpe [TIPC_NLA_NET_ID] = { .type = NLA_U32 } 75*49cc66eaSRichard Alpe }; 76*49cc66eaSRichard Alpe 77*49cc66eaSRichard Alpe const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = { 78*49cc66eaSRichard Alpe [TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC }, 79*49cc66eaSRichard Alpe [TIPC_NLA_LINK_NAME] = { .type = NLA_STRING, 80*49cc66eaSRichard Alpe .len = TIPC_MAX_LINK_NAME }, 81*49cc66eaSRichard Alpe [TIPC_NLA_LINK_MTU] = { .type = NLA_U32 }, 82*49cc66eaSRichard Alpe [TIPC_NLA_LINK_BROADCAST] = { .type = NLA_FLAG }, 83*49cc66eaSRichard Alpe [TIPC_NLA_LINK_UP] = { .type = NLA_FLAG }, 84*49cc66eaSRichard Alpe [TIPC_NLA_LINK_ACTIVE] = { .type = NLA_FLAG }, 85*49cc66eaSRichard Alpe [TIPC_NLA_LINK_PROP] = { .type = NLA_NESTED }, 86*49cc66eaSRichard Alpe [TIPC_NLA_LINK_STATS] = { .type = NLA_NESTED }, 87*49cc66eaSRichard Alpe [TIPC_NLA_LINK_RX] = { .type = NLA_U32 }, 88*49cc66eaSRichard Alpe [TIPC_NLA_LINK_TX] = { .type = NLA_U32 } 89*49cc66eaSRichard Alpe }; 90*49cc66eaSRichard Alpe 91*49cc66eaSRichard Alpe const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = { 92*49cc66eaSRichard Alpe [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC }, 93*49cc66eaSRichard Alpe [TIPC_NLA_NODE_ADDR] = { .type = NLA_U32 }, 94*49cc66eaSRichard Alpe [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG } 95*49cc66eaSRichard Alpe }; 96*49cc66eaSRichard Alpe 97*49cc66eaSRichard Alpe /* Properties valid for media, bearer and link */ 98*49cc66eaSRichard Alpe const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = { 99*49cc66eaSRichard Alpe [TIPC_NLA_PROP_UNSPEC] = { .type = NLA_UNSPEC }, 100*49cc66eaSRichard Alpe [TIPC_NLA_PROP_PRIO] = { .type = NLA_U32 }, 101*49cc66eaSRichard Alpe [TIPC_NLA_PROP_TOL] = { .type = NLA_U32 }, 102*49cc66eaSRichard Alpe [TIPC_NLA_PROP_WIN] = { .type = NLA_U32 } 103*49cc66eaSRichard Alpe }; 104*49cc66eaSRichard Alpe 105*49cc66eaSRichard Alpe const struct nla_policy tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = { 106*49cc66eaSRichard Alpe [TIPC_NLA_BEARER_UNSPEC] = { .type = NLA_UNSPEC }, 107*49cc66eaSRichard Alpe [TIPC_NLA_BEARER_NAME] = { .type = NLA_STRING, 108*49cc66eaSRichard Alpe .len = TIPC_MAX_BEARER_NAME }, 109*49cc66eaSRichard Alpe [TIPC_NLA_BEARER_PROP] = { .type = NLA_NESTED }, 110*49cc66eaSRichard Alpe [TIPC_NLA_BEARER_DOMAIN] = { .type = NLA_U32 } 111*49cc66eaSRichard Alpe }; 112*49cc66eaSRichard Alpe 113*49cc66eaSRichard Alpe const struct nla_policy tipc_nl_media_policy[TIPC_NLA_MEDIA_MAX + 1] = { 114*49cc66eaSRichard Alpe [TIPC_NLA_MEDIA_UNSPEC] = { .type = NLA_UNSPEC }, 115*49cc66eaSRichard Alpe [TIPC_NLA_MEDIA_NAME] = { .type = NLA_STRING }, 116*49cc66eaSRichard Alpe [TIPC_NLA_MEDIA_PROP] = { .type = NLA_NESTED } 117*49cc66eaSRichard Alpe }; 118*49cc66eaSRichard Alpe 119*49cc66eaSRichard Alpe const struct nla_policy tipc_nl_udp_policy[TIPC_NLA_UDP_MAX + 1] = { 120*49cc66eaSRichard Alpe [TIPC_NLA_UDP_UNSPEC] = {.type = NLA_UNSPEC}, 121*49cc66eaSRichard Alpe [TIPC_NLA_UDP_LOCAL] = {.type = NLA_BINARY, 122*49cc66eaSRichard Alpe .len = sizeof(struct sockaddr_storage)}, 123*49cc66eaSRichard Alpe [TIPC_NLA_UDP_REMOTE] = {.type = NLA_BINARY, 124*49cc66eaSRichard Alpe .len = sizeof(struct sockaddr_storage)}, 125*49cc66eaSRichard Alpe }; 126*49cc66eaSRichard Alpe 1270655f6a8SRichard Alpe /* Users of the legacy API (tipc-config) can't handle that we add operations, 1280655f6a8SRichard Alpe * so we have a separate genl handling for the new API. 1290655f6a8SRichard Alpe */ 130bfb3e5ddSRichard Alpe struct genl_family tipc_genl_family = { 1310655f6a8SRichard Alpe .id = GENL_ID_GENERATE, 1320655f6a8SRichard Alpe .name = TIPC_GENL_V2_NAME, 1330655f6a8SRichard Alpe .version = TIPC_GENL_V2_VERSION, 1340655f6a8SRichard Alpe .hdrsize = 0, 1350655f6a8SRichard Alpe .maxattr = TIPC_NLA_MAX, 136d49e2041SYing Xue .netnsok = true, 1370655f6a8SRichard Alpe }; 1380655f6a8SRichard Alpe 1390655f6a8SRichard Alpe static const struct genl_ops tipc_genl_v2_ops[] = { 1400655f6a8SRichard Alpe { 1410655f6a8SRichard Alpe .cmd = TIPC_NL_BEARER_DISABLE, 1420655f6a8SRichard Alpe .doit = tipc_nl_bearer_disable, 1430655f6a8SRichard Alpe .policy = tipc_nl_policy, 1440655f6a8SRichard Alpe }, 1450655f6a8SRichard Alpe { 1460655f6a8SRichard Alpe .cmd = TIPC_NL_BEARER_ENABLE, 1470655f6a8SRichard Alpe .doit = tipc_nl_bearer_enable, 1480655f6a8SRichard Alpe .policy = tipc_nl_policy, 14935b9dd76SRichard Alpe }, 15035b9dd76SRichard Alpe { 15135b9dd76SRichard Alpe .cmd = TIPC_NL_BEARER_GET, 15235b9dd76SRichard Alpe .doit = tipc_nl_bearer_get, 15335b9dd76SRichard Alpe .dumpit = tipc_nl_bearer_dump, 15435b9dd76SRichard Alpe .policy = tipc_nl_policy, 155315c00bcSRichard Alpe }, 156315c00bcSRichard Alpe { 157315c00bcSRichard Alpe .cmd = TIPC_NL_BEARER_SET, 158315c00bcSRichard Alpe .doit = tipc_nl_bearer_set, 159315c00bcSRichard Alpe .policy = tipc_nl_policy, 16034b78a12SRichard Alpe }, 16134b78a12SRichard Alpe { 16234b78a12SRichard Alpe .cmd = TIPC_NL_SOCK_GET, 16334b78a12SRichard Alpe .dumpit = tipc_nl_sk_dump, 16434b78a12SRichard Alpe .policy = tipc_nl_policy, 1651a1a143dSRichard Alpe }, 1661a1a143dSRichard Alpe { 1671a1a143dSRichard Alpe .cmd = TIPC_NL_PUBL_GET, 1681a1a143dSRichard Alpe .dumpit = tipc_nl_publ_dump, 1691a1a143dSRichard Alpe .policy = tipc_nl_policy, 1707be57fc6SRichard Alpe }, 1717be57fc6SRichard Alpe { 1727be57fc6SRichard Alpe .cmd = TIPC_NL_LINK_GET, 1735be9c086SJon Paul Maloy .doit = tipc_nl_node_get_link, 17438206d59SJon Paul Maloy .dumpit = tipc_nl_node_dump_link, 1757be57fc6SRichard Alpe .policy = tipc_nl_policy, 176f96ce7a2SRichard Alpe }, 177f96ce7a2SRichard Alpe { 178f96ce7a2SRichard Alpe .cmd = TIPC_NL_LINK_SET, 1795be9c086SJon Paul Maloy .doit = tipc_nl_node_set_link, 180f96ce7a2SRichard Alpe .policy = tipc_nl_policy, 181ae36342bSRichard Alpe }, 182ae36342bSRichard Alpe { 183ae36342bSRichard Alpe .cmd = TIPC_NL_LINK_RESET_STATS, 1845be9c086SJon Paul Maloy .doit = tipc_nl_node_reset_link_stats, 185ae36342bSRichard Alpe .policy = tipc_nl_policy, 18646f15c67SRichard Alpe }, 18746f15c67SRichard Alpe { 18846f15c67SRichard Alpe .cmd = TIPC_NL_MEDIA_GET, 18946f15c67SRichard Alpe .doit = tipc_nl_media_get, 19046f15c67SRichard Alpe .dumpit = tipc_nl_media_dump, 19146f15c67SRichard Alpe .policy = tipc_nl_policy, 1921e55417dSRichard Alpe }, 1931e55417dSRichard Alpe { 1941e55417dSRichard Alpe .cmd = TIPC_NL_MEDIA_SET, 1951e55417dSRichard Alpe .doit = tipc_nl_media_set, 1961e55417dSRichard Alpe .policy = tipc_nl_policy, 1973e4b6ab5SRichard Alpe }, 1983e4b6ab5SRichard Alpe { 1993e4b6ab5SRichard Alpe .cmd = TIPC_NL_NODE_GET, 2003e4b6ab5SRichard Alpe .dumpit = tipc_nl_node_dump, 2013e4b6ab5SRichard Alpe .policy = tipc_nl_policy, 202fd3cf2adSRichard Alpe }, 203fd3cf2adSRichard Alpe { 204fd3cf2adSRichard Alpe .cmd = TIPC_NL_NET_GET, 205fd3cf2adSRichard Alpe .dumpit = tipc_nl_net_dump, 206fd3cf2adSRichard Alpe .policy = tipc_nl_policy, 20727c21416SRichard Alpe }, 20827c21416SRichard Alpe { 20927c21416SRichard Alpe .cmd = TIPC_NL_NET_SET, 21027c21416SRichard Alpe .doit = tipc_nl_net_set, 21127c21416SRichard Alpe .policy = tipc_nl_policy, 2121593123aSRichard Alpe }, 2131593123aSRichard Alpe { 2141593123aSRichard Alpe .cmd = TIPC_NL_NAME_TABLE_GET, 2151593123aSRichard Alpe .dumpit = tipc_nl_name_table_dump, 2161593123aSRichard Alpe .policy = tipc_nl_policy, 2170655f6a8SRichard Alpe } 2180655f6a8SRichard Alpe }; 2190655f6a8SRichard Alpe 2201a1a143dSRichard Alpe int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr) 2211a1a143dSRichard Alpe { 222bfb3e5ddSRichard Alpe u32 maxattr = tipc_genl_family.maxattr; 2231a1a143dSRichard Alpe 224bfb3e5ddSRichard Alpe *attr = tipc_genl_family.attrbuf; 2251a1a143dSRichard Alpe if (!*attr) 2261a1a143dSRichard Alpe return -EOPNOTSUPP; 2271a1a143dSRichard Alpe 2281a1a143dSRichard Alpe return nlmsg_parse(nlh, GENL_HDRLEN, *attr, maxattr, tipc_nl_policy); 2291a1a143dSRichard Alpe } 2301a1a143dSRichard Alpe 2314323add6SPer Liden int tipc_netlink_start(void) 232b97bf3fdSPer Liden { 233acb0a200SMichał Mirosław int res; 234b70e4f45SJon Maloy 235bfb3e5ddSRichard Alpe res = genl_register_family_with_ops(&tipc_genl_family, 2360655f6a8SRichard Alpe tipc_genl_v2_ops); 2370655f6a8SRichard Alpe if (res) { 2382cf8aa19SErik Hugne pr_err("Failed to register netlink interface\n"); 239acb0a200SMichał Mirosław return res; 240acb0a200SMichał Mirosław } 241acb0a200SMichał Mirosław return 0; 242b97bf3fdSPer Liden } 243b97bf3fdSPer Liden 2444323add6SPer Liden void tipc_netlink_stop(void) 245b97bf3fdSPer Liden { 246acb0a200SMichał Mirosław genl_unregister_family(&tipc_genl_family); 247b97bf3fdSPer Liden } 248