diff mbox series

[net,v2,2/3] net/sched: flow_dissector: Fix matching on zone id for invalid conns

Message ID 20211209075734.10199-3-paulb@nvidia.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series net/sched: Fix ct zone matching for invalid conntrack state | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net
netdev/fixes_present success Fixes tag present in non-next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 6019 this patch: 6019
netdev/cc_maintainers fail 1 blamed authors not CCed: kuba@kernel.org; 4 maintainers not CCed: alobakin@pm.me jonathan.lemon@gmail.com jiri@resnulli.us kuba@kernel.org
netdev/build_clang success Errors and warnings before: 1028 this patch: 1028
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 6169 this patch: 6169
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 67 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Paul Blakey Dec. 9, 2021, 7:57 a.m. UTC
If ct rejects a flow, it removes the conntrack info from the skb.
act_ct sets the post_ct variable so the dissector will see this case
as an +tracked +invalid state, but the zone id is lost with the
conntrack info.

To restore the zone id on such cases, set the last executed zone,
via the tc control block, when passing ct, and read it back in the
dissector if there is no ct info on the skb (invalid connection).

Fixes: 7baf2429a1a9 ("net/sched: cls_flower add CT_FLAGS_INVALID flag support")
Signed-off-by: Paul Blakey <paulb@nvidia.com>
---
 include/linux/skbuff.h    | 3 +--
 include/net/pkt_sched.h   | 1 +
 net/core/flow_dissector.c | 6 +++++-
 net/sched/act_ct.c        | 1 +
 net/sched/cls_flower.c    | 5 ++---
 5 files changed, 10 insertions(+), 6 deletions(-)

Comments

Jakub Kicinski Dec. 11, 2021, 4:52 a.m. UTC | #1
On Thu, 9 Dec 2021 09:57:33 +0200 Paul Blakey wrote:
> @@ -238,10 +239,12 @@ void
>  skb_flow_dissect_ct(const struct sk_buff *skb,
>  		    struct flow_dissector *flow_dissector,
>  		    void *target_container, u16 *ctinfo_map,
> -		    size_t mapsize, bool post_ct)
> +		    size_t mapsize)
>  {
>  #if IS_ENABLED(CONFIG_NF_CONNTRACK)
> +	bool post_ct = tc_skb_cb(skb)->post_ct;
>  	struct flow_dissector_key_ct *key;
> +	u16 zone = tc_skb_cb(skb)->zone;
>  	enum ip_conntrack_info ctinfo;
>  	struct nf_conn_labels *cl;
>  	struct nf_conn *ct;
> @@ -260,6 +263,7 @@ skb_flow_dissect_ct(const struct sk_buff *skb,
>  	if (!ct) {
>  		key->ct_state = TCA_FLOWER_KEY_CT_FLAGS_TRACKED |
>  				TCA_FLOWER_KEY_CT_FLAGS_INVALID;
> +		key->ct_zone = zone;
>  		return;
>  	}
>  

Why is flow dissector expecting skb cb to be TC now?
Please keep the appropriate abstractions intact.
Cong Wang Dec. 12, 2021, 12:47 a.m. UTC | #2
On Fri, Dec 10, 2021 at 8:52 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Thu, 9 Dec 2021 09:57:33 +0200 Paul Blakey wrote:
> > @@ -238,10 +239,12 @@ void
> >  skb_flow_dissect_ct(const struct sk_buff *skb,
> >                   struct flow_dissector *flow_dissector,
> >                   void *target_container, u16 *ctinfo_map,
> > -                 size_t mapsize, bool post_ct)
> > +                 size_t mapsize)
> >  {
> >  #if IS_ENABLED(CONFIG_NF_CONNTRACK)
> > +     bool post_ct = tc_skb_cb(skb)->post_ct;
> >       struct flow_dissector_key_ct *key;
> > +     u16 zone = tc_skb_cb(skb)->zone;
> >       enum ip_conntrack_info ctinfo;
> >       struct nf_conn_labels *cl;
> >       struct nf_conn *ct;
> > @@ -260,6 +263,7 @@ skb_flow_dissect_ct(const struct sk_buff *skb,
> >       if (!ct) {
> >               key->ct_state = TCA_FLOWER_KEY_CT_FLAGS_TRACKED |
> >                               TCA_FLOWER_KEY_CT_FLAGS_INVALID;
> > +             key->ct_zone = zone;
> >               return;
> >       }
> >
>
> Why is flow dissector expecting skb cb to be TC now?
> Please keep the appropriate abstractions intact.

Probably because only fl_classify() calls it, but I agree with you
on this point, this function is supposed to be TC independent.

Thanks.
Paul Blakey Dec. 14, 2021, 5:07 p.m. UTC | #3
On Sat, 11 Dec 2021, Jakub Kicinski wrote:

> On Thu, 9 Dec 2021 09:57:33 +0200 Paul Blakey wrote:
> > @@ -238,10 +239,12 @@ void
> >  skb_flow_dissect_ct(const struct sk_buff *skb,
> >  		    struct flow_dissector *flow_dissector,
> >  		    void *target_container, u16 *ctinfo_map,
> > -		    size_t mapsize, bool post_ct)
> > +		    size_t mapsize)
> >  {
> >  #if IS_ENABLED(CONFIG_NF_CONNTRACK)
> > +	bool post_ct = tc_skb_cb(skb)->post_ct;
> >  	struct flow_dissector_key_ct *key;
> > +	u16 zone = tc_skb_cb(skb)->zone;
> >  	enum ip_conntrack_info ctinfo;
> >  	struct nf_conn_labels *cl;
> >  	struct nf_conn *ct;
> > @@ -260,6 +263,7 @@ skb_flow_dissect_ct(const struct sk_buff *skb,
> >  	if (!ct) {
> >  		key->ct_state = TCA_FLOWER_KEY_CT_FLAGS_TRACKED |
> >  				TCA_FLOWER_KEY_CT_FLAGS_INVALID;
> > +		key->ct_zone = zone;
> >  		return;
> >  	}
> >  
> 
> Why is flow dissector expecting skb cb to be TC now?
> Please keep the appropriate abstractions intact.
> 

Will do. Sending v3.
diff mbox series

Patch

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c8cb7e697d47..155eb2ec54d8 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1379,8 +1379,7 @@  void
 skb_flow_dissect_ct(const struct sk_buff *skb,
 		    struct flow_dissector *flow_dissector,
 		    void *target_container,
-		    u16 *ctinfo_map, size_t mapsize,
-		    bool post_ct);
+		    u16 *ctinfo_map, size_t mapsize);
 void
 skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
 			     struct flow_dissector *flow_dissector,
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 05f18e81f3e8..9e71691c491b 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -198,6 +198,7 @@  struct tc_skb_cb {
 
 	u16 mru;
 	bool post_ct;
+	u16 zone; /* Only valid if post_ct = true */
 };
 
 static inline struct tc_skb_cb *tc_skb_cb(const struct sk_buff *skb)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 3255f57f5131..b52a4370162b 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -12,6 +12,7 @@ 
 #include <net/gre.h>
 #include <net/pptp.h>
 #include <net/tipc.h>
+#include <net/pkt_sched.h>
 #include <linux/igmp.h>
 #include <linux/icmp.h>
 #include <linux/sctp.h>
@@ -238,10 +239,12 @@  void
 skb_flow_dissect_ct(const struct sk_buff *skb,
 		    struct flow_dissector *flow_dissector,
 		    void *target_container, u16 *ctinfo_map,
-		    size_t mapsize, bool post_ct)
+		    size_t mapsize)
 {
 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
+	bool post_ct = tc_skb_cb(skb)->post_ct;
 	struct flow_dissector_key_ct *key;
+	u16 zone = tc_skb_cb(skb)->zone;
 	enum ip_conntrack_info ctinfo;
 	struct nf_conn_labels *cl;
 	struct nf_conn *ct;
@@ -260,6 +263,7 @@  skb_flow_dissect_ct(const struct sk_buff *skb,
 	if (!ct) {
 		key->ct_state = TCA_FLOWER_KEY_CT_FLAGS_TRACKED |
 				TCA_FLOWER_KEY_CT_FLAGS_INVALID;
+		key->ct_zone = zone;
 		return;
 	}
 
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index 98e248b9c0b1..ab3591408419 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -1049,6 +1049,7 @@  static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
 	skb_push_rcsum(skb, nh_ofs);
 
 	tc_skb_cb(skb)->post_ct = true;
+	tc_skb_cb(skb)->zone = p->zone;
 out_clear:
 	if (defrag)
 		qdisc_skb_cb(skb)->pkt_len = skb->len;
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 9782b93db1b3..c1a017822c6e 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -310,7 +310,6 @@  static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 		       struct tcf_result *res)
 {
 	struct cls_fl_head *head = rcu_dereference_bh(tp->root);
-	bool post_ct = tc_skb_cb(skb)->post_ct;
 	struct fl_flow_key skb_key;
 	struct fl_flow_mask *mask;
 	struct cls_fl_filter *f;
@@ -327,8 +326,8 @@  static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 		skb_flow_dissect_tunnel_info(skb, &mask->dissector, &skb_key);
 		skb_flow_dissect_ct(skb, &mask->dissector, &skb_key,
 				    fl_ct_info_to_flower_map,
-				    ARRAY_SIZE(fl_ct_info_to_flower_map),
-				    post_ct);
+				    ARRAY_SIZE(fl_ct_info_to_flower_map));
+
 		skb_flow_dissect_hash(skb, &mask->dissector, &skb_key);
 		skb_flow_dissect(skb, &mask->dissector, &skb_key,
 				 FLOW_DISSECTOR_F_STOP_BEFORE_ENCAP);