aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q
diff options
context:
space:
mode:
Diffstat (limited to 'net/8021q')
-rw-r--r--net/8021q/vlan.c28
-rw-r--r--net/8021q/vlan_dev.c2
2 files changed, 27 insertions, 3 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 2a739adaa92b..ab2225da0ee2 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -382,6 +382,18 @@ static void vlan_sync_address(struct net_device *dev,
382 memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); 382 memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN);
383} 383}
384 384
385static void vlan_transfer_features(struct net_device *dev,
386 struct net_device *vlandev)
387{
388 unsigned long old_features = vlandev->features;
389
390 vlandev->features &= ~dev->vlan_features;
391 vlandev->features |= dev->features & dev->vlan_features;
392
393 if (old_features != vlandev->features)
394 netdev_features_change(vlandev);
395}
396
385static void __vlan_device_event(struct net_device *dev, unsigned long event) 397static void __vlan_device_event(struct net_device *dev, unsigned long event)
386{ 398{
387 switch (event) { 399 switch (event) {
@@ -410,10 +422,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
410 int i, flgs; 422 int i, flgs;
411 struct net_device *vlandev; 423 struct net_device *vlandev;
412 424
413 if (is_vlan_dev(dev)) { 425 if (is_vlan_dev(dev))
414 __vlan_device_event(dev, event); 426 __vlan_device_event(dev, event);
415 goto out;
416 }
417 427
418 grp = __vlan_find_group(dev); 428 grp = __vlan_find_group(dev);
419 if (!grp) 429 if (!grp)
@@ -450,6 +460,18 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
450 } 460 }
451 break; 461 break;
452 462
463 case NETDEV_FEAT_CHANGE:
464 /* Propagate device features to underlying device */
465 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
466 vlandev = vlan_group_get_device(grp, i);
467 if (!vlandev)
468 continue;
469
470 vlan_transfer_features(dev, vlandev);
471 }
472
473 break;
474
453 case NETDEV_DOWN: 475 case NETDEV_DOWN:
454 /* Put all VLANs for this dev in the down state too. */ 476 /* Put all VLANs for this dev in the down state too. */
455 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 477 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index c961f0826005..5d055c242ed8 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -663,6 +663,8 @@ static int vlan_dev_init(struct net_device *dev)
663 (1<<__LINK_STATE_DORMANT))) | 663 (1<<__LINK_STATE_DORMANT))) |
664 (1<<__LINK_STATE_PRESENT); 664 (1<<__LINK_STATE_PRESENT);
665 665
666 dev->features |= real_dev->features & real_dev->vlan_features;
667
666 /* ipv6 shared card related stuff */ 668 /* ipv6 shared card related stuff */
667 dev->dev_id = real_dev->dev_id; 669 dev->dev_id = real_dev->dev_id;
668 670