From a86e6b5a9fb3ea15d5e5f7d41a144c9fe1d4fb79 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 25 Feb 2018 15:48:23 +0100 Subject: kernel: add minimal TCP state tracking to flow offload support Fixes issues with connections hanging after >30 seconds idle time Signed-off-by: Felix Fietkau --- ...f_flow_table-add-a-new-flow-state-for-tea.patch | 74 ++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 target/linux/generic/backport-4.14/361-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch (limited to 'target/linux/generic/backport-4.14/361-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch') diff --git a/target/linux/generic/backport-4.14/361-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch b/target/linux/generic/backport-4.14/361-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch new file mode 100644 index 0000000000..83751d8cb1 --- /dev/null +++ b/target/linux/generic/backport-4.14/361-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch @@ -0,0 +1,74 @@ +From: Felix Fietkau +Date: Sun, 25 Feb 2018 15:38:31 +0100 +Subject: [PATCH] netfilter: nf_flow_table: add a new flow state for + tearing down offloading + +Will be used to tear down the offload entry while keeping the conntrack +entry alive. + +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/netfilter/nf_flow_table.h ++++ b/include/net/netfilter/nf_flow_table.h +@@ -68,6 +68,7 @@ struct flow_offload_tuple_rhash { + #define FLOW_OFFLOAD_SNAT 0x1 + #define FLOW_OFFLOAD_DNAT 0x2 + #define FLOW_OFFLOAD_DYING 0x4 ++#define FLOW_OFFLOAD_TEARDOWN 0x8 + + struct flow_offload { + struct flow_offload_tuple_rhash tuplehash[FLOW_OFFLOAD_DIR_MAX]; +@@ -108,6 +109,11 @@ static inline void flow_offload_dead(str + flow->flags |= FLOW_OFFLOAD_DYING; + } + ++static inline void flow_offload_teardown(struct flow_offload *flow) ++{ ++ flow->flags |= FLOW_OFFLOAD_TEARDOWN; ++} ++ + int nf_flow_snat_port(const struct flow_offload *flow, + struct sk_buff *skb, unsigned int thoff, + u8 protocol, enum flow_offload_tuple_dir dir); +--- a/net/netfilter/nf_flow_table_core.c ++++ b/net/netfilter/nf_flow_table_core.c +@@ -226,11 +226,6 @@ static inline bool nf_flow_has_expired(c + return (__s32)(flow->timeout - (u32)jiffies) <= 0; + } + +-static inline bool nf_flow_is_dying(const struct flow_offload *flow) +-{ +- return flow->flags & FLOW_OFFLOAD_DYING; +-} +- + static int nf_flow_offload_gc_step(struct nf_flowtable *flow_table) + { + struct flow_offload_tuple_rhash *tuplehash; +@@ -258,7 +253,8 @@ static int nf_flow_offload_gc_step(struc + flow = container_of(tuplehash, struct flow_offload, tuplehash[0]); + + if (nf_flow_has_expired(flow) || +- nf_flow_is_dying(flow)) ++ (flow->flags & (FLOW_OFFLOAD_DYING | ++ FLOW_OFFLOAD_TEARDOWN))) + flow_offload_del(flow_table, flow); + } + out: +@@ -419,10 +415,14 @@ static void nf_flow_table_do_cleanup(str + { + struct net_device *dev = data; + +- if (dev && flow->tuplehash[0].tuple.iifidx != dev->ifindex) ++ if (!dev) { ++ flow_offload_teardown(flow); + return; ++ } + +- flow_offload_dead(flow); ++ if (flow->tuplehash[0].tuple.iifidx == dev->ifindex || ++ flow->tuplehash[1].tuple.iifidx == dev->ifindex) ++ flow_offload_dead(flow); + } + + static void nf_flow_table_iterate_cleanup(struct nf_flowtable *flowtable, -- cgit v1.2.3