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" 38b97bf3fdSPer Liden #include "config.h" 390655f6a8SRichard Alpe #include "bearer.h" 40b97bf3fdSPer Liden #include <net/genetlink.h> 41b97bf3fdSPer Liden 42b97bf3fdSPer Liden static int handle_cmd(struct sk_buff *skb, struct genl_info *info) 43b97bf3fdSPer Liden { 44b97bf3fdSPer Liden struct sk_buff *rep_buf; 45b97bf3fdSPer Liden struct nlmsghdr *rep_nlh; 46b97bf3fdSPer Liden struct nlmsghdr *req_nlh = info->nlhdr; 47b97bf3fdSPer Liden struct tipc_genlmsghdr *req_userhdr = info->userhdr; 48573ce260SHong zhi guo int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); 4959f0c452SAllan Stephens u16 cmd; 50b97bf3fdSPer Liden 5190f62cf3SEric W. Biederman if ((req_userhdr->cmd & 0xC000) && (!netlink_capable(skb, CAP_NET_ADMIN))) 5259f0c452SAllan Stephens cmd = TIPC_CMD_NOT_NET_ADMIN; 53b97bf3fdSPer Liden else 5459f0c452SAllan Stephens cmd = req_userhdr->cmd; 5559f0c452SAllan Stephens 5659f0c452SAllan Stephens rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, cmd, 57573ce260SHong zhi guo nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN, 58573ce260SHong zhi guo nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN), 59b97bf3fdSPer Liden hdr_space); 60b97bf3fdSPer Liden 61b97bf3fdSPer Liden if (rep_buf) { 62b97bf3fdSPer Liden skb_push(rep_buf, hdr_space); 63b529ccf2SArnaldo Carvalho de Melo rep_nlh = nlmsg_hdr(rep_buf); 64b97bf3fdSPer Liden memcpy(rep_nlh, req_nlh, hdr_space); 65b97bf3fdSPer Liden rep_nlh->nlmsg_len = rep_buf->len; 6615e47304SEric W. Biederman genlmsg_unicast(&init_net, rep_buf, NETLINK_CB(skb).portid); 67b97bf3fdSPer Liden } 68b97bf3fdSPer Liden 69b97bf3fdSPer Liden return 0; 70b97bf3fdSPer Liden } 71b97bf3fdSPer Liden 720655f6a8SRichard Alpe static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { 730655f6a8SRichard Alpe [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, 740655f6a8SRichard Alpe [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, 750655f6a8SRichard Alpe }; 760655f6a8SRichard Alpe 770655f6a8SRichard Alpe /* Legacy ASCII API */ 78acb0a200SMichał Mirosław static struct genl_family tipc_genl_family = { 791dba9743SPer Liden .id = GENL_ID_GENERATE, 80b97bf3fdSPer Liden .name = TIPC_GENL_NAME, 81b97bf3fdSPer Liden .version = TIPC_GENL_VERSION, 82b97bf3fdSPer Liden .hdrsize = TIPC_GENL_HDRLEN, 83b97bf3fdSPer Liden .maxattr = 0, 84b97bf3fdSPer Liden }; 85b97bf3fdSPer Liden 860655f6a8SRichard Alpe /* Legacy ASCII API */ 87c53ed742SJohannes Berg static struct genl_ops tipc_genl_ops[] = { 88c53ed742SJohannes Berg { 89b97bf3fdSPer Liden .cmd = TIPC_GENL_CMD, 90b97bf3fdSPer Liden .doit = handle_cmd, 91c53ed742SJohannes Berg }, 92b97bf3fdSPer Liden }; 93b97bf3fdSPer Liden 940655f6a8SRichard Alpe /* Users of the legacy API (tipc-config) can't handle that we add operations, 950655f6a8SRichard Alpe * so we have a separate genl handling for the new API. 960655f6a8SRichard Alpe */ 970655f6a8SRichard Alpe struct genl_family tipc_genl_v2_family = { 980655f6a8SRichard Alpe .id = GENL_ID_GENERATE, 990655f6a8SRichard Alpe .name = TIPC_GENL_V2_NAME, 1000655f6a8SRichard Alpe .version = TIPC_GENL_V2_VERSION, 1010655f6a8SRichard Alpe .hdrsize = 0, 1020655f6a8SRichard Alpe .maxattr = TIPC_NLA_MAX, 1030655f6a8SRichard Alpe }; 1040655f6a8SRichard Alpe 1050655f6a8SRichard Alpe static const struct genl_ops tipc_genl_v2_ops[] = { 1060655f6a8SRichard Alpe { 1070655f6a8SRichard Alpe .cmd = TIPC_NL_BEARER_DISABLE, 1080655f6a8SRichard Alpe .doit = tipc_nl_bearer_disable, 1090655f6a8SRichard Alpe .policy = tipc_nl_policy, 1100655f6a8SRichard Alpe }, 1110655f6a8SRichard Alpe { 1120655f6a8SRichard Alpe .cmd = TIPC_NL_BEARER_ENABLE, 1130655f6a8SRichard Alpe .doit = tipc_nl_bearer_enable, 1140655f6a8SRichard Alpe .policy = tipc_nl_policy, 11535b9dd76SRichard Alpe }, 11635b9dd76SRichard Alpe { 11735b9dd76SRichard Alpe .cmd = TIPC_NL_BEARER_GET, 11835b9dd76SRichard Alpe .doit = tipc_nl_bearer_get, 11935b9dd76SRichard Alpe .dumpit = tipc_nl_bearer_dump, 12035b9dd76SRichard Alpe .policy = tipc_nl_policy, 121*315c00bcSRichard Alpe }, 122*315c00bcSRichard Alpe { 123*315c00bcSRichard Alpe .cmd = TIPC_NL_BEARER_SET, 124*315c00bcSRichard Alpe .doit = tipc_nl_bearer_set, 125*315c00bcSRichard Alpe .policy = tipc_nl_policy, 1260655f6a8SRichard Alpe } 1270655f6a8SRichard Alpe }; 1280655f6a8SRichard Alpe 1294323add6SPer Liden int tipc_netlink_start(void) 130b97bf3fdSPer Liden { 131acb0a200SMichał Mirosław int res; 132b70e4f45SJon Maloy 133c53ed742SJohannes Berg res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_ops); 134acb0a200SMichał Mirosław if (res) { 1350655f6a8SRichard Alpe pr_err("Failed to register legacy interface\n"); 1360655f6a8SRichard Alpe return res; 1370655f6a8SRichard Alpe } 1380655f6a8SRichard Alpe 1390655f6a8SRichard Alpe res = genl_register_family_with_ops(&tipc_genl_v2_family, 1400655f6a8SRichard Alpe tipc_genl_v2_ops); 1410655f6a8SRichard Alpe if (res) { 1422cf8aa19SErik Hugne pr_err("Failed to register netlink interface\n"); 143acb0a200SMichał Mirosław return res; 144acb0a200SMichał Mirosław } 145acb0a200SMichał Mirosław return 0; 146b97bf3fdSPer Liden } 147b97bf3fdSPer Liden 1484323add6SPer Liden void tipc_netlink_stop(void) 149b97bf3fdSPer Liden { 150acb0a200SMichał Mirosław genl_unregister_family(&tipc_genl_family); 1510655f6a8SRichard Alpe genl_unregister_family(&tipc_genl_v2_family); 152b97bf3fdSPer Liden } 153