diff options
Diffstat (limited to 'net/8021q/vlan.c')
-rw-r--r-- | net/8021q/vlan.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index cda936b77d2..3fe4fc86055 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -31,6 +31,7 @@ #include <net/arp.h> #include <linux/rtnetlink.h> #include <linux/notifier.h> +#include <net/net_namespace.h> #include <linux/if_vlan.h> #include "vlan.h" @@ -50,7 +51,7 @@ static char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>"; static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>"; static int vlan_device_event(struct notifier_block *, unsigned long, void *); -static int vlan_ioctl_handler(void __user *); +static int vlan_ioctl_handler(struct net *net, void __user *); static int unregister_vlan_dev(struct net_device *, unsigned short ); static struct notifier_block vlan_notifier_block = { @@ -313,6 +314,12 @@ int unregister_vlan_device(struct net_device *dev) */ static struct lock_class_key vlan_netdev_xmit_lock_key; +static const struct header_ops vlan_header_ops = { + .create = vlan_dev_hard_header, + .rebuild = vlan_dev_rebuild_header, + .parse = eth_header_parse, +}; + static int vlan_dev_init(struct net_device *dev) { struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; @@ -324,24 +331,23 @@ static int vlan_dev_init(struct net_device *dev) (1<<__LINK_STATE_DORMANT))) | (1<<__LINK_STATE_PRESENT); + /* ipv6 shared card related stuff */ + dev->dev_id = real_dev->dev_id; + if (is_zero_ether_addr(dev->dev_addr)) memcpy(dev->dev_addr, real_dev->dev_addr, dev->addr_len); if (is_zero_ether_addr(dev->broadcast)) memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); if (real_dev->features & NETIF_F_HW_VLAN_TX) { - dev->hard_header = real_dev->hard_header; + dev->header_ops = real_dev->header_ops; dev->hard_header_len = real_dev->hard_header_len; dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit; - dev->rebuild_header = real_dev->rebuild_header; } else { - dev->hard_header = vlan_dev_hard_header; + dev->header_ops = &vlan_header_ops; dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; dev->hard_start_xmit = vlan_dev_hard_start_xmit; - dev->rebuild_header = vlan_dev_rebuild_header; } - dev->hard_header_parse = real_dev->hard_header_parse; - dev->hard_header_cache = NULL; lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key); return 0; @@ -349,8 +355,6 @@ static int vlan_dev_init(struct net_device *dev) void vlan_setup(struct net_device *new_dev) { - SET_MODULE_OWNER(new_dev); - ether_setup(new_dev); /* new_dev->ifindex = 0; it will be set when added to @@ -562,8 +566,6 @@ static int register_vlan_device(struct net_device *real_dev, if (err < 0) goto out_free_newdev; - /* Account for reference in struct vlan_dev_info */ - dev_hold(real_dev); #ifdef VLAN_DEBUG printk(VLAN_DBG "Allocated new device successfully, returning.\n"); #endif @@ -605,6 +607,9 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, int i, flgs; struct net_device *vlandev; + if (dev->nd_net != &init_net) + return NOTIFY_DONE; + if (!grp) goto out; @@ -695,7 +700,7 @@ out: * o execute requested action or pass command to the device driver * arg is really a struct vlan_ioctl_args __user *. */ -static int vlan_ioctl_handler(void __user *arg) +static int vlan_ioctl_handler(struct net *net, void __user *arg) { int err; unsigned short vid = 0; @@ -724,7 +729,7 @@ static int vlan_ioctl_handler(void __user *arg) case GET_VLAN_REALDEV_NAME_CMD: case GET_VLAN_VID_CMD: err = -ENODEV; - dev = __dev_get_by_name(args.device1); + dev = __dev_get_by_name(&init_net, args.device1); if (!dev) goto out; @@ -810,6 +815,7 @@ static int vlan_ioctl_handler(void __user *arg) err = -EINVAL; break; case GET_VLAN_REALDEV_NAME_CMD: + err = 0; vlan_dev_get_realdev_name(dev, args.u.device2); if (copy_to_user(arg, &args, sizeof(struct vlan_ioctl_args))) { @@ -818,6 +824,7 @@ static int vlan_ioctl_handler(void __user *arg) break; case GET_VLAN_VID_CMD: + err = 0; vlan_dev_get_vid(dev, &vid); args.u.VID = vid; if (copy_to_user(arg, &args, |