diff options
author | David S. Miller <davem@davemloft.net> | 2015-02-09 16:20:53 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-02-09 16:20:53 -0500 |
commit | 9dce285b70c157754d753203112cfef22770b1f9 (patch) | |
tree | 4859799a8311ecd637e2a582600af1057a78e08b /net/tipc/netlink.c | |
parent | c8ac18f2006b2926ce375c01646b2f487d1c33b2 (diff) | |
parent | 941787b82982b3f33ac398c8c00035ddd0f8c514 (diff) |
Merge branch 'tipc-next'
Richard Alpe says:
====================
tipc: new compat layer for the legacy NL API
This is a compatibility / transcoding layer for the old netlink API.
It relies on the new netlink API to collect data or perform actions
(dumpit / doit).
The main benefit of this compat layer is that it removes a lot of
complex code from the tipc core as only the new API needs to be able
harness data or perform actions. I.e. the compat layer isn't concerned
with locking or how the internal data-structures look. As long as the
new API stays relatively intact the compat layer should be fine.
The main challenge in this compat layer is the randomness of the legacy
API. Some commands send binary data and some send ASCII data, some are
very picky in optimizing there buffer sizes and some just don't care.
Most legacy commands put there data in a single TLV (data container) but some
segment the data into multiple TLV's. This list of randomness goes on and on..
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/netlink.c')
-rw-r--r-- | net/tipc/netlink.c | 67 |
1 files changed, 4 insertions, 63 deletions
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 | ||
47 | static 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 | |||
80 | static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { | 46 | static 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 */ | ||
93 | static 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 */ | ||
103 | static 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 | */ |
113 | struct genl_family tipc_genl_v2_family = { | 61 | struct 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 | ||
203 | int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr) | 151 | int 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) | |||
233 | void tipc_netlink_stop(void) | 175 | void 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 | } |