[][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, ð))
break;
if (skb_hnat_is_decap(skb))
break;