[][openwrt][mt7988][tops][change tops encap_offload api]

[Description]
Change the TOPS encap_offload API. Since the ethhdr in skb will no longer
be pre-filled in the HNAT get_nexthop functions. TOPS encap_offload API
need an extra auguement to pass the L2 info to TOPS driver to offload
the encapsulation of most tunnels.

[Release-log]
N/A

Change-Id: I60d957cb76021e314be9cbd87d9cf2ab7fbf2b1c
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/9717843
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
index 8101261..e9508eb 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c
@@ -52,7 +52,7 @@
 EXPORT_SYMBOL(ppe_dev_register_hook);
 void (*ppe_dev_unregister_hook)(struct net_device *dev) = NULL;
 EXPORT_SYMBOL(ppe_dev_unregister_hook);
-int (*mtk_tnl_encap_offload)(struct sk_buff *skb) = NULL;
+int (*mtk_tnl_encap_offload)(struct sk_buff *skb, struct ethhdr *eth) = NULL;
 EXPORT_SYMBOL(mtk_tnl_encap_offload);
 int (*mtk_tnl_decap_offload)(struct sk_buff *skb) = NULL;
 EXPORT_SYMBOL(mtk_tnl_decap_offload);
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 ad23b8d..534fc03 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
@@ -1332,7 +1332,7 @@
 extern int mape_toggle;
 extern int qos_toggle;
 extern int tnl_toggle;
-extern int (*mtk_tnl_encap_offload)(struct sk_buff *skb);
+extern int (*mtk_tnl_encap_offload)(struct sk_buff *skb, struct ethhdr *eth);
 extern int (*mtk_tnl_decap_offload)(struct sk_buff *skb);
 extern bool (*mtk_tnl_decap_offloadable)(struct sk_buff *skb);
 extern bool (*mtk_crypto_offloadable)(struct sk_buff *skb);
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 6286310..17f5e4e 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
@@ -1224,24 +1224,9 @@
 		return -1;
 	}
 
-	/*
-	 * if this packet is a tunnel packet and is about to construct
-	 * outer header, we must update its outer mac header pointer
-	 * before filling outer mac or it may screw up inner mac
-	 */
-	if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) ||
-	    (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb))) {
-		skb_push(skb, sizeof(struct ethhdr));
-		skb_reset_mac_header(skb);
-	}
-
 	memcpy(hw_path->eth_dest, neigh->ha, ETH_ALEN);
 	memcpy(hw_path->eth_src, out->dev_addr, ETH_ALEN);
 
-	if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) ||
-	    (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb)))
-		skb_pull(skb, sizeof(struct ethhdr));
-
 	rcu_read_unlock_bh();
 
 	return 0;
@@ -1474,14 +1459,14 @@
 	if (eth->h_proto != htons(ETH_P_IP))
 		return 0;
 
-	if (skb_hnat_tops(skb) && mtk_tnl_encap_offload)
-		mtk_tnl_encap_offload(skb);
-
 	hnat_get_filled_unbind_entry(skb, &entry);
 
 	if (dev->netdev_ops->ndo_flow_offload_check)
 		dev->netdev_ops->ndo_flow_offload_check(&hw_path);
 
+	if (skb_hnat_tops(skb) && mtk_tnl_encap_offload)
+		mtk_tnl_encap_offload(skb, eth);
+
 	/* For packets pass through VTI (route-based IPSec),
 	 * We need to fill the inner packet info into hnat entry.
 	 * Since the skb->mac_header is not pointed to correct position
@@ -1547,7 +1532,7 @@
 		}
 	}
 
-	entry = ppe_fill_info_blk(eth, entry, &hw_path);
+	entry = ppe_fill_info_blk(entry, &hw_path);
 
 	if (IS_LAN(dev)) {
 		if (IS_BOND(dev))
@@ -3191,6 +3176,7 @@
 		  struct flow_offload_hw_path *),
 	const char *func)
 {
+	struct ethhdr eth = {0};
 	struct foe_entry *entry;
 	struct flow_offload_hw_path hw_path = { .dev = (struct net_device*)out,
 						.virt_dev = (struct net_device*)out };
@@ -3276,8 +3262,15 @@
 		}
 		/* skb_hnat_tops(skb) is updated in mtk_tnl_offload() */
 		if (skb_hnat_tops(skb)) {
+			memcpy(eth.h_dest, hw_path.eth_dest, ETH_ALEN);
+			memcpy(eth.h_source, hw_path.eth_src, ETH_ALEN);
+			if (ip_hdr(skb)->version == IPVERSION_V4)
+				eth.h_proto = htons(ETH_P_IP);
+			else if (ip_hdr(skb)->version == IPVERSION_V6)
+				eth.h_proto = htons(ETH_P_IPV6);
+
 			if (skb_hnat_is_encap(skb) && !is_virt_dev &&
-			    mtk_tnl_encap_offload && mtk_tnl_encap_offload(skb))
+			    mtk_tnl_encap_offload && mtk_tnl_encap_offload(skb, &eth))
 				break;
 			if (skb_hnat_is_decap(skb))
 				break;