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