aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q/vlan.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-07-06 00:26:57 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-06 00:26:57 -0400
commit70c03b49b80ba3634958acc31853771019c0ebd3 (patch)
tree097861a5da46fc10696c97f21720c1e5053b322f /net/8021q/vlan.c
parentce305002e1c9b90c2c151ce18bab0b895dd55ae6 (diff)
vlan: Add GVRP support
Add GVRP support for dynamically registering VLANs with switches. By default GVRP is disabled because we only support the applicant-only participant model, which means it should not be enabled on vlans that are members of a bridge. Since there is currently no way to cleanly determine that, the user is responsible for enabling it. The code is pretty small and low impact, its wrapped in a config option though because it depends on the GARP implementation and the STP core. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/8021q/vlan.c')
-rw-r--r--net/8021q/vlan.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 8cae2daeb1cc..b529110c9355 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -169,6 +169,8 @@ void unregister_vlan_dev(struct net_device *dev)
169 169
170 /* If the group is now empty, kill off the group. */ 170 /* If the group is now empty, kill off the group. */
171 if (grp->nr_vlans == 0) { 171 if (grp->nr_vlans == 0) {
172 vlan_gvrp_uninit_applicant(real_dev);
173
172 if (real_dev->features & NETIF_F_HW_VLAN_RX) 174 if (real_dev->features & NETIF_F_HW_VLAN_RX)
173 real_dev->vlan_rx_register(real_dev, NULL); 175 real_dev->vlan_rx_register(real_dev, NULL);
174 176
@@ -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);
@@ -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);