]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
net/sched: flow_dissector: Fix matching on zone id for invalid conns
authorPaul Blakey <paulb@nvidia.com>
Tue, 14 Dec 2021 17:24:34 +0000 (19:24 +0200)
committerPaolo Pisati <paolo.pisati@canonical.com>
Fri, 28 Jan 2022 09:59:55 +0000 (10:59 +0100)
BugLink: https://bugs.launchpad.net/bugs/1959376
[ Upstream commit 3849595866166b23bf6a0cb9ff87e06423167f67 ]

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>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
include/linux/skbuff.h
include/net/pkt_sched.h
net/core/flow_dissector.c
net/sched/act_ct.c
net/sched/cls_flower.c

index b8c273af2910c780dcfbc8f18fc05e115089010b..4f31ca71a82a7af17454ae70132af6d65accd807 100644 (file)
@@ -1370,7 +1370,7 @@ 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);
+                   bool post_ct, u16 zone);
 void
 skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
                             struct flow_dissector *flow_dissector,
index 05f18e81f3e87df005d222f253aa243c48dc0393..9e71691c491b7a1a00c5fb4ab55cb409704a3f3a 100644 (file)
@@ -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)
index bac0184cf3de773d4e02a98eb06cfd8b6a0adebe..edffdaa875f1f5bafca9735f6ed92be9750eaa98 100644 (file)
@@ -238,7 +238,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)
+                   size_t mapsize, bool post_ct, u16 zone)
 {
 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
        struct flow_dissector_key_ct *key;
@@ -260,6 +260,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;
        }
 
index 98e248b9c0b17e76bc764997ddc2bcd134b18c7a..ab3591408419ff54ec249266da3a364bb62fad94 100644 (file)
@@ -1049,6 +1049,7 @@ out_push:
        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;
index 161bd91c8c6b0efd46c51b3bb53d0dd42e8f4fc9..709348262410c9f7dd7c896aa8517f55bd0e104c 100644 (file)
@@ -311,6 +311,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 {
        struct cls_fl_head *head = rcu_dereference_bh(tp->root);
        bool post_ct = tc_skb_cb(skb)->post_ct;
+       u16 zone = tc_skb_cb(skb)->zone;
        struct fl_flow_key skb_key;
        struct fl_flow_mask *mask;
        struct cls_fl_filter *f;
@@ -328,7 +329,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
                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);
+                                   post_ct, zone);
                skb_flow_dissect_hash(skb, &mask->dissector, &skb_key);
                skb_flow_dissect(skb, &mask->dissector, &skb_key, 0);