diff options
Diffstat (limited to 'drivers/net/vrf.c')
-rw-r--r-- | drivers/net/vrf.c | 70 |
1 files changed, 6 insertions, 64 deletions
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 0a242b200df4..66addb7a7911 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c | |||
@@ -46,17 +46,7 @@ | |||
46 | #define vrf_master_get_rcu(dev) \ | 46 | #define vrf_master_get_rcu(dev) \ |
47 | ((struct net_device *)rcu_dereference(dev->rx_handler_data)) | 47 | ((struct net_device *)rcu_dereference(dev->rx_handler_data)) |
48 | 48 | ||
49 | struct slave { | ||
50 | struct list_head list; | ||
51 | struct net_device *dev; | ||
52 | }; | ||
53 | |||
54 | struct slave_queue { | ||
55 | struct list_head all_slaves; | ||
56 | }; | ||
57 | |||
58 | struct net_vrf { | 49 | struct net_vrf { |
59 | struct slave_queue queue; | ||
60 | struct rtable *rth; | 50 | struct rtable *rth; |
61 | struct rt6_info *rt6; | 51 | struct rt6_info *rt6; |
62 | u32 tb_id; | 52 | u32 tb_id; |
@@ -621,42 +611,9 @@ static void cycle_netdev(struct net_device *dev) | |||
621 | } | 611 | } |
622 | } | 612 | } |
623 | 613 | ||
624 | static struct slave *__vrf_find_slave_dev(struct slave_queue *queue, | ||
625 | struct net_device *dev) | ||
626 | { | ||
627 | struct list_head *head = &queue->all_slaves; | ||
628 | struct slave *slave; | ||
629 | |||
630 | list_for_each_entry(slave, head, list) { | ||
631 | if (slave->dev == dev) | ||
632 | return slave; | ||
633 | } | ||
634 | |||
635 | return NULL; | ||
636 | } | ||
637 | |||
638 | /* inverse of __vrf_insert_slave */ | ||
639 | static void __vrf_remove_slave(struct slave_queue *queue, struct slave *slave) | ||
640 | { | ||
641 | list_del(&slave->list); | ||
642 | } | ||
643 | |||
644 | static void __vrf_insert_slave(struct slave_queue *queue, struct slave *slave) | ||
645 | { | ||
646 | list_add(&slave->list, &queue->all_slaves); | ||
647 | } | ||
648 | |||
649 | static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev) | 614 | static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev) |
650 | { | 615 | { |
651 | struct slave *slave = kzalloc(sizeof(*slave), GFP_KERNEL); | 616 | int ret; |
652 | struct net_vrf *vrf = netdev_priv(dev); | ||
653 | struct slave_queue *queue = &vrf->queue; | ||
654 | int ret = -ENOMEM; | ||
655 | |||
656 | if (!slave) | ||
657 | goto out_fail; | ||
658 | |||
659 | slave->dev = port_dev; | ||
660 | 617 | ||
661 | /* register the packet handler for slave ports */ | 618 | /* register the packet handler for slave ports */ |
662 | ret = netdev_rx_handler_register(port_dev, vrf_handle_frame, dev); | 619 | ret = netdev_rx_handler_register(port_dev, vrf_handle_frame, dev); |
@@ -667,12 +624,11 @@ static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev) | |||
667 | goto out_fail; | 624 | goto out_fail; |
668 | } | 625 | } |
669 | 626 | ||
670 | ret = netdev_master_upper_dev_link(port_dev, dev); | 627 | ret = netdev_master_upper_dev_link(port_dev, dev, NULL, NULL); |
671 | if (ret < 0) | 628 | if (ret < 0) |
672 | goto out_unregister; | 629 | goto out_unregister; |
673 | 630 | ||
674 | port_dev->priv_flags |= IFF_L3MDEV_SLAVE; | 631 | port_dev->priv_flags |= IFF_L3MDEV_SLAVE; |
675 | __vrf_insert_slave(queue, slave); | ||
676 | cycle_netdev(port_dev); | 632 | cycle_netdev(port_dev); |
677 | 633 | ||
678 | return 0; | 634 | return 0; |
@@ -680,7 +636,6 @@ static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev) | |||
680 | out_unregister: | 636 | out_unregister: |
681 | netdev_rx_handler_unregister(port_dev); | 637 | netdev_rx_handler_unregister(port_dev); |
682 | out_fail: | 638 | out_fail: |
683 | kfree(slave); | ||
684 | return ret; | 639 | return ret; |
685 | } | 640 | } |
686 | 641 | ||
@@ -695,10 +650,6 @@ static int vrf_add_slave(struct net_device *dev, struct net_device *port_dev) | |||
695 | /* inverse of do_vrf_add_slave */ | 650 | /* inverse of do_vrf_add_slave */ |
696 | static int do_vrf_del_slave(struct net_device *dev, struct net_device *port_dev) | 651 | static int do_vrf_del_slave(struct net_device *dev, struct net_device *port_dev) |
697 | { | 652 | { |
698 | struct net_vrf *vrf = netdev_priv(dev); | ||
699 | struct slave_queue *queue = &vrf->queue; | ||
700 | struct slave *slave; | ||
701 | |||
702 | netdev_upper_dev_unlink(port_dev, dev); | 653 | netdev_upper_dev_unlink(port_dev, dev); |
703 | port_dev->priv_flags &= ~IFF_L3MDEV_SLAVE; | 654 | port_dev->priv_flags &= ~IFF_L3MDEV_SLAVE; |
704 | 655 | ||
@@ -706,12 +657,6 @@ static int do_vrf_del_slave(struct net_device *dev, struct net_device *port_dev) | |||
706 | 657 | ||
707 | cycle_netdev(port_dev); | 658 | cycle_netdev(port_dev); |
708 | 659 | ||
709 | slave = __vrf_find_slave_dev(queue, port_dev); | ||
710 | if (slave) | ||
711 | __vrf_remove_slave(queue, slave); | ||
712 | |||
713 | kfree(slave); | ||
714 | |||
715 | return 0; | 660 | return 0; |
716 | } | 661 | } |
717 | 662 | ||
@@ -723,15 +668,14 @@ static int vrf_del_slave(struct net_device *dev, struct net_device *port_dev) | |||
723 | static void vrf_dev_uninit(struct net_device *dev) | 668 | static void vrf_dev_uninit(struct net_device *dev) |
724 | { | 669 | { |
725 | struct net_vrf *vrf = netdev_priv(dev); | 670 | struct net_vrf *vrf = netdev_priv(dev); |
726 | struct slave_queue *queue = &vrf->queue; | 671 | struct net_device *port_dev; |
727 | struct list_head *head = &queue->all_slaves; | 672 | struct list_head *iter; |
728 | struct slave *slave, *next; | ||
729 | 673 | ||
730 | vrf_rtable_destroy(vrf); | 674 | vrf_rtable_destroy(vrf); |
731 | vrf_rt6_destroy(vrf); | 675 | vrf_rt6_destroy(vrf); |
732 | 676 | ||
733 | list_for_each_entry_safe(slave, next, head, list) | 677 | netdev_for_each_lower_dev(dev, port_dev, iter) |
734 | vrf_del_slave(dev, slave->dev); | 678 | vrf_del_slave(dev, port_dev); |
735 | 679 | ||
736 | free_percpu(dev->dstats); | 680 | free_percpu(dev->dstats); |
737 | dev->dstats = NULL; | 681 | dev->dstats = NULL; |
@@ -741,8 +685,6 @@ static int vrf_dev_init(struct net_device *dev) | |||
741 | { | 685 | { |
742 | struct net_vrf *vrf = netdev_priv(dev); | 686 | struct net_vrf *vrf = netdev_priv(dev); |
743 | 687 | ||
744 | INIT_LIST_HEAD(&vrf->queue.all_slaves); | ||
745 | |||
746 | dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats); | 688 | dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats); |
747 | if (!dev->dstats) | 689 | if (!dev->dstats) |
748 | goto out_nomem; | 690 | goto out_nomem; |