summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorScott Feldman <sfeldma@gmail.com>2015-07-18 18:24:48 -0700
committerDavid S. Miller <davem@davemloft.net>2015-07-20 18:32:44 -0700
commit0c4f691ff6791e55ac831666df0b49b1679c56e4 (patch)
tree18117c556b621eb90c9d9ce1ebfd131ca2f681b6 /net
parent8254973fa3459b512b6c0cd5b0e4641e4d7c048c (diff)
net: don't reforward packets already forwarded by offload device
Just before queuing skb for xmit on port, check if skb has been marked by switchdev port driver as already fordwarded by device. If so, drop skb. A non-zero skb->offload_fwd_mark field is set by the switchdev port driver/device on ingress to indicate the skb has already been forwarded by the device to egress ports with matching dev->skb_mark. The switchdev port driver would assign a non-zero dev->offload_skb_mark for each device port netdev during registration, for example. Signed-off-by: Scott Feldman <sfeldma@gmail.com> Acked-by: Jiri Pirko <jiri@resnulli.us> Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com> Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 8810b6bbebfe..2ee15afb412d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3061,6 +3061,16 @@ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv)
else
skb_dst_force(skb);
+#ifdef CONFIG_NET_SWITCHDEV
+ /* Don't forward if offload device already forwarded */
+ if (skb->offload_fwd_mark &&
+ skb->offload_fwd_mark == dev->offload_fwd_mark) {
+ consume_skb(skb);
+ rc = NET_XMIT_SUCCESS;
+ goto out;
+ }
+#endif
+
txq = netdev_pick_tx(dev, skb, accel_priv);
q = rcu_dereference_bh(txq->qdisc);