kernel: fix conntrack fixup of offloaded flows on timeout
authorFelix Fietkau <nbd@nbd.name>
Thu, 14 Jun 2018 09:25:23 +0000 (11:25 +0200)
committerFelix Fietkau <nbd@nbd.name>
Thu, 14 Jun 2018 09:48:05 +0000 (11:48 +0200)
Fixes excessively long conntrack timeout of short lived connections

Signed-off-by: Felix Fietkau <nbd@nbd.name>
target/linux/generic/backport-4.14/371-netfilter-nf_flow_table-fix-up-ct-state-of-flows-aft.patch [new file with mode: 0644]
target/linux/generic/pending-4.14/640-netfilter-nf_flow_table-add-hardware-offload-support.patch
target/linux/generic/pending-4.14/645-netfilter-nf_flow_table-rework-hardware-offload-time.patch

diff --git a/target/linux/generic/backport-4.14/371-netfilter-nf_flow_table-fix-up-ct-state-of-flows-aft.patch b/target/linux/generic/backport-4.14/371-netfilter-nf_flow_table-fix-up-ct-state-of-flows-aft.patch
new file mode 100644 (file)
index 0000000..fb14a28
--- /dev/null
@@ -0,0 +1,24 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 14 Jun 2018 11:20:09 +0200
+Subject: [PATCH] netfilter: nf_flow_table: fix up ct state of flows after
+ timeout
+
+If a connection simply times out instead of being torn down, it is left
+active with a long timeout. Fix this by calling flow_offload_fixup_ct_state
+here as well.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/netfilter/nf_flow_table_core.c
++++ b/net/netfilter/nf_flow_table_core.c
+@@ -233,6 +233,9 @@ static void flow_offload_del(struct nf_f
+       e = container_of(flow, struct flow_offload_entry, flow);
+       clear_bit(IPS_OFFLOAD_BIT, &e->ct->status);
++      if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN))
++              flow_offload_fixup_ct_state(e->ct);
++
+       flow_offload_free(flow);
+ }
index ad77215843e96be6235b80ecb333a81fac0971e8..73475a54335f20857c66c0afb6bd8a48d30e0c24 100644 (file)
@@ -173,9 +173,9 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  
        rhashtable_remove_fast(&flow_table->rhashtable,
                               &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node,
-@@ -233,6 +239,9 @@ static void flow_offload_del(struct nf_f
-       e = container_of(flow, struct flow_offload_entry, flow);
-       clear_bit(IPS_OFFLOAD_BIT, &e->ct->status);
+@@ -236,6 +242,9 @@ static void flow_offload_del(struct nf_f
+       if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN))
+               flow_offload_fixup_ct_state(e->ct);
  
 +      if (nf_flow_in_hw(flow))
 +              nf_flow_offload_hw_del(net, flow);
@@ -183,7 +183,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
        flow_offload_free(flow);
  }
  
-@@ -346,6 +355,9 @@ static int nf_flow_offload_gc_step(struc
+@@ -349,6 +358,9 @@ static int nf_flow_offload_gc_step(struc
                if (!teardown)
                        nf_ct_offload_timeout(flow);
  
@@ -193,7 +193,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
                if (nf_flow_has_expired(flow) || teardown)
                        flow_offload_del(flow_table, flow);
        }
-@@ -481,10 +493,43 @@ int nf_flow_dnat_port(const struct flow_
+@@ -484,10 +496,43 @@ int nf_flow_dnat_port(const struct flow_
  }
  EXPORT_SYMBOL_GPL(nf_flow_dnat_port);
  
@@ -237,7 +237,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
        INIT_DEFERRABLE_WORK(&flowtable->gc_work, nf_flow_offload_work_gc);
  
        err = rhashtable_init(&flowtable->rhashtable,
-@@ -522,6 +567,8 @@ static void nf_flow_table_iterate_cleanu
+@@ -525,6 +570,8 @@ static void nf_flow_table_iterate_cleanu
  {
        nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev);
        flush_delayed_work(&flowtable->gc_work);
@@ -246,7 +246,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  }
  
  void nf_flow_table_cleanup(struct net *net, struct net_device *dev)
-@@ -535,6 +582,26 @@ void nf_flow_table_cleanup(struct net *n
+@@ -538,6 +585,26 @@ void nf_flow_table_cleanup(struct net *n
  }
  EXPORT_SYMBOL_GPL(nf_flow_table_cleanup);
  
@@ -273,7 +273,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  void nf_flow_table_free(struct nf_flowtable *flow_table)
  {
        mutex_lock(&flowtable_lock);
-@@ -544,9 +611,58 @@ void nf_flow_table_free(struct nf_flowta
+@@ -547,9 +614,58 @@ void nf_flow_table_free(struct nf_flowta
        nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL);
        WARN_ON(!nf_flow_offload_gc_step(flow_table));
        rhashtable_destroy(&flow_table->rhashtable);
index 2b3725f81e05be7798292ee30e0ce5080d02812b..8f0793491ba4e30249fc79cbcaff158ff5946eaf 100644 (file)
@@ -26,7 +26,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        struct flow_offload_tuple_rhash         tuplehash[FLOW_OFFLOAD_DIR_MAX];
 --- a/net/netfilter/nf_flow_table_core.c
 +++ b/net/netfilter/nf_flow_table_core.c
-@@ -355,7 +355,7 @@ static int nf_flow_offload_gc_step(struc
+@@ -358,7 +358,7 @@ static int nf_flow_offload_gc_step(struc
                if (!teardown)
                        nf_ct_offload_timeout(flow);