misc: added trafgen config file
[ana-net.git] / src / fb_ethvlink.c
blob6b02582b0e0b3dbc60d081fd48e5e6d4e07b8910
1 /*
2 * Lightweight Autonomic Network Architecture
4 * Ethernet vlink layer. This module allows to operate virtual LANA Ethernet
5 * devices which are configurable via ifconfig et. al. and bound to a real
6 * underlying device. Similar to VLANs, multiple virtual devices can be
7 * bound to a real network device. Multiplexing and demultiplexing happens
8 * within this driver.
10 * Copyright 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,
11 * Swiss federal institute of technology (ETH Zurich)
12 * Subject to the GPL.
15 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 #include <linux/notifier.h>
19 #include <linux/netdevice.h>
20 #include <linux/rtnetlink.h>
21 #include <linux/ethtool.h>
22 #include <linux/etherdevice.h>
23 #include <linux/if_ether.h>
24 #include <linux/if_arp.h>
25 #include <linux/if.h>
26 #include <linux/list.h>
27 #include <linux/u64_stats_sync.h>
28 #include <linux/seqlock.h>
29 #include <net/rtnetlink.h>
31 #include "xt_idp.h"
32 #include "xt_engine.h"
33 #include "xt_skb.h"
34 #include "xt_vlink.h"
35 #include "xt_fblock.h"
37 #define IFF_VLINK_MAS 0x20000 /* Master device */
38 #define IFF_VLINK_DEV 0x40000 /* Slave device */
39 #define IFF_IS_BRIDGED 0x60000
41 /* Ethernet LANA packet with 10 Bit tag ID */
42 #define ETH_P_LANA 0xAC00
44 struct pcpu_dstats {
45 u64 rx_packets;
46 u64 rx_bytes;
47 u64 rx_multicast;
48 u64 tx_packets;
49 u64 tx_bytes;
50 struct u64_stats_sync syncp;
51 u32 rx_errors;
52 u32 tx_dropped;
55 static struct net_device_ops fb_ethvlink_netdev_ops __read_mostly;
56 static struct rtnl_link_ops fb_ethvlink_rtnl_ops __read_mostly;
57 static struct ethtool_ops fb_ethvlink_ethtool_ops __read_mostly;
58 static struct header_ops fb_ethvlink_header_ops __read_mostly;
60 static LIST_HEAD(fb_ethvlink_vdevs);
61 static DEFINE_SPINLOCK(fb_ethvlink_vdevs_lock);
63 struct fb_ethvlink_private;
65 struct fb_ethvlink_private_inner {
66 idp_t port[2];
67 seqlock_t lock;
68 struct fb_ethvlink_private *vdev;
71 struct fb_ethvlink_private {
72 u16 tag;
73 struct list_head list;
74 struct net_device *self;
75 struct net_device *real_dev;
76 int (*netvif_rx)(struct sk_buff *skb, struct fb_ethvlink_private *vdev);
77 struct fblock *fb;
80 static int fb_ethvlink_init(struct net_device *dev)
82 dev->dstats = alloc_percpu(struct pcpu_dstats);
83 if (!dev->dstats)
84 return -ENOMEM;
85 return 0;
88 static void fb_ethvlink_uninit(struct net_device *dev)
90 free_percpu(dev->dstats);
93 static int fb_ethvlink_open(struct net_device *dev)
95 struct fb_ethvlink_private *dev_priv = netdev_priv(dev);
97 netif_start_queue(dev);
98 if (netif_carrier_ok(dev_priv->real_dev)) {
99 netif_tx_lock_bh(dev);
100 netif_carrier_on(dev);
101 netif_tx_unlock_bh(dev);
104 return 0;
107 static int fb_ethvlink_stop(struct net_device *dev)
109 netif_tx_lock_bh(dev);
110 netif_carrier_off(dev);
111 netif_tx_unlock_bh(dev);
112 netif_stop_queue(dev);
114 return 0;
117 static inline int fb_eth_dev_is_bridged(struct net_device *dev)
119 return (dev->priv_flags & IFF_IS_BRIDGED) == IFF_IS_BRIDGED;
122 static inline int fb_ethvlink_real_dev_is_hooked(struct net_device *dev)
124 return (dev->priv_flags & IFF_VLINK_MAS) == IFF_VLINK_MAS;
127 static inline void fb_ethvlink_make_real_dev_hooked(struct net_device *dev)
129 dev->priv_flags |= IFF_VLINK_MAS;
132 static inline void fb_ethvlink_make_real_dev_unhooked(struct net_device *dev)
134 dev->priv_flags &= ~IFF_VLINK_MAS;
137 static int fb_ethvlink_event(struct notifier_block *self, unsigned long cmd,
138 void *args)
140 int ret = NOTIFY_OK;
141 unsigned int cpu;
142 struct fblock *fb;
143 struct fb_ethvlink_private_inner __percpu *fb_priv;
145 rcu_read_lock();
146 fb = rcu_dereference_raw(container_of(self, struct fblock_notifier,
147 nb)->self);
148 fb_priv = (struct fb_ethvlink_private_inner __percpu *)
149 rcu_dereference_raw(fb->private_data);
150 rcu_read_unlock();
152 switch (cmd) {
153 case FBLOCK_BIND_IDP: {
154 int bound = 0;
155 struct fblock_bind_msg *msg = args;
156 get_online_cpus();
157 for_each_online_cpu(cpu) {
158 struct fb_ethvlink_private_inner *fb_priv_cpu;
159 fb_priv_cpu = per_cpu_ptr(fb_priv, cpu);
160 if (fb_priv_cpu->port[msg->dir] == IDP_UNKNOWN) {
161 write_seqlock(&fb_priv_cpu->lock);
162 fb_priv_cpu->port[msg->dir] = msg->idp;
163 write_sequnlock(&fb_priv_cpu->lock);
164 bound = 1;
165 } else {
166 ret = NOTIFY_BAD;
167 break;
170 put_online_cpus();
171 if (bound)
172 printk(KERN_INFO "[%s::vlink] port %s bound to IDP%u\n",
173 fb->name, path_names[msg->dir], msg->idp);
174 } break;
175 case FBLOCK_UNBIND_IDP: {
176 int unbound = 0;
177 struct fblock_bind_msg *msg = args;
178 get_online_cpus();
179 for_each_online_cpu(cpu) {
180 struct fb_ethvlink_private_inner *fb_priv_cpu;
181 fb_priv_cpu = per_cpu_ptr(fb_priv, cpu);
182 if (fb_priv_cpu->port[msg->dir] == msg->idp) {
183 write_seqlock(&fb_priv_cpu->lock);
184 fb_priv_cpu->port[msg->dir] = IDP_UNKNOWN;
185 write_sequnlock(&fb_priv_cpu->lock);
186 unbound = 1;
187 } else {
188 ret = NOTIFY_BAD;
189 break;
192 put_online_cpus();
193 if (unbound)
194 printk(KERN_INFO "[%s::vlink] port %s unbound\n",
195 fb->name, path_names[msg->dir]);
196 } break;
197 default:
198 break;
201 return ret;
204 static int fb_ethvlink_queue_xmit(struct sk_buff *skb,
205 struct net_device *dev)
207 struct fb_ethvlink_private *dev_priv = netdev_priv(dev);
208 skb_set_dev(skb, dev_priv->real_dev);
209 return dev_queue_xmit(skb);
212 netdev_tx_t fb_ethvlink_start_xmit(struct sk_buff *skb,
213 struct net_device *dev)
215 int ret;
216 struct pcpu_dstats *dstats;
218 dstats = this_cpu_ptr(dev->dstats);
219 ret = fb_ethvlink_queue_xmit(skb, dev);
220 if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
221 u64_stats_update_begin(&dstats->syncp);
222 dstats->tx_packets++;
223 dstats->tx_bytes += skb->len;
224 u64_stats_update_end(&dstats->syncp);
225 } else
226 this_cpu_inc(dstats->tx_dropped);
228 return ret;
231 static int fb_ethvlink_netrx(const struct fblock * const fb,
232 struct sk_buff * const skb,
233 enum path_type * const dir)
235 struct fb_ethvlink_private_inner __percpu *fb_priv_cpu;
236 fb_priv_cpu = this_cpu_ptr(rcu_dereference(fb->private_data));
237 skb->dev = fb_priv_cpu->vdev->self;
238 write_next_idp_to_skb(skb, fb->idp, IDP_UNKNOWN);
239 dev_queue_xmit(skb);
240 return PPE_DROPPED;
243 int fb_ethvlink_handle_frame_virt(struct sk_buff *skb,
244 struct fb_ethvlink_private *vdev)
246 unsigned int seq;
247 struct fb_ethvlink_private_inner __percpu *fb_priv_cpu;
249 skb_orphan(skb);
251 fb_priv_cpu = this_cpu_ptr(rcu_dereference(vdev->fb->private_data));
252 if (fb_priv_cpu->port[TYPE_INGRESS] == IDP_UNKNOWN)
253 goto drop;
254 do {
255 seq = read_seqbegin(&fb_priv_cpu->lock);
256 write_next_idp_to_skb(skb, vdev->fb->idp,
257 fb_priv_cpu->port[TYPE_INGRESS]);
258 } while (read_seqretry(&fb_priv_cpu->lock, seq));
260 process_packet(skb, TYPE_INGRESS);
262 return NET_RX_SUCCESS;
263 drop:
264 kfree_skb(skb);
265 return NET_RX_SUCCESS;
268 static rx_handler_result_t fb_ethvlink_handle_frame(struct sk_buff **pskb)
270 int ret, bypass_drop = 0;
271 u16 vtag;
272 struct sk_buff *skb = *pskb;
273 struct net_device *dev;
274 struct fb_ethvlink_private *vdev;
275 struct pcpu_dstats *dstats;
277 dev = skb->dev;
278 if (unlikely((dev->flags & IFF_UP) != IFF_UP))
279 goto drop;
281 if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
282 return RX_HANDLER_PASS;
284 if (unlikely(!is_valid_ether_addr(eth_hdr(skb)->h_source)))
285 goto drop;
287 skb = skb_share_check(skb, GFP_ATOMIC);
288 if (unlikely(!skb))
289 return RX_HANDLER_CONSUMED;
291 if ((eth_hdr(skb)->h_proto & __constant_htons(ETH_P_LANA)) !=
292 __constant_htons(ETH_P_LANA))
293 return RX_HANDLER_PASS;
295 vtag = ntohs(eth_hdr(skb)->h_proto &
296 ~__constant_htons(ETH_P_LANA));
298 list_for_each_entry_rcu(vdev, &fb_ethvlink_vdevs, list) {
299 if (vtag == vdev->tag && dev == vdev->real_dev) {
300 dstats = this_cpu_ptr(vdev->self->dstats);
301 ret = vdev->netvif_rx(skb, vdev);
302 bypass_drop = 1;
303 if (ret == NET_RX_SUCCESS) {
304 u64_stats_update_begin(&dstats->syncp);
305 dstats->rx_packets++;
306 dstats->rx_bytes += skb->len;
307 u64_stats_update_end(&dstats->syncp);
308 } else
309 this_cpu_inc(dstats->rx_errors);
310 break;
314 drop:
315 if (!bypass_drop)
316 kfree_skb(skb);
317 return RX_HANDLER_CONSUMED;
320 static void fb_ethvlink_ethtool_get_drvinfo(struct net_device *dev,
321 struct ethtool_drvinfo *drvinfo)
323 snprintf(drvinfo->driver, sizeof(drvinfo->driver), "ethvlink");
324 snprintf(drvinfo->version, sizeof(drvinfo->version), "0.1");
327 static u32 fb_ethvlink_ethtool_get_rx_csum(struct net_device *dev)
329 const struct fb_ethvlink_private *vdev = netdev_priv(dev);
330 return dev_ethtool_get_rx_csum(vdev->real_dev);
333 static int fb_ethvlink_ethtool_get_settings(struct net_device *dev,
334 struct ethtool_cmd *cmd)
336 const struct fb_ethvlink_private *vdev = netdev_priv(dev);
337 return dev_ethtool_get_settings(vdev->real_dev, cmd);
340 static u32 fb_ethvlink_ethtool_get_flags(struct net_device *dev)
342 const struct fb_ethvlink_private *vdev = netdev_priv(dev);
343 return dev_ethtool_get_flags(vdev->real_dev);
346 static void fb_ethvlink_dev_setup(struct net_device *dev)
348 ether_setup(dev);
350 dev->ethtool_ops = &fb_ethvlink_ethtool_ops;
351 dev->netdev_ops = &fb_ethvlink_netdev_ops;
352 dev->rtnl_link_ops = &fb_ethvlink_rtnl_ops;
353 dev->header_ops = &fb_ethvlink_header_ops;
354 dev->tx_queue_len = 0;
355 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
356 dev->destructor = free_netdev;
358 random_ether_addr(dev->dev_addr);
359 memset(dev->broadcast, 0, sizeof(dev->broadcast));
362 static int fb_ethvlink_validate(struct nlattr **tb, struct nlattr **data)
364 if (tb[IFLA_ADDRESS]) {
365 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
366 return -EINVAL;
367 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
368 return -EADDRNOTAVAIL;
371 return 0;
374 static int fb_ethvlink_create_header(struct sk_buff *skb,
375 struct net_device *dev,
376 unsigned short type, const void *daddr,
377 const void *saddr, unsigned len)
379 const struct fb_ethvlink_private *vdev = netdev_priv(dev);
380 return dev_hard_header(skb, vdev->real_dev, type, daddr,
381 saddr ? : dev->dev_addr, len);
384 static struct rtnl_link_stats64 *
385 fb_ethvlink_get_stats64(struct net_device *dev,
386 struct rtnl_link_stats64 *stats)
388 int i;
390 for_each_possible_cpu(i) {
391 u64 tbytes, tpackets, rbytes, rpackets;
392 unsigned int start;
393 const struct pcpu_dstats *dstats;
395 dstats = per_cpu_ptr(dev->dstats, i);
397 do {
398 start = u64_stats_fetch_begin(&dstats->syncp);
399 tbytes = dstats->tx_bytes;
400 tpackets = dstats->tx_packets;
401 rbytes = dstats->rx_bytes;
402 rpackets = dstats->rx_packets;
403 } while (u64_stats_fetch_retry(&dstats->syncp, start));
405 stats->tx_bytes += tbytes;
406 stats->tx_packets += tpackets;
407 stats->rx_bytes += rbytes;
408 stats->rx_packets += rpackets;
411 return stats;
414 static void fb_ethvlink_destroy_fblock(struct fblock *fb)
416 unregister_fblock_namespace_no_rcu(fb);
417 cleanup_fblock(fb);
418 free_percpu(rcu_dereference_raw(fb->private_data));
419 kfree_fblock(fb);
420 module_put(THIS_MODULE);
423 static struct fblock *fb_ethvlink_build_fblock(struct fb_ethvlink_private *vdev)
425 int ret = 0;
426 unsigned int cpu;
427 struct fblock *fb;
428 struct fb_ethvlink_private_inner __percpu *fb_priv;
430 fb = alloc_fblock(GFP_ATOMIC);
431 if (!fb)
432 return NULL;
434 fb_priv = alloc_percpu(struct fb_ethvlink_private_inner);
435 if (!fb_priv)
436 goto err;
438 get_online_cpus();
439 for_each_online_cpu(cpu) {
440 struct fb_ethvlink_private_inner *fb_priv_cpu;
441 fb_priv_cpu = per_cpu_ptr(fb_priv, cpu);
442 seqlock_init(&fb_priv_cpu->lock);
443 fb_priv_cpu->port[0] = IDP_UNKNOWN;
444 fb_priv_cpu->port[1] = IDP_UNKNOWN;
445 fb_priv_cpu->vdev = vdev;
447 put_online_cpus();
449 ret = init_fblock(fb, vdev->self->name, fb_priv);
450 if (ret)
451 goto err2;
452 fb->netfb_rx = fb_ethvlink_netrx;
453 fb->event_rx = fb_ethvlink_event;
454 fb->factory = NULL;
456 ret = register_fblock_namespace(fb);
457 if (ret)
458 goto err3;
459 __module_get(THIS_MODULE);
460 smp_wmb();
461 return fb;
462 err3:
463 cleanup_fblock_ctor(fb);
464 err2:
465 free_percpu(fb_priv);
466 err:
467 kfree_fblock(fb);
468 fb = NULL;
469 return NULL;
472 static int fb_ethvlink_add_dev(struct vlinknlmsg *vhdr,
473 struct nlmsghdr *nlh)
475 int ret;
476 unsigned long flags;
477 struct net_device *dev;
478 struct net_device *root;
479 struct fb_ethvlink_private *dev_priv, *vdev;
481 if (vhdr->cmd != VLINKNLCMD_ADD_DEVICE)
482 return NETLINK_VLINK_RX_NXT;
484 root = dev_get_by_name(&init_net, vhdr->virt_name);
485 if (root)
486 goto err_put;
488 root = dev_get_by_name(&init_net, vhdr->real_name);
489 if (root && (root->priv_flags & IFF_VLINK_DEV) == IFF_VLINK_DEV)
490 goto err_put;
491 else if (!root)
492 goto err;
494 vhdr->port &= 0x3FF;
496 rcu_read_lock();
497 list_for_each_entry_rcu(vdev, &fb_ethvlink_vdevs, list) {
498 if (vdev->tag == vhdr->port) {
499 rcu_read_unlock();
500 goto err_put;
503 rcu_read_unlock();
505 dev = alloc_netdev(sizeof(*dev_priv), vhdr->virt_name,
506 fb_ethvlink_dev_setup);
507 if (!dev)
508 goto err_put;
510 ret = dev_alloc_name(dev, dev->name);
511 if (ret)
512 goto err_free;
514 ret = register_netdev(dev);
515 if (ret)
516 goto err_free;
518 dev_priv = netdev_priv(dev);
519 dev->priv_flags |= vhdr->flags;
520 dev->priv_flags |= IFF_VLINK_DEV;
521 dev_priv->tag = vhdr->port;
522 dev_priv->self = dev;
523 dev_priv->real_dev = root;
524 dev_priv->netvif_rx = fb_ethvlink_handle_frame_virt;
525 dev_priv->fb = fb_ethvlink_build_fblock(dev_priv);
526 if (!dev_priv->fb)
527 goto err_unreg;
529 netif_stacked_transfer_operstate(dev_priv->real_dev, dev);
530 dev_put(dev_priv->real_dev);
532 spin_lock_irqsave(&fb_ethvlink_vdevs_lock, flags);
533 list_add_rcu(&dev_priv->list, &fb_ethvlink_vdevs);
534 spin_unlock_irqrestore(&fb_ethvlink_vdevs_lock, flags);
536 netif_tx_lock_bh(dev);
537 netif_carrier_off(dev);
538 netif_tx_unlock_bh(dev);
540 printk(KERN_INFO "[lana] %s stacked on carrier %s:%u\n",
541 vhdr->virt_name, vhdr->real_name, dev_priv->tag);
542 return NETLINK_VLINK_RX_STOP;
544 err_unreg:
545 unregister_netdevice(dev);
546 err_free:
547 dev_put(root);
548 free_netdev(dev);
549 err:
550 return NETLINK_VLINK_RX_EMERG;
551 err_put:
552 dev_put(root);
553 goto err;
556 static int fb_ethvlink_start_hook_dev(struct vlinknlmsg *vhdr,
557 struct nlmsghdr *nlh)
559 int ret;
560 struct net_device *root;
562 if (vhdr->cmd != VLINKNLCMD_START_HOOK_DEVICE)
563 return NETLINK_VLINK_RX_NXT;
565 root = dev_get_by_name(&init_net, vhdr->real_name);
566 if (root && (root->priv_flags & IFF_VLINK_DEV) == IFF_VLINK_DEV)
567 goto err;
568 else if (!root)
569 return NETLINK_VLINK_RX_EMERG;
571 if (fb_eth_dev_is_bridged(root))
572 goto out;
573 if (fb_ethvlink_real_dev_is_hooked(root))
574 goto out;
576 rtnl_lock();
577 ret = netdev_rx_handler_register(root, fb_ethvlink_handle_frame,
578 NULL);
579 rtnl_unlock();
580 if (ret)
581 goto err;
583 fb_ethvlink_make_real_dev_hooked(root);
584 printk(KERN_INFO "[lana] hook attached to carrier %s\n",
585 vhdr->real_name);
586 out:
587 dev_put(root);
588 return NETLINK_VLINK_RX_STOP;
589 err:
590 dev_put(root);
591 return NETLINK_VLINK_RX_EMERG;
594 static int fb_ethvlink_stop_hook_dev(struct vlinknlmsg *vhdr,
595 struct nlmsghdr *nlh)
597 struct net_device *root;
599 if (vhdr->cmd != VLINKNLCMD_STOP_HOOK_DEVICE)
600 return NETLINK_VLINK_RX_NXT;
602 root = dev_get_by_name(&init_net, vhdr->real_name);
603 if (root && (root->priv_flags & IFF_VLINK_DEV) == IFF_VLINK_DEV)
604 goto err;
605 else if (!root)
606 return NETLINK_VLINK_RX_EMERG;
608 if (!fb_ethvlink_real_dev_is_hooked(root))
609 goto out;
611 rtnl_lock();
612 netdev_rx_handler_unregister(root);
613 rtnl_unlock();
615 fb_ethvlink_make_real_dev_unhooked(root);
616 printk(KERN_INFO "[lana] hook detached from carrier %s\n",
617 vhdr->real_name);
618 out:
619 dev_put(root);
620 return NETLINK_VLINK_RX_STOP;
621 err:
622 dev_put(root);
623 return NETLINK_VLINK_RX_EMERG;
626 static void fb_ethvlink_rm_dev_common(struct net_device *dev)
628 netif_tx_lock_bh(dev);
629 netif_carrier_off(dev);
630 netif_tx_unlock_bh(dev);
632 printk(KERN_INFO "[lana] %s unregistered\n", dev->name);
634 rtnl_lock();
635 unregister_netdevice(dev);
636 rtnl_unlock();
639 static int fb_ethvlink_rm_dev(struct vlinknlmsg *vhdr, struct nlmsghdr *nlh)
641 int count;
642 unsigned long flags;
643 struct fb_ethvlink_private *dev_priv, *vdev;
644 struct net_device *dev;
646 if (vhdr->cmd != VLINKNLCMD_RM_DEVICE)
647 return NETLINK_VLINK_RX_NXT;
649 dev = dev_get_by_name(&init_net, vhdr->virt_name);
650 if (!dev)
651 return NETLINK_VLINK_RX_EMERG;
652 if ((dev->priv_flags & IFF_VLINK_DEV) != IFF_VLINK_DEV)
653 goto err_put;
654 if ((dev->flags & IFF_RUNNING) == IFF_RUNNING)
655 goto err_put;
656 dev_priv = netdev_priv(dev);
657 if (atomic_read(&dev_priv->fb->refcnt) > 2) {
658 printk(KERN_INFO "Cannot remove vlink dev! Still in use by "
659 "others!\n");
660 goto err_put;
663 dev_put(dev);
665 count = 0;
666 rcu_read_lock();
667 list_for_each_entry_rcu(vdev, &fb_ethvlink_vdevs, list)
668 if (dev_priv->real_dev == vdev->real_dev)
669 count++;
670 rcu_read_unlock();
672 if (count == 1) {
673 /* We're last client on carrier! */
674 if (fb_ethvlink_real_dev_is_hooked(dev_priv->real_dev)) {
675 rtnl_lock();
676 netdev_rx_handler_unregister(dev_priv->real_dev);
677 rtnl_unlock();
679 fb_ethvlink_make_real_dev_unhooked(dev_priv->real_dev);
680 printk(KERN_INFO "[lana] hook detached from %s\n",
681 dev_priv->real_dev->name);
685 spin_lock_irqsave(&fb_ethvlink_vdevs_lock, flags);
686 list_del_rcu(&dev_priv->list);
687 spin_unlock_irqrestore(&fb_ethvlink_vdevs_lock, flags);
689 fb_ethvlink_destroy_fblock(dev_priv->fb);
690 fb_ethvlink_rm_dev_common(dev);
692 return NETLINK_VLINK_RX_STOP;
694 err_put:
695 dev_put(dev);
696 return NETLINK_VLINK_RX_EMERG;
699 static int fb_ethvlink_dev_event(struct notifier_block *self,
700 unsigned long event, void *ptr)
702 unsigned long flags;
703 struct net_device *dev = ptr;
704 struct fb_ethvlink_private *vdev;
705 struct vlinknlmsg vhdr;
707 if (!dev)
708 return NOTIFY_DONE;
710 switch (event) {
711 case NETDEV_CHANGE:
712 rcu_read_lock();
713 list_for_each_entry_rcu(vdev, &fb_ethvlink_vdevs, list)
714 if (vdev->real_dev == dev)
715 netif_stacked_transfer_operstate(vdev->real_dev,
716 vdev->self);
717 rcu_read_unlock();
718 break;
719 case NETDEV_FEAT_CHANGE:
720 /* Nothing right now */
721 break;
722 case NETDEV_UNREGISTER:
723 if (dev->reg_state != NETREG_UNREGISTERING)
724 break;
726 memset(&vhdr, 0, sizeof(vhdr));
727 vhdr.cmd = VLINKNLCMD_RM_DEVICE;
728 spin_lock_irqsave(&fb_ethvlink_vdevs_lock, flags);
729 list_for_each_entry_rcu(vdev, &fb_ethvlink_vdevs, list) {
730 if (vdev->real_dev == dev) {
731 memset(vhdr.virt_name, 0,
732 sizeof(vhdr.virt_name));
733 strlcpy(vhdr.virt_name, vdev->self->name,
734 strlen(vdev->self->name));
735 fb_ethvlink_rm_dev(&vhdr, NULL);
738 spin_unlock_irqrestore(&fb_ethvlink_vdevs_lock, flags);
739 break;
740 case NETDEV_PRE_TYPE_CHANGE:
741 return NOTIFY_BAD;
742 default:
743 return NOTIFY_DONE;
746 return NOTIFY_DONE;
749 static struct ethtool_ops fb_ethvlink_ethtool_ops __read_mostly = {
750 .get_link = ethtool_op_get_link,
751 .get_settings = fb_ethvlink_ethtool_get_settings,
752 .get_rx_csum = fb_ethvlink_ethtool_get_rx_csum,
753 .get_drvinfo = fb_ethvlink_ethtool_get_drvinfo,
754 .get_flags = fb_ethvlink_ethtool_get_flags,
757 static struct net_device_ops fb_ethvlink_netdev_ops __read_mostly = {
758 .ndo_init = fb_ethvlink_init,
759 .ndo_uninit = fb_ethvlink_uninit,
760 .ndo_open = fb_ethvlink_open,
761 .ndo_stop = fb_ethvlink_stop,
762 .ndo_start_xmit = fb_ethvlink_start_xmit,
763 .ndo_get_stats64 = fb_ethvlink_get_stats64,
764 .ndo_change_mtu = eth_change_mtu,
765 .ndo_set_mac_address = eth_mac_addr,
766 .ndo_validate_addr = eth_validate_addr,
769 static struct header_ops fb_ethvlink_header_ops __read_mostly = {
770 .create = fb_ethvlink_create_header,
771 .rebuild = eth_rebuild_header,
772 .parse = eth_header_parse,
773 .cache = eth_header_cache,
774 .cache_update = eth_header_cache_update,
777 static struct rtnl_link_ops fb_ethvlink_rtnl_ops __read_mostly = {
778 .kind = "lana",
779 .priv_size = sizeof(struct fb_ethvlink_private),
780 .setup = fb_ethvlink_dev_setup,
781 .validate = fb_ethvlink_validate,
784 static struct vlink_subsys fb_ethvlink_sys __read_mostly = {
785 .name = "eth-tagged",
786 .owner = THIS_MODULE,
787 .type = VLINKNLGRP_ETHERNET,
788 .rwsem = __RWSEM_INITIALIZER(fb_ethvlink_sys.rwsem),
791 static struct notifier_block fb_ethvlink_notifier_block __read_mostly = {
792 .notifier_call = fb_ethvlink_dev_event,
795 static struct vlink_callback fb_ethvlink_add_dev_cb =
796 VLINK_CALLBACK_INIT(fb_ethvlink_add_dev, NETLINK_VLINK_PRIO_NORM);
797 static struct vlink_callback fb_ethvlink_rm_dev_cb =
798 VLINK_CALLBACK_INIT(fb_ethvlink_rm_dev, NETLINK_VLINK_PRIO_NORM);
799 static struct vlink_callback fb_ethvlink_start_hook_dev_cb =
800 VLINK_CALLBACK_INIT(fb_ethvlink_start_hook_dev, NETLINK_VLINK_PRIO_HIGH);
801 static struct vlink_callback fb_ethvlink_stop_hook_dev_cb =
802 VLINK_CALLBACK_INIT(fb_ethvlink_stop_hook_dev, NETLINK_VLINK_PRIO_HIGH);
804 static int __init init_fb_ethvlink_module(void)
806 int ret = 0;
808 ret = vlink_subsys_register(&fb_ethvlink_sys);
809 if (ret)
810 return ret;
812 vlink_add_callback(&fb_ethvlink_sys, &fb_ethvlink_add_dev_cb);
813 vlink_add_callback(&fb_ethvlink_sys, &fb_ethvlink_rm_dev_cb);
814 vlink_add_callback(&fb_ethvlink_sys, &fb_ethvlink_start_hook_dev_cb);
815 vlink_add_callback(&fb_ethvlink_sys, &fb_ethvlink_stop_hook_dev_cb);
817 ret = rtnl_link_register(&fb_ethvlink_rtnl_ops);
818 if (ret)
819 goto err;
821 register_netdevice_notifier(&fb_ethvlink_notifier_block);
823 printk(KERN_INFO "[lana] Ethernet tagged vlink layer loaded!\n");
824 return 0;
826 err:
827 vlink_subsys_unregister_batch(&fb_ethvlink_sys);
828 return ret;
831 static void __exit cleanup_fb_ethvlink_module(void)
833 struct fb_ethvlink_private *vdev;
835 rcu_read_lock();
836 list_for_each_entry_rcu(vdev, &fb_ethvlink_vdevs, list) {
837 if (fb_ethvlink_real_dev_is_hooked(vdev->real_dev)) {
838 rtnl_lock();
839 netdev_rx_handler_unregister(vdev->real_dev);
840 rtnl_unlock();
842 fb_ethvlink_make_real_dev_unhooked(vdev->real_dev);
843 printk(KERN_INFO "[lana] hook detached from %s\n",
844 vdev->real_dev->name);
847 fb_ethvlink_rm_dev_common(vdev->self);
849 rcu_read_unlock();
851 unregister_netdevice_notifier(&fb_ethvlink_notifier_block);
852 rtnl_link_unregister(&fb_ethvlink_rtnl_ops);
853 vlink_subsys_unregister_batch(&fb_ethvlink_sys);
855 printk(KERN_INFO "[lana] Ethernet tagged vlink layer removed!\n");
858 module_init(init_fb_ethvlink_module);
859 module_exit(cleanup_fb_ethvlink_module);
861 MODULE_ALIAS_RTNL_LINK("lana");
862 MODULE_LICENSE("GPL");
863 MODULE_AUTHOR("Daniel Borkmann <dborkma@tik.ee.ethz.ch>");
864 MODULE_DESCRIPTION("Ethernet tagged virtual link layer driver");