aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/tipc/Makefile4
-rw-r--r--net/tipc/bcast.c2
-rw-r--r--net/tipc/bearer.c4
-rw-r--r--net/tipc/core.c7
-rw-r--r--net/tipc/core.h1
-rw-r--r--net/tipc/link.c2
-rw-r--r--net/tipc/name_table.c2
-rw-r--r--net/tipc/net.c2
-rw-r--r--net/tipc/netlink.c67
-rw-r--r--net/tipc/netlink.h4
-rw-r--r--net/tipc/netlink_compat.c105
-rw-r--r--net/tipc/node.c2
-rw-r--r--net/tipc/socket.c4
13 files changed, 130 insertions, 76 deletions
diff --git a/net/tipc/Makefile b/net/tipc/Makefile
index 333e4592772c..69b82bbc60d3 100644
--- a/net/tipc/Makefile
+++ b/net/tipc/Makefile
@@ -7,8 +7,8 @@ obj-$(CONFIG_TIPC) := tipc.o
7tipc-y += addr.o bcast.o bearer.o config.o \ 7tipc-y += addr.o bcast.o bearer.o config.o \
8 core.o link.o discover.o msg.o \ 8 core.o link.o discover.o msg.o \
9 name_distr.o subscr.o name_table.o net.o \ 9 name_distr.o subscr.o name_table.o net.o \
10 netlink.o node.o socket.o log.o eth_media.o \ 10 netlink.o netlink_compat.o node.o socket.o log.o eth_media.o \
11 server.o 11 server.o socket.o
12 12
13tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o 13tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o
14tipc-$(CONFIG_SYSCTL) += sysctl.o 14tipc-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 81b1fef1f5e0..e96fd6a6d5c2 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -810,7 +810,7 @@ int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg)
810 810
811 tipc_bclink_lock(net); 811 tipc_bclink_lock(net);
812 812
813 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, 813 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
814 NLM_F_MULTI, TIPC_NL_LINK_GET); 814 NLM_F_MULTI, TIPC_NL_LINK_GET);
815 if (!hdr) 815 if (!hdr)
816 return -EMSGSIZE; 816 return -EMSGSIZE;
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 33dc3486d16c..35d400e8c2e5 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -658,7 +658,7 @@ static int __tipc_nl_add_bearer(struct tipc_nl_msg *msg,
658 struct nlattr *attrs; 658 struct nlattr *attrs;
659 struct nlattr *prop; 659 struct nlattr *prop;
660 660
661 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, 661 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
662 NLM_F_MULTI, TIPC_NL_BEARER_GET); 662 NLM_F_MULTI, TIPC_NL_BEARER_GET);
663 if (!hdr) 663 if (!hdr)
664 return -EMSGSIZE; 664 return -EMSGSIZE;
@@ -924,7 +924,7 @@ static int __tipc_nl_add_media(struct tipc_nl_msg *msg,
924 struct nlattr *attrs; 924 struct nlattr *attrs;
925 struct nlattr *prop; 925 struct nlattr *prop;
926 926
927 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, 927 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
928 NLM_F_MULTI, TIPC_NL_MEDIA_GET); 928 NLM_F_MULTI, TIPC_NL_MEDIA_GET);
929 if (!hdr) 929 if (!hdr)
930 return -EMSGSIZE; 930 return -EMSGSIZE;
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 674bd2698528..2d06d1f8b6e6 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -111,6 +111,10 @@ static int __init tipc_init(void)
111 if (err) 111 if (err)
112 goto out_netlink; 112 goto out_netlink;
113 113
114 err = tipc_netlink_compat_start();
115 if (err)
116 goto out_netlink_compat;
117
114 err = tipc_socket_init(); 118 err = tipc_socket_init();
115 if (err) 119 if (err)
116 goto out_socket; 120 goto out_socket;
@@ -136,6 +140,8 @@ out_pernet:
136out_sysctl: 140out_sysctl:
137 tipc_socket_stop(); 141 tipc_socket_stop();
138out_socket: 142out_socket:
143 tipc_netlink_compat_stop();
144out_netlink_compat:
139 tipc_netlink_stop(); 145 tipc_netlink_stop();
140out_netlink: 146out_netlink:
141 pr_err("Unable to start in single node mode\n"); 147 pr_err("Unable to start in single node mode\n");
@@ -146,6 +152,7 @@ static void __exit tipc_exit(void)
146{ 152{
147 tipc_bearer_cleanup(); 153 tipc_bearer_cleanup();
148 tipc_netlink_stop(); 154 tipc_netlink_stop();
155 tipc_netlink_compat_stop();
149 tipc_socket_stop(); 156 tipc_socket_stop();
150 tipc_unregister_sysctl(); 157 tipc_unregister_sysctl();
151 unregister_pernet_subsys(&tipc_net_ops); 158 unregister_pernet_subsys(&tipc_net_ops);
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 817b2e9d4227..451c346fd3cf 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -115,5 +115,4 @@ void tipc_unregister_sysctl(void);
115#define tipc_register_sysctl() 0 115#define tipc_register_sysctl() 0
116#define tipc_unregister_sysctl() 116#define tipc_unregister_sysctl()
117#endif 117#endif
118
119#endif 118#endif
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 942491234099..466f28fcf215 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2498,7 +2498,7 @@ static int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg,
2498 struct nlattr *prop; 2498 struct nlattr *prop;
2499 struct tipc_net *tn = net_generic(net, tipc_net_id); 2499 struct tipc_net *tn = net_generic(net, tipc_net_id);
2500 2500
2501 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, 2501 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
2502 NLM_F_MULTI, TIPC_NL_LINK_GET); 2502 NLM_F_MULTI, TIPC_NL_LINK_GET);
2503 if (!hdr) 2503 if (!hdr)
2504 return -EMSGSIZE; 2504 return -EMSGSIZE;
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 18a3d44238bc..2251912264a2 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -1055,7 +1055,7 @@ static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg,
1055 *last_publ = p->key; 1055 *last_publ = p->key;
1056 1056
1057 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, 1057 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq,
1058 &tipc_genl_v2_family, NLM_F_MULTI, 1058 &tipc_genl_family, NLM_F_MULTI,
1059 TIPC_NL_NAME_TABLE_GET); 1059 TIPC_NL_NAME_TABLE_GET);
1060 if (!hdr) 1060 if (!hdr)
1061 return -EMSGSIZE; 1061 return -EMSGSIZE;
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 263267e0e7fe..8b0fb0966628 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -156,7 +156,7 @@ static int __tipc_nl_add_net(struct net *net, struct tipc_nl_msg *msg)
156 void *hdr; 156 void *hdr;
157 struct nlattr *attrs; 157 struct nlattr *attrs;
158 158
159 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, 159 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
160 NLM_F_MULTI, TIPC_NL_NET_GET); 160 NLM_F_MULTI, TIPC_NL_NET_GET);
161 if (!hdr) 161 if (!hdr)
162 return -EMSGSIZE; 162 return -EMSGSIZE;
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index fe0f5134ce15..7f6475efc984 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -35,7 +35,6 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "config.h"
39#include "socket.h" 38#include "socket.h"
40#include "name_table.h" 39#include "name_table.h"
41#include "bearer.h" 40#include "bearer.h"
@@ -44,39 +43,6 @@
44#include "net.h" 43#include "net.h"
45#include <net/genetlink.h> 44#include <net/genetlink.h>
46 45
47static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
48{
49 struct net *net = genl_info_net(info);
50 struct sk_buff *rep_buf;
51 struct nlmsghdr *rep_nlh;
52 struct nlmsghdr *req_nlh = info->nlhdr;
53 struct tipc_genlmsghdr *req_userhdr = info->userhdr;
54 int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN);
55 u16 cmd;
56
57 if ((req_userhdr->cmd & 0xC000) &&
58 (!netlink_net_capable(skb, CAP_NET_ADMIN)))
59 cmd = TIPC_CMD_NOT_NET_ADMIN;
60 else
61 cmd = req_userhdr->cmd;
62
63 rep_buf = tipc_cfg_do_cmd(net, req_userhdr->dest, cmd,
64 nlmsg_data(req_nlh) + GENL_HDRLEN +
65 TIPC_GENL_HDRLEN,
66 nlmsg_attrlen(req_nlh, GENL_HDRLEN +
67 TIPC_GENL_HDRLEN), hdr_space);
68
69 if (rep_buf) {
70 skb_push(rep_buf, hdr_space);
71 rep_nlh = nlmsg_hdr(rep_buf);
72 memcpy(rep_nlh, req_nlh, hdr_space);
73 rep_nlh->nlmsg_len = rep_buf->len;
74 genlmsg_unicast(net, rep_buf, NETLINK_CB(skb).portid);
75 }
76
77 return 0;
78}
79
80static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { 46static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
81 [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, 47 [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, },
82 [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, 48 [TIPC_NLA_BEARER] = { .type = NLA_NESTED, },
@@ -89,28 +55,10 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
89 [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, } 55 [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, }
90}; 56};
91 57
92/* Legacy ASCII API */
93static struct genl_family tipc_genl_family = {
94 .id = GENL_ID_GENERATE,
95 .name = TIPC_GENL_NAME,
96 .version = TIPC_GENL_VERSION,
97 .hdrsize = TIPC_GENL_HDRLEN,
98 .maxattr = 0,
99 .netnsok = true,
100};
101
102/* Legacy ASCII API */
103static struct genl_ops tipc_genl_ops[] = {
104 {
105 .cmd = TIPC_GENL_CMD,
106 .doit = handle_cmd,
107 },
108};
109
110/* Users of the legacy API (tipc-config) can't handle that we add operations, 58/* Users of the legacy API (tipc-config) can't handle that we add operations,
111 * so we have a separate genl handling for the new API. 59 * so we have a separate genl handling for the new API.
112 */ 60 */
113struct genl_family tipc_genl_v2_family = { 61struct genl_family tipc_genl_family = {
114 .id = GENL_ID_GENERATE, 62 .id = GENL_ID_GENERATE,
115 .name = TIPC_GENL_V2_NAME, 63 .name = TIPC_GENL_V2_NAME,
116 .version = TIPC_GENL_V2_VERSION, 64 .version = TIPC_GENL_V2_VERSION,
@@ -202,9 +150,9 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
202 150
203int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr) 151int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr)
204{ 152{
205 u32 maxattr = tipc_genl_v2_family.maxattr; 153 u32 maxattr = tipc_genl_family.maxattr;
206 154
207 *attr = tipc_genl_v2_family.attrbuf; 155 *attr = tipc_genl_family.attrbuf;
208 if (!*attr) 156 if (!*attr)
209 return -EOPNOTSUPP; 157 return -EOPNOTSUPP;
210 158
@@ -215,13 +163,7 @@ int tipc_netlink_start(void)
215{ 163{
216 int res; 164 int res;
217 165
218 res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_ops); 166 res = genl_register_family_with_ops(&tipc_genl_family,
219 if (res) {
220 pr_err("Failed to register legacy interface\n");
221 return res;
222 }
223
224 res = genl_register_family_with_ops(&tipc_genl_v2_family,
225 tipc_genl_v2_ops); 167 tipc_genl_v2_ops);
226 if (res) { 168 if (res) {
227 pr_err("Failed to register netlink interface\n"); 169 pr_err("Failed to register netlink interface\n");
@@ -233,5 +175,4 @@ int tipc_netlink_start(void)
233void tipc_netlink_stop(void) 175void tipc_netlink_stop(void)
234{ 176{
235 genl_unregister_family(&tipc_genl_family); 177 genl_unregister_family(&tipc_genl_family);
236 genl_unregister_family(&tipc_genl_v2_family);
237} 178}
diff --git a/net/tipc/netlink.h b/net/tipc/netlink.h
index ae2f2d923a15..08a1db67b927 100644
--- a/net/tipc/netlink.h
+++ b/net/tipc/netlink.h
@@ -36,7 +36,7 @@
36#ifndef _TIPC_NETLINK_H 36#ifndef _TIPC_NETLINK_H
37#define _TIPC_NETLINK_H 37#define _TIPC_NETLINK_H
38 38
39extern struct genl_family tipc_genl_v2_family; 39extern struct genl_family tipc_genl_family;
40int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***buf); 40int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***buf);
41 41
42struct tipc_nl_msg { 42struct tipc_nl_msg {
@@ -46,6 +46,8 @@ struct tipc_nl_msg {
46}; 46};
47 47
48int tipc_netlink_start(void); 48int tipc_netlink_start(void);
49int tipc_netlink_compat_start(void);
49void tipc_netlink_stop(void); 50void tipc_netlink_stop(void);
51void tipc_netlink_compat_stop(void);
50 52
51#endif 53#endif
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
new file mode 100644
index 000000000000..f752854c8b10
--- /dev/null
+++ b/net/tipc/netlink_compat.c
@@ -0,0 +1,105 @@
1/*
2 * Copyright (c) 2014, Ericsson AB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the names of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU General Public License ("GPL") version 2 as published by the Free
19 * Software Foundation.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include "core.h"
35#include "config.h"
36#include <net/genetlink.h>
37#include <linux/tipc_config.h>
38
39static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
40{
41 struct net *net = genl_info_net(info);
42 struct sk_buff *rep_buf;
43 struct nlmsghdr *rep_nlh;
44 struct nlmsghdr *req_nlh = info->nlhdr;
45 struct tipc_genlmsghdr *req_userhdr = info->userhdr;
46 int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN);
47 u16 cmd;
48
49 if ((req_userhdr->cmd & 0xC000) &&
50 (!netlink_net_capable(skb, CAP_NET_ADMIN)))
51 cmd = TIPC_CMD_NOT_NET_ADMIN;
52 else
53 cmd = req_userhdr->cmd;
54
55 rep_buf = tipc_cfg_do_cmd(net, req_userhdr->dest, cmd,
56 nlmsg_data(req_nlh) + GENL_HDRLEN +
57 TIPC_GENL_HDRLEN,
58 nlmsg_attrlen(req_nlh, GENL_HDRLEN +
59 TIPC_GENL_HDRLEN), hdr_space);
60
61 if (rep_buf) {
62 skb_push(rep_buf, hdr_space);
63 rep_nlh = nlmsg_hdr(rep_buf);
64 memcpy(rep_nlh, req_nlh, hdr_space);
65 rep_nlh->nlmsg_len = rep_buf->len;
66 genlmsg_unicast(net, rep_buf, NETLINK_CB(skb).portid);
67 }
68
69 return 0;
70}
71
72static struct genl_family tipc_genl_compat_family = {
73 .id = GENL_ID_GENERATE,
74 .name = TIPC_GENL_NAME,
75 .version = TIPC_GENL_VERSION,
76 .hdrsize = TIPC_GENL_HDRLEN,
77 .maxattr = 0,
78 .netnsok = true,
79};
80
81static struct genl_ops tipc_genl_compat_ops[] = {
82 {
83 .cmd = TIPC_GENL_CMD,
84 .doit = handle_cmd,
85 },
86};
87
88int tipc_netlink_compat_start(void)
89{
90 int res;
91
92 res = genl_register_family_with_ops(&tipc_genl_compat_family,
93 tipc_genl_compat_ops);
94 if (res) {
95 pr_err("Failed to register legacy compat interface\n");
96 return res;
97 }
98
99 return 0;
100}
101
102void tipc_netlink_compat_stop(void)
103{
104 genl_unregister_family(&tipc_genl_compat_family);
105}
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 52308498f208..995618d6da9d 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -623,7 +623,7 @@ static int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node)
623 void *hdr; 623 void *hdr;
624 struct nlattr *attrs; 624 struct nlattr *attrs;
625 625
626 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, 626 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
627 NLM_F_MULTI, TIPC_NL_NODE_GET); 627 NLM_F_MULTI, TIPC_NL_NODE_GET);
628 if (!hdr) 628 if (!hdr)
629 return -EMSGSIZE; 629 return -EMSGSIZE;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 4a98d15a1323..d76c171f7b7e 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2783,7 +2783,7 @@ static int __tipc_nl_add_sk(struct sk_buff *skb, struct netlink_callback *cb,
2783 struct tipc_net *tn = net_generic(net, tipc_net_id); 2783 struct tipc_net *tn = net_generic(net, tipc_net_id);
2784 2784
2785 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 2785 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
2786 &tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_SOCK_GET); 2786 &tipc_genl_family, NLM_F_MULTI, TIPC_NL_SOCK_GET);
2787 if (!hdr) 2787 if (!hdr)
2788 goto msg_cancel; 2788 goto msg_cancel;
2789 2789
@@ -2864,7 +2864,7 @@ static int __tipc_nl_add_sk_publ(struct sk_buff *skb,
2864 struct nlattr *attrs; 2864 struct nlattr *attrs;
2865 2865
2866 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 2866 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
2867 &tipc_genl_v2_family, NLM_F_MULTI, TIPC_NL_PUBL_GET); 2867 &tipc_genl_family, NLM_F_MULTI, TIPC_NL_PUBL_GET);
2868 if (!hdr) 2868 if (!hdr)
2869 goto msg_cancel; 2869 goto msg_cancel;
2870 2870