net: Audit drivers to identify those needing IFF_TX_SKB_SHARING cleared
authorNeil Horman <nhorman@tuxdriver.com>
Tue, 26 Jul 2011 06:05:38 +0000 (06:05 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 28 Jul 2011 05:39:30 +0000 (22:39 -0700)
After the last patch, We are left in a state in which only drivers calling
ether_setup have IFF_TX_SKB_SHARING set (we assume that drivers touching real
hardware call ether_setup for their net_devices and don't hold any state in
their skbs.  There are a handful of drivers that violate this assumption of
course, and need to be fixed up.  This patch identifies those drivers, and marks
them as not being able to support the safe transmission of skbs by clearning the
IFF_TX_SKB_SHARING flag in priv_flags

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Karsten Keil <isdn@linux-pingi.de>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: Patrick McHardy <kaber@trash.net>
CC: Krzysztof Halasa <khc@pm.waw.pl>
CC: "John W. Linville" <linville@tuxdriver.com>
CC: Greg Kroah-Hartman <gregkh@suse.de>
CC: Marcel Holtmann <marcel@holtmann.org>
CC: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
14 files changed:
drivers/isdn/i4l/isdn_net.c
drivers/net/bonding/bond_main.c
drivers/net/ifb.c
drivers/net/macvlan.c
drivers/net/tun.c
drivers/net/veth.c
drivers/net/wan/hdlc_fr.c
drivers/net/wireless/airo.c
drivers/net/wireless/hostap/hostap_main.c
drivers/staging/ath6kl/os/linux/ar6000_drv.c
net/8021q/vlan_dev.c
net/bluetooth/bnep/netdev.c
net/l2tp/l2tp_eth.c
net/mac80211/iface.c

index 48e9cc0369b10214d798b4a857248340e444a7b3..1f73d7f7e0242e4e73d55582935f4ff0a11f6646 100644 (file)
@@ -2532,6 +2532,9 @@ static void _isdn_setup(struct net_device *dev)
 
        /* Setup the generic properties */
        dev->flags = IFF_NOARP|IFF_POINTOPOINT;
+
+       /* isdn prepends a header in the tx path, can't share skbs */
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        dev->header_ops = NULL;
        dev->netdev_ops = &isdn_netdev_ops;
 
index 02842d05c11f4fce72069db79de1ed155d3919cd..df21e84f8198f1e989026a71d5e2c1ccee0aa607 100644 (file)
@@ -1557,8 +1557,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
                        if (slave_dev->type != ARPHRD_ETHER)
                                bond_setup_by_slave(bond_dev, slave_dev);
-                       else
+                       else {
                                ether_setup(bond_dev);
+                               bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+                       }
 
                        netdev_bonding_change(bond_dev,
                                              NETDEV_POST_TYPE_CHANGE);
@@ -4330,7 +4332,7 @@ static void bond_setup(struct net_device *bond_dev)
        bond_dev->tx_queue_len = 0;
        bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
        bond_dev->priv_flags |= IFF_BONDING;
-       bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
+       bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
 
        /* At first, we block adding VLANs. That's the only way to
         * prevent problems that occur when adding VLANs over an
index 6e82dd32e8063b019dcba2918c8fb108d6ab7eb5..46b5f5fd686bab98b98aff86fbf3e43b0702ddb8 100644 (file)
@@ -183,7 +183,7 @@ static void ifb_setup(struct net_device *dev)
 
        dev->flags |= IFF_NOARP;
        dev->flags &= ~IFF_MULTICAST;
-       dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
+       dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
        random_ether_addr(dev->dev_addr);
 }
 
index ba631fcece34d795c4bfea754d0d192178cc622e..05172c39a0ceaab229c4c89411c7fabc7201ce0c 100644 (file)
@@ -572,7 +572,7 @@ void macvlan_common_setup(struct net_device *dev)
 {
        ether_setup(dev);
 
-       dev->priv_flags        &= ~IFF_XMIT_DST_RELEASE;
+       dev->priv_flags        &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
        dev->netdev_ops         = &macvlan_netdev_ops;
        dev->destructor         = free_netdev;
        dev->header_ops         = &macvlan_hard_header_ops,
index 9a6b3824da146bdc8943eaba02b0e48ec5dac74c..71f3d1a35b74ea4c0d1615bb5326e254a4475e63 100644 (file)
@@ -528,6 +528,7 @@ static void tun_net_init(struct net_device *dev)
                dev->netdev_ops = &tap_netdev_ops;
                /* Ethernet TAP Device */
                ether_setup(dev);
+               dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 
                random_ether_addr(dev->dev_addr);
 
index 7f78db7bd68db33e24a805bf4cfd3d995fe50011..5b23767ea817232a24b33a479f9b2014e895d1b6 100644 (file)
@@ -263,6 +263,8 @@ static void veth_setup(struct net_device *dev)
 {
        ether_setup(dev);
 
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+
        dev->netdev_ops = &veth_netdev_ops;
        dev->ethtool_ops = &veth_ethtool_ops;
        dev->features |= NETIF_F_LLTX;
index b25c9229a6a94646d4c6fccd4a7a3faff694b13e..eb2028187fbe1a5e7de31f862bd908d45fcd82e8 100644 (file)
@@ -1074,9 +1074,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
 
        used = pvc_is_used(pvc);
 
-       if (type == ARPHRD_ETHER)
+       if (type == ARPHRD_ETHER) {
                dev = alloc_netdev(0, "pvceth%d", ether_setup);
-       else
+               dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+       } else
                dev = alloc_netdev(0, "pvc%d", pvc_setup);
 
        if (!dev) {
index 55cf71fbffe32125d9bdbbbe429b98ed0acea35e..e1b3e3c134fdfaeccbd2f575734fa9754b9660e6 100644 (file)
@@ -2823,6 +2823,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
        dev->wireless_data = &ai->wireless_data;
        dev->irq = irq;
        dev->base_addr = port;
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 
        SET_NETDEV_DEV(dev, dmdev);
 
index d5084829c9e5426946ce6554e712d40796fa2695..89a116fba1de24f81d4fd3b25f7d5ad6e059c27a 100644 (file)
@@ -855,6 +855,7 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local,
 
        iface = netdev_priv(dev);
        ether_setup(dev);
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 
        /* kernel callbacks */
        if (iface) {
index 48dd9e3635967a61bdab81eac517c4076b8c29e1..8ff52899ddee175b27a2de32be2291aabb8a35a3 100644 (file)
@@ -6179,6 +6179,7 @@ int ar6000_create_ap_interface(struct ar6_softc *ar, char *ap_ifname)
     
     ether_setup(dev);
     init_netdev(dev, ap_ifname);
+    dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 
     if (register_netdev(dev)) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n"));
index 934e221c1d071e5403bd805e0064debc19d5b3f0..9d40a071d0382e7e893483066fa3bb5285fa8bc0 100644 (file)
@@ -695,7 +695,7 @@ void vlan_setup(struct net_device *dev)
        ether_setup(dev);
 
        dev->priv_flags         |= IFF_802_1Q_VLAN;
-       dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
+       dev->priv_flags         &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
        dev->tx_queue_len       = 0;
 
        dev->netdev_ops         = &vlan_netdev_ops;
index 8c100c9dae2833bcf3963a2cc4c8a9a2fcbdc064..d4f5dff7c95510f9b31cbd0797210f9105c0e098 100644 (file)
@@ -231,6 +231,7 @@ void bnep_net_setup(struct net_device *dev)
        dev->addr_len = ETH_ALEN;
 
        ether_setup(dev);
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        dev->netdev_ops = &bnep_netdev_ops;
 
        dev->watchdog_timeo  = HZ * 2;
index a8193f52c13c28ddb17c3e1c100b009d259a3d8f..d2726a74597d104eb3fa57b2f6b48ab297106f23 100644 (file)
@@ -103,7 +103,7 @@ static struct net_device_ops l2tp_eth_netdev_ops = {
 static void l2tp_eth_dev_setup(struct net_device *dev)
 {
        ether_setup(dev);
-
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        dev->netdev_ops         = &l2tp_eth_netdev_ops;
        dev->destructor         = free_netdev;
 }
index cd5fb40d3fd4bbb7579d21e8a37a1e27a1e1ffe4..556e7e6ddf0a6b26dda29a33c00ee6c4d0ffed5b 100644 (file)
@@ -698,6 +698,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
 static void ieee80211_if_setup(struct net_device *dev)
 {
        ether_setup(dev);
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        dev->netdev_ops = &ieee80211_dataif_ops;
        dev->destructor = free_netdev;
 }