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.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index ab2225da0ee2..b529110c9355 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -165,8 +165,12 @@ void unregister_vlan_dev(struct net_device *dev)
165 165
166 synchronize_net(); 166 synchronize_net();
167 167
168 unregister_netdevice(dev);
169
168 /* If the group is now empty, kill off the group. */ 170 /* If the group is now empty, kill off the group. */
169 if (grp->nr_vlans == 0) { 171 if (grp->nr_vlans == 0) {
172 vlan_gvrp_uninit_applicant(real_dev);
173
170 if (real_dev->features & NETIF_F_HW_VLAN_RX) 174 if (real_dev->features & NETIF_F_HW_VLAN_RX)
171 real_dev->vlan_rx_register(real_dev, NULL); 175 real_dev->vlan_rx_register(real_dev, NULL);
172 176
@@ -178,8 +182,6 @@ void unregister_vlan_dev(struct net_device *dev)
178 182
179 /* Get rid of the vlan's reference to real_dev */ 183 /* Get rid of the vlan's reference to real_dev */
180 dev_put(real_dev); 184 dev_put(real_dev);
181
182 unregister_netdevice(dev);
183} 185}
184 186
185static void vlan_transfer_operstate(const struct net_device *dev, 187static void vlan_transfer_operstate(const struct net_device *dev,
@@ -249,15 +251,18 @@ int register_vlan_dev(struct net_device *dev)
249 ngrp = grp = vlan_group_alloc(real_dev); 251 ngrp = grp = vlan_group_alloc(real_dev);
250 if (!grp) 252 if (!grp)
251 return -ENOBUFS; 253 return -ENOBUFS;
254 err = vlan_gvrp_init_applicant(real_dev);
255 if (err < 0)
256 goto out_free_group;
252 } 257 }
253 258
254 err = vlan_group_prealloc_vid(grp, vlan_id); 259 err = vlan_group_prealloc_vid(grp, vlan_id);
255 if (err < 0) 260 if (err < 0)
256 goto out_free_group; 261 goto out_uninit_applicant;
257 262
258 err = register_netdevice(dev); 263 err = register_netdevice(dev);
259 if (err < 0) 264 if (err < 0)
260 goto out_free_group; 265 goto out_uninit_applicant;
261 266
262 /* Account for reference in struct vlan_dev_info */ 267 /* Account for reference in struct vlan_dev_info */
263 dev_hold(real_dev); 268 dev_hold(real_dev);
@@ -278,6 +283,9 @@ int register_vlan_dev(struct net_device *dev)
278 283
279 return 0; 284 return 0;
280 285
286out_uninit_applicant:
287 if (ngrp)
288 vlan_gvrp_uninit_applicant(real_dev);
281out_free_group: 289out_free_group:
282 if (ngrp) 290 if (ngrp)
283 vlan_group_free(ngrp); 291 vlan_group_free(ngrp);
@@ -591,9 +599,9 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg)
591 err = -EPERM; 599 err = -EPERM;
592 if (!capable(CAP_NET_ADMIN)) 600 if (!capable(CAP_NET_ADMIN))
593 break; 601 break;
594 err = vlan_dev_set_vlan_flag(dev, 602 err = vlan_dev_change_flags(dev,
595 args.u.flag, 603 args.vlan_qos ? args.u.flag : 0,
596 args.vlan_qos); 604 args.u.flag);
597 break; 605 break;
598 606
599 case SET_VLAN_NAME_TYPE_CMD: 607 case SET_VLAN_NAME_TYPE_CMD:
@@ -713,14 +721,20 @@ static int __init vlan_proto_init(void)
713 if (err < 0) 721 if (err < 0)
714 goto err2; 722 goto err2;
715 723
716 err = vlan_netlink_init(); 724 err = vlan_gvrp_init();
717 if (err < 0) 725 if (err < 0)
718 goto err3; 726 goto err3;
719 727
728 err = vlan_netlink_init();
729 if (err < 0)
730 goto err4;
731
720 dev_add_pack(&vlan_packet_type); 732 dev_add_pack(&vlan_packet_type);
721 vlan_ioctl_set(vlan_ioctl_handler); 733 vlan_ioctl_set(vlan_ioctl_handler);
722 return 0; 734 return 0;
723 735
736err4:
737 vlan_gvrp_uninit();
724err3: 738err3:
725 unregister_netdevice_notifier(&vlan_notifier_block); 739 unregister_netdevice_notifier(&vlan_notifier_block);
726err2: 740err2:
@@ -745,8 +759,9 @@ static void __exit vlan_cleanup_module(void)
745 BUG_ON(!hlist_empty(&vlan_group_hash[i])); 759 BUG_ON(!hlist_empty(&vlan_group_hash[i]));
746 760
747 unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops); 761 unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops);
748
749 synchronize_net(); 762 synchronize_net();
763
764 vlan_gvrp_uninit();
750} 765}
751 766
752module_init(vlan_proto_init); 767module_init(vlan_proto_init);