diff mbox series

[SRU,F:linux-bluefield,3/5] net/sched: act_ct: clear post_ct if doing ct_clear

Message ID 20210411114602.2003649-4-roid@nvidia.com
State New
Headers show
Series offload support for ct state invalid and reply | expand

Commit Message

Roi Dayan April 11, 2021, 11:46 a.m. UTC
From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>

BugLink: https://bugs.launchpad.net/bugs/1922682

Invalid detection works with two distinct moments: act_ct tries to find
a conntrack entry and set post_ct true, indicating that that was
attempted. Then, when flow dissector tries to dissect CT info and no
entry is there, it knows that it was tried and no entry was found, and
                  key->ct_state = TCA_FLOWER_KEY_CT_FLAGS_TRACKED |
mimicing what OVS does.

OVS has this a bit more streamlined, as it recomputes the key after
trying to find a conntrack entry for it.

Issue here is, when we have 'tc action ct clear', it didn't clear
post_ct, causing a subsequent match on 'ct_state -trk' to fail, due to
the above. The fix, thus, is to clear it.

Reproducer rules:
tc filter add dev enp130s0f0np0_0 ingress prio 1 chain 0 \
	protocol ip flower ip_proto tcp ct_state -trk \
	action ct zone 1 pipe \
	action goto chain 2
tc filter add dev enp130s0f0np0_0 ingress prio 1 chain 2 \
	protocol ip flower \
	action ct clear pipe \
	action goto chain 4
tc filter add dev enp130s0f0np0_0 ingress prio 1 chain 4 \
	protocol ip flower ct_state -trk \
	action mirred egress redirect dev enp130s0f1np1_0

With the fix, the 3rd rule matches, like it does with OVS kernel

Fixes: 7baf2429a1a9 ("net/sched: cls_flower add CT_FLAGS_INVALID flag support")
Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Reviewed-by: wenxu <wenxu@ucloud.cn>
Signed-off-by: David S. Miller <davem@davemloft.net>
(backported from commit 8ca1b090e5c9a71abeea1dda8757f4ec3811f06e)
Signed-off-by: Roi Dayan <roid@nvidia.com>
 net/sched/act_ct.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
diff mbox series


diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index a117beaf063e..fe132943eac2 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -926,13 +926,14 @@  static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
 	tmpl = p->tmpl;
 	if (clear) {
+		qdisc_skb_cb(skb)->post_ct = false;
 		ct = nf_ct_get(skb, &ctinfo);
 		if (ct) {
 			nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
-		goto out;
+		goto out_clear;
 	family = tcf_ct_skb_nf_family(skb);
@@ -1011,8 +1012,9 @@  static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
 	skb_push_rcsum(skb, nh_ofs);
-	tcf_action_update_bstats(&c->common, skb);
 	qdisc_skb_cb(skb)->post_ct = true;
+	tcf_action_update_bstats(&c->common, skb);
 	return retval;