[][kernel][common][hnat][Refine HNAT prefilled flow for the WiFi Tx]

[Description]
Refactor HNAT prefilled flow for the WiFi Tx.

If without this patch, the HNAT BIND info might be dameged by
skb_to_hnat_info() in the WiFi Tx case.

[Release-log]
N/A


Change-Id: I00602dcdeabb6e04a053b56c9a4bd2a72ebb853e
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7658230
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
index 8f5f37b..8026921 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
@@ -1165,9 +1165,24 @@
 #define NEXTHDR_IPIP 4
 #endif
 
+#define UDF_PINGPONG_IFIDX GENMASK(3, 0)
+#define UDF_HNAT_PRE_FILLED BIT(4)
+
 extern const struct of_device_id of_hnat_match[];
 extern struct mtk_hnat *hnat_priv;
 
+static inline int is_hnat_pre_filled(struct foe_entry *entry)
+{
+	u32 udf = 0;
+
+	if (IS_IPV4_GRP(entry))
+		udf = entry->ipv4_hnapt.act_dp;
+	else
+		udf = entry->ipv6_5t_route.act_dp;
+
+	return !!(udf & UDF_HNAT_PRE_FILLED);
+}
+
 #if defined(CONFIG_NET_DSA_MT7530)
 u32 hnat_dsa_fill_stag(const struct net_device *netdev,
 		       struct foe_entry *entry,
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
index 05f4955..c644e55 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
@@ -491,9 +491,9 @@
 	entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
 
 	if (IS_IPV4_GRP(entry))
-		index = entry->ipv4_hnapt.act_dp;
+		index = entry->ipv4_hnapt.act_dp & UDF_PINGPONG_IFIDX;
 	else
-		index = entry->ipv6_5t_route.act_dp;
+		index = entry->ipv6_5t_route.act_dp & UDF_PINGPONG_IFIDX;
 
 	dev = get_dev_from_index(index);
 	if (!dev) {
@@ -548,9 +548,9 @@
 	if (entry_hnat_is_bound(entry)) {
 		entry->bfib1.state = INVALID;
 		if (IS_IPV4_GRP(entry))
-			entry->ipv4_hnapt.act_dp = 0;
+			entry->ipv4_hnapt.act_dp &= ~UDF_PINGPONG_IFIDX;
 		else
-			entry->ipv6_5t_route.act_dp = 0;
+			entry->ipv6_5t_route.act_dp &= ~UDF_PINGPONG_IFIDX;
 
 		/* clear HWNAT cache */
 		hnat_cache_ebl(1);
@@ -1222,6 +1222,9 @@
 	if (!hnat_priv->data->mcast && is_multicast_ether_addr(eth->h_dest))
 		return 0;
 
+	if (whnat && is_hnat_pre_filled(foe))
+		return 0;
+
 	entry.bfib1.pkt_type = foe->udib1.pkt_type; /* Get packte type state*/
 	entry.bfib1.state = foe->udib1.state;
 
@@ -1637,7 +1640,8 @@
 		if (mape_toggle && mape == 1) {
 			gmac = NR_PDMA_PORT;
 			/* Set act_dp = wan_dev */
-			entry.ipv4_hnapt.act_dp = dev->ifindex;
+			entry.ipv4_hnapt.act_dp &= ~UDF_PINGPONG_IFIDX;
+			entry.ipv4_hnapt.act_dp |= dev->ifindex & UDF_PINGPONG_IFIDX;
 		} else {
 			gmac = (IS_GMAC1_MODE) ? NR_GMAC1_PORT : NR_GMAC2_PORT;
 		}
@@ -1659,10 +1663,13 @@
 		 * Current setting is PDMA RX.
 		 */
 		gmac = NR_PDMA_PORT;
-		if (IS_IPV4_GRP(foe))
-			entry.ipv4_hnapt.act_dp = dev->ifindex;
-		else
-			entry.ipv6_5t_route.act_dp = dev->ifindex;
+		if (IS_IPV4_GRP(foe)) {
+			entry.ipv4_hnapt.act_dp &= ~UDF_PINGPONG_IFIDX;
+			entry.ipv4_hnapt.act_dp |= dev->ifindex & UDF_PINGPONG_IFIDX;
+		} else {
+			entry.ipv6_5t_route.act_dp &= ~UDF_PINGPONG_IFIDX;
+			entry.ipv6_5t_route.act_dp |= dev->ifindex & UDF_PINGPONG_IFIDX;
+		}
 	} else {
 		printk_ratelimited(KERN_WARNING
 					"Unknown case of dp, iif=%x --> %s\n",
@@ -1780,6 +1787,11 @@
 	if (!whnat) {
 		entry.bfib1.ttl = 1;
 		entry.bfib1.state = BIND;
+	} else {
+		if (IS_IPV4_GRP(foe))
+			entry.ipv4_hnapt.act_dp |= UDF_HNAT_PRE_FILLED;
+		else
+			entry.ipv6_5t_route.act_dp |= UDF_HNAT_PRE_FILLED;
 	}
 
 	wmb();
@@ -1791,8 +1803,6 @@
 		memset(&hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)],
 		       0, sizeof(struct mib_entry));
 
-	skb_hnat_filled(skb) = HNAT_INFO_FILLED;
-
 	return 0;
 }
 
@@ -1802,7 +1812,7 @@
 	struct ethhdr *eth;
 	struct hnat_bind_info_blk bfib1_tx;
 
-	if (skb_hnat_alg(skb) || !is_hnat_info_filled(skb) ||
+	if (skb_hnat_alg(skb) ||
 	    !is_magic_tag_valid(skb) || !IS_SPACE_AVAILABLE_HEAD(skb))
 		return NF_ACCEPT;
 
@@ -1833,6 +1843,9 @@
 	if (skb_hnat_reason(skb) != HIT_UNBIND_RATE_REACH)
 		return NF_ACCEPT;
 
+	if (!is_hnat_pre_filled(entry))
+		return NF_ACCEPT;
+
 	eth = eth_hdr(skb);
 	memcpy(&bfib1_tx, &entry->bfib1, sizeof(entry->bfib1));
 
@@ -2017,6 +2030,11 @@
 	wmb();
 	memcpy(&entry->bfib1, &bfib1_tx, sizeof(bfib1_tx));
 
+	if (IS_IPV4_GRP(entry))
+		entry->ipv4_hnapt.act_dp &= ~UDF_HNAT_PRE_FILLED;
+	else
+		entry->ipv6_5t_route.act_dp &= ~UDF_HNAT_PRE_FILLED;
+
 	return NF_ACCEPT;
 }
 
@@ -2028,7 +2046,6 @@
 	}
 
 	skb_hnat_alg(skb) = 0;
-	skb_hnat_filled(skb) = 0;
 	skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
 
 	if (skb_hnat_iface(skb) == FOE_MAGIC_WED0)
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
index d9eba8d..800c821 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h
@@ -85,7 +85,6 @@
 #define HAS_HQOS_MAGIC_TAG(skb) (qos_toggle && skb->protocol == HQOS_MAGIC_TAG)
 
 #define HNAT_MAGIC_TAG 0x6789
-#define HNAT_INFO_FILLED 0x7
 #define WIFI_INFO_LEN 6
 #define FOE_INFO_LEN (10 + WIFI_INFO_LEN)
 #define IS_SPACE_AVAILABLE_HEAD(skb)                                           \
@@ -136,7 +135,6 @@
 #define clr_from_extge(skb) (HNAT_SKB_CB2(skb)->magic = 0x0)
 #define set_to_ppe(skb) (HNAT_SKB_CB2(skb)->magic = 0x78681415)
 #define is_from_extge(skb) (HNAT_SKB_CB2(skb)->magic == 0x78786688)
-#define is_hnat_info_filled(skb) (skb_hnat_filled(skb) == HNAT_INFO_FILLED)
 #define is_magic_tag_valid(skb) (skb_hnat_magic_tag(skb) == HNAT_MAGIC_TAG)
 #define set_from_mape(skb) (HNAT_SKB_CB2(skb)->magic = 0x78787788)
 #define is_from_mape(skb) (HNAT_SKB_CB2(skb)->magic == 0x78787788)