Merge tag 'nf-23-10-25' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf
authorJakub Kicinski <kuba@kernel.org>
Wed, 25 Oct 2023 23:02:06 +0000 (16:02 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 25 Oct 2023 23:02:06 +0000 (16:02 -0700)
Pablo Neira Ayuso says:

====================
Netfilter fixes for net

This patch contains two late Netfilter's flowtable fixes for net:

1) Flowtable GC pushes back packets to classic path in every GC run,
   ie. every second. This is because NF_FLOW_HW_ESTABLISHED is only
   used by sched/act_ct (never set) and IPS_SEEN_REPLY might be unset
   by the time the flow is offloaded (this status bit is only reliable
   in the sched/act_ct datapath).

2) sched/act_ct logic to push back packets to classic path to reevaluate
   if UDP flow is unidirectional only applies if IPS_HW_OFFLOAD_BIT is
   set on and no hardware offload request is pending to be handled.
   From Vlad Buslov.

These two patches fixes two problems that were introduced in the
previous 6.5 development cycle.

* tag 'nf-23-10-25' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
  net/sched: act_ct: additional checks for outdated flows
  netfilter: flowtable: GC pushes back packets to classic path
====================

Link: https://lore.kernel.org/r/20231025100819.2664-1-pablo@netfilter.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/netfilter/nf_flow_table.h
net/netfilter/nf_flow_table_core.c
net/sched/act_ct.c

index d466e1a..fe1507c 100644 (file)
@@ -53,6 +53,7 @@ struct nf_flowtable_type {
        struct list_head                list;
        int                             family;
        int                             (*init)(struct nf_flowtable *ft);
+       bool                            (*gc)(const struct flow_offload *flow);
        int                             (*setup)(struct nf_flowtable *ft,
                                                 struct net_device *dev,
                                                 enum flow_block_command cmd);
index 1d34d70..920a5a2 100644 (file)
@@ -316,12 +316,6 @@ void flow_offload_refresh(struct nf_flowtable *flow_table,
 }
 EXPORT_SYMBOL_GPL(flow_offload_refresh);
 
-static bool nf_flow_is_outdated(const struct flow_offload *flow)
-{
-       return test_bit(IPS_SEEN_REPLY_BIT, &flow->ct->status) &&
-               !test_bit(NF_FLOW_HW_ESTABLISHED, &flow->flags);
-}
-
 static inline bool nf_flow_has_expired(const struct flow_offload *flow)
 {
        return nf_flow_timeout_delta(flow->timeout) <= 0;
@@ -407,12 +401,18 @@ nf_flow_table_iterate(struct nf_flowtable *flow_table,
        return err;
 }
 
+static bool nf_flow_custom_gc(struct nf_flowtable *flow_table,
+                             const struct flow_offload *flow)
+{
+       return flow_table->type->gc && flow_table->type->gc(flow);
+}
+
 static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table,
                                    struct flow_offload *flow, void *data)
 {
        if (nf_flow_has_expired(flow) ||
            nf_ct_is_dying(flow->ct) ||
-           nf_flow_is_outdated(flow))
+           nf_flow_custom_gc(flow_table, flow))
                flow_offload_teardown(flow);
 
        if (test_bit(NF_FLOW_TEARDOWN, &flow->flags)) {
index 7c652d1..fb52d6f 100644 (file)
@@ -278,7 +278,16 @@ err_nat:
        return err;
 }
 
+static bool tcf_ct_flow_is_outdated(const struct flow_offload *flow)
+{
+       return test_bit(IPS_SEEN_REPLY_BIT, &flow->ct->status) &&
+              test_bit(IPS_HW_OFFLOAD_BIT, &flow->ct->status) &&
+              !test_bit(NF_FLOW_HW_PENDING, &flow->flags) &&
+              !test_bit(NF_FLOW_HW_ESTABLISHED, &flow->flags);
+}
+
 static struct nf_flowtable_type flowtable_ct = {
+       .gc             = tcf_ct_flow_is_outdated,
        .action         = tcf_ct_flow_table_fill_actions,
        .owner          = THIS_MODULE,
 };