This is a note to let you know that I've just added the patch titled
batman-adv: mcast: fix duplicate mcast packets from BLA backbone to mesh
to the 4.9-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summ...
The filename of the patch is: batman-adv-mcast-fix-duplicate-mcast-packets-from-bla-backbone-to-mesh.patch and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
From foo@baz Tue Nov 23 01:37:10 PM CET 2021 From: Sven Eckelmann sven@narfation.org Date: Sat, 20 Nov 2021 13:39:55 +0100 Subject: batman-adv: mcast: fix duplicate mcast packets from BLA backbone to mesh To: stable@vger.kernel.org Cc: b.a.t.m.a.n@lists.open-mesh.org, "Linus Lüssing" linus.luessing@c0d3.blue, "Simon Wunderlich" sw@simonwunderlich.de, "Sven Eckelmann" sven@narfation.org Message-ID: 20211120123958.260826-5-sven@narfation.org
From: Linus Lüssing linus.luessing@c0d3.blue
commit 2369e827046920ef0599e6a36b975ac5c0a359c2 upstream.
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: Simon Wunderlich sw@simonwunderlich.de [ bp: 4.9 backported: adjust context, correct fixes line ] Signed-off-by: Sven Eckelmann sven@narfation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/batman-adv/bridge_loop_avoidance.c | 105 +++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 17 deletions(-)
--- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1593,13 +1593,16 @@ int batadv_bla_init(struct batadv_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 - * - * 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. + * @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. * * 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 @@ -1608,19 +1611,17 @@ int batadv_bla_init(struct batadv_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);
@@ -1639,8 +1640,21 @@ bool batadv_bla_check_bcast_duplist(stru 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. @@ -1656,7 +1670,14 @@ bool batadv_bla_check_bcast_duplist(stru 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 @@ out: }
/** + * 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. * @bat_priv: the bat priv with all the soft interface information @@ -1879,6 +1942,14 @@ bool batadv_bla_rx(struct batadv_priv *b 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);
Patches currently in stable-queue which might be from sven@narfation.org are
queue-4.9/batman-adv-consider-fragmentation-for-needed_headroom.patch queue-4.9/ath9k-fix-potential-interrupt-storm-on-queue-reset.patch queue-4.9/batman-adv-mcast-fix-duplicate-mcast-packets-from-bla-backbone-to-mesh.patch queue-4.9/ath10k-fix-max-antenna-gain-unit.patch queue-4.9/batman-adv-mcast-fix-duplicate-mcast-packets-in-bla-backbone-from-lan.patch queue-4.9/batman-adv-reserve-needed_-room-for-fragments.patch queue-4.9/batman-adv-fix-own-ogm-check-in-aggregated-ogms.patch queue-4.9/batman-adv-keep-fragments-equally-sized.patch queue-4.9/batman-adv-don-t-always-reallocate-the-fragmentation-skb-head.patch