Merge pull request #859 from ecsv/batadv-for-21.02
openwrt-21.02: batman-adv: Merge bugfixes from 2022.0
This commit is contained in:
commit
d159eb55d2
|
@ -0,0 +1,22 @@
|
|||
From: Sven Eckelmann <sven@narfation.org>
|
||||
Date: Sat, 19 Feb 2022 08:51:28 +0100
|
||||
Subject: alfred: Ensure processed change_iface packet is 0-terminated
|
||||
|
||||
A client sending a alfred_change_interface_v0 packet to the alfred server
|
||||
might have forgotten to 0-terminate the string. In this case, strstr in
|
||||
unix_sock_change_iface might read outside of the available buffer.
|
||||
|
||||
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||
Origin: upstream, https://git.open-mesh.org/alfred.git/commit/d2d27e4b9d697928d21dfa5c79908618ef8b56ac
|
||||
|
||||
--- a/unix_sock.c
|
||||
+++ b/unix_sock.c
|
||||
@@ -329,6 +329,8 @@ unix_sock_change_iface(struct globals *g
|
||||
if (len < (int)(sizeof(*change_iface) - sizeof(change_iface->header)))
|
||||
goto err;
|
||||
|
||||
+ change_iface->ifaces[sizeof(change_iface->ifaces) - 1] = '\0';
|
||||
+
|
||||
if (globals->opmode == OPMODE_SECONDARY) {
|
||||
if (strstr(change_iface->ifaces, ",") != NULL) {
|
||||
ret = -EINVAL;
|
|
@ -0,0 +1,29 @@
|
|||
From: Sven Eckelmann <sven@narfation.org>
|
||||
Date: Fri, 22 Apr 2022 11:14:08 +0200
|
||||
Subject: batctl: ping: Skip sleep after last packet
|
||||
|
||||
The -i option for ping is documented as interval between ping requests. But
|
||||
the sleep was also applied after all the requested pings already sent out.
|
||||
As result, the user had to wait additional time until the statistics for
|
||||
the (limited) ping test was printed.
|
||||
|
||||
Just skip the last sleep in case there will be no next ping packet to avoid
|
||||
this problem.
|
||||
|
||||
Reported-by: Roman Le bg <roman@romanlebg.fr>
|
||||
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/47d063213d5843d1ca33c557bd4a874db3e90e9e)
|
||||
|
||||
--- a/ping.c
|
||||
+++ b/ping.c
|
||||
@@ -282,6 +282,10 @@ read_packet:
|
||||
}
|
||||
|
||||
sleep:
|
||||
+ /* skip last sleep in case no more packets will be sent out */
|
||||
+ if (loop_count == 0)
|
||||
+ continue;
|
||||
+
|
||||
if (loop_interval > 0)
|
||||
sleep(loop_interval);
|
||||
else if ((tv.tv_sec != 0) || (tv.tv_usec != 0))
|
|
@ -0,0 +1,44 @@
|
|||
From: Sven Eckelmann <sven@narfation.org>
|
||||
Date: Wed, 2 Mar 2022 19:49:44 +0100
|
||||
Subject: batman-adv: Request iflink once in batadv-on-batadv check
|
||||
|
||||
There is no need to call dev_get_iflink multiple times for the same
|
||||
net_device in batadv_is_on_batman_iface. And since some of the
|
||||
.ndo_get_iflink callbacks are dynamic (for example via RCUs like in
|
||||
vxcan_get_iflink), it could easily happen that the returned values are not
|
||||
stable. The pre-checks before __dev_get_by_index are then of course bogus.
|
||||
|
||||
Fixes: 3d48811b27f5 ("batman-adv: prevent using any virtual device created on batman-adv as hard-interface")
|
||||
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/f6c0c45356fe3ab9c5e01b81d060f8a436658037
|
||||
|
||||
--- a/net/batman-adv/hard-interface.c
|
||||
+++ b/net/batman-adv/hard-interface.c
|
||||
@@ -149,22 +149,23 @@ static bool batadv_is_on_batman_iface(co
|
||||
struct net *net = dev_net(net_dev);
|
||||
struct net_device *parent_dev;
|
||||
struct net *parent_net;
|
||||
+ int iflink;
|
||||
bool ret;
|
||||
|
||||
/* check if this is a batman-adv mesh interface */
|
||||
if (batadv_softif_is_valid(net_dev))
|
||||
return true;
|
||||
|
||||
+ iflink = dev_get_iflink(net_dev);
|
||||
+
|
||||
/* no more parents..stop recursion */
|
||||
- if (dev_get_iflink(net_dev) == 0 ||
|
||||
- dev_get_iflink(net_dev) == net_dev->ifindex)
|
||||
+ if (iflink == 0 || iflink == net_dev->ifindex)
|
||||
return false;
|
||||
|
||||
parent_net = batadv_getlink_net(net_dev, net);
|
||||
|
||||
/* recurse over the parent device */
|
||||
- parent_dev = __dev_get_by_index((struct net *)parent_net,
|
||||
- dev_get_iflink(net_dev));
|
||||
+ parent_dev = __dev_get_by_index((struct net *)parent_net, iflink);
|
||||
/* if we got a NULL parent_dev there is something broken.. */
|
||||
if (!parent_dev) {
|
||||
pr_err("Cannot find parent device\n");
|
|
@ -0,0 +1,46 @@
|
|||
From: Sven Eckelmann <sven@narfation.org>
|
||||
Date: Wed, 2 Mar 2022 19:49:45 +0100
|
||||
Subject: batman-adv: Request iflink once in batadv_get_real_netdevice
|
||||
|
||||
There is no need to call dev_get_iflink multiple times for the same
|
||||
net_device in batadv_get_real_netdevice. And since some of the
|
||||
ndo_get_iflink callbacks are dynamic (for example via RCUs like in
|
||||
vxcan_get_iflink), it could easily happen that the returned values are not
|
||||
stable. The pre-checks before __dev_get_by_index are then of course bogus.
|
||||
|
||||
Fixes: 2b45bb6c3aad ("batman-adv: additional checks for virtual interfaces on top of WiFi")
|
||||
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/445f477ec3e805425186f5fbe8ed0fe89cc226b6
|
||||
|
||||
--- a/net/batman-adv/hard-interface.c
|
||||
+++ b/net/batman-adv/hard-interface.c
|
||||
@@ -215,14 +215,16 @@ static struct net_device *batadv_get_rea
|
||||
struct net_device *real_netdev = NULL;
|
||||
struct net *real_net;
|
||||
struct net *net;
|
||||
- int ifindex;
|
||||
+ int iflink;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (!netdev)
|
||||
return NULL;
|
||||
|
||||
- if (netdev->ifindex == dev_get_iflink(netdev)) {
|
||||
+ iflink = dev_get_iflink(netdev);
|
||||
+
|
||||
+ if (netdev->ifindex == iflink) {
|
||||
dev_hold(netdev);
|
||||
return netdev;
|
||||
}
|
||||
@@ -232,9 +234,8 @@ static struct net_device *batadv_get_rea
|
||||
goto out;
|
||||
|
||||
net = dev_net(hard_iface->soft_iface);
|
||||
- ifindex = dev_get_iflink(netdev);
|
||||
real_net = batadv_getlink_net(netdev, net);
|
||||
- real_netdev = dev_get_by_index(real_net, ifindex);
|
||||
+ real_netdev = dev_get_by_index(real_net, iflink);
|
||||
|
||||
out:
|
||||
if (hard_iface)
|
|
@ -0,0 +1,86 @@
|
|||
From: Sven Eckelmann <sven@narfation.org>
|
||||
Date: Wed, 2 Mar 2022 19:49:46 +0100
|
||||
Subject: batman-adv: Don't expect inter-netns unique iflink indices
|
||||
|
||||
The ifindex doesn't have to be unique for multiple network namespaces on
|
||||
the same machine.
|
||||
|
||||
$ ip netns add test1
|
||||
$ ip -net test1 link add dummy1 type dummy
|
||||
$ ip netns add test2
|
||||
$ ip -net test2 link add dummy2 type dummy
|
||||
|
||||
$ ip -net test1 link show dev dummy1
|
||||
6: dummy1: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
|
||||
link/ether 96:81:55:1e:dd:85 brd ff:ff:ff:ff:ff:ff
|
||||
$ ip -net test2 link show dev dummy2
|
||||
6: dummy2: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
|
||||
link/ether 5a:3c:af:35:07:c3 brd ff:ff:ff:ff:ff:ff
|
||||
|
||||
But the batman-adv code to walk through the various layers of virtual
|
||||
interfaces uses this assumption because dev_get_iflink handles it
|
||||
internally and doesn't return the actual netns of the iflink. And
|
||||
dev_get_iflink only documents the situation where ifindex == iflink for
|
||||
physical devices.
|
||||
|
||||
But only checking for dev->netdev_ops->ndo_get_iflink is also not an option
|
||||
because ipoib_get_iflink implements it even when it sometimes returns an
|
||||
iflink != ifindex and sometimes iflink == ifindex. The caller must
|
||||
therefore make sure itself to check both netns and iflink + ifindex for
|
||||
equality. Only when they are equal, a "physical" interface was detected
|
||||
which should stop the traversal. On the other hand, vxcan_get_iflink can
|
||||
also return 0 in case there was currently no valid peer. In this case, it
|
||||
is still necessary to stop.
|
||||
|
||||
Fixes: 3d48811b27f5 ("batman-adv: prevent using any virtual device created on batman-adv as hard-interface")
|
||||
Fixes: 2b45bb6c3aad ("batman-adv: additional checks for virtual interfaces on top of WiFi")
|
||||
Reported-by: Sabrina Dubroca <sd@queasysnail.net>
|
||||
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/0aac7a9fbbbeec25f2f54a9e6d53ea91217ba720
|
||||
|
||||
--- a/net/batman-adv/hard-interface.c
|
||||
+++ b/net/batman-adv/hard-interface.c
|
||||
@@ -157,13 +157,15 @@ static bool batadv_is_on_batman_iface(co
|
||||
return true;
|
||||
|
||||
iflink = dev_get_iflink(net_dev);
|
||||
-
|
||||
- /* no more parents..stop recursion */
|
||||
- if (iflink == 0 || iflink == net_dev->ifindex)
|
||||
+ if (iflink == 0)
|
||||
return false;
|
||||
|
||||
parent_net = batadv_getlink_net(net_dev, net);
|
||||
|
||||
+ /* iflink to itself, most likely physical device */
|
||||
+ if (net == parent_net && iflink == net_dev->ifindex)
|
||||
+ return false;
|
||||
+
|
||||
/* recurse over the parent device */
|
||||
parent_dev = __dev_get_by_index((struct net *)parent_net, iflink);
|
||||
/* if we got a NULL parent_dev there is something broken.. */
|
||||
@@ -223,8 +225,7 @@ static struct net_device *batadv_get_rea
|
||||
return NULL;
|
||||
|
||||
iflink = dev_get_iflink(netdev);
|
||||
-
|
||||
- if (netdev->ifindex == iflink) {
|
||||
+ if (iflink == 0) {
|
||||
dev_hold(netdev);
|
||||
return netdev;
|
||||
}
|
||||
@@ -235,6 +236,14 @@ static struct net_device *batadv_get_rea
|
||||
|
||||
net = dev_net(hard_iface->soft_iface);
|
||||
real_net = batadv_getlink_net(netdev, net);
|
||||
+
|
||||
+ /* iflink to itself, most likely physical device */
|
||||
+ if (net == real_net && netdev->ifindex == iflink) {
|
||||
+ real_netdev = netdev;
|
||||
+ dev_hold(real_netdev);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
real_netdev = dev_get_by_index(real_net, iflink);
|
||||
|
||||
out:
|
|
@ -0,0 +1,46 @@
|
|||
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;
|
Loading…
Reference in New Issue