aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/netlink.c')
-rw-r--r--net/tipc/netlink.c133
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
41static int handle_cmd(struct sk_buff *skb, struct genl_info *info) 47static 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
77static 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 */
71static struct genl_family tipc_genl_family = { 90static 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 */
79static struct genl_ops tipc_genl_ops[] = { 99static 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 */
109struct 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
117static 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
198int 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
86int tipc_netlink_start(void) 209int 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)
98void tipc_netlink_stop(void) 228void 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}