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" 44832629caSRichard Alpe #include "udp_media.h" 45b97bf3fdSPer Liden #include <net/genetlink.h> 46b97bf3fdSPer Liden 470655f6a8SRichard Alpe static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { 480655f6a8SRichard Alpe [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, 490655f6a8SRichard Alpe [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, 5034b78a12SRichard Alpe [TIPC_NLA_SOCK] = { .type = NLA_NESTED, }, 517be57fc6SRichard Alpe [TIPC_NLA_PUBL] = { .type = NLA_NESTED, }, 527be57fc6SRichard Alpe [TIPC_NLA_LINK] = { .type = NLA_NESTED, }, 5346f15c67SRichard Alpe [TIPC_NLA_MEDIA] = { .type = NLA_NESTED, }, 54fd3cf2adSRichard Alpe [TIPC_NLA_NODE] = { .type = NLA_NESTED, }, 551593123aSRichard Alpe [TIPC_NLA_NET] = { .type = NLA_NESTED, }, 567b3f5229SParthasarathy Bhuvaragan [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, }, 577b3f5229SParthasarathy Bhuvaragan [TIPC_NLA_MON] = { .type = NLA_NESTED, }, 580655f6a8SRichard Alpe }; 590655f6a8SRichard Alpe 6049cc66eaSRichard Alpe const struct nla_policy 6149cc66eaSRichard Alpe tipc_nl_name_table_policy[TIPC_NLA_NAME_TABLE_MAX + 1] = { 6249cc66eaSRichard Alpe [TIPC_NLA_NAME_TABLE_UNSPEC] = { .type = NLA_UNSPEC }, 6349cc66eaSRichard Alpe [TIPC_NLA_NAME_TABLE_PUBL] = { .type = NLA_NESTED } 6449cc66eaSRichard Alpe }; 6549cc66eaSRichard Alpe 667b3f5229SParthasarathy Bhuvaragan const struct nla_policy tipc_nl_monitor_policy[TIPC_NLA_MON_MAX + 1] = { 677b3f5229SParthasarathy Bhuvaragan [TIPC_NLA_MON_UNSPEC] = { .type = NLA_UNSPEC }, 68cf6f7e1dSParthasarathy Bhuvaragan [TIPC_NLA_MON_REF] = { .type = NLA_U32 }, 697b3f5229SParthasarathy Bhuvaragan [TIPC_NLA_MON_ACTIVATION_THRESHOLD] = { .type = NLA_U32 }, 707b3f5229SParthasarathy Bhuvaragan }; 717b3f5229SParthasarathy Bhuvaragan 7249cc66eaSRichard Alpe const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = { 7349cc66eaSRichard Alpe [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC }, 7449cc66eaSRichard Alpe [TIPC_NLA_SOCK_ADDR] = { .type = NLA_U32 }, 7549cc66eaSRichard Alpe [TIPC_NLA_SOCK_REF] = { .type = NLA_U32 }, 7649cc66eaSRichard Alpe [TIPC_NLA_SOCK_CON] = { .type = NLA_NESTED }, 7749cc66eaSRichard Alpe [TIPC_NLA_SOCK_HAS_PUBL] = { .type = NLA_FLAG } 7849cc66eaSRichard Alpe }; 7949cc66eaSRichard Alpe 8049cc66eaSRichard Alpe const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { 8149cc66eaSRichard Alpe [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC }, 82ec518f21SEric Dumazet [TIPC_NLA_NET_ID] = { .type = NLA_U32 }, 83ec518f21SEric Dumazet [TIPC_NLA_NET_ADDR] = { .type = NLA_U32 }, 84c6404122SEric Dumazet [TIPC_NLA_NET_NODEID] = { .type = NLA_U64 }, 85c6404122SEric Dumazet [TIPC_NLA_NET_NODEID_W1] = { .type = NLA_U64 }, 8649cc66eaSRichard Alpe }; 8749cc66eaSRichard Alpe 8849cc66eaSRichard Alpe const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = { 8949cc66eaSRichard Alpe [TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC }, 9049cc66eaSRichard Alpe [TIPC_NLA_LINK_NAME] = { .type = NLA_STRING, 9149cc66eaSRichard Alpe .len = TIPC_MAX_LINK_NAME }, 9249cc66eaSRichard Alpe [TIPC_NLA_LINK_MTU] = { .type = NLA_U32 }, 9349cc66eaSRichard Alpe [TIPC_NLA_LINK_BROADCAST] = { .type = NLA_FLAG }, 9449cc66eaSRichard Alpe [TIPC_NLA_LINK_UP] = { .type = NLA_FLAG }, 9549cc66eaSRichard Alpe [TIPC_NLA_LINK_ACTIVE] = { .type = NLA_FLAG }, 9649cc66eaSRichard Alpe [TIPC_NLA_LINK_PROP] = { .type = NLA_NESTED }, 9749cc66eaSRichard Alpe [TIPC_NLA_LINK_STATS] = { .type = NLA_NESTED }, 9849cc66eaSRichard Alpe [TIPC_NLA_LINK_RX] = { .type = NLA_U32 }, 9949cc66eaSRichard Alpe [TIPC_NLA_LINK_TX] = { .type = NLA_U32 } 10049cc66eaSRichard Alpe }; 10149cc66eaSRichard Alpe 10249cc66eaSRichard Alpe const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = { 10349cc66eaSRichard Alpe [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC }, 10449cc66eaSRichard Alpe [TIPC_NLA_NODE_ADDR] = { .type = NLA_U32 }, 10549cc66eaSRichard Alpe [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG } 10649cc66eaSRichard Alpe }; 10749cc66eaSRichard Alpe 10849cc66eaSRichard Alpe /* Properties valid for media, bearer and link */ 10949cc66eaSRichard Alpe const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = { 11049cc66eaSRichard Alpe [TIPC_NLA_PROP_UNSPEC] = { .type = NLA_UNSPEC }, 11149cc66eaSRichard Alpe [TIPC_NLA_PROP_PRIO] = { .type = NLA_U32 }, 11249cc66eaSRichard Alpe [TIPC_NLA_PROP_TOL] = { .type = NLA_U32 }, 11302ec6cafSHoang Le [TIPC_NLA_PROP_WIN] = { .type = NLA_U32 }, 11402ec6cafSHoang Le [TIPC_NLA_PROP_BROADCAST] = { .type = NLA_U32 }, 11502ec6cafSHoang Le [TIPC_NLA_PROP_BROADCAST_RATIO] = { .type = NLA_U32 } 11649cc66eaSRichard Alpe }; 11749cc66eaSRichard Alpe 11849cc66eaSRichard Alpe const struct nla_policy tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = { 11949cc66eaSRichard Alpe [TIPC_NLA_BEARER_UNSPEC] = { .type = NLA_UNSPEC }, 12049cc66eaSRichard Alpe [TIPC_NLA_BEARER_NAME] = { .type = NLA_STRING, 12149cc66eaSRichard Alpe .len = TIPC_MAX_BEARER_NAME }, 12249cc66eaSRichard Alpe [TIPC_NLA_BEARER_PROP] = { .type = NLA_NESTED }, 12349cc66eaSRichard Alpe [TIPC_NLA_BEARER_DOMAIN] = { .type = NLA_U32 } 12449cc66eaSRichard Alpe }; 12549cc66eaSRichard Alpe 12649cc66eaSRichard Alpe const struct nla_policy tipc_nl_media_policy[TIPC_NLA_MEDIA_MAX + 1] = { 12749cc66eaSRichard Alpe [TIPC_NLA_MEDIA_UNSPEC] = { .type = NLA_UNSPEC }, 12849cc66eaSRichard Alpe [TIPC_NLA_MEDIA_NAME] = { .type = NLA_STRING }, 12949cc66eaSRichard Alpe [TIPC_NLA_MEDIA_PROP] = { .type = NLA_NESTED } 13049cc66eaSRichard Alpe }; 13149cc66eaSRichard Alpe 13249cc66eaSRichard Alpe const struct nla_policy tipc_nl_udp_policy[TIPC_NLA_UDP_MAX + 1] = { 13349cc66eaSRichard Alpe [TIPC_NLA_UDP_UNSPEC] = {.type = NLA_UNSPEC}, 13449cc66eaSRichard Alpe [TIPC_NLA_UDP_LOCAL] = {.type = NLA_BINARY, 13549cc66eaSRichard Alpe .len = sizeof(struct sockaddr_storage)}, 13649cc66eaSRichard Alpe [TIPC_NLA_UDP_REMOTE] = {.type = NLA_BINARY, 13749cc66eaSRichard Alpe .len = sizeof(struct sockaddr_storage)}, 13849cc66eaSRichard Alpe }; 13949cc66eaSRichard Alpe 1400655f6a8SRichard Alpe /* Users of the legacy API (tipc-config) can't handle that we add operations, 1410655f6a8SRichard Alpe * so we have a separate genl handling for the new API. 1420655f6a8SRichard Alpe */ 1430655f6a8SRichard Alpe static const struct genl_ops tipc_genl_v2_ops[] = { 1440655f6a8SRichard Alpe { 1450655f6a8SRichard Alpe .cmd = TIPC_NL_BEARER_DISABLE, 146ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1470655f6a8SRichard Alpe .doit = tipc_nl_bearer_disable, 1480655f6a8SRichard Alpe }, 1490655f6a8SRichard Alpe { 1500655f6a8SRichard Alpe .cmd = TIPC_NL_BEARER_ENABLE, 151ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1520655f6a8SRichard Alpe .doit = tipc_nl_bearer_enable, 15335b9dd76SRichard Alpe }, 15435b9dd76SRichard Alpe { 15535b9dd76SRichard Alpe .cmd = TIPC_NL_BEARER_GET, 156ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 15735b9dd76SRichard Alpe .doit = tipc_nl_bearer_get, 15835b9dd76SRichard Alpe .dumpit = tipc_nl_bearer_dump, 159315c00bcSRichard Alpe }, 160315c00bcSRichard Alpe { 161ef20cd4dSRichard Alpe .cmd = TIPC_NL_BEARER_ADD, 162ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 163ef20cd4dSRichard Alpe .doit = tipc_nl_bearer_add, 164ef20cd4dSRichard Alpe }, 165ef20cd4dSRichard Alpe { 166315c00bcSRichard Alpe .cmd = TIPC_NL_BEARER_SET, 167ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 168315c00bcSRichard Alpe .doit = tipc_nl_bearer_set, 16934b78a12SRichard Alpe }, 17034b78a12SRichard Alpe { 17134b78a12SRichard Alpe .cmd = TIPC_NL_SOCK_GET, 172ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1739a07efa9SCong Wang .start = tipc_dump_start, 17434b78a12SRichard Alpe .dumpit = tipc_nl_sk_dump, 1759a07efa9SCong Wang .done = tipc_dump_done, 1761a1a143dSRichard Alpe }, 1771a1a143dSRichard Alpe { 1781a1a143dSRichard Alpe .cmd = TIPC_NL_PUBL_GET, 179*057af707SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | 180*057af707SJiri Pirko GENL_DONT_VALIDATE_DUMP_STRICT, 1811a1a143dSRichard Alpe .dumpit = tipc_nl_publ_dump, 1827be57fc6SRichard Alpe }, 1837be57fc6SRichard Alpe { 1847be57fc6SRichard Alpe .cmd = TIPC_NL_LINK_GET, 185ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1865be9c086SJon Paul Maloy .doit = tipc_nl_node_get_link, 18738206d59SJon Paul Maloy .dumpit = tipc_nl_node_dump_link, 188f96ce7a2SRichard Alpe }, 189f96ce7a2SRichard Alpe { 190f96ce7a2SRichard Alpe .cmd = TIPC_NL_LINK_SET, 191ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1925be9c086SJon Paul Maloy .doit = tipc_nl_node_set_link, 193ae36342bSRichard Alpe }, 194ae36342bSRichard Alpe { 195ae36342bSRichard Alpe .cmd = TIPC_NL_LINK_RESET_STATS, 196ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1975be9c086SJon Paul Maloy .doit = tipc_nl_node_reset_link_stats, 19846f15c67SRichard Alpe }, 19946f15c67SRichard Alpe { 20046f15c67SRichard Alpe .cmd = TIPC_NL_MEDIA_GET, 201ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 20246f15c67SRichard Alpe .doit = tipc_nl_media_get, 20346f15c67SRichard Alpe .dumpit = tipc_nl_media_dump, 2041e55417dSRichard Alpe }, 2051e55417dSRichard Alpe { 2061e55417dSRichard Alpe .cmd = TIPC_NL_MEDIA_SET, 207ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2081e55417dSRichard Alpe .doit = tipc_nl_media_set, 2093e4b6ab5SRichard Alpe }, 2103e4b6ab5SRichard Alpe { 2113e4b6ab5SRichard Alpe .cmd = TIPC_NL_NODE_GET, 212ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2133e4b6ab5SRichard Alpe .dumpit = tipc_nl_node_dump, 214fd3cf2adSRichard Alpe }, 215fd3cf2adSRichard Alpe { 216fd3cf2adSRichard Alpe .cmd = TIPC_NL_NET_GET, 217ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 218fd3cf2adSRichard Alpe .dumpit = tipc_nl_net_dump, 21927c21416SRichard Alpe }, 22027c21416SRichard Alpe { 22127c21416SRichard Alpe .cmd = TIPC_NL_NET_SET, 222ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 22327c21416SRichard Alpe .doit = tipc_nl_net_set, 2241593123aSRichard Alpe }, 2251593123aSRichard Alpe { 2261593123aSRichard Alpe .cmd = TIPC_NL_NAME_TABLE_GET, 227ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2281593123aSRichard Alpe .dumpit = tipc_nl_name_table_dump, 2297b3f5229SParthasarathy Bhuvaragan }, 2307b3f5229SParthasarathy Bhuvaragan { 2317b3f5229SParthasarathy Bhuvaragan .cmd = TIPC_NL_MON_SET, 232ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2337b3f5229SParthasarathy Bhuvaragan .doit = tipc_nl_node_set_monitor, 2347b3f5229SParthasarathy Bhuvaragan }, 235bf1035b2SParthasarathy Bhuvaragan { 236bf1035b2SParthasarathy Bhuvaragan .cmd = TIPC_NL_MON_GET, 237ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 238bf1035b2SParthasarathy Bhuvaragan .doit = tipc_nl_node_get_monitor, 239cf6f7e1dSParthasarathy Bhuvaragan .dumpit = tipc_nl_node_dump_monitor, 240cf6f7e1dSParthasarathy Bhuvaragan }, 241cf6f7e1dSParthasarathy Bhuvaragan { 242cf6f7e1dSParthasarathy Bhuvaragan .cmd = TIPC_NL_MON_PEER_GET, 243*057af707SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | 244*057af707SJiri Pirko GENL_DONT_VALIDATE_DUMP_STRICT, 245cf6f7e1dSParthasarathy Bhuvaragan .dumpit = tipc_nl_node_dump_monitor_peer, 246bf1035b2SParthasarathy Bhuvaragan }, 247b3404022SRichard Alpe { 248b3404022SRichard Alpe .cmd = TIPC_NL_PEER_REMOVE, 249ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 250b3404022SRichard Alpe .doit = tipc_nl_peer_rm, 251832629caSRichard Alpe }, 252832629caSRichard Alpe #ifdef CONFIG_TIPC_MEDIA_UDP 253832629caSRichard Alpe { 254832629caSRichard Alpe .cmd = TIPC_NL_UDP_GET_REMOTEIP, 255*057af707SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | 256*057af707SJiri Pirko GENL_DONT_VALIDATE_DUMP_STRICT, 257832629caSRichard Alpe .dumpit = tipc_udp_nl_dump_remoteip, 258832629caSRichard Alpe }, 259832629caSRichard Alpe #endif 2600655f6a8SRichard Alpe }; 2610655f6a8SRichard Alpe 26256989f6dSJohannes Berg struct genl_family tipc_genl_family __ro_after_init = { 263489111e5SJohannes Berg .name = TIPC_GENL_V2_NAME, 264489111e5SJohannes Berg .version = TIPC_GENL_V2_VERSION, 265489111e5SJohannes Berg .hdrsize = 0, 266489111e5SJohannes Berg .maxattr = TIPC_NLA_MAX, 2673b0f31f2SJohannes Berg .policy = tipc_nl_policy, 268489111e5SJohannes Berg .netnsok = true, 269489111e5SJohannes Berg .module = THIS_MODULE, 270489111e5SJohannes Berg .ops = tipc_genl_v2_ops, 271489111e5SJohannes Berg .n_ops = ARRAY_SIZE(tipc_genl_v2_ops), 272489111e5SJohannes Berg }; 273489111e5SJohannes Berg 2741a1a143dSRichard Alpe int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr) 2751a1a143dSRichard Alpe { 276bfb3e5ddSRichard Alpe u32 maxattr = tipc_genl_family.maxattr; 2771a1a143dSRichard Alpe 278c90c39daSJohannes Berg *attr = genl_family_attrbuf(&tipc_genl_family); 2791a1a143dSRichard Alpe if (!*attr) 2801a1a143dSRichard Alpe return -EOPNOTSUPP; 2811a1a143dSRichard Alpe 2828cb08174SJohannes Berg return nlmsg_parse_deprecated(nlh, GENL_HDRLEN, *attr, maxattr, 2838cb08174SJohannes Berg tipc_nl_policy, NULL); 2841a1a143dSRichard Alpe } 2851a1a143dSRichard Alpe 28656989f6dSJohannes Berg int __init tipc_netlink_start(void) 287b97bf3fdSPer Liden { 288acb0a200SMichał Mirosław int res; 289b70e4f45SJon Maloy 290489111e5SJohannes Berg res = genl_register_family(&tipc_genl_family); 2910655f6a8SRichard Alpe if (res) { 2922cf8aa19SErik Hugne pr_err("Failed to register netlink interface\n"); 293acb0a200SMichał Mirosław return res; 294acb0a200SMichał Mirosław } 295acb0a200SMichał Mirosław return 0; 296b97bf3fdSPer Liden } 297b97bf3fdSPer Liden 2984323add6SPer Liden void tipc_netlink_stop(void) 299b97bf3fdSPer Liden { 300acb0a200SMichał Mirosław genl_unregister_family(&tipc_genl_family); 301b97bf3fdSPer Liden } 302