X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2F8021q%2Fvlan_dev.c;h=460aabc09d2967758838eb938f0ef46d7879cc4b;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=b91d251f3fed2a142cbc91d931fac2b8e017bf8a;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index b91d251f3..460aabc09 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -138,15 +138,15 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, /* We have 12 bits of vlan ID. * - * We must not drop the vlan_group_lock until we hold a + * We must not drop allow preempt until we hold a * reference to the device (netif_rx does that) or we * fail. */ - spin_lock_bh(&vlan_group_lock); + rcu_read_lock(); skb->dev = __find_vlan_dev(dev, vid); if (!skb->dev) { - spin_unlock_bh(&vlan_group_lock); + rcu_read_unlock(); #ifdef VLAN_DEBUG printk(VLAN_DBG "%s: ERROR: No net_device for VID: %i on dev: %s [%i]\n", @@ -170,7 +170,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, */ if (dev != VLAN_DEV_INFO(skb->dev)->real_dev) { - spin_unlock_bh(&vlan_group_lock); + rcu_read_unlock(); #ifdef VLAN_DEBUG printk(VLAN_DBG "%s: dropping skb: %p because came in on wrong device, dev: %s real_dev: %s, skb_dev: %s\n", @@ -244,7 +244,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, /* TODO: Add a more specific counter here. */ stats->rx_errors++; } - spin_unlock_bh(&vlan_group_lock); + rcu_read_lock(); return 0; } @@ -273,7 +273,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, /* TODO: Add a more specific counter here. */ stats->rx_errors++; } - spin_unlock_bh(&vlan_group_lock); + rcu_read_unlock(); return 0; } @@ -296,7 +296,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, /* TODO: Add a more specific counter here. */ stats->rx_errors++; } - spin_unlock_bh(&vlan_group_lock); + rcu_read_unlock(); return 0; } @@ -727,7 +727,6 @@ static void vlan_flush_mc_list(struct net_device *dev) struct dev_mc_list *dmi = dev->mc_list; while (dmi) { - dev_mc_delete(dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); printk(KERN_DEBUG "%s: del %.2x:%.2x:%.2x:%.2x:%.2x:%.2x mcast address from vlan interface\n", dev->name, dmi->dmi_addr[0], @@ -736,6 +735,7 @@ static void vlan_flush_mc_list(struct net_device *dev) dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]); + dev_mc_delete(dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); dmi = dev->mc_list; } @@ -757,6 +757,34 @@ int vlan_dev_stop(struct net_device *dev) vlan_flush_mc_list(dev); return 0; } + +int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; + struct ifreq ifrr; + int err = -EOPNOTSUPP; + + strncpy(ifrr.ifr_name, real_dev->name, IFNAMSIZ); + ifrr.ifr_ifru = ifr->ifr_ifru; + + switch(cmd) { + case SIOCGMIIPHY: + case SIOCGMIIREG: + case SIOCSMIIREG: + if (real_dev->do_ioctl && netif_device_present(real_dev)) + err = real_dev->do_ioctl(dev, &ifrr, cmd); + break; + + case SIOCETHTOOL: + err = dev_ethtool(&ifrr); + } + + if (!err) + ifr->ifr_ifru = ifrr.ifr_ifru; + + return err; +} + /** Taken from Gleb + Lennert's VLAN code, and modified... */ void vlan_dev_set_multicast_list(struct net_device *vlan_dev) {