aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q/vlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/8021q/vlan.c')
-rw-r--r--net/8021q/vlan.c90
1 files changed, 29 insertions, 61 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index a29c5ab5815c..33f90e7362cc 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -41,7 +41,7 @@
41 41
42/* Global VLAN variables */ 42/* Global VLAN variables */
43 43
44int vlan_net_id; 44int vlan_net_id __read_mostly;
45 45
46/* Our listing of VLAN group(s) */ 46/* Our listing of VLAN group(s) */
47static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE]; 47static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
@@ -140,7 +140,7 @@ static void vlan_rcu_free(struct rcu_head *rcu)
140 vlan_group_free(container_of(rcu, struct vlan_group, rcu)); 140 vlan_group_free(container_of(rcu, struct vlan_group, rcu));
141} 141}
142 142
143void unregister_vlan_dev(struct net_device *dev) 143void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
144{ 144{
145 struct vlan_dev_info *vlan = vlan_dev_info(dev); 145 struct vlan_dev_info *vlan = vlan_dev_info(dev);
146 struct net_device *real_dev = vlan->real_dev; 146 struct net_device *real_dev = vlan->real_dev;
@@ -159,12 +159,13 @@ void unregister_vlan_dev(struct net_device *dev)
159 if (real_dev->features & NETIF_F_HW_VLAN_FILTER) 159 if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
160 ops->ndo_vlan_rx_kill_vid(real_dev, vlan_id); 160 ops->ndo_vlan_rx_kill_vid(real_dev, vlan_id);
161 161
162 vlan_group_set_device(grp, vlan_id, NULL);
163 grp->nr_vlans--; 162 grp->nr_vlans--;
164 163
165 synchronize_net(); 164 vlan_group_set_device(grp, vlan_id, NULL);
165 if (!grp->killall)
166 synchronize_net();
166 167
167 unregister_netdevice(dev); 168 unregister_netdevice_queue(dev, head);
168 169
169 /* If the group is now empty, kill off the group. */ 170 /* If the group is now empty, kill off the group. */
170 if (grp->nr_vlans == 0) { 171 if (grp->nr_vlans == 0) {
@@ -183,27 +184,6 @@ void unregister_vlan_dev(struct net_device *dev)
183 dev_put(real_dev); 184 dev_put(real_dev);
184} 185}
185 186
186static void vlan_transfer_operstate(const struct net_device *dev,
187 struct net_device *vlandev)
188{
189 /* Have to respect userspace enforced dormant state
190 * of real device, also must allow supplicant running
191 * on VLAN device
192 */
193 if (dev->operstate == IF_OPER_DORMANT)
194 netif_dormant_on(vlandev);
195 else
196 netif_dormant_off(vlandev);
197
198 if (netif_carrier_ok(dev)) {
199 if (!netif_carrier_ok(vlandev))
200 netif_carrier_on(vlandev);
201 } else {
202 if (netif_carrier_ok(vlandev))
203 netif_carrier_off(vlandev);
204 }
205}
206
207int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id) 187int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id)
208{ 188{
209 const char *name = real_dev->name; 189 const char *name = real_dev->name;
@@ -261,7 +241,7 @@ int register_vlan_dev(struct net_device *dev)
261 /* Account for reference in struct vlan_dev_info */ 241 /* Account for reference in struct vlan_dev_info */
262 dev_hold(real_dev); 242 dev_hold(real_dev);
263 243
264 vlan_transfer_operstate(real_dev, dev); 244 netif_stacked_transfer_operstate(real_dev, dev);
265 linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */ 245 linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */
266 246
267 /* So, got the sucker initialized, now lets place 247 /* So, got the sucker initialized, now lets place
@@ -430,6 +410,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
430 struct vlan_group *grp; 410 struct vlan_group *grp;
431 int i, flgs; 411 int i, flgs;
432 struct net_device *vlandev; 412 struct net_device *vlandev;
413 struct vlan_dev_info *vlan;
414 LIST_HEAD(list);
433 415
434 if (is_vlan_dev(dev)) 416 if (is_vlan_dev(dev))
435 __vlan_device_event(dev, event); 417 __vlan_device_event(dev, event);
@@ -450,7 +432,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
450 if (!vlandev) 432 if (!vlandev)
451 continue; 433 continue;
452 434
453 vlan_transfer_operstate(dev, vlandev); 435 netif_stacked_transfer_operstate(dev, vlandev);
454 } 436 }
455 break; 437 break;
456 438
@@ -505,8 +487,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
505 if (!(flgs & IFF_UP)) 487 if (!(flgs & IFF_UP))
506 continue; 488 continue;
507 489
508 dev_change_flags(vlandev, flgs & ~IFF_UP); 490 vlan = vlan_dev_info(vlandev);
509 vlan_transfer_operstate(dev, vlandev); 491 if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
492 dev_change_flags(vlandev, flgs & ~IFF_UP);
493 netif_stacked_transfer_operstate(dev, vlandev);
510 } 494 }
511 break; 495 break;
512 496
@@ -521,13 +505,17 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
521 if (flgs & IFF_UP) 505 if (flgs & IFF_UP)
522 continue; 506 continue;
523 507
524 dev_change_flags(vlandev, flgs | IFF_UP); 508 vlan = vlan_dev_info(vlandev);
525 vlan_transfer_operstate(dev, vlandev); 509 if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
510 dev_change_flags(vlandev, flgs | IFF_UP);
511 netif_stacked_transfer_operstate(dev, vlandev);
526 } 512 }
527 break; 513 break;
528 514
529 case NETDEV_UNREGISTER: 515 case NETDEV_UNREGISTER:
530 /* Delete all VLANs for this dev. */ 516 /* Delete all VLANs for this dev. */
517 grp->killall = 1;
518
531 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 519 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
532 vlandev = vlan_group_get_device(grp, i); 520 vlandev = vlan_group_get_device(grp, i);
533 if (!vlandev) 521 if (!vlandev)
@@ -538,8 +526,9 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
538 if (grp->nr_vlans == 1) 526 if (grp->nr_vlans == 1)
539 i = VLAN_GROUP_ARRAY_LEN; 527 i = VLAN_GROUP_ARRAY_LEN;
540 528
541 unregister_vlan_dev(vlandev); 529 unregister_vlan_dev(vlandev, &list);
542 } 530 }
531 unregister_netdevice_many(&list);
543 break; 532 break;
544 } 533 }
545 534
@@ -645,7 +634,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg)
645 err = -EPERM; 634 err = -EPERM;
646 if (!capable(CAP_NET_ADMIN)) 635 if (!capable(CAP_NET_ADMIN))
647 break; 636 break;
648 unregister_vlan_dev(dev); 637 unregister_vlan_dev(dev, NULL);
649 err = 0; 638 err = 0;
650 break; 639 break;
651 640
@@ -676,47 +665,26 @@ out:
676 665
677static int vlan_init_net(struct net *net) 666static int vlan_init_net(struct net *net)
678{ 667{
668 struct vlan_net *vn = net_generic(net, vlan_net_id);
679 int err; 669 int err;
680 struct vlan_net *vn;
681
682 err = -ENOMEM;
683 vn = kzalloc(sizeof(struct vlan_net), GFP_KERNEL);
684 if (vn == NULL)
685 goto err_alloc;
686
687 err = net_assign_generic(net, vlan_net_id, vn);
688 if (err < 0)
689 goto err_assign;
690 670
691 vn->name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD; 671 vn->name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;
692 672
693 err = vlan_proc_init(net); 673 err = vlan_proc_init(net);
694 if (err < 0)
695 goto err_proc;
696
697 return 0;
698 674
699err_proc:
700 /* nothing */
701err_assign:
702 kfree(vn);
703err_alloc:
704 return err; 675 return err;
705} 676}
706 677
707static void vlan_exit_net(struct net *net) 678static void vlan_exit_net(struct net *net)
708{ 679{
709 struct vlan_net *vn;
710
711 vn = net_generic(net, vlan_net_id);
712 rtnl_kill_links(net, &vlan_link_ops);
713 vlan_proc_cleanup(net); 680 vlan_proc_cleanup(net);
714 kfree(vn);
715} 681}
716 682
717static struct pernet_operations vlan_net_ops = { 683static struct pernet_operations vlan_net_ops = {
718 .init = vlan_init_net, 684 .init = vlan_init_net,
719 .exit = vlan_exit_net, 685 .exit = vlan_exit_net,
686 .id = &vlan_net_id,
687 .size = sizeof(struct vlan_net),
720}; 688};
721 689
722static int __init vlan_proto_init(void) 690static int __init vlan_proto_init(void)
@@ -726,7 +694,7 @@ static int __init vlan_proto_init(void)
726 pr_info("%s v%s %s\n", vlan_fullname, vlan_version, vlan_copyright); 694 pr_info("%s v%s %s\n", vlan_fullname, vlan_version, vlan_copyright);
727 pr_info("All bugs added by %s\n", vlan_buggyright); 695 pr_info("All bugs added by %s\n", vlan_buggyright);
728 696
729 err = register_pernet_gen_device(&vlan_net_id, &vlan_net_ops); 697 err = register_pernet_subsys(&vlan_net_ops);
730 if (err < 0) 698 if (err < 0)
731 goto err0; 699 goto err0;
732 700
@@ -751,7 +719,7 @@ err4:
751err3: 719err3:
752 unregister_netdevice_notifier(&vlan_notifier_block); 720 unregister_netdevice_notifier(&vlan_notifier_block);
753err2: 721err2:
754 unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops); 722 unregister_pernet_subsys(&vlan_net_ops);
755err0: 723err0:
756 return err; 724 return err;
757} 725}
@@ -771,7 +739,7 @@ static void __exit vlan_cleanup_module(void)
771 for (i = 0; i < VLAN_GRP_HASH_SIZE; i++) 739 for (i = 0; i < VLAN_GRP_HASH_SIZE; i++)
772 BUG_ON(!hlist_empty(&vlan_group_hash[i])); 740 BUG_ON(!hlist_empty(&vlan_group_hash[i]));
773 741
774 unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops); 742 unregister_pernet_subsys(&vlan_net_ops);
775 rcu_barrier(); /* Wait for completion of call_rcu()'s */ 743 rcu_barrier(); /* Wait for completion of call_rcu()'s */
776 744
777 vlan_gvrp_uninit(); 745 vlan_gvrp_uninit();