[][kernel][common][hnat][Add support to identify bond slave device]

[Description]
Add support to identify bond slave device.

Without this patch, the traffic destinate to a bond device can only
forward to GMAC1 or GMAC2 after HNAT offload is enabled, this patch
can identify the slave device and set the correct PPE entry dp.

[Release-log]
N/A


Change-Id: I3f213f1e404000e188b2129c133a244397f1b3ac
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/9527579
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
index c59e97e..50cc41f 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
@@ -1155,15 +1155,19 @@
 #define NR_WDMA2_PORT 13
 #define NR_GMAC3_PORT 15
 #define NR_QDMA_TPORT 1
+#define WAN_DEV_NAME hnat_priv->wan
 #define LAN_DEV_NAME hnat_priv->lan
 #define LAN2_DEV_NAME hnat_priv->lan2
-#define IS_WAN(dev)                                                            \
-	(!strncmp((dev)->name, hnat_priv->wan, strlen(hnat_priv->wan)))
+#define IS_WAN(dev) (!strncmp((dev)->name, WAN_DEV_NAME, strlen(WAN_DEV_NAME)))
 #define IS_LAN_GRP(dev) (IS_LAN(dev) | IS_LAN2(dev))
-#define IS_LAN(dev) (!strncmp(dev->name, LAN_DEV_NAME, strlen(LAN_DEV_NAME)))
-#define IS_LAN2(dev) (!strncmp(dev->name, LAN2_DEV_NAME,			\
-		      strlen(LAN2_DEV_NAME)))
+#define IS_LAN(dev)								\
+	(!strncmp(dev->name, LAN_DEV_NAME, strlen(LAN_DEV_NAME)) ||		\
+	 IS_BOND(dev))
+#define IS_LAN2(dev)								\
+	(!strncmp(dev->name, LAN2_DEV_NAME, strlen(LAN2_DEV_NAME)) ||		\
+	 IS_BOND(dev))
 #define IS_BR(dev) (!strncmp(dev->name, "br", 2))
+#define IS_BOND(dev) (!strncmp(dev->name, "bond", 4))
 #define IS_WHNAT(dev)								\
 	((hnat_priv->data->whnat &&						\
 	 (get_wifi_hook_if_index_from_dev(dev) != 0)) ? 1 : 0)
@@ -1184,7 +1188,6 @@
 	(IS_IPV6_3T_ROUTE(x) | IS_IPV6_5T_ROUTE(x) | IS_IPV6_6RD(x) |          \
 	 IS_IPV4_DSLITE(x) | IS_IPV4_MAPE(x) | IS_IPV4_MAPT(x) |	       \
 	 IS_IPV6_HNAPT(x) | IS_IPV6_HNAT(x))
-#define IS_BOND_MODE (!strncmp(LAN_DEV_NAME, "bond", 4))
 #define IS_GMAC1_MODE ((hnat_priv->gmac_num == 1) ? 1 : 0)
 #define IS_HQOS_MODE (qos_toggle == 1)
 #define IS_PPPQ_MODE (qos_toggle == 2)		/* Per Port Per Queue */
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
index 8b4641f..3abfbf2 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
@@ -447,7 +447,7 @@
 				return -1;
 		}
 
-		if (IS_BOND_MODE &&
+		if (IS_BOND(dev) &&
 		    (((hnat_priv->data->version == MTK_HNAT_V2 ||
 		       hnat_priv->data->version == MTK_HNAT_V3) &&
 				(skb_hnat_entry(skb) != 0x7fff)) ||
@@ -1246,8 +1246,9 @@
 				     struct flow_offload_hw_path *hw_path)
 {
 	struct net_device *master_dev = (struct net_device *)dev;
+	struct net_device *slave_dev[10];
+	struct list_head *iter;
 	struct foe_entry entry = { 0 };
-	int whnat = IS_WHNAT(dev);
 	struct mtk_mac *mac;
 	struct ethhdr *eth;
 	struct iphdr *iph;
@@ -1256,12 +1257,14 @@
 	const struct tcpudphdr *pptr;
 	struct nf_conn *ct;
 	enum ip_conntrack_info ctinfo;
+	int whnat = IS_WHNAT(dev);
 	int gmac = NR_DISCARD;
 	int udp = 0;
 	int port_id = 0;
 	u32 qid = 0;
 	u32 payload_len = 0;
 	int mape = 0;
+	int i = 0;
 
 	if (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPIP)
 		/* point to ethernet header for DS-Lite and MapE */
@@ -1714,6 +1717,23 @@
 	entry = ppe_fill_info_blk(eth, entry, hw_path);
 
 	if (IS_LAN_GRP(dev) || IS_WAN(dev)) { /* Forward to GMAC Ports */
+		if (IS_BOND(dev)) {
+			/* Retrieve subordinate devices that are connected to the Bond device */
+			netdev_for_each_lower_dev(master_dev, slave_dev[i], iter) {
+				/* Check the link status of the slave device */
+				if (!(slave_dev[i]->flags & IFF_UP) ||
+				    !netif_carrier_ok(slave_dev[i]))
+					continue;
+				i++;
+				if (i >= ARRAY_SIZE(slave_dev))
+					break;
+			}
+			if (i > 0) {
+				/* Choose a subordinate device according to the hash index */
+				dev = slave_dev[(skb_hnat_entry(skb) >> 1) % i];
+				master_dev = slave_dev[(skb_hnat_entry(skb) >> 1) % i];
+			}
+		}
 		port_id = hnat_dsa_get_port(&master_dev);
 		if (port_id >= 0) {
 			if (hnat_dsa_fill_stag(dev, &entry, hw_path,
@@ -1724,10 +1744,7 @@
 		mac = netdev_priv(master_dev);
 		gmac = HNAT_GMAC_FP(mac->id);
 
-		if (IS_LAN(dev) && IS_BOND_MODE) {
-			gmac = ((skb_hnat_entry(skb) >> 1) % hnat_priv->gmac_num) ?
-				 NR_GMAC2_PORT : NR_GMAC1_PORT;
-		} else if (IS_WAN(dev) && mape_toggle && mape == 1) {
+		if (IS_WAN(dev) && mape_toggle && mape == 1) {
 			gmac = NR_PDMA_PORT;
 			/* Set act_dp = wan_dev */
 			entry.ipv4_hnapt.act_dp &= ~UDF_PINGPONG_IFIDX;