[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <2f1e72e3-5740-f1d3-2748-39d103772435@solarflare.com>
Date: Thu, 5 Jul 2018 15:47:39 +0100
From: Edward Cree <ecree@...arflare.com>
To: <davem@...emloft.net>
CC: <netdev@...r.kernel.org>
Subject: [PATCH net-next 1/2] net: ipv4: fix list processing on L3 slave
devices
If we have an L3 master device, l3mdev_ip_rcv() will steal the skb, but
we were returning NET_RX_SUCCESS from ip_rcv_finish_core() which meant
that ip_list_rcv_finish() would keep it on the list. Instead let's
move the l3mdev_ip_rcv() call into the caller, so that our response to
a steal can be different in the single packet path (return
NET_RX_SUCCESS) and the list path (forget this packet and continue).
Fixes: 5fa12739a53d net: ipv4: listify ip_rcv_finish
Signed-off-by: Edward Cree <ecree@...arflare.com>
---
net/ipv4/ip_input.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 14ba628b2761..1a3b6f32b1c9 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -316,13 +316,6 @@ static int ip_rcv_finish_core(struct net *net, struct sock *sk,
struct rtable *rt;
int err;
- /* if ingress device is enslaved to an L3 master device pass the
- * skb to its handler for processing
- */
- skb = l3mdev_ip_rcv(skb);
- if (!skb)
- return NET_RX_SUCCESS;
-
if (net->ipv4.sysctl_ip_early_demux &&
!skb_dst(skb) &&
!skb->sk &&
@@ -408,8 +401,16 @@ static int ip_rcv_finish_core(struct net *net, struct sock *sk,
static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
- int ret = ip_rcv_finish_core(net, sk, skb);
+ int ret;
+
+ /* if ingress device is enslaved to an L3 master device pass the
+ * skb to its handler for processing
+ */
+ skb = l3mdev_ip_rcv(skb);
+ if (!skb)
+ return NET_RX_SUCCESS;
+ ret = ip_rcv_finish_core(net, sk, skb);
if (ret != NET_RX_DROP)
ret = dst_input(skb);
return ret;
@@ -545,6 +546,12 @@ static void ip_list_rcv_finish(struct net *net, struct sock *sk,
struct dst_entry *dst;
list_del(&skb->list);
+ /* if ingress device is enslaved to an L3 master device pass the
+ * skb to its handler for processing
+ */
+ skb = l3mdev_ip_rcv(skb);
+ if (!skb)
+ continue;
if (ip_rcv_finish_core(net, sk, skb) == NET_RX_DROP)
continue;
Powered by blists - more mailing lists