Commit b40863c6 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

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: default avatarJamie Gloudon <jamie.gloudon@gmail.com>
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent adccff34
...@@ -2213,9 +2213,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, ...@@ -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) if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
skb_dst_drop(skb); skb_dst_drop(skb);
if (!list_empty(&ptype_all))
dev_queue_xmit_nit(skb, dev);
features = netif_skb_features(skb); features = netif_skb_features(skb);
if (vlan_tx_tag_present(skb) && if (vlan_tx_tag_present(skb) &&
...@@ -2250,6 +2247,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, ...@@ -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; skb_len = skb->len;
rc = ops->ndo_start_xmit(skb, dev); rc = ops->ndo_start_xmit(skb, dev);
trace_net_dev_xmit(skb, rc, dev, skb_len); trace_net_dev_xmit(skb, rc, dev, skb_len);
...@@ -2272,6 +2272,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, ...@@ -2272,6 +2272,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
if (dev->priv_flags & IFF_XMIT_DST_RELEASE) if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
skb_dst_drop(nskb); skb_dst_drop(nskb);
if (!list_empty(&ptype_all))
dev_queue_xmit_nit(nskb, dev);
skb_len = nskb->len; skb_len = nskb->len;
rc = ops->ndo_start_xmit(nskb, dev); rc = ops->ndo_start_xmit(nskb, dev);
trace_net_dev_xmit(nskb, rc, dev, skb_len); trace_net_dev_xmit(nskb, rc, dev, skb_len);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment