mirror of
https://github.com/openwrt/routing.git
synced 2025-02-23 22:05:07 +00:00
* Request iflink once in batadv-on-batadv check * Request iflink once in batadv_get_real_netdevice * Don't expect inter-netns unique iflink indices * Don't skb_split skbuffs with frag_list Signed-off-by: Sven Eckelmann <sven@narfation.org>
47 lines
2.0 KiB
Diff
47 lines
2.0 KiB
Diff
From: Sven Eckelmann <sven@narfation.org>
|
|
Date: Sat, 16 Apr 2022 14:24:34 +0200
|
|
Subject: batman-adv: Don't skb_split skbuffs with frag_list
|
|
|
|
The receiving interface might have used GRO to receive more fragments than
|
|
MAX_SKB_FRAGS fragments. In this case, these will not be stored in
|
|
skb_shinfo(skb)->frags but merged into the frag list.
|
|
|
|
batman-adv relies on the function skb_split to split packets up into
|
|
multiple smaller packets which are not larger than the MTU on the outgoing
|
|
interface. But this function cannot handle frag_list entries and is only
|
|
operating on skb_shinfo(skb)->frags. If it is still trying to split such an
|
|
skb and xmit'ing it on an interface without support for NETIF_F_FRAGLIST,
|
|
then validate_xmit_skb() will try to linearize it. But this fails due to
|
|
inconsistent information. And __pskb_pull_tail will trigger a BUG_ON after
|
|
skb_copy_bits() returns an error.
|
|
|
|
In case of entries in frag_list, just linearize the skb before operating on
|
|
it with skb_split().
|
|
|
|
Reported-by: Felix Kaechele <felix@kaechele.ca>
|
|
Tested-by: Felix Kaechele <felix@kaechele.ca>
|
|
Fixes: 9de347143505 ("batman-adv: layer2 unicast packet fragmentation")
|
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d467720acaf1b22b0cee58144eeaf9ef6c5e285c
|
|
|
|
--- a/net/batman-adv/fragmentation.c
|
|
+++ b/net/batman-adv/fragmentation.c
|
|
@@ -477,6 +477,17 @@ int batadv_frag_send_packet(struct sk_bu
|
|
goto free_skb;
|
|
}
|
|
|
|
+ /* GRO might have added fragments to the fragment list instead of
|
|
+ * frags[]. But this is not handled by skb_split and must be
|
|
+ * linearized to avoid incorrect length information after all
|
|
+ * batman-adv fragments were created and submitted to the
|
|
+ * hard-interface
|
|
+ */
|
|
+ if (skb_has_frag_list(skb) && __skb_linearize(skb)) {
|
|
+ ret = -ENOMEM;
|
|
+ goto free_skb;
|
|
+ }
|
|
+
|
|
/* Create one header to be copied to all fragments */
|
|
frag_header.packet_type = BATADV_UNICAST_FRAG;
|
|
frag_header.version = BATADV_COMPAT_VERSION;
|