[][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;
- }