aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q/vlan_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/8021q/vlan_dev.c')
-rw-r--r--net/8021q/vlan_dev.c18
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
556static int vlan_dev_stop(struct net_device *dev) 566static 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);