diff options
author | Patrick McHardy <kaber@trash.net> | 2008-07-06 00:26:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-06 00:26:57 -0400 |
commit | 70c03b49b80ba3634958acc31853771019c0ebd3 (patch) | |
tree | 097861a5da46fc10696c97f21720c1e5053b322f /net/8021q/vlan_dev.c | |
parent | ce305002e1c9b90c2c151ce18bab0b895dd55ae6 (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_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) | |||
512 | struct vlan_dev_info *vlan = vlan_dev_info(dev); | 512 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
513 | u32 old_flags = vlan->flags; | 513 | u32 old_flags = vlan->flags; |
514 | 514 | ||
515 | if (mask & ~VLAN_FLAG_REORDER_HDR) | 515 | if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP)) |
516 | return -EINVAL; | 516 | return -EINVAL; |
517 | 517 | ||
518 | vlan->flags = (old_flags & ~mask) | (flags & mask); | 518 | vlan->flags = (old_flags & ~mask) | (flags & mask); |
519 | |||
520 | if (netif_running(dev) && (vlan->flags ^ old_flags) & VLAN_FLAG_GVRP) { | ||
521 | if (vlan->flags & VLAN_FLAG_GVRP) | ||
522 | vlan_gvrp_request_join(dev); | ||
523 | else | ||
524 | vlan_gvrp_request_leave(dev); | ||
525 | } | ||
519 | return 0; | 526 | return 0; |
520 | } | 527 | } |
521 | 528 | ||
@@ -550,12 +557,19 @@ static int vlan_dev_open(struct net_device *dev) | |||
550 | if (dev->flags & IFF_PROMISC) | 557 | if (dev->flags & IFF_PROMISC) |
551 | dev_set_promiscuity(real_dev, 1); | 558 | dev_set_promiscuity(real_dev, 1); |
552 | 559 | ||
560 | if (vlan->flags & VLAN_FLAG_GVRP) | ||
561 | vlan_gvrp_request_join(dev); | ||
562 | |||
553 | return 0; | 563 | return 0; |
554 | } | 564 | } |
555 | 565 | ||
556 | static int vlan_dev_stop(struct net_device *dev) | 566 | static int vlan_dev_stop(struct net_device *dev) |
557 | { | 567 | { |
558 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; | 568 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
569 | struct net_device *real_dev = vlan->real_dev; | ||
570 | |||
571 | if (vlan->flags & VLAN_FLAG_GVRP) | ||
572 | vlan_gvrp_request_leave(dev); | ||
559 | 573 | ||
560 | dev_mc_unsync(real_dev, dev); | 574 | dev_mc_unsync(real_dev, dev); |
561 | dev_unicast_unsync(real_dev, dev); | 575 | dev_unicast_unsync(real_dev, dev); |