[][MAC80211][hnat][Update conntrack of per flow accounting data lost issue]

[Description]
Fix conntrack of per flow accounting data lost issue.

When the framework detects FIN packets, it will set up the
NF_FLOW_TEARDOWN flag to the flow. Then GC thread intention
clears the hardware entry and releases the software flow immedately.
Therefore, the framework has to issue a FLOW_CLS_STATS command which
updates residue MIB data to the conntrack.

If without this patch, the conntrack might lost some MIB data in the
corner case.

[Release-log]
N/A


Change-Id: I381f847e4ddbf1e0a2e098488a1db03ceaf64dba
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7285620
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch
index 13b754e..7d4c5d6 100755
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch
@@ -2415,7 +2415,7 @@
  	};
  };
  
-@@ -67,52 +152,139 @@ struct flow_offload_tuple_rhash {
+@@ -67,52 +152,140 @@ struct flow_offload_tuple_rhash {
  	struct flow_offload_tuple	tuple;
  };
  
@@ -2428,6 +2428,7 @@
 +	NF_FLOW_DNAT,
 +	NF_FLOW_TEARDOWN,
 +	NF_FLOW_HW,
++	NF_FLOW_HW_ACCT_DYING,
 +	NF_FLOW_HW_DYING,
 +	NF_FLOW_HW_DEAD,
 +	NF_FLOW_HW_PENDING,
@@ -2586,7 +2587,7 @@
 +void nf_flow_offload_del(struct nf_flowtable *flowtable,
 +			 struct flow_offload *flow);
 +void nf_flow_offload_stats(struct nf_flowtable *flowtable,
-+			   struct flow_offload *flow);
++			   struct flow_offload *flow, bool force);
 +
 +void nf_flow_table_offload_flush(struct nf_flowtable *flowtable);
 +int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
@@ -3903,7 +3904,7 @@
  		if (IS_ERR(tuplehash)) {
  			if (PTR_ERR(tuplehash) != -EAGAIN) {
  				err = PTR_ERR(tuplehash);
-@@ -359,23 +430,49 @@ nf_flow_table_iterate(struct nf_flowtable *flow_table,
+@@ -359,23 +430,52 @@ nf_flow_table_iterate(struct nf_flowtable *flow_table,
  
  	return err;
  }
@@ -3951,6 +3952,9 @@
 +
 +	if (test_bit(NF_FLOW_TEARDOWN, &flow->flags)) {
 +		if (test_bit(NF_FLOW_HW, &flow->flags)) {
++			if (!test_and_set_bit(NF_FLOW_HW_ACCT_DYING, &flow->flags))
++				nf_flow_offload_stats(flow_table, flow, true);
++
 +			if (!test_bit(NF_FLOW_HW_DYING, &flow->flags))
 +				nf_flow_offload_del(flow_table, flow);
 +			else if (test_bit(NF_FLOW_HW_DEAD, &flow->flags))
@@ -3959,7 +3963,7 @@
 +			flow_offload_del(flow_table, flow);
 +		}
 +	} else if (test_bit(NF_FLOW_HW, &flow->flags)) {
-+		nf_flow_offload_stats(flow_table, flow);
++		nf_flow_offload_stats(flow_table, flow, false);
 +	}
  }
  
@@ -4918,7 +4922,7 @@
 index 000000000..d94c6fb92
 --- /dev/null
 +++ b/net/netfilter/nf_flow_table_offload.c
-@@ -0,0 +1,1195 @@
+@@ -0,0 +1,1197 @@
 +#include <linux/kernel.h>
 +#include <linux/init.h>
 +#include <linux/module.h>
@@ -5956,14 +5960,16 @@
 +}
 +
 +void nf_flow_offload_stats(struct nf_flowtable *flowtable,
-+			   struct flow_offload *flow)
++			   struct flow_offload *flow, bool force)
 +{
 +	struct flow_offload_work *offload;
 +	__s32 delta;
 +
-+	delta = nf_flow_timeout_delta(flow->timeout);
-+	if ((delta >= (9 * flow_offload_get_timeout(flow)) / 10))
-+		return;
++	if (!force) {
++		delta = nf_flow_timeout_delta(flow->timeout);
++		if ((delta >= (9 * flow_offload_get_timeout(flow)) / 10))
++			return;
++	}
 +
 +	offload = nf_flow_offload_work_alloc(flowtable, flow, FLOW_CLS_STATS);
 +	if (!offload)