]> git.proxmox.com Git - mirror_ovs.git/blame - datapath/brcompat.c
datapath: Reformat copyright messages.
[mirror_ovs.git] / datapath / brcompat.c
CommitLineData
a14bc59f 1/*
a9a29d22 2 * Copyright (c) 2007-2011 Nicira Networks.
a14bc59f 3 *
a9a29d22
JG
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301, USA
a14bc59f
BP
17 */
18
dfffaef1
JP
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
143af30e 21#include <linux/module.h>
064af421 22#include <linux/kernel.h>
6455100f 23#include <linux/uaccess.h>
064af421 24#include <linux/completion.h>
064af421
BP
25#include <linux/etherdevice.h>
26#include <linux/if_bridge.h>
064af421
BP
27#include <linux/netdevice.h>
28#include <linux/rtnetlink.h>
29#include <net/genetlink.h>
30
064af421 31#include "openvswitch/brcompat-netlink.h"
064af421 32#include "datapath.h"
064af421
BP
33
34static struct genl_family brc_genl_family;
35static struct genl_multicast_group brc_mc_group;
36
37/* Time to wait for ovs-vswitchd to respond to a datapath action, in
38 * jiffies. */
39#define BRC_TIMEOUT (HZ * 5)
40
41/* Mutex to serialize ovs-brcompatd callbacks. (Some callbacks naturally hold
42 * br_ioctl_mutex, others hold rtnl_lock, but we can't take the former
43 * ourselves and we don't want to hold the latter over a potentially long
44 * period of time.) */
45static DEFINE_MUTEX(brc_serial);
46
47/* Userspace communication. */
48static DEFINE_SPINLOCK(brc_lock); /* Ensure atomic access to these vars. */
49static DECLARE_COMPLETION(brc_done); /* Userspace signaled operation done? */
e5307f55 50static struct sk_buff *brc_reply; /* Reply from userspace. */
064af421
BP
51static u32 brc_seq; /* Sequence number for current op. */
52
6455100f
PS
53static struct sk_buff *brc_send_command(struct sk_buff *,
54 struct nlattr **attrs);
e5307f55 55static int brc_send_simple_command(struct sk_buff *);
064af421 56
fceb2a5b
JG
57static struct sk_buff *brc_make_request(int op, const char *bridge,
58 const char *port)
e5307f55
BP
59{
60 struct sk_buff *skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
61 if (!skb)
62 goto error;
63
64 genlmsg_put(skb, 0, 0, &brc_genl_family, 0, op);
db322751
BP
65 if (bridge)
66 NLA_PUT_STRING(skb, BRC_GENL_A_DP_NAME, bridge);
e5307f55
BP
67 if (port)
68 NLA_PUT_STRING(skb, BRC_GENL_A_PORT_NAME, port);
69 return skb;
70
71nla_put_failure:
72 kfree_skb(skb);
73error:
74 return NULL;
75}
76
77static int brc_send_simple_command(struct sk_buff *request)
78{
79 struct nlattr *attrs[BRC_GENL_A_MAX + 1];
80 struct sk_buff *reply;
81 int error;
82
83 reply = brc_send_command(request, attrs);
84 if (IS_ERR(reply))
85 return PTR_ERR(reply);
86
87 error = nla_get_u32(attrs[BRC_GENL_A_ERR_CODE]);
88 kfree_skb(reply);
89 return -error;
90}
91
064af421
BP
92static int brc_add_del_bridge(char __user *uname, int add)
93{
e5307f55 94 struct sk_buff *request;
064af421
BP
95 char name[IFNAMSIZ];
96
bbf4f269
VBR
97 if (!capable(CAP_NET_ADMIN))
98 return -EPERM;
99
064af421
BP
100 if (copy_from_user(name, uname, IFNAMSIZ))
101 return -EFAULT;
102
103 name[IFNAMSIZ - 1] = 0;
e5307f55
BP
104 request = brc_make_request(add ? BRC_GENL_C_DP_ADD : BRC_GENL_C_DP_DEL,
105 name, NULL);
106 if (!request)
107 return -ENOMEM;
108
109 return brc_send_simple_command(request);
064af421
BP
110}
111
db322751
BP
112static int brc_get_indices(int op, const char *br_name,
113 int __user *uindices, int n)
064af421 114{
db322751
BP
115 struct nlattr *attrs[BRC_GENL_A_MAX + 1];
116 struct sk_buff *request, *reply;
064af421
BP
117 int *indices;
118 int ret;
db322751 119 int len;
064af421 120
db322751
BP
121 if (n < 0)
122 return -EINVAL;
064af421
BP
123 if (n >= 2048)
124 return -ENOMEM;
125
db322751
BP
126 request = brc_make_request(op, br_name, NULL);
127 if (!request)
064af421
BP
128 return -ENOMEM;
129
db322751
BP
130 reply = brc_send_command(request, attrs);
131 ret = PTR_ERR(reply);
132 if (IS_ERR(reply))
133 goto exit;
134
135 ret = -nla_get_u32(attrs[BRC_GENL_A_ERR_CODE]);
136 if (ret < 0)
137 goto exit_free_skb;
138
139 ret = -EINVAL;
140 if (!attrs[BRC_GENL_A_IFINDEXES])
141 goto exit_free_skb;
142
143 len = nla_len(attrs[BRC_GENL_A_IFINDEXES]);
144 indices = nla_data(attrs[BRC_GENL_A_IFINDEXES]);
145 if (len % sizeof(int))
146 goto exit_free_skb;
064af421 147
db322751 148 n = min_t(int, n, len / sizeof(int));
064af421
BP
149 ret = copy_to_user(uindices, indices, n * sizeof(int)) ? -EFAULT : n;
150
db322751
BP
151exit_free_skb:
152 kfree_skb(reply);
153exit:
064af421
BP
154 return ret;
155}
156
db322751
BP
157/* Called with br_ioctl_mutex. */
158static int brc_get_bridges(int __user *uindices, int n)
159{
160 return brc_get_indices(BRC_GENL_C_GET_BRIDGES, NULL, uindices, n);
161}
162
064af421 163/* Legacy deviceless bridge ioctl's. Called with br_ioctl_mutex. */
fceb2a5b 164static int old_deviceless(void __user *uarg)
064af421
BP
165{
166 unsigned long args[3];
167
168 if (copy_from_user(args, uarg, sizeof(args)))
169 return -EFAULT;
170
171 switch (args[0]) {
172 case BRCTL_GET_BRIDGES:
173 return brc_get_bridges((int __user *)args[1], args[2]);
174
175 case BRCTL_ADD_BRIDGE:
176 return brc_add_del_bridge((void __user *)args[1], 1);
177 case BRCTL_DEL_BRIDGE:
178 return brc_add_del_bridge((void __user *)args[1], 0);
179 }
180
181 return -EOPNOTSUPP;
182}
183
184/* Called with the br_ioctl_mutex. */
185static int
186#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
187brc_ioctl_deviceless_stub(unsigned int cmd, void __user *uarg)
188#else
189brc_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uarg)
190#endif
191{
192 switch (cmd) {
193 case SIOCGIFBR:
194 case SIOCSIFBR:
195 return old_deviceless(uarg);
196
197 case SIOCBRADDBR:
198 return brc_add_del_bridge(uarg, 1);
199 case SIOCBRDELBR:
200 return brc_add_del_bridge(uarg, 0);
201 }
202
203 return -EOPNOTSUPP;
204}
205
fceb2a5b 206static int brc_add_del_port(struct net_device *dev, int port_ifindex, int add)
064af421 207{
e5307f55 208 struct sk_buff *request;
064af421 209 struct net_device *port;
064af421
BP
210 int err;
211
bbf4f269
VBR
212 if (!capable(CAP_NET_ADMIN))
213 return -EPERM;
214
064af421
BP
215 port = __dev_get_by_index(&init_net, port_ifindex);
216 if (!port)
217 return -EINVAL;
218
219 /* Save name of dev and port because there's a race between the
e5307f55
BP
220 * rtnl_unlock() and the brc_send_simple_command(). */
221 request = brc_make_request(add ? BRC_GENL_C_PORT_ADD : BRC_GENL_C_PORT_DEL,
222 dev->name, port->name);
223 if (!request)
224 return -ENOMEM;
064af421
BP
225
226 rtnl_unlock();
e5307f55 227 err = brc_send_simple_command(request);
064af421
BP
228 rtnl_lock();
229
230 return err;
231}
232
fceb2a5b
JG
233static int brc_get_bridge_info(struct net_device *dev,
234 struct __bridge_info __user *ub)
064af421
BP
235{
236 struct __bridge_info b;
064af421
BP
237
238 memset(&b, 0, sizeof(struct __bridge_info));
239
6d6266e6
JG
240 /* First two bytes are the priority, which we should skip. This comes
241 * from struct bridge_id in br_private.h, which is unavailable to us.
242 */
243 memcpy((u8 *)&b.bridge_id + 2, dev->dev_addr, ETH_ALEN);
064af421
BP
244 b.stp_enabled = 0;
245
246 if (copy_to_user(ub, &b, sizeof(struct __bridge_info)))
247 return -EFAULT;
248
249 return 0;
250}
251
fceb2a5b
JG
252static int brc_get_port_list(struct net_device *dev, int __user *uindices,
253 int num)
064af421 254{
db322751 255 int retval;
064af421 256
db322751
BP
257 rtnl_unlock();
258 retval = brc_get_indices(BRC_GENL_C_GET_PORTS, dev->name,
259 uindices, num);
260 rtnl_lock();
064af421 261
db322751 262 return retval;
064af421
BP
263}
264
3c303e5f
BP
265/*
266 * Format up to a page worth of forwarding table entries
267 * userbuf -- where to copy result
268 * maxnum -- maximum number of entries desired
269 * (limited to a page for sanity)
270 * offset -- number of records to skip
271 */
d295e8e9 272static int brc_get_fdb_entries(struct net_device *dev, void __user *userbuf,
3c303e5f
BP
273 unsigned long maxnum, unsigned long offset)
274{
275 struct nlattr *attrs[BRC_GENL_A_MAX + 1];
276 struct sk_buff *request, *reply;
277 int retval;
278 int len;
279
280 /* Clamp size to PAGE_SIZE, test maxnum to avoid overflow */
281 if (maxnum > PAGE_SIZE/sizeof(struct __fdb_entry))
282 maxnum = PAGE_SIZE/sizeof(struct __fdb_entry);
283
284 request = brc_make_request(BRC_GENL_C_FDB_QUERY, dev->name, NULL);
285 if (!request)
286 return -ENOMEM;
287 NLA_PUT_U64(request, BRC_GENL_A_FDB_COUNT, maxnum);
288 NLA_PUT_U64(request, BRC_GENL_A_FDB_SKIP, offset);
289
290 rtnl_unlock();
291 reply = brc_send_command(request, attrs);
292 retval = PTR_ERR(reply);
293 if (IS_ERR(reply))
294 goto exit;
295
296 retval = -nla_get_u32(attrs[BRC_GENL_A_ERR_CODE]);
297 if (retval < 0)
298 goto exit_free_skb;
299
300 retval = -EINVAL;
301 if (!attrs[BRC_GENL_A_FDB_DATA])
302 goto exit_free_skb;
303 len = nla_len(attrs[BRC_GENL_A_FDB_DATA]);
304 if (len % sizeof(struct __fdb_entry) ||
305 len / sizeof(struct __fdb_entry) > maxnum)
306 goto exit_free_skb;
307
308 retval = len / sizeof(struct __fdb_entry);
309 if (copy_to_user(userbuf, nla_data(attrs[BRC_GENL_A_FDB_DATA]), len))
310 retval = -EFAULT;
311
312exit_free_skb:
313 kfree_skb(reply);
314exit:
315 rtnl_lock();
316 return retval;
317
318nla_put_failure:
319 kfree_skb(request);
320 return -ENOMEM;
321}
322
064af421 323/* Legacy ioctl's through SIOCDEVPRIVATE. Called with rtnl_lock. */
fceb2a5b 324static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
064af421
BP
325{
326 unsigned long args[4];
327
328 if (copy_from_user(args, rq->ifr_data, sizeof(args)))
329 return -EFAULT;
330
331 switch (args[0]) {
332 case BRCTL_ADD_IF:
333 return brc_add_del_port(dev, args[1], 1);
334 case BRCTL_DEL_IF:
335 return brc_add_del_port(dev, args[1], 0);
336
337 case BRCTL_GET_BRIDGE_INFO:
338 return brc_get_bridge_info(dev, (struct __bridge_info __user *)args[1]);
339
340 case BRCTL_GET_PORT_LIST:
341 return brc_get_port_list(dev, (int __user *)args[1], args[2]);
3c303e5f
BP
342
343 case BRCTL_GET_FDB_ENTRIES:
344 return brc_get_fdb_entries(dev, (void __user *)args[1],
345 args[2], args[3]);
064af421
BP
346 }
347
348 return -EOPNOTSUPP;
349}
350
351/* Called with the rtnl_lock. */
fceb2a5b 352static int brc_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
064af421
BP
353{
354 int err;
355
356 switch (cmd) {
6455100f
PS
357 case SIOCDEVPRIVATE:
358 err = old_dev_ioctl(dev, rq, cmd);
359 break;
360
361 case SIOCBRADDIF:
362 return brc_add_del_port(dev, rq->ifr_ifindex, 1);
363 case SIOCBRDELIF:
364 return brc_add_del_port(dev, rq->ifr_ifindex, 0);
365
366 default:
367 err = -EOPNOTSUPP;
368 break;
064af421
BP
369 }
370
371 return err;
372}
373
374
375static struct genl_family brc_genl_family = {
376 .id = GENL_ID_GENERATE,
377 .hdrsize = 0,
378 .name = BRC_GENL_FAMILY_NAME,
379 .version = 1,
380 .maxattr = BRC_GENL_A_MAX,
381};
382
383static int brc_genl_query(struct sk_buff *skb, struct genl_info *info)
384{
385 int err = -EINVAL;
386 struct sk_buff *ans_skb;
387 void *data;
388
389 ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
d295e8e9 390 if (!ans_skb)
064af421
BP
391 return -ENOMEM;
392
393 data = genlmsg_put_reply(ans_skb, info, &brc_genl_family,
394 0, BRC_GENL_C_QUERY_MC);
395 if (data == NULL) {
396 err = -ENOMEM;
397 goto err;
398 }
399 NLA_PUT_U32(ans_skb, BRC_GENL_A_MC_GROUP, brc_mc_group.id);
400
401 genlmsg_end(ans_skb, data);
402 return genlmsg_reply(ans_skb, info);
403
404err:
405nla_put_failure:
406 kfree_skb(ans_skb);
407 return err;
408}
409
064af421
BP
410/* Attribute policy: what each attribute may contain. */
411static struct nla_policy brc_genl_policy[BRC_GENL_A_MAX + 1] = {
412 [BRC_GENL_A_ERR_CODE] = { .type = NLA_U32 },
3c303e5f 413 [BRC_GENL_A_FDB_DATA] = { .type = NLA_UNSPEC },
064af421
BP
414};
415
fceb2a5b 416static int brc_genl_dp_result(struct sk_buff *skb, struct genl_info *info)
064af421
BP
417{
418 unsigned long int flags;
419 int err;
420
421 if (!info->attrs[BRC_GENL_A_ERR_CODE])
422 return -EINVAL;
423
e5307f55
BP
424 skb = skb_clone(skb, GFP_KERNEL);
425 if (!skb)
426 return -ENOMEM;
427
064af421
BP
428 spin_lock_irqsave(&brc_lock, flags);
429 if (brc_seq == info->snd_seq) {
e5307f55
BP
430 brc_seq++;
431
f2d9c30b 432 kfree_skb(brc_reply);
e5307f55
BP
433 brc_reply = skb;
434
064af421
BP
435 complete(&brc_done);
436 err = 0;
437 } else {
e5307f55 438 kfree_skb(skb);
064af421
BP
439 err = -ESTALE;
440 }
441 spin_unlock_irqrestore(&brc_lock, flags);
442
443 return err;
444}
445
e2c779b3
BP
446static struct genl_ops brc_genl_ops[] = {
447 { .cmd = BRC_GENL_C_QUERY_MC,
448 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privelege. */
449 .policy = NULL,
450 .doit = brc_genl_query,
451 },
452 { .cmd = BRC_GENL_C_DP_RESULT,
453 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privelege. */
454 .policy = brc_genl_policy,
455 .doit = brc_genl_dp_result,
456 },
064af421
BP
457};
458
fceb2a5b
JG
459static struct sk_buff *brc_send_command(struct sk_buff *request,
460 struct nlattr **attrs)
064af421
BP
461{
462 unsigned long int flags;
e5307f55 463 struct sk_buff *reply;
064af421
BP
464 int error;
465
466 mutex_lock(&brc_serial);
467
468 /* Increment sequence number first, so that we ignore any replies
469 * to stale requests. */
470 spin_lock_irqsave(&brc_lock, flags);
e5307f55 471 nlmsg_hdr(request)->nlmsg_seq = ++brc_seq;
064af421
BP
472 INIT_COMPLETION(brc_done);
473 spin_unlock_irqrestore(&brc_lock, flags);
474
e5307f55 475 nlmsg_end(request, nlmsg_hdr(request));
064af421
BP
476
477 /* Send message. */
e5307f55 478 error = genlmsg_multicast(request, 0, brc_mc_group.id, GFP_KERNEL);
064af421 479 if (error < 0)
e5307f55 480 goto error;
064af421
BP
481
482 /* Wait for reply. */
483 error = -ETIMEDOUT;
ca063bcd 484 if (!wait_for_completion_timeout(&brc_done, BRC_TIMEOUT)) {
dfffaef1 485 pr_warn("timed out waiting for userspace\n");
e5307f55 486 goto error;
6455100f 487 }
064af421 488
e5307f55
BP
489 /* Grab reply. */
490 spin_lock_irqsave(&brc_lock, flags);
491 reply = brc_reply;
492 brc_reply = NULL;
493 spin_unlock_irqrestore(&brc_lock, flags);
064af421 494
064af421 495 mutex_unlock(&brc_serial);
e5307f55
BP
496
497 /* Re-parse message. Can't fail, since it parsed correctly once
498 * already. */
499 error = nlmsg_parse(nlmsg_hdr(reply), GENL_HDRLEN,
500 attrs, BRC_GENL_A_MAX, brc_genl_policy);
501 WARN_ON(error);
502
503 return reply;
504
505error:
506 mutex_unlock(&brc_serial);
507 return ERR_PTR(error);
064af421
BP
508}
509
fceb2a5b 510static int __init brc_init(void)
064af421 511{
064af421
BP
512 int err;
513
6455100f 514 pr_info("Open vSwitch Bridge Compatibility, built "__DATE__" "__TIME__"\n");
064af421 515
064af421
BP
516 /* Set the bridge ioctl handler */
517 brioctl_set(brc_ioctl_deviceless_stub);
518
519 /* Set the openvswitch_mod device ioctl handler */
520 dp_ioctl_hook = brc_dev_ioctl;
521
064af421
BP
522 /* Randomize the initial sequence number. This is not a security
523 * feature; it only helps avoid crossed wires between userspace and
524 * the kernel when the module is unloaded and reloaded. */
525 brc_seq = net_random();
526
527 /* Register generic netlink family to communicate changes to
528 * userspace. */
e2c779b3
BP
529 err = genl_register_family_with_ops(&brc_genl_family,
530 brc_genl_ops, ARRAY_SIZE(brc_genl_ops));
064af421
BP
531 if (err)
532 goto error;
533
064af421
BP
534 strcpy(brc_mc_group.name, "brcompat");
535 err = genl_register_mc_group(&brc_genl_family, &brc_mc_group);
536 if (err < 0)
537 goto err_unregister;
538
539 return 0;
540
541err_unregister:
542 genl_unregister_family(&brc_genl_family);
543error:
dfffaef1 544 pr_emerg("failed to install!\n");
064af421
BP
545 return err;
546}
547
fceb2a5b 548static void brc_cleanup(void)
064af421 549{
064af421
BP
550 /* Unregister ioctl hooks */
551 dp_ioctl_hook = NULL;
552 brioctl_set(NULL);
553
554 genl_unregister_family(&brc_genl_family);
064af421
BP
555}
556
557module_init(brc_init);
558module_exit(brc_cleanup);
559
560MODULE_DESCRIPTION("Open vSwitch bridge compatibility");
561MODULE_AUTHOR("Nicira Networks");
562MODULE_LICENSE("GPL");