Merge pull request #621 from ecsv/batadv-for-18.06
openwrt-18.06: batman-adv: Merge bugfixes from 2020.4
This commit is contained in:
commit
8f47c32d58
|
@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
|
||||||
PKG_NAME:=batctl
|
PKG_NAME:=batctl
|
||||||
|
|
||||||
PKG_VERSION:=2018.1
|
PKG_VERSION:=2018.1
|
||||||
PKG_RELEASE:=3
|
PKG_RELEASE:=4
|
||||||
PKG_HASH:=27877d0da6916f88a6cecbbb3f3d23cc4558ef7c7294324bf4fd050ed606b553
|
PKG_HASH:=27877d0da6916f88a6cecbbb3f3d23cc4558ef7c7294324bf4fd050ed606b553
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Date: Sun, 13 Sep 2020 23:30:19 +0200
|
||||||
|
Subject: batctl: tcpdump: Fix endianness in ICMPv6 Echo Request/Reply parsing
|
||||||
|
|
||||||
|
The ICMPv6 Echo Request/Reply sequence number and id as well as the
|
||||||
|
IPv6 header length are two byte long fields and therefore might need a
|
||||||
|
conversion on a little endian system. Otherwise the output will be
|
||||||
|
broken on such a machine.
|
||||||
|
|
||||||
|
Fixes: 35b37756f4a3 ("add IPv6 support to tcpdump parser")
|
||||||
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/e42f73d0d2a04edfbed1b9d0ad9fd57af9e90faf
|
||||||
|
|
||||||
|
diff --git a/tcpdump.c b/tcpdump.c
|
||||||
|
index c41500e21eda0abc1f024a3265c23fc3a4802d17..22847aecf887566ac62ff2084079683d0acf83aa 100644
|
||||||
|
--- a/tcpdump.c
|
||||||
|
+++ b/tcpdump.c
|
||||||
|
@@ -551,13 +551,15 @@ static void dump_ipv6(unsigned char *packet_buff, ssize_t buff_len,
|
||||||
|
break;
|
||||||
|
case ICMP6_ECHO_REQUEST:
|
||||||
|
printf(" echo request, id: %d, seq: %d, length: %hu\n",
|
||||||
|
- icmphdr->icmp6_id, icmphdr->icmp6_seq,
|
||||||
|
- iphdr->ip6_plen);
|
||||||
|
+ ntohs(icmphdr->icmp6_id),
|
||||||
|
+ ntohs(icmphdr->icmp6_seq),
|
||||||
|
+ ntohs(iphdr->ip6_plen));
|
||||||
|
break;
|
||||||
|
case ICMP6_ECHO_REPLY:
|
||||||
|
printf(" echo reply, id: %d, seq: %d, length: %hu\n",
|
||||||
|
- icmphdr->icmp6_id, icmphdr->icmp6_seq,
|
||||||
|
- iphdr->ip6_plen);
|
||||||
|
+ ntohs(icmphdr->icmp6_id),
|
||||||
|
+ ntohs(icmphdr->icmp6_seq),
|
||||||
|
+ ntohs(iphdr->ip6_plen));
|
||||||
|
break;
|
||||||
|
case ICMP6_TIME_EXCEEDED:
|
||||||
|
printf(" time exceeded in-transit, length %zu\n",
|
|
@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
|
||||||
PKG_NAME:=batman-adv
|
PKG_NAME:=batman-adv
|
||||||
|
|
||||||
PKG_VERSION:=2018.1
|
PKG_VERSION:=2018.1
|
||||||
PKG_RELEASE:=12
|
PKG_RELEASE:=13
|
||||||
PKG_HASH:=b866b28dbbe5c9238abbdf5abbc30fc526dea56898ce4c1bd76d5c017843048b
|
PKG_HASH:=b866b28dbbe5c9238abbdf5abbc30fc526dea56898ce4c1bd76d5c017843048b
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
From: Linus Lüssing <ll@simonwunderlich.de>
|
||||||
|
Date: Thu, 27 Aug 2020 17:34:48 +0200
|
||||||
|
Subject: batman-adv: bla: fix type misuse for backbone_gw hash indexing
|
||||||
|
|
||||||
|
It seems that due to a copy & paste error the void pointer
|
||||||
|
in batadv_choose_backbone_gw() is cast to the wrong type.
|
||||||
|
|
||||||
|
Fixing this by using "struct batadv_bla_backbone_gw" instead of "struct
|
||||||
|
batadv_bla_claim" which better matches the caller's side.
|
||||||
|
|
||||||
|
For now it seems that we were lucky because the two structs both have
|
||||||
|
their orig/vid and addr/vid in the beginning. However I stumbled over
|
||||||
|
this issue when I was trying to add some debug variables in front of
|
||||||
|
"orig" in batadv_backbone_gw, which caused hash lookups to fail.
|
||||||
|
|
||||||
|
Fixes: 7e15c9305ce0 ("batman-adv: don't rely on positions in struct for hashing")
|
||||||
|
Signed-off-by: Linus Lüssing <ll@simonwunderlich.de>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/398a706cd46c1fc085aef56ae8ed11f76e182bd1
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
index ed8259ff0dc7ba129825a369a757b37cc62ce829..9dc574f5659e2bce97bd7e0f3793f8c1edf1fbd5 100644
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
@@ -96,11 +96,12 @@ static inline u32 batadv_choose_claim(const void *data, u32 size)
|
||||||
|
*/
|
||||||
|
static inline u32 batadv_choose_backbone_gw(const void *data, u32 size)
|
||||||
|
{
|
||||||
|
- const struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data;
|
||||||
|
+ const struct batadv_bla_backbone_gw *gw;
|
||||||
|
u32 hash = 0;
|
||||||
|
|
||||||
|
- hash = jhash(&claim->addr, sizeof(claim->addr), hash);
|
||||||
|
- hash = jhash(&claim->vid, sizeof(claim->vid), hash);
|
||||||
|
+ gw = (struct batadv_bla_backbone_gw *)data;
|
||||||
|
+ hash = jhash(&gw->orig, sizeof(gw->orig), hash);
|
||||||
|
+ hash = jhash(&gw->vid, sizeof(gw->vid), hash);
|
||||||
|
|
||||||
|
return hash % size;
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Date: Fri, 4 Sep 2020 20:28:00 +0200
|
||||||
|
Subject: batman-adv: mcast/TT: fix wrongly dropped or rerouted packets
|
||||||
|
|
||||||
|
The unicast packet rerouting code makes several assumptions. For
|
||||||
|
instance it assumes that there is always exactly one destination in the
|
||||||
|
TT. This breaks for multicast frames in a unicast packets in several ways:
|
||||||
|
|
||||||
|
For one thing if there is actually no TT entry and the destination node
|
||||||
|
was selected due to the multicast tvlv flags it announced. Then an
|
||||||
|
intermediate node will wrongly drop the packet.
|
||||||
|
|
||||||
|
For another thing if there is a TT entry but the TTVN of this entry is
|
||||||
|
newer than the originally addressed destination node: Then the
|
||||||
|
intermediate node will wrongly redirect the packet, leading to
|
||||||
|
duplicated multicast packets at a multicast listener and missing
|
||||||
|
packets at other multicast listeners or multicast routers.
|
||||||
|
|
||||||
|
Fixing this by not applying the unicast packet rerouting to batman-adv
|
||||||
|
unicast packets with a multicast payload. We are not able to detect a
|
||||||
|
roaming multicast listener at the moment and will just continue to send
|
||||||
|
the multicast frame to both the new and old destination for a while in
|
||||||
|
case of such a roaming multicast listener.
|
||||||
|
|
||||||
|
Fixes: cea194d90b11 ("batman-adv: improved client announcement mechanism")
|
||||||
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/22e740c5e6c9342e0f5028beb3d14b84a018d113
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
|
||||||
|
index cc3ed93a6d513dffd4711cac50545d65ef7d640e..98af41e3810dcdf96edad8dff89d4d2b624c5d7f 100644
|
||||||
|
--- a/net/batman-adv/routing.c
|
||||||
|
+++ b/net/batman-adv/routing.c
|
||||||
|
@@ -838,6 +838,10 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
|
||||||
|
vid = batadv_get_vid(skb, hdr_len);
|
||||||
|
ethhdr = (struct ethhdr *)(skb->data + hdr_len);
|
||||||
|
|
||||||
|
+ /* do not reroute multicast frames in a unicast header */
|
||||||
|
+ if (is_multicast_ether_addr(ethhdr->h_dest))
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
/* check if the destination client was served by this node and it is now
|
||||||
|
* roaming. In this case, it means that the node has got a ROAM_ADV
|
||||||
|
* message and that it knows the new destination in the mesh to re-route
|
|
@ -0,0 +1,26 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Mon, 14 Sep 2020 13:58:16 +0200
|
||||||
|
Subject: batman-adv: Add missing include for in_interrupt()
|
||||||
|
|
||||||
|
The fix for receiving (internally generated) bla packets outside the
|
||||||
|
interrupt context introduced the usage of in_interrupt(). But this
|
||||||
|
functionality is only defined in linux/preempt.h which was not included
|
||||||
|
with the same patch.
|
||||||
|
|
||||||
|
Fixes: 3747f81a1380 ("batman-adv: bla: use netif_rx_ni when not in interrupt context")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6ea99cd9c82b2d1bc4a313fe9006bcf5d956380e
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
index 9dc574f5659e2bce97bd7e0f3793f8c1edf1fbd5..26f590ba31d49a85143f67f1c002a25dc007b594 100644
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
@@ -37,6 +37,7 @@
|
||||||
|
#include <linux/lockdep.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
+#include <linux/preempt.h>
|
||||||
|
#include <linux/rculist.h>
|
||||||
|
#include <linux/rcupdate.h>
|
||||||
|
#include <linux/seq_file.h>
|
|
@ -0,0 +1,139 @@
|
||||||
|
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Date: Tue, 15 Sep 2020 09:54:08 +0200
|
||||||
|
Subject: batman-adv: mcast: fix duplicate mcast packets in BLA backbone from LAN
|
||||||
|
|
||||||
|
Scenario:
|
||||||
|
* Multicast frame send from a BLA backbone (multiple nodes with
|
||||||
|
their bat0 bridged together, with BLA enabled)
|
||||||
|
|
||||||
|
Issue:
|
||||||
|
* BLA backbone nodes receive the frame multiple times on bat0
|
||||||
|
|
||||||
|
For multicast frames received via batman-adv broadcast packets the
|
||||||
|
originator of the broadcast packet is checked before decapsulating and
|
||||||
|
forwarding the frame to bat0 (batadv_bla_is_backbone_gw()->
|
||||||
|
batadv_recv_bcast_packet()). If it came from a node which shares the
|
||||||
|
same BLA backbone with us then it is not forwarded to bat0 to avoid a
|
||||||
|
loop.
|
||||||
|
|
||||||
|
When sending a multicast frame in a non-4-address batman-adv unicast
|
||||||
|
packet we are currently missing this check - and cannot do so because
|
||||||
|
the batman-adv unicast packet has no originator address field.
|
||||||
|
|
||||||
|
However, we can simply fix this on the sender side by only sending the
|
||||||
|
multicast frame via unicasts to interested nodes which do not share the
|
||||||
|
same BLA backbone with us. This also nicely avoids some unnecessary
|
||||||
|
transmissions on mesh side.
|
||||||
|
|
||||||
|
Note that no infinite loop was observed, probably because of dropping
|
||||||
|
via batadv_interface_tx()->batadv_bla_tx(). However the duplicates still
|
||||||
|
utterly confuse switches/bridges, ICMPv6 duplicate address detection and
|
||||||
|
neighbor discovery and therefore leads to long delays before being able
|
||||||
|
to establish TCP connections, for instance. And it also leads to the Linux
|
||||||
|
bridge printing messages like:
|
||||||
|
"br-lan: received packet on eth1 with own address as source address ..."
|
||||||
|
|
||||||
|
Fixes: 405cc1e5a81e ("batman-adv: Modified forwarding behaviour for multicast packets")
|
||||||
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Acked-by: Simon Wunderlich <sw@simonwunderlich.de>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: backport, https://git.open-mesh.org/batman-adv.git/commit/3c39a2455a5be02ecceeaf1a15976bddd611392e
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c
|
||||||
|
index 39640d3d6fbdf8244344db6e79f2d769eb0972d9..adfad7cb34b4d3a8b6ebffd6b19854616ca0f97b 100644
|
||||||
|
--- a/net/batman-adv/multicast.c
|
||||||
|
+++ b/net/batman-adv/multicast.c
|
||||||
|
@@ -62,6 +62,7 @@
|
||||||
|
#include <uapi/linux/batadv_packet.h>
|
||||||
|
#include <uapi/linux/batman_adv.h>
|
||||||
|
|
||||||
|
+#include "bridge_loop_avoidance.h"
|
||||||
|
#include "hard-interface.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "log.h"
|
||||||
|
@@ -1027,6 +1028,35 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * batadv_mcast_forw_send_orig() - send a multicast packet to an originator
|
||||||
|
+ * @bat_priv: the bat priv with all the soft interface information
|
||||||
|
+ * @skb: the multicast packet to send
|
||||||
|
+ * @vid: the vlan identifier
|
||||||
|
+ * @orig_node: the originator to send the packet to
|
||||||
|
+ *
|
||||||
|
+ * Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
|
||||||
|
+ */
|
||||||
|
+int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
|
||||||
|
+ struct sk_buff *skb,
|
||||||
|
+ unsigned short vid,
|
||||||
|
+ struct batadv_orig_node *orig_node)
|
||||||
|
+{
|
||||||
|
+ /* Avoid sending multicast-in-unicast packets to other BLA
|
||||||
|
+ * gateways - they already got the frame from the LAN side
|
||||||
|
+ * we share with them.
|
||||||
|
+ * TODO: Refactor to take BLA into account earlier, to avoid
|
||||||
|
+ * reducing the mcast_fanout count.
|
||||||
|
+ */
|
||||||
|
+ if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) {
|
||||||
|
+ dev_kfree_skb(skb);
|
||||||
|
+ return NET_XMIT_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0,
|
||||||
|
+ orig_node, vid);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* batadv_mcast_want_unsnoop_update() - update unsnoop counter and list
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
diff --git a/net/batman-adv/multicast.h b/net/batman-adv/multicast.h
|
||||||
|
index 3b04ab13f0eb1044454315c04e75a22ce4351afd..6f9f3813fc59a8e8798b71297c8d8f9ef50b5e72 100644
|
||||||
|
--- a/net/batman-adv/multicast.h
|
||||||
|
+++ b/net/batman-adv/multicast.h
|
||||||
|
@@ -51,6 +51,11 @@ enum batadv_forw_mode
|
||||||
|
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
struct batadv_orig_node **mcast_single_orig);
|
||||||
|
|
||||||
|
+int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
|
||||||
|
+ struct sk_buff *skb,
|
||||||
|
+ unsigned short vid,
|
||||||
|
+ struct batadv_orig_node *orig_node);
|
||||||
|
+
|
||||||
|
void batadv_mcast_init(struct batadv_priv *bat_priv);
|
||||||
|
|
||||||
|
int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset);
|
||||||
|
@@ -78,6 +83,16 @@ static inline int batadv_mcast_init(struct batadv_priv *bat_priv)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline int
|
||||||
|
+batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
|
||||||
|
+ struct sk_buff *skb,
|
||||||
|
+ unsigned short vid,
|
||||||
|
+ struct batadv_orig_node *orig_node)
|
||||||
|
+{
|
||||||
|
+ kfree_skb(skb);
|
||||||
|
+ return NET_XMIT_DROP;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static inline int
|
||||||
|
batadv_mcast_mesh_info_put(struct sk_buff *msg, struct batadv_priv *bat_priv)
|
||||||
|
{
|
||||||
|
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
|
||||||
|
index 97e28907a0acbb3d64d8ceebf7b1df13dc396300..267f6e6c802f1a7d3eb41a0f3aa2142ca3b21414 100644
|
||||||
|
--- a/net/batman-adv/soft-interface.c
|
||||||
|
+++ b/net/batman-adv/soft-interface.c
|
||||||
|
@@ -367,9 +367,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
||||||
|
goto dropped;
|
||||||
|
ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
|
||||||
|
} else if (mcast_single_orig) {
|
||||||
|
- ret = batadv_send_skb_unicast(bat_priv, skb,
|
||||||
|
- BATADV_UNICAST, 0,
|
||||||
|
- mcast_single_orig, vid);
|
||||||
|
+ ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid,
|
||||||
|
+ mcast_single_orig);
|
||||||
|
} else {
|
||||||
|
if (batadv_dat_snoop_outgoing_arp_request(bat_priv,
|
||||||
|
skb))
|
|
@ -0,0 +1,156 @@
|
||||||
|
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Date: Tue, 15 Sep 2020 09:54:09 +0200
|
||||||
|
Subject: batman-adv: mcast: fix duplicate mcast packets in BLA backbone from mesh
|
||||||
|
|
||||||
|
Scenario:
|
||||||
|
* Multicast frame send from mesh to a BLA backbone (multiple nodes
|
||||||
|
with their bat0 bridged together, with BLA enabled)
|
||||||
|
|
||||||
|
Issue:
|
||||||
|
* BLA backbone nodes receive the frame multiple times on bat0,
|
||||||
|
once from mesh->bat0 and once from each backbone_gw from LAN
|
||||||
|
|
||||||
|
For unicast, a node will send only to the best backbone gateway
|
||||||
|
according to the TQ. However for multicast we currently cannot determine
|
||||||
|
if multiple destination nodes share the same backbone if they don't share
|
||||||
|
the same backbone with us. So we need to keep sending the unicasts to
|
||||||
|
all backbone gateways and let the backbone gateways decide which one
|
||||||
|
will forward the frame. We can use the CLAIM mechanism to make this
|
||||||
|
decision.
|
||||||
|
|
||||||
|
One catch: The batman-adv gateway feature for DHCP packets potentially
|
||||||
|
sends multicast packets in the same batman-adv unicast header as the
|
||||||
|
multicast optimizations code. And we are not allowed to drop those even
|
||||||
|
if we did not claim the source address of the sender, as for such
|
||||||
|
packets there is only this one multicast-in-unicast packet.
|
||||||
|
|
||||||
|
How can we distinguish the two cases?
|
||||||
|
|
||||||
|
The gateway feature uses a batman-adv unicast 4 address header. While
|
||||||
|
the multicast-to-unicasts feature uses a simple, 3 address batman-adv
|
||||||
|
unicast header. So let's use this to distinguish.
|
||||||
|
|
||||||
|
Fixes: e32470167379 ("batman-adv: check incoming packet type for bla")
|
||||||
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Acked-by: Simon Wunderlich <sw@simonwunderlich.de>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d7665cf8a824c41c61c6e2110ab63d37eb7a8ef7
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
index 26f590ba31d49a85143f67f1c002a25dc007b594..4dc67a0d081c06507aba87f7bec03488817791b2 100644
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
@@ -1827,7 +1827,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @skb: the frame to be checked
|
||||||
|
* @vid: the VLAN ID of the frame
|
||||||
|
- * @is_bcast: the packet came in a broadcast packet type.
|
||||||
|
+ * @packet_type: the batman packet type this frame came in
|
||||||
|
*
|
||||||
|
* batadv_bla_rx avoidance checks if:
|
||||||
|
* * we have to race for a claim
|
||||||
|
@@ -1839,7 +1839,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
* further process the skb.
|
||||||
|
*/
|
||||||
|
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
- unsigned short vid, bool is_bcast)
|
||||||
|
+ unsigned short vid, int packet_type)
|
||||||
|
{
|
||||||
|
struct batadv_bla_backbone_gw *backbone_gw;
|
||||||
|
struct ethhdr *ethhdr;
|
||||||
|
@@ -1861,9 +1861,24 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
goto handled;
|
||||||
|
|
||||||
|
if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
|
||||||
|
- /* don't allow broadcasts while requests are in flight */
|
||||||
|
- if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
|
||||||
|
- goto handled;
|
||||||
|
+ /* don't allow multicast packets while requests are in flight */
|
||||||
|
+ if (is_multicast_ether_addr(ethhdr->h_dest))
|
||||||
|
+ /* Both broadcast flooding or multicast-via-unicasts
|
||||||
|
+ * delivery might send to multiple backbone gateways
|
||||||
|
+ * sharing the same LAN and therefore need to coordinate
|
||||||
|
+ * which backbone gateway forwards into the LAN,
|
||||||
|
+ * by claiming the payload source address.
|
||||||
|
+ *
|
||||||
|
+ * Broadcast flooding and multicast-via-unicasts
|
||||||
|
+ * delivery use the following two batman packet types.
|
||||||
|
+ * Note: explicitly exclude BATADV_UNICAST_4ADDR,
|
||||||
|
+ * as the DHCP gateway feature will send explicitly
|
||||||
|
+ * to only one BLA gateway, so the claiming process
|
||||||
|
+ * should be avoided there.
|
||||||
|
+ */
|
||||||
|
+ if (packet_type == BATADV_BCAST ||
|
||||||
|
+ packet_type == BATADV_UNICAST)
|
||||||
|
+ goto handled;
|
||||||
|
|
||||||
|
ether_addr_copy(search_claim.addr, ethhdr->h_source);
|
||||||
|
search_claim.vid = vid;
|
||||||
|
@@ -1898,13 +1913,14 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
goto allow;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* if it is a broadcast ... */
|
||||||
|
- if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) {
|
||||||
|
+ /* if it is a multicast ... */
|
||||||
|
+ if (is_multicast_ether_addr(ethhdr->h_dest) &&
|
||||||
|
+ (packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) {
|
||||||
|
/* ... drop it. the responsible gateway is in charge.
|
||||||
|
*
|
||||||
|
- * We need to check is_bcast because with the gateway
|
||||||
|
+ * We need to check packet type because with the gateway
|
||||||
|
* feature, broadcasts (like DHCP requests) may be sent
|
||||||
|
- * using a unicast packet type.
|
||||||
|
+ * using a unicast 4 address packet type. See comment above.
|
||||||
|
*/
|
||||||
|
goto handled;
|
||||||
|
} else {
|
||||||
|
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h
|
||||||
|
index 71f95a3e4d3f335890408685432f18e5d7411a76..af28fdb01467ce290c2a00d0741f01a6e4f347ee 100644
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.h
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.h
|
||||||
|
@@ -48,7 +48,7 @@ static inline bool batadv_bla_is_loopdetect_mac(const uint8_t *mac)
|
||||||
|
|
||||||
|
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||||
|
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
- unsigned short vid, bool is_bcast);
|
||||||
|
+ unsigned short vid, int packet_type);
|
||||||
|
bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
unsigned short vid);
|
||||||
|
bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
|
||||||
|
@@ -79,7 +79,7 @@ bool batadv_bla_check_claim(struct batadv_priv *bat_priv, u8 *addr,
|
||||||
|
|
||||||
|
static inline bool batadv_bla_rx(struct batadv_priv *bat_priv,
|
||||||
|
struct sk_buff *skb, unsigned short vid,
|
||||||
|
- bool is_bcast)
|
||||||
|
+ int packet_type)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
|
||||||
|
index 267f6e6c802f1a7d3eb41a0f3aa2142ca3b21414..82582abd92485b68254789fb6e2108ae5e547dd6 100644
|
||||||
|
--- a/net/batman-adv/soft-interface.c
|
||||||
|
+++ b/net/batman-adv/soft-interface.c
|
||||||
|
@@ -425,10 +425,10 @@ void batadv_interface_rx(struct net_device *soft_iface,
|
||||||
|
struct vlan_ethhdr *vhdr;
|
||||||
|
struct ethhdr *ethhdr;
|
||||||
|
unsigned short vid;
|
||||||
|
- bool is_bcast;
|
||||||
|
+ int packet_type;
|
||||||
|
|
||||||
|
batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||||
|
- is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST);
|
||||||
|
+ packet_type = batadv_bcast_packet->packet_type;
|
||||||
|
|
||||||
|
skb_pull_rcsum(skb, hdr_size);
|
||||||
|
skb_reset_mac_header(skb);
|
||||||
|
@@ -471,7 +471,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
|
||||||
|
/* Let the bridge loop avoidance check the packet. If will
|
||||||
|
* not handle it, we can safely push it up.
|
||||||
|
*/
|
||||||
|
- if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
|
||||||
|
+ if (batadv_bla_rx(bat_priv, skb, vid, packet_type))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (orig_node)
|
|
@ -0,0 +1,190 @@
|
||||||
|
From: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Date: Tue, 15 Sep 2020 09:54:10 +0200
|
||||||
|
Subject: batman-adv: mcast: fix duplicate mcast packets from BLA backbone to mesh
|
||||||
|
|
||||||
|
Scenario:
|
||||||
|
* Multicast frame send from BLA backbone gateways (multiple nodes
|
||||||
|
with their bat0 bridged together, with BLA enabled) sharing the same
|
||||||
|
LAN to nodes in the mesh
|
||||||
|
|
||||||
|
Issue:
|
||||||
|
* Nodes receive the frame multiple times on bat0 from the mesh,
|
||||||
|
once from each foreign BLA backbone gateway which shares the same LAN
|
||||||
|
with another
|
||||||
|
|
||||||
|
For multicast frames via batman-adv broadcast packets coming from the
|
||||||
|
same BLA backbone but from different backbone gateways duplicates are
|
||||||
|
currently detected via a CRC history of previously received packets.
|
||||||
|
|
||||||
|
However this CRC so far was not performed for multicast frames received
|
||||||
|
via batman-adv unicast packets. Fixing this by appyling the same check
|
||||||
|
for such packets, too.
|
||||||
|
|
||||||
|
Room for improvements in the future: Ideally we would introduce the
|
||||||
|
possibility to not only claim a client, but a complete originator, too.
|
||||||
|
This would allow us to only send a multicast-in-unicast packet from a BLA
|
||||||
|
backbone gateway claiming the node and by that avoid potential redundant
|
||||||
|
transmissions in the first place.
|
||||||
|
|
||||||
|
Fixes: e5cf86d30a9b ("batman-adv: add broadcast duplicate check")
|
||||||
|
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/c5cb6a670cc3070d9d5c5562f95fa75faac767ba
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
index 4dc67a0d081c06507aba87f7bec03488817791b2..4996bd7b8256557bddaf8ebe87cc606def588adf 100644
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
@@ -1594,13 +1594,16 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
|
||||||
|
+ * batadv_bla_check_duplist() - Check if a frame is in the broadcast dup.
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
- * @skb: contains the bcast_packet to be checked
|
||||||
|
+ * @skb: contains the multicast packet to be checked
|
||||||
|
+ * @payload_ptr: pointer to position inside the head buffer of the skb
|
||||||
|
+ * marking the start of the data to be CRC'ed
|
||||||
|
+ * @orig: originator mac address, NULL if unknown
|
||||||
|
*
|
||||||
|
- * check if it is on our broadcast list. Another gateway might
|
||||||
|
- * have sent the same packet because it is connected to the same backbone,
|
||||||
|
- * so we have to remove this duplicate.
|
||||||
|
+ * Check if it is on our broadcast list. Another gateway might have sent the
|
||||||
|
+ * same packet because it is connected to the same backbone, so we have to
|
||||||
|
+ * remove this duplicate.
|
||||||
|
*
|
||||||
|
* This is performed by checking the CRC, which will tell us
|
||||||
|
* with a good chance that it is the same packet. If it is furthermore
|
||||||
|
@@ -1609,19 +1612,17 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
|
||||||
|
*
|
||||||
|
* Return: true if a packet is in the duplicate list, false otherwise.
|
||||||
|
*/
|
||||||
|
-bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||||
|
- struct sk_buff *skb)
|
||||||
|
+static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv,
|
||||||
|
+ struct sk_buff *skb, u8 *payload_ptr,
|
||||||
|
+ const u8 *orig)
|
||||||
|
{
|
||||||
|
- int i, curr;
|
||||||
|
- __be32 crc;
|
||||||
|
- struct batadv_bcast_packet *bcast_packet;
|
||||||
|
struct batadv_bcast_duplist_entry *entry;
|
||||||
|
bool ret = false;
|
||||||
|
-
|
||||||
|
- bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||||
|
+ int i, curr;
|
||||||
|
+ __be32 crc;
|
||||||
|
|
||||||
|
/* calculate the crc ... */
|
||||||
|
- crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1));
|
||||||
|
+ crc = batadv_skb_crc32(skb, payload_ptr);
|
||||||
|
|
||||||
|
spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
|
||||||
|
|
||||||
|
@@ -1640,8 +1641,21 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||||
|
if (entry->crc != crc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- if (batadv_compare_eth(entry->orig, bcast_packet->orig))
|
||||||
|
- continue;
|
||||||
|
+ /* are the originators both known and not anonymous? */
|
||||||
|
+ if (orig && !is_zero_ether_addr(orig) &&
|
||||||
|
+ !is_zero_ether_addr(entry->orig)) {
|
||||||
|
+ /* If known, check if the new frame came from
|
||||||
|
+ * the same originator:
|
||||||
|
+ * We are safe to take identical frames from the
|
||||||
|
+ * same orig, if known, as multiplications in
|
||||||
|
+ * the mesh are detected via the (orig, seqno) pair.
|
||||||
|
+ * So we can be a bit more liberal here and allow
|
||||||
|
+ * identical frames from the same orig which the source
|
||||||
|
+ * host might have sent multiple times on purpose.
|
||||||
|
+ */
|
||||||
|
+ if (batadv_compare_eth(entry->orig, orig))
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* this entry seems to match: same crc, not too old,
|
||||||
|
* and from another gw. therefore return true to forbid it.
|
||||||
|
@@ -1657,7 +1671,14 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||||
|
entry = &bat_priv->bla.bcast_duplist[curr];
|
||||||
|
entry->crc = crc;
|
||||||
|
entry->entrytime = jiffies;
|
||||||
|
- ether_addr_copy(entry->orig, bcast_packet->orig);
|
||||||
|
+
|
||||||
|
+ /* known originator */
|
||||||
|
+ if (orig)
|
||||||
|
+ ether_addr_copy(entry->orig, orig);
|
||||||
|
+ /* anonymous originator */
|
||||||
|
+ else
|
||||||
|
+ eth_zero_addr(entry->orig);
|
||||||
|
+
|
||||||
|
bat_priv->bla.bcast_duplist_curr = curr;
|
||||||
|
|
||||||
|
out:
|
||||||
|
@@ -1666,6 +1687,48 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup.
|
||||||
|
+ * @bat_priv: the bat priv with all the soft interface information
|
||||||
|
+ * @skb: contains the multicast packet to be checked, decapsulated from a
|
||||||
|
+ * unicast_packet
|
||||||
|
+ *
|
||||||
|
+ * Check if it is on our broadcast list. Another gateway might have sent the
|
||||||
|
+ * same packet because it is connected to the same backbone, so we have to
|
||||||
|
+ * remove this duplicate.
|
||||||
|
+ *
|
||||||
|
+ * Return: true if a packet is in the duplicate list, false otherwise.
|
||||||
|
+ */
|
||||||
|
+static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv,
|
||||||
|
+ struct sk_buff *skb)
|
||||||
|
+{
|
||||||
|
+ return batadv_bla_check_duplist(bat_priv, skb, (u8 *)skb->data, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
|
||||||
|
+ * @bat_priv: the bat priv with all the soft interface information
|
||||||
|
+ * @skb: contains the bcast_packet to be checked
|
||||||
|
+ *
|
||||||
|
+ * Check if it is on our broadcast list. Another gateway might have sent the
|
||||||
|
+ * same packet because it is connected to the same backbone, so we have to
|
||||||
|
+ * remove this duplicate.
|
||||||
|
+ *
|
||||||
|
+ * Return: true if a packet is in the duplicate list, false otherwise.
|
||||||
|
+ */
|
||||||
|
+bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||||
|
+ struct sk_buff *skb)
|
||||||
|
+{
|
||||||
|
+ struct batadv_bcast_packet *bcast_packet;
|
||||||
|
+ u8 *payload_ptr;
|
||||||
|
+
|
||||||
|
+ bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||||
|
+ payload_ptr = (u8 *)(bcast_packet + 1);
|
||||||
|
+
|
||||||
|
+ return batadv_bla_check_duplist(bat_priv, skb, payload_ptr,
|
||||||
|
+ bcast_packet->orig);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for
|
||||||
|
* the VLAN identified by vid.
|
||||||
|
@@ -1880,6 +1943,14 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
packet_type == BATADV_UNICAST)
|
||||||
|
goto handled;
|
||||||
|
|
||||||
|
+ /* potential duplicates from foreign BLA backbone gateways via
|
||||||
|
+ * multicast-in-unicast packets
|
||||||
|
+ */
|
||||||
|
+ if (is_multicast_ether_addr(ethhdr->h_dest) &&
|
||||||
|
+ packet_type == BATADV_UNICAST &&
|
||||||
|
+ batadv_bla_check_ucast_duplist(bat_priv, skb))
|
||||||
|
+ goto handled;
|
||||||
|
+
|
||||||
|
ether_addr_copy(search_claim.addr, ethhdr->h_source);
|
||||||
|
search_claim.vid = vid;
|
||||||
|
claim = batadv_claim_hash_find(bat_priv, &search_claim);
|
Loading…
Reference in New Issue