diff options
author | Patrick McHardy <kaber@trash.net> | 2008-07-06 08:26:57 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-06 08:26:57 +0400 |
commit | 70c03b49b80ba3634958acc31853771019c0ebd3 (patch) | |
tree | 097861a5da46fc10696c97f21720c1e5053b322f /net/8021q/vlan_dev.c | |
parent | ce305002e1c9b90c2c151ce18bab0b895dd55ae6 (diff) | |
download | linux-70c03b49b80ba3634958acc31853771019c0ebd3.tar.xz |
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_dev.c')
-rw-r--r-- | net/8021q/vlan_dev.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 76c665cdab66..a0617bf7cec6 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -512,10 +512,17 @@ int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask) struct vlan_dev_info *vlan = vlan_dev_info(dev); u32 old_flags = vlan->flags; - if (mask & ~VLAN_FLAG_REORDER_HDR) + if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP)) return -EINVAL; vlan->flags = (old_flags & ~mask) | (flags & mask); + + if (netif_running(dev) && (vlan->flags ^ old_flags) & VLAN_FLAG_GVRP) { + if (vlan->flags & VLAN_FLAG_GVRP) + vlan_gvrp_request_join(dev); + else + vlan_gvrp_request_leave(dev); + } return 0; } @@ -550,12 +557,19 @@ static int vlan_dev_open(struct net_device *dev) if (dev->flags & IFF_PROMISC) dev_set_promiscuity(real_dev, 1); + if (vlan->flags & VLAN_FLAG_GVRP) + vlan_gvrp_request_join(dev); + return 0; } static int vlan_dev_stop(struct net_device *dev) { - struct net_device *real_dev = vlan_dev_info(dev)->real_dev; + struct vlan_dev_info *vlan = vlan_dev_info(dev); + struct net_device *real_dev = vlan->real_dev; + + if (vlan->flags & VLAN_FLAG_GVRP) + vlan_gvrp_request_leave(dev); dev_mc_unsync(real_dev, dev); dev_unicast_unsync(real_dev, dev); |