diff options
author | Eric Dumazet <edumazet@google.com> | 2012-09-19 00:44:49 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-09-19 23:32:42 +0400 |
commit | b40863c667c16b7a73d4f034a8eab67029b5b15a (patch) | |
tree | eb69adf4283657af39e74c9a9fa3928603b780bb /net/core | |
parent | adccff34de1ef81564b7e6c436f762e7a1caf807 (diff) | |
download | linux-b40863c667c16b7a73d4f034a8eab67029b5b15a.tar.xz |
net: more accurate network taps in transmit path
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>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index dcc673d0674c..52cd1d7f004a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -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); |