net: more accurate network taps in transmit path
authorEric Dumazet <edumazet@google.com>
Tue, 18 Sep 2012 20:44:49 +0000 (20:44 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 19 Sep 2012 19:32:42 +0000 (15:32 -0400)
dev_queue_xmit_nit() should be called right before ndo_start_xmit()
calls or we might give wrong packet contents to taps users :

Packet checksum can be changed, or packet can be linearized or
segmented, and segments partially sent for the later case.

Also a memory allocation can fail and packet never really hit the
driver entry point.

Reported-by: Jamie Gloudon <jamie.gloudon@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/dev.c

index dcc673d0674c676128b0c66e499d60cf24281fe9..52cd1d7f004afac3065d7bdf190609573896b15e 100644 (file)
@@ -2213,9 +2213,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
                        skb_dst_drop(skb);
 
-               if (!list_empty(&ptype_all))
-                       dev_queue_xmit_nit(skb, dev);
-
                features = netif_skb_features(skb);
 
                if (vlan_tx_tag_present(skb) &&
@@ -2250,6 +2247,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                        }
                }
 
+               if (!list_empty(&ptype_all))
+                       dev_queue_xmit_nit(skb, dev);
+
                skb_len = skb->len;
                rc = ops->ndo_start_xmit(skb, dev);
                trace_net_dev_xmit(skb, rc, dev, skb_len);
@@ -2272,6 +2272,9 @@ gso:
                if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
                        skb_dst_drop(nskb);
 
+               if (!list_empty(&ptype_all))
+                       dev_queue_xmit_nit(nskb, dev);
+
                skb_len = nskb->len;
                rc = ops->ndo_start_xmit(nskb, dev);
                trace_net_dev_xmit(nskb, rc, dev, skb_len);