diff options
Diffstat (limited to 'net/8021q')
-rw-r--r-- | net/8021q/vlan.c | 28 | ||||
-rw-r--r-- | net/8021q/vlan_dev.c | 2 | ||||
-rw-r--r-- | net/8021q/vlanproc.c | 7 |
3 files changed, 30 insertions, 7 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 2a739ad..ab2225d 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -382,6 +382,18 @@ static void vlan_sync_address(struct net_device *dev, memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); } +static void vlan_transfer_features(struct net_device *dev, + struct net_device *vlandev) +{ + unsigned long old_features = vlandev->features; + + vlandev->features &= ~dev->vlan_features; + vlandev->features |= dev->features & dev->vlan_features; + + if (old_features != vlandev->features) + netdev_features_change(vlandev); +} + static void __vlan_device_event(struct net_device *dev, unsigned long event) { switch (event) { @@ -410,10 +422,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, int i, flgs; struct net_device *vlandev; - if (is_vlan_dev(dev)) { + if (is_vlan_dev(dev)) __vlan_device_event(dev, event); - goto out; - } grp = __vlan_find_group(dev); if (!grp) @@ -450,6 +460,18 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, } break; + case NETDEV_FEAT_CHANGE: + /* Propagate device features to underlying device */ + for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + vlandev = vlan_group_get_device(grp, i); + if (!vlandev) + continue; + + vlan_transfer_features(dev, vlandev); + } + + break; + case NETDEV_DOWN: /* Put all VLANs for this dev in the down state too. */ for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index c961f08..5d055c2 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) (1<<__LINK_STATE_DORMANT))) | (1<<__LINK_STATE_PRESENT); + dev->features |= real_dev->features & real_dev->vlan_features; + /* ipv6 shared card related stuff */ dev->dev_id = real_dev->dev_id; diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index daad006..08b54b5 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c @@ -176,12 +176,11 @@ int vlan_proc_add_dev(struct net_device *vlandev) struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id); - dev_info->dent = proc_create(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR, - vn->proc_vlan_dir, &vlandev_fops); + dev_info->dent = + proc_create_data(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR, + vn->proc_vlan_dir, &vlandev_fops, vlandev); if (!dev_info->dent) return -ENOBUFS; - - dev_info->dent->data = vlandev; return 0; } |