[][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)