Patch "net: Fix return value of qdisc ingress handling on success" has been added to the 6.0-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net: Fix return value of qdisc ingress handling on success

to the 6.0-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-fix-return-value-of-qdisc-ingress-handling-on-su.patch
and it can be found in the queue-6.0 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 2d515bbb2d4ebd5575bb24e6fb554eee2012d9cd
Author: Paul Blakey <paulb@xxxxxxxxxx>
Date:   Tue Oct 18 10:34:38 2022 +0300

    net: Fix return value of qdisc ingress handling on success
    
    [ Upstream commit 672e97ef689a38cb20c2cc6a1814298fea34461e ]
    
    Currently qdisc ingress handling (sch_handle_ingress()) doesn't
    set a return value and it is left to the old return value of
    the caller (__netif_receive_skb_core()) which is RX drop, so if
    the packet is consumed, caller will stop and return this value
    as if the packet was dropped.
    
    This causes a problem in the kernel tcp stack when having a
    egress tc rule forwarding to a ingress tc rule.
    The tcp stack sending packets on the device having the egress rule
    will see the packets as not successfully transmitted (although they
    actually were), will not advance it's internal state of sent data,
    and packets returning on such tcp stream will be dropped by the tcp
    stack with reason ack-of-unsent-data. See reproduction in [0] below.
    
    Fix that by setting the return value to RX success if
    the packet was handled successfully.
    
    [0] Reproduction steps:
     $ ip link add veth1 type veth peer name peer1
     $ ip link add veth2 type veth peer name peer2
     $ ifconfig peer1 5.5.5.6/24 up
     $ ip netns add ns0
     $ ip link set dev peer2 netns ns0
     $ ip netns exec ns0 ifconfig peer2 5.5.5.5/24 up
     $ ifconfig veth2 0 up
     $ ifconfig veth1 0 up
    
     #ingress forwarding veth1 <-> veth2
     $ tc qdisc add dev veth2 ingress
     $ tc qdisc add dev veth1 ingress
     $ tc filter add dev veth2 ingress prio 1 proto all flower \
       action mirred egress redirect dev veth1
     $ tc filter add dev veth1 ingress prio 1 proto all flower \
       action mirred egress redirect dev veth2
    
     #steal packet from peer1 egress to veth2 ingress, bypassing the veth pipe
     $ tc qdisc add dev peer1 clsact
     $ tc filter add dev peer1 egress prio 20 proto ip flower \
       action mirred ingress redirect dev veth1
    
     #run iperf and see connection not running
     $ iperf3 -s&
     $ ip netns exec ns0 iperf3 -c 5.5.5.6 -i 1
    
     #delete egress rule, and run again, now should work
     $ tc filter del dev peer1 egress
     $ ip netns exec ns0 iperf3 -c 5.5.5.6 -i 1
    
    Fixes: f697c3e8b35c ("[NET]: Avoid unnecessary cloning for ingress filtering")
    Signed-off-by: Paul Blakey <paulb@xxxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/core/dev.c b/net/core/dev.c
index 56c8b0921c9f..2c14f48d2457 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5136,11 +5136,13 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
 	case TC_ACT_SHOT:
 		mini_qdisc_qstats_cpu_drop(miniq);
 		kfree_skb_reason(skb, SKB_DROP_REASON_TC_INGRESS);
+		*ret = NET_RX_DROP;
 		return NULL;
 	case TC_ACT_STOLEN:
 	case TC_ACT_QUEUED:
 	case TC_ACT_TRAP:
 		consume_skb(skb);
+		*ret = NET_RX_SUCCESS;
 		return NULL;
 	case TC_ACT_REDIRECT:
 		/* skb_mac_header check was done by cls/act_bpf, so
@@ -5153,8 +5155,10 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
 			*another = true;
 			break;
 		}
+		*ret = NET_RX_SUCCESS;
 		return NULL;
 	case TC_ACT_CONSUMED:
+		*ret = NET_RX_SUCCESS;
 		return NULL;
 	default:
 		break;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux