summaryrefslogtreecommitdiff
path: root/net/8021q/vlan.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-07-05 21:26:57 -0700
committerDavid S. Miller <davem@davemloft.net>2008-07-05 21:26:57 -0700
commit70c03b49b80ba3634958acc31853771019c0ebd3 (patch)
tree097861a5da46fc10696c97f21720c1e5053b322f /net/8021q/vlan.c
parentce305002e1c9b90c2c151ce18bab0b895dd55ae6 (diff)
downloadlwn-70c03b49b80ba3634958acc31853771019c0ebd3.tar.gz
lwn-70c03b49b80ba3634958acc31853771019c0ebd3.zip
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)
/* If the group is now empty, kill off the group. */
if (grp->nr_vlans == 0) {
+ vlan_gvrp_uninit_applicant(real_dev);
+
if (real_dev->features & NETIF_F_HW_VLAN_RX)
real_dev->vlan_rx_register(real_dev, NULL);
@@ -249,15 +251,18 @@ int register_vlan_dev(struct net_device *dev)
ngrp = grp = vlan_group_alloc(real_dev);
if (!grp)
return -ENOBUFS;
+ err = vlan_gvrp_init_applicant(real_dev);
+ if (err < 0)
+ goto out_free_group;
}
err = vlan_group_prealloc_vid(grp, vlan_id);
if (err < 0)
- goto out_free_group;
+ goto out_uninit_applicant;
err = register_netdevice(dev);
if (err < 0)
- goto out_free_group;
+ goto out_uninit_applicant;
/* Account for reference in struct vlan_dev_info */
dev_hold(real_dev);
@@ -278,6 +283,9 @@ int register_vlan_dev(struct net_device *dev)
return 0;
+out_uninit_applicant:
+ if (ngrp)
+ vlan_gvrp_uninit_applicant(real_dev);
out_free_group:
if (ngrp)
vlan_group_free(ngrp);
@@ -713,14 +721,20 @@ static int __init vlan_proto_init(void)
if (err < 0)
goto err2;
- err = vlan_netlink_init();
+ err = vlan_gvrp_init();
if (err < 0)
goto err3;
+ err = vlan_netlink_init();
+ if (err < 0)
+ goto err4;
+
dev_add_pack(&vlan_packet_type);
vlan_ioctl_set(vlan_ioctl_handler);
return 0;
+err4:
+ vlan_gvrp_uninit();
err3:
unregister_netdevice_notifier(&vlan_notifier_block);
err2:
@@ -745,8 +759,9 @@ static void __exit vlan_cleanup_module(void)
BUG_ON(!hlist_empty(&vlan_group_hash[i]));
unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops);
-
synchronize_net();
+
+ vlan_gvrp_uninit();
}
module_init(vlan_proto_init);