2e437ccd9f8f6bbd47ddd0373ec2352cc57b6662
[sliver-openvswitch.git] / datapath / brcompat.c
1 #include <linux/kernel.h>
2 #include <asm/uaccess.h>
3 #include <linux/completion.h>
4 #include <linux/delay.h>
5 #include <linux/etherdevice.h>
6 #include <linux/if_bridge.h>
7 #include <linux/rculist.h>
8 #include <linux/netdevice.h>
9 #include <linux/rtnetlink.h>
10 #include <net/genetlink.h>
11
12 #include "compat.h"
13 #include "openvswitch/brcompat-netlink.h"
14 #include "brc_procfs.h"
15 #include "brc_sysfs.h"
16 #include "datapath.h"
17 #include "dp_dev.h"
18
19 static struct genl_family brc_genl_family;
20 static struct genl_multicast_group brc_mc_group;
21
22 /* Time to wait for ovs-vswitchd to respond to a datapath action, in
23  * jiffies. */
24 #define BRC_TIMEOUT (HZ * 5)
25
26 /* Mutex to serialize ovs-brcompatd callbacks.  (Some callbacks naturally hold
27  * br_ioctl_mutex, others hold rtnl_lock, but we can't take the former
28  * ourselves and we don't want to hold the latter over a potentially long
29  * period of time.) */
30 static DEFINE_MUTEX(brc_serial);
31
32 /* Userspace communication. */
33 static DEFINE_SPINLOCK(brc_lock);    /* Ensure atomic access to these vars. */
34 static DECLARE_COMPLETION(brc_done); /* Userspace signaled operation done? */
35 static int brc_err;                  /* Error code from userspace. */
36 static u32 brc_seq;                  /* Sequence number for current op. */
37
38 static int brc_send_command(const char *bridge, const char *port, int op);
39
40 static int
41 get_dp_ifindices(int *indices, int num)
42 {
43         int i, index = 0;
44
45         rcu_read_lock();
46         for (i=0; i < ODP_MAX && index < num; i++) {
47                 struct datapath *dp = get_dp(i);
48                 if (!dp)
49                         continue;
50                 indices[index++] = dp->ports[ODPP_LOCAL]->dev->ifindex;
51         }
52         rcu_read_unlock();
53
54         return index;
55 }
56
57 static void
58 get_port_ifindices(struct datapath *dp, int *ifindices, int num)
59 {
60         struct net_bridge_port *p;
61
62         rcu_read_lock();
63         list_for_each_entry_rcu (p, &dp->port_list, node) {
64                 if (p->port_no < num)
65                         ifindices[p->port_no] = p->dev->ifindex;
66         }
67         rcu_read_unlock();
68 }
69
70 static int brc_add_del_bridge(char __user *uname, int add)
71 {
72         char name[IFNAMSIZ];
73
74         if (copy_from_user(name, uname, IFNAMSIZ))
75                 return -EFAULT;
76
77         name[IFNAMSIZ - 1] = 0;
78         return brc_send_command(name, NULL,
79                                 add ? BRC_GENL_C_DP_ADD : BRC_GENL_C_DP_DEL);
80 }
81
82 static int brc_get_bridges(int __user *uindices, int n)
83 {
84         int *indices;
85         int ret;
86
87         if (n >= 2048)
88                 return -ENOMEM;
89
90         indices = kcalloc(n, sizeof(int), GFP_KERNEL);
91         if (indices == NULL)
92                 return -ENOMEM;
93
94         n = get_dp_ifindices(indices, n);
95
96         ret = copy_to_user(uindices, indices, n * sizeof(int)) ? -EFAULT : n;
97
98         kfree(indices);
99         return ret;
100 }
101
102 /* Legacy deviceless bridge ioctl's.  Called with br_ioctl_mutex. */
103 static int
104 old_deviceless(void __user *uarg)
105 {
106         unsigned long args[3];
107
108         if (copy_from_user(args, uarg, sizeof(args)))
109                 return -EFAULT;
110
111         switch (args[0]) {
112         case BRCTL_GET_BRIDGES:
113                 return brc_get_bridges((int __user *)args[1], args[2]);
114
115         case BRCTL_ADD_BRIDGE:
116                 return brc_add_del_bridge((void __user *)args[1], 1);
117         case BRCTL_DEL_BRIDGE:
118                 return brc_add_del_bridge((void __user *)args[1], 0);
119         }
120
121         return -EOPNOTSUPP;
122 }
123
124 /* Called with the br_ioctl_mutex. */
125 static int
126 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
127 brc_ioctl_deviceless_stub(unsigned int cmd, void __user *uarg)
128 #else
129 brc_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uarg)
130 #endif
131 {
132         switch (cmd) {
133         case SIOCGIFBR:
134         case SIOCSIFBR:
135                 return old_deviceless(uarg);
136
137         case SIOCBRADDBR:
138                 return brc_add_del_bridge(uarg, 1);
139         case SIOCBRDELBR:
140                 return brc_add_del_bridge(uarg, 0);
141         }
142
143         return -EOPNOTSUPP;
144 }
145
146 static int
147 brc_add_del_port(struct net_device *dev, int port_ifindex, int add)
148 {
149         struct net_device *port;
150         char dev_name[IFNAMSIZ], port_name[IFNAMSIZ];
151         int err;
152
153         port = __dev_get_by_index(&init_net, port_ifindex);
154         if (!port)
155                 return -EINVAL;
156
157         /* Save name of dev and port because there's a race between the
158          * rtnl_unlock() and the brc_send_command(). */
159         strcpy(dev_name, dev->name);
160         strcpy(port_name, port->name);
161
162         rtnl_unlock();
163         err = brc_send_command(dev_name, port_name,
164                                add ? BRC_GENL_C_PORT_ADD : BRC_GENL_C_PORT_DEL);
165         rtnl_lock();
166
167         return err;
168 }
169
170 static int
171 brc_get_bridge_info(struct net_device *dev, struct __bridge_info __user *ub)
172 {
173         struct __bridge_info b;
174         u64 id = 0;
175         int i;
176
177         memset(&b, 0, sizeof(struct __bridge_info));
178
179         for (i=0; i<ETH_ALEN; i++)
180                 id |= (u64)dev->dev_addr[i] << (8*(ETH_ALEN-1 - i));
181         b.bridge_id = cpu_to_be64(id);
182         b.stp_enabled = 0;
183
184         if (copy_to_user(ub, &b, sizeof(struct __bridge_info)))
185                 return -EFAULT;
186
187         return 0;
188 }
189
190 static int
191 brc_get_port_list(struct net_device *dev, int __user *uindices, int num)
192 {
193         struct dp_dev *dp_dev = netdev_priv(dev);
194         struct datapath *dp = dp_dev->dp;
195         int *indices;
196
197         if (num < 0)
198                 return -EINVAL;
199         if (num == 0)
200                 num = 256;
201         if (num > DP_MAX_PORTS)
202                 num = DP_MAX_PORTS;
203
204         indices = kcalloc(num, sizeof(int), GFP_KERNEL);
205         if (indices == NULL)
206                 return -ENOMEM;
207
208         get_port_ifindices(dp, indices, num);
209         if (copy_to_user(uindices, indices, num * sizeof(int)))
210                 num = -EFAULT;
211         kfree(indices);
212         return num;
213 }
214
215 /* Legacy ioctl's through SIOCDEVPRIVATE.  Called with rtnl_lock. */
216 static int
217 old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
218 {
219         unsigned long args[4];
220
221         if (copy_from_user(args, rq->ifr_data, sizeof(args)))
222                 return -EFAULT;
223
224         switch (args[0]) {
225         case BRCTL_ADD_IF:
226                 return brc_add_del_port(dev, args[1], 1);
227         case BRCTL_DEL_IF:
228                 return brc_add_del_port(dev, args[1], 0);
229
230         case BRCTL_GET_BRIDGE_INFO:
231                 return brc_get_bridge_info(dev, (struct __bridge_info __user *)args[1]);
232
233         case BRCTL_GET_PORT_LIST:
234                 return brc_get_port_list(dev, (int __user *)args[1], args[2]);
235         }
236
237         return -EOPNOTSUPP;
238 }
239
240 /* Called with the rtnl_lock. */
241 static int
242 brc_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
243 {
244         int err;
245
246         switch (cmd) {
247                 case SIOCDEVPRIVATE:
248                         err = old_dev_ioctl(dev, rq, cmd);
249                         break;
250
251                 case SIOCBRADDIF:
252                         return brc_add_del_port(dev, rq->ifr_ifindex, 1);
253                 case SIOCBRDELIF:
254                         return brc_add_del_port(dev, rq->ifr_ifindex, 0);
255
256                 default:
257                         err = -EOPNOTSUPP;
258                         break;
259         }
260
261         return err;
262 }
263
264
265 static struct genl_family brc_genl_family = {
266         .id = GENL_ID_GENERATE,
267         .hdrsize = 0,
268         .name = BRC_GENL_FAMILY_NAME,
269         .version = 1,
270         .maxattr = BRC_GENL_A_MAX,
271 };
272
273 static int brc_genl_query(struct sk_buff *skb, struct genl_info *info)
274 {
275         int err = -EINVAL;
276         struct sk_buff *ans_skb;
277         void *data;
278
279         ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
280         if (!ans_skb) 
281                 return -ENOMEM;
282
283         data = genlmsg_put_reply(ans_skb, info, &brc_genl_family,
284                                  0, BRC_GENL_C_QUERY_MC);
285         if (data == NULL) {
286                 err = -ENOMEM;
287                 goto err;
288         }
289         NLA_PUT_U32(ans_skb, BRC_GENL_A_MC_GROUP, brc_mc_group.id);
290
291         genlmsg_end(ans_skb, data);
292         return genlmsg_reply(ans_skb, info);
293
294 err:
295 nla_put_failure:
296         kfree_skb(ans_skb);
297         return err;
298 }
299
300 static struct genl_ops brc_genl_ops_query_dp = {
301         .cmd = BRC_GENL_C_QUERY_MC,
302         .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privelege. */
303         .policy = NULL,
304         .doit = brc_genl_query,
305         .dumpit = NULL
306 };
307
308 /* Attribute policy: what each attribute may contain.  */
309 static struct nla_policy brc_genl_policy[BRC_GENL_A_MAX + 1] = {
310         [BRC_GENL_A_ERR_CODE] = { .type = NLA_U32 },
311         [BRC_GENL_A_PROC_DIR] = { .type = NLA_NUL_STRING },
312         [BRC_GENL_A_PROC_NAME] = { .type = NLA_NUL_STRING },
313         [BRC_GENL_A_PROC_DATA] = { .type = NLA_NUL_STRING },
314 };
315
316 static int
317 brc_genl_dp_result(struct sk_buff *skb, struct genl_info *info)
318 {
319         unsigned long int flags;
320         int err;
321
322         if (!info->attrs[BRC_GENL_A_ERR_CODE])
323                 return -EINVAL;
324
325         spin_lock_irqsave(&brc_lock, flags);
326         if (brc_seq == info->snd_seq) {
327                 brc_err = nla_get_u32(info->attrs[BRC_GENL_A_ERR_CODE]);
328                 complete(&brc_done);
329                 err = 0;
330         } else {
331                 err = -ESTALE;
332         }
333         spin_unlock_irqrestore(&brc_lock, flags);
334
335         return err;
336 }
337
338 static struct genl_ops brc_genl_ops_dp_result = {
339         .cmd = BRC_GENL_C_DP_RESULT,
340         .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privelege. */
341         .policy = brc_genl_policy,
342         .doit = brc_genl_dp_result,
343         .dumpit = NULL
344 };
345
346 static struct genl_ops brc_genl_ops_set_proc = {
347         .cmd = BRC_GENL_C_SET_PROC,
348         .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privelege. */
349         .policy = brc_genl_policy,
350         .doit = brc_genl_set_proc,
351         .dumpit = NULL
352 };
353
354 static int brc_send_command(const char *bridge, const char *port, int op)
355 {
356         unsigned long int flags;
357         struct sk_buff *skb;
358         void *data;
359         int error;
360
361         mutex_lock(&brc_serial);
362
363         /* Increment sequence number first, so that we ignore any replies
364          * to stale requests. */
365         spin_lock_irqsave(&brc_lock, flags);
366         brc_seq++;
367         INIT_COMPLETION(brc_done);
368         spin_unlock_irqrestore(&brc_lock, flags);
369
370         /* Compose message. */
371         skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
372         error = -ENOMEM;
373         if (skb == NULL)
374                 goto exit_unlock;
375         data = genlmsg_put(skb, 0, brc_seq, &brc_genl_family, 0, op);
376
377         NLA_PUT_STRING(skb, BRC_GENL_A_DP_NAME, bridge);
378         if (port)
379                 NLA_PUT_STRING(skb, BRC_GENL_A_PORT_NAME, port);
380
381         genlmsg_end(skb, data);
382
383         /* Send message. */
384         error = genlmsg_multicast(skb, 0, brc_mc_group.id, GFP_KERNEL);
385         if (error < 0)
386                 goto exit_unlock;
387
388         /* Wait for reply. */
389         error = -ETIMEDOUT;
390         if (!wait_for_completion_timeout(&brc_done, BRC_TIMEOUT))
391                 goto exit_unlock;
392
393         error = -brc_err;
394         goto exit_unlock;
395
396 nla_put_failure:
397         kfree_skb(skb);
398 exit_unlock:
399         mutex_unlock(&brc_serial);
400         return error;
401 }
402
403 int brc_add_dp(struct datapath *dp)
404 {
405         if (!try_module_get(THIS_MODULE))
406                 return -ENODEV;
407 #ifdef SUPPORT_SYSFS
408         brc_sysfs_add_dp(dp);
409 #endif
410
411         return 0;
412 }
413
414 int brc_del_dp(struct datapath *dp) 
415 {
416 #ifdef SUPPORT_SYSFS
417         brc_sysfs_del_dp(dp);
418 #endif
419         module_put(THIS_MODULE);
420
421         return 0;
422 }
423
424 static int 
425 __init brc_init(void)
426 {
427         int i;
428         int err;
429
430         printk("Open vSwitch Bridge Compatibility, built "__DATE__" "__TIME__"\n");
431
432         rcu_read_lock();
433         for (i=0; i<ODP_MAX; i++) {
434                 if (get_dp(i)) {
435                         rcu_read_unlock();
436                         printk(KERN_EMERG "brcompat: no datapaths may exist!\n");
437                         return -EEXIST;
438                 }
439         }
440         rcu_read_unlock();
441
442         /* Set the bridge ioctl handler */
443         brioctl_set(brc_ioctl_deviceless_stub);
444
445         /* Set the openvswitch_mod device ioctl handler */
446         dp_ioctl_hook = brc_dev_ioctl;
447
448         /* Register hooks for datapath adds and deletes */
449         dp_add_dp_hook = brc_add_dp;
450         dp_del_dp_hook = brc_del_dp;
451
452         /* Register hooks for interface adds and deletes */
453 #ifdef SUPPORT_SYSFS
454         dp_add_if_hook = brc_sysfs_add_if;
455         dp_del_if_hook = brc_sysfs_del_if;
456 #endif
457
458         /* Randomize the initial sequence number.  This is not a security
459          * feature; it only helps avoid crossed wires between userspace and
460          * the kernel when the module is unloaded and reloaded. */
461         brc_seq = net_random();
462
463         /* Register generic netlink family to communicate changes to
464          * userspace. */
465         err = genl_register_family(&brc_genl_family);
466         if (err)
467                 goto error;
468
469         err = genl_register_ops(&brc_genl_family, &brc_genl_ops_query_dp);
470         if (err != 0) 
471                 goto err_unregister;
472
473         err = genl_register_ops(&brc_genl_family, &brc_genl_ops_dp_result);
474         if (err != 0) 
475                 goto err_unregister;
476
477         err = genl_register_ops(&brc_genl_family, &brc_genl_ops_set_proc);
478         if (err != 0) 
479                 goto err_unregister;
480
481         strcpy(brc_mc_group.name, "brcompat");
482         err = genl_register_mc_group(&brc_genl_family, &brc_mc_group);
483         if (err < 0)
484                 goto err_unregister;
485
486         return 0;
487
488 err_unregister:
489         genl_unregister_family(&brc_genl_family);
490 error:
491         printk(KERN_EMERG "brcompat: failed to install!");
492         return err;
493 }
494
495 static void 
496 brc_cleanup(void)
497 {
498         /* Unregister hooks for datapath adds and deletes */
499         dp_add_dp_hook = NULL;
500         dp_del_dp_hook = NULL;
501         
502         /* Unregister hooks for interface adds and deletes */
503         dp_add_if_hook = NULL;
504         dp_del_if_hook = NULL;
505
506         /* Unregister ioctl hooks */
507         dp_ioctl_hook = NULL;
508         brioctl_set(NULL);
509
510         genl_unregister_family(&brc_genl_family);
511         brc_procfs_exit();
512 }
513
514 module_init(brc_init);
515 module_exit(brc_cleanup);
516
517 MODULE_DESCRIPTION("Open vSwitch bridge compatibility");
518 MODULE_AUTHOR("Nicira Networks");
519 MODULE_LICENSE("GPL");