]> Git Repo - linux.git/commitdiff
act_ct: prepare for stolen verdict coming from conntrack and nat engine
authorFlorian Westphal <[email protected]>
Thu, 4 Jul 2024 11:29:20 +0000 (13:29 +0200)
committerDavid S. Miller <[email protected]>
Mon, 8 Jul 2024 10:35:31 +0000 (11:35 +0100)
At this time, conntrack either returns NF_ACCEPT or NF_DROP.
To improve debuging it would be nice to be able to replace NF_DROP verdict
with NF_DROP_REASON() helper,

This helper releases the skb instantly (so drop_monitor can pinpoint
exact location) and returns NF_STOLEN.

Prepare call sites to deal with this before introducing such changes
in conntrack and nat core.

Signed-off-by: Florian Westphal <[email protected]>
Reviewed-by: Simon Horman <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
net/sched/act_ct.c

index 2a96d9c1db65b9003b93b9719613eaa5fdef65f7..a6b7c514a181ce9cabcad9b536276cee7de92224 100644 (file)
@@ -944,6 +944,8 @@ static int tcf_ct_act_nat(struct sk_buff *skb,
                action |= BIT(NF_NAT_MANIP_DST);
 
        err = nf_ct_nat(skb, ct, ctinfo, &action, range, commit);
+       if (err != NF_ACCEPT)
+               return err & NF_VERDICT_MASK;
 
        if (action & BIT(NF_NAT_MANIP_SRC))
                tc_skb_cb(skb)->post_ct_snat = 1;
@@ -1035,7 +1037,7 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
                state.pf = family;
                err = nf_conntrack_in(skb, &state);
                if (err != NF_ACCEPT)
-                       goto out_push;
+                       goto nf_error;
        }
 
 do_nat:
@@ -1047,7 +1049,7 @@ do_nat:
 
        err = tcf_ct_act_nat(skb, ct, ctinfo, p->ct_action, &p->range, commit);
        if (err != NF_ACCEPT)
-               goto drop;
+               goto nf_error;
 
        if (!nf_ct_is_confirmed(ct) && commit && p->helper && !nfct_help(ct)) {
                err = __nf_ct_try_assign_helper(ct, p->tmpl, GFP_ATOMIC);
@@ -1061,8 +1063,9 @@ do_nat:
        }
 
        if (nf_ct_is_confirmed(ct) ? ((!cached && !skip_add) || add_helper) : commit) {
-               if (nf_ct_helper(skb, ct, ctinfo, family) != NF_ACCEPT)
-                       goto drop;
+               err = nf_ct_helper(skb, ct, ctinfo, family);
+               if (err != NF_ACCEPT)
+                       goto nf_error;
        }
 
        if (commit) {
@@ -1075,8 +1078,9 @@ do_nat:
                /* This will take care of sending queued events
                 * even if the connection is already confirmed.
                 */
-               if (nf_conntrack_confirm(skb) != NF_ACCEPT)
-                       goto drop;
+               err = nf_conntrack_confirm(skb);
+               if (err != NF_ACCEPT)
+                       goto nf_error;
        }
 
        if (!skip_add)
@@ -1100,6 +1104,21 @@ out_frag:
 drop:
        tcf_action_inc_drop_qstats(&c->common);
        return TC_ACT_SHOT;
+
+nf_error:
+       /* some verdicts store extra data in upper bits, such
+        * as errno or queue number.
+        */
+       switch (err & NF_VERDICT_MASK) {
+       case NF_DROP:
+               goto drop;
+       case NF_STOLEN:
+               tcf_action_inc_drop_qstats(&c->common);
+               return TC_ACT_CONSUMED;
+       default:
+               DEBUG_NET_WARN_ON_ONCE(1);
+               goto drop;
+       }
 }
 
 static const struct nla_policy ct_policy[TCA_CT_MAX + 1] = {
This page took 0.062831 seconds and 4 git commands to generate.