From 9092e15defbe6c7bc241c306093ca9d358a578e7 Mon Sep 17 00:00:00 2001 From: Zihan Xi Date: Sun, 14 Jun 2026 01:42:39 +0800 Subject: [PATCH 1/2] net/sched: act_ct: preserve tc_skb_cb across defragmentation tcf_ct_handle_fragments() calls nf_ct_handle_fragments() without saving and restoring skb->cb. The defrag helper clears IPCB/IP6CB, which aliases the tc_skb_cb/qdisc_skb_cb control buffer. Fragmented traffic through act_ct therefore loses qdisc metadata such as pkt_segs and can trigger WARN_ON_ONCE() in qdisc_pkt_segs() when panic_on_warn is enabled. Save and restore the full tc_skb_cb around nf_ct_handle_fragments(), matching the pattern used by ovs_ct_handle_fragments(). Fixes: ec624fe740b4 ("net/sched: Extend qdisc control block with tc control block") Cc: stable@vger.kernel.org Reported-by: Yuan Tan Reported-by: Yifan Wu Reported-by: Juefei Pu Reported-by: Xin Liu Signed-off-by: Zihan Xi Signed-off-by: Ren Wei Link: https://patch.msgid.link/510c51217fd7aaf29c6dc298bab8d643fe229b1c.1781358692.git.xizh2024@lzu.edu.cn Signed-off-by: Jakub Kicinski --- net/sched/act_ct.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c index 6158e13c98d3..d47a82f9ac6c 100644 --- a/net/sched/act_ct.c +++ b/net/sched/act_ct.c @@ -844,11 +844,11 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, u8 family, u16 zone, bool *defrag) { enum ip_conntrack_info ctinfo; + struct tc_skb_cb cb; struct nf_conn *ct; int err = 0; bool frag; u8 proto; - u16 mru; /* Previously seen (loopback)? Ignore. */ ct = nf_ct_get(skb, &ctinfo); @@ -862,12 +862,13 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, if (err || !frag) return err; - err = nf_ct_handle_fragments(net, skb, zone, family, &proto, &mru); + cb = *tc_skb_cb(skb); + err = nf_ct_handle_fragments(net, skb, zone, family, &proto, &cb.mru); if (err) return err; *defrag = true; - tc_skb_cb(skb)->mru = mru; + *tc_skb_cb(skb) = cb; return 0; } From 1fd8f80a199d321dd429c9881adccd1413417ad9 Mon Sep 17 00:00:00 2001 From: Zihan Xi Date: Sun, 14 Jun 2026 01:42:40 +0800 Subject: [PATCH 2/2] selftests/tc-testing: act_ct: add TDC test for skb cb preservation across defrag Add a tc-testing case that sends IPv4 fragments through act_ct on clsact egress while a root prio qdisc is present on the transmit path. The test verifies that packet processing and qdisc accounting continue to work after conntrack defragmentation, covering tc_skb_cb preservation across defragmentation. Signed-off-by: Zihan Xi Signed-off-by: Ren Wei Link: https://patch.msgid.link/53493549fdbcb2de25788b7894c56baadbc5fede.1781358692.git.xizh2024@lzu.edu.cn Signed-off-by: Jakub Kicinski --- .../tc-testing/tc-tests/actions/ct.json | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/ct.json b/tools/testing/selftests/tc-testing/tc-tests/actions/ct.json index 33bb8f3ff8ed..da65f838bd52 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/ct.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/ct.json @@ -664,5 +664,43 @@ "teardown": [ "$TC qdisc del dev $DEV1 ingress_block 21 clsact" ] + }, + { + "id": "9c2a", + "name": "Act_ct preserves skb cb across defrag before prio dequeue", + "category": [ + "actions", + "ct", + "scapy" + ], + "plugins": { + "requires": [ + "nsPlugin", + "scapyPlugin" + ] + }, + "setup": [ + "$TC qdisc add dev $DUMMY root handle 1: prio", + "$TC qdisc add dev $DUMMY clsact", + "$TC qdisc add dev $DEV1 clsact", + "$TC filter add dev $DEV1 ingress protocol ip prio 1 matchall action mirred egress redirect dev $DUMMY" + ], + "cmdUnderTest": "$TC filter add dev $DUMMY egress protocol ip prio 1 matchall action ct zone 1 pipe", + "scapy": [ + { + "iface": "$DEV0", + "count": 1, + "packet": "[Ether()/frag for frag in fragment(IP(src='10.0.0.10', dst='10.0.0.1', id=1)/UDP(sport=12345, dport=9)/Raw(b'A' * 4000), fragsize=1400)]" + } + ], + "expExitCode": "0", + "verifyCmd": "$TC -s qdisc show dev $DUMMY | grep -A 1 '^qdisc prio 1:'", + "matchPattern": "Sent [1-9][0-9]* bytes [1-9][0-9]* pkt", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 clsact", + "$TC qdisc del dev $DUMMY clsact", + "$TC qdisc del dev $DUMMY root handle 1:" + ] } ]