diff options
Diffstat (limited to 'net/tipc/netlink.c')
-rw-r--r-- | net/tipc/netlink.c | 133 |
1 files changed, 132 insertions, 1 deletions
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index ad844d365340..b891e3905bc4 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/netlink.c: TIPC configuration handling | 2 | * net/tipc/netlink.c: TIPC configuration handling |
3 | * | 3 | * |
4 | * Copyright (c) 2005-2006, Ericsson AB | 4 | * Copyright (c) 2005-2006, 2014, Ericsson AB |
5 | * Copyright (c) 2005-2007, Wind River Systems | 5 | * Copyright (c) 2005-2007, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -36,6 +36,12 @@ | |||
36 | 36 | ||
37 | #include "core.h" | 37 | #include "core.h" |
38 | #include "config.h" | 38 | #include "config.h" |
39 | #include "socket.h" | ||
40 | #include "name_table.h" | ||
41 | #include "bearer.h" | ||
42 | #include "link.h" | ||
43 | #include "node.h" | ||
44 | #include "net.h" | ||
39 | #include <net/genetlink.h> | 45 | #include <net/genetlink.h> |
40 | 46 | ||
41 | static int handle_cmd(struct sk_buff *skb, struct genl_info *info) | 47 | static int handle_cmd(struct sk_buff *skb, struct genl_info *info) |
@@ -68,6 +74,19 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info) | |||
68 | return 0; | 74 | return 0; |
69 | } | 75 | } |
70 | 76 | ||
77 | static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { | ||
78 | [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, | ||
79 | [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, | ||
80 | [TIPC_NLA_SOCK] = { .type = NLA_NESTED, }, | ||
81 | [TIPC_NLA_PUBL] = { .type = NLA_NESTED, }, | ||
82 | [TIPC_NLA_LINK] = { .type = NLA_NESTED, }, | ||
83 | [TIPC_NLA_MEDIA] = { .type = NLA_NESTED, }, | ||
84 | [TIPC_NLA_NODE] = { .type = NLA_NESTED, }, | ||
85 | [TIPC_NLA_NET] = { .type = NLA_NESTED, }, | ||
86 | [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, } | ||
87 | }; | ||
88 | |||
89 | /* Legacy ASCII API */ | ||
71 | static struct genl_family tipc_genl_family = { | 90 | static struct genl_family tipc_genl_family = { |
72 | .id = GENL_ID_GENERATE, | 91 | .id = GENL_ID_GENERATE, |
73 | .name = TIPC_GENL_NAME, | 92 | .name = TIPC_GENL_NAME, |
@@ -76,6 +95,7 @@ static struct genl_family tipc_genl_family = { | |||
76 | .maxattr = 0, | 95 | .maxattr = 0, |
77 | }; | 96 | }; |
78 | 97 | ||
98 | /* Legacy ASCII API */ | ||
79 | static struct genl_ops tipc_genl_ops[] = { | 99 | static struct genl_ops tipc_genl_ops[] = { |
80 | { | 100 | { |
81 | .cmd = TIPC_GENL_CMD, | 101 | .cmd = TIPC_GENL_CMD, |
@@ -83,12 +103,122 @@ static struct genl_ops tipc_genl_ops[] = { | |||
83 | }, | 103 | }, |
84 | }; | 104 | }; |
85 | 105 | ||
106 | /* Users of the legacy API (tipc-config) can't handle that we add operations, | ||
107 | * so we have a separate genl handling for the new API. | ||
108 | */ | ||
109 | struct genl_family tipc_genl_v2_family = { | ||
110 | .id = GENL_ID_GENERATE, | ||
111 | .name = TIPC_GENL_V2_NAME, | ||
112 | .version = TIPC_GENL_V2_VERSION, | ||
113 | .hdrsize = 0, | ||
114 | .maxattr = TIPC_NLA_MAX, | ||
115 | }; | ||
116 | |||
117 | static const struct genl_ops tipc_genl_v2_ops[] = { | ||
118 | { | ||
119 | .cmd = TIPC_NL_BEARER_DISABLE, | ||
120 | .doit = tipc_nl_bearer_disable, | ||
121 | .policy = tipc_nl_policy, | ||
122 | }, | ||
123 | { | ||
124 | .cmd = TIPC_NL_BEARER_ENABLE, | ||
125 | .doit = tipc_nl_bearer_enable, | ||
126 | .policy = tipc_nl_policy, | ||
127 | }, | ||
128 | { | ||
129 | .cmd = TIPC_NL_BEARER_GET, | ||
130 | .doit = tipc_nl_bearer_get, | ||
131 | .dumpit = tipc_nl_bearer_dump, | ||
132 | .policy = tipc_nl_policy, | ||
133 | }, | ||
134 | { | ||
135 | .cmd = TIPC_NL_BEARER_SET, | ||
136 | .doit = tipc_nl_bearer_set, | ||
137 | .policy = tipc_nl_policy, | ||
138 | }, | ||
139 | { | ||
140 | .cmd = TIPC_NL_SOCK_GET, | ||
141 | .dumpit = tipc_nl_sk_dump, | ||
142 | .policy = tipc_nl_policy, | ||
143 | }, | ||
144 | { | ||
145 | .cmd = TIPC_NL_PUBL_GET, | ||
146 | .dumpit = tipc_nl_publ_dump, | ||
147 | .policy = tipc_nl_policy, | ||
148 | }, | ||
149 | { | ||
150 | .cmd = TIPC_NL_LINK_GET, | ||
151 | .doit = tipc_nl_link_get, | ||
152 | .dumpit = tipc_nl_link_dump, | ||
153 | .policy = tipc_nl_policy, | ||
154 | }, | ||
155 | { | ||
156 | .cmd = TIPC_NL_LINK_SET, | ||
157 | .doit = tipc_nl_link_set, | ||
158 | .policy = tipc_nl_policy, | ||
159 | }, | ||
160 | { | ||
161 | .cmd = TIPC_NL_LINK_RESET_STATS, | ||
162 | .doit = tipc_nl_link_reset_stats, | ||
163 | .policy = tipc_nl_policy, | ||
164 | }, | ||
165 | { | ||
166 | .cmd = TIPC_NL_MEDIA_GET, | ||
167 | .doit = tipc_nl_media_get, | ||
168 | .dumpit = tipc_nl_media_dump, | ||
169 | .policy = tipc_nl_policy, | ||
170 | }, | ||
171 | { | ||
172 | .cmd = TIPC_NL_MEDIA_SET, | ||
173 | .doit = tipc_nl_media_set, | ||
174 | .policy = tipc_nl_policy, | ||
175 | }, | ||
176 | { | ||
177 | .cmd = TIPC_NL_NODE_GET, | ||
178 | .dumpit = tipc_nl_node_dump, | ||
179 | .policy = tipc_nl_policy, | ||
180 | }, | ||
181 | { | ||
182 | .cmd = TIPC_NL_NET_GET, | ||
183 | .dumpit = tipc_nl_net_dump, | ||
184 | .policy = tipc_nl_policy, | ||
185 | }, | ||
186 | { | ||
187 | .cmd = TIPC_NL_NET_SET, | ||
188 | .doit = tipc_nl_net_set, | ||
189 | .policy = tipc_nl_policy, | ||
190 | }, | ||
191 | { | ||
192 | .cmd = TIPC_NL_NAME_TABLE_GET, | ||
193 | .dumpit = tipc_nl_name_table_dump, | ||
194 | .policy = tipc_nl_policy, | ||
195 | } | ||
196 | }; | ||
197 | |||
198 | int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr) | ||
199 | { | ||
200 | u32 maxattr = tipc_genl_v2_family.maxattr; | ||
201 | |||
202 | *attr = tipc_genl_v2_family.attrbuf; | ||
203 | if (!*attr) | ||
204 | return -EOPNOTSUPP; | ||
205 | |||
206 | return nlmsg_parse(nlh, GENL_HDRLEN, *attr, maxattr, tipc_nl_policy); | ||
207 | } | ||
208 | |||
86 | int tipc_netlink_start(void) | 209 | int tipc_netlink_start(void) |
87 | { | 210 | { |
88 | int res; | 211 | int res; |
89 | 212 | ||
90 | res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_ops); | 213 | res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_ops); |
91 | if (res) { | 214 | if (res) { |
215 | pr_err("Failed to register legacy interface\n"); | ||
216 | return res; | ||
217 | } | ||
218 | |||
219 | res = genl_register_family_with_ops(&tipc_genl_v2_family, | ||
220 | tipc_genl_v2_ops); | ||
221 | if (res) { | ||
92 | pr_err("Failed to register netlink interface\n"); | 222 | pr_err("Failed to register netlink interface\n"); |
93 | return res; | 223 | return res; |
94 | } | 224 | } |
@@ -98,4 +228,5 @@ int tipc_netlink_start(void) | |||
98 | void tipc_netlink_stop(void) | 228 | void tipc_netlink_stop(void) |
99 | { | 229 | { |
100 | genl_unregister_family(&tipc_genl_family); | 230 | genl_unregister_family(&tipc_genl_family); |
231 | genl_unregister_family(&tipc_genl_v2_family); | ||
101 | } | 232 | } |