[][openwrt][mt7988][tops][fix tunnel fragment unbinding issue]

[Description]
Fix tunnel fragment unbinding issue by reserving
headroom for fragmented tunnel packets

[Release-log]
N/A

Change-Id: Id01090e6a18e7bce50111dcbb5aa476ae1b760da
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/10913073
diff --git a/21.02/files/target/linux/mediatek/patches-5.4/999-2745-mtk-frag-gso-skb-headroom-copy.patch b/21.02/files/target/linux/mediatek/patches-5.4/999-2745-mtk-frag-gso-skb-headroom-copy.patch
new file mode 100644
index 0000000..b2f37f2
--- /dev/null
+++ b/21.02/files/target/linux/mediatek/patches-5.4/999-2745-mtk-frag-gso-skb-headroom-copy.patch
@@ -0,0 +1,60 @@
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -5076,4 +5076,5 @@ extern struct net_device *blackhole_netd
+ 		atomic_long_add((VAL), &(DEV)->stats.__##FIELD)
+ #define DEV_STATS_READ(DEV, FIELD) atomic_long_read(&(DEV)->stats.__##FIELD)
+ 
++extern int (*mtk_skb_headroom_copy)(struct sk_buff *new, struct sk_buff *old);
+ #endif	/* _LINUX_NETDEVICE_H */
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -198,6 +198,9 @@ static DEFINE_READ_MOSTLY_HASHTABLE(napi
+ 
+ static DECLARE_RWSEM(devnet_rename_sem);
+ 
++int (*mtk_skb_headroom_copy)(struct sk_buff *new, struct sk_buff *old) = NULL;
++EXPORT_SYMBOL(mtk_skb_headroom_copy);
++
+ static inline void dev_base_seq_inc(struct net *net)
+ {
+ 	while (++net->dev_base_seq == 0)
+@@ -3448,6 +3451,9 @@ static struct sk_buff *validate_xmit_skb
+ 		if (IS_ERR(segs)) {
+ 			goto out_kfree_skb;
+ 		} else if (segs) {
++			if (mtk_skb_headroom_copy)
++				mtk_skb_headroom_copy(segs, skb);
++
+ 			consume_skb(skb);
+ 			skb = segs;
+ 		}
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -705,7 +705,7 @@ struct sk_buff *ip_frag_next(struct sk_b
+ 	}
+ 
+ 	/* Allocate buffer */
+-	skb2 = alloc_skb(len + state->hlen + state->ll_rs, GFP_ATOMIC);
++	skb2 = alloc_skb(len + state->hlen + state->ll_rs + NET_SKB_PAD + NET_IP_ALIGN, GFP_ATOMIC);
+ 	if (!skb2)
+ 		return ERR_PTR(-ENOMEM);
+ 
+@@ -714,7 +714,7 @@ struct sk_buff *ip_frag_next(struct sk_b
+ 	 */
+ 
+ 	ip_copy_metadata(skb2, skb);
+-	skb_reserve(skb2, state->ll_rs);
++	skb_reserve(skb2, state->ll_rs + NET_SKB_PAD + NET_IP_ALIGN);
+ 	skb_put(skb2, len + state->hlen);
+ 	skb_reset_network_header(skb2);
+ 	skb2->transport_header = skb2->network_header + state->hlen;
+@@ -909,6 +909,9 @@ slow_path:
+ 		}
+ 		ip_frag_ipcb(skb, skb2, first_frag, &state);
+ 
++		if (mtk_skb_headroom_copy)
++			mtk_skb_headroom_copy(skb2, skb);
++
+ 		/*
+ 		 *	Put this fragment into the sending queue.
+ 		 */
diff --git a/21.02/files/target/linux/mediatek/patches-5.4/999-2745-mtk-gso-skb-headroom-copy.patch b/21.02/files/target/linux/mediatek/patches-5.4/999-2745-mtk-gso-skb-headroom-copy.patch
deleted file mode 100644
index 72b031c..0000000
--- a/21.02/files/target/linux/mediatek/patches-5.4/999-2745-mtk-gso-skb-headroom-copy.patch
+++ /dev/null
@@ -1,30 +0,0 @@
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -5076,4 +5076,5 @@ extern struct net_device *blackhole_netd
- 		atomic_long_add((VAL), &(DEV)->stats.__##FIELD)
- #define DEV_STATS_READ(DEV, FIELD) atomic_long_read(&(DEV)->stats.__##FIELD)
- 
-+extern int (*mtk_skb_headroom_copy)(struct sk_buff *new, struct sk_buff *old);
- #endif	/* _LINUX_NETDEVICE_H */
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -198,6 +198,9 @@ static DEFINE_READ_MOSTLY_HASHTABLE(napi
- 
- static DECLARE_RWSEM(devnet_rename_sem);
- 
-+int (*mtk_skb_headroom_copy)(struct sk_buff *new, struct sk_buff *old) = NULL;
-+EXPORT_SYMBOL(mtk_skb_headroom_copy);
-+
- static inline void dev_base_seq_inc(struct net *net)
- {
- 	while (++net->dev_base_seq == 0)
-@@ -3448,6 +3451,9 @@ static struct sk_buff *validate_xmit_skb
- 		if (IS_ERR(segs)) {
- 			goto out_kfree_skb;
- 		} else if (segs) {
-+			if (mtk_skb_headroom_copy)
-+				mtk_skb_headroom_copy(segs, skb);
-+
- 			consume_skb(skb);
- 			skb = segs;
- 		}