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 e7ddbfa0e02f..08f14f6c5fd6 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -383,6 +383,18 @@ static void vlan_sync_address(struct net_device *dev,
383 memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); 383 memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN);
384} 384}
385 385
386static void vlan_transfer_features(struct net_device *dev,
387 struct net_device *vlandev)
388{
389 unsigned long old_features = vlandev->features;
390
391 vlandev->features &= ~dev->vlan_features;
392 vlandev->features |= dev->features & dev->vlan_features;
393
394 if (old_features != vlandev->features)
395 netdev_features_change(vlandev);
396}
397
386static void __vlan_device_event(struct net_device *dev, unsigned long event) 398static void __vlan_device_event(struct net_device *dev, unsigned long event)
387{ 399{
388 switch (event) { 400 switch (event) {
@@ -411,10 +423,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
411 int i, flgs; 423 int i, flgs;
412 struct net_device *vlandev; 424 struct net_device *vlandev;
413 425
414 if (is_vlan_dev(dev)) { 426 if (is_vlan_dev(dev))
415 __vlan_device_event(dev, event); 427 __vlan_device_event(dev, event);
416 goto out;
417 }
418 428
419 grp = __vlan_find_group(dev); 429 grp = __vlan_find_group(dev);
420 if (!grp) 430 if (!grp)
@@ -451,6 +461,18 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
451 } 461 }
452 break; 462 break;
453 463
464 case NETDEV_FEAT_CHANGE:
465 /* Propagate device features to underlying device */
466 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
467 vlandev = vlan_group_get_device(grp, i);
468 if (!vlandev)
469 continue;
470
471 vlan_transfer_features(dev, vlandev);
472 }
473
474 break;
475
454 case NETDEV_DOWN: 476 case NETDEV_DOWN:
455 /* Put all VLANs for this dev in the down state too. */ 477 /* Put all VLANs for this dev in the down state too. */
456 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 478 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