From: Simon Wunderlich <sw@simonwunderlich.de>
To: b.a.t.m.a.n@lists.open-mesh.org
Cc: "Linus Lüssing" <linus.luessing@c0d3.blue>
Subject: Re: [PATCH maint v5 3/3] batman-adv: mcast: fix duplicate mcast packets from BLA backbone to mesh
Date: Tue, 15 Sep 2020 09:18:54 +0200 [thread overview]
Message-ID: <3934010.JrcoLyHp49@prime> (raw)
In-Reply-To: <20200914195347.10505-4-linus.luessing@c0d3.blue>
[-- Attachment #1: Type: text/plain, Size: 8123 bytes --]
On Monday, September 14, 2020 9:53:47 PM CEST Linus Lüssing wrote:
> 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>
> ---
> net/batman-adv/bridge_loop_avoidance.c | 107 +++++++++++++++++++++----
> 1 file changed, 92 insertions(+), 15 deletions(-)
>
> diff --git a/net/batman-adv/bridge_loop_avoidance.c
> b/net/batman-adv/bridge_loop_avoidance.c index 3d2a66f2..e4f66dd8 100644
> --- a/net/batman-adv/bridge_loop_avoidance.c
> +++ b/net/batman-adv/bridge_loop_avoidance.c
> @@ -1580,13 +1580,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
> @@ -1595,23 +1598,23 @@ 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)
> {
> + struct batadv_bcast_duplist_entry *entry;
> + bool ret = false;
> 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;
>
> /* 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);
>
> for (i = 0; i < BATADV_DUPLIST_SIZE; i++) {
> + bool is_from_same_orig = false;
> +
> curr = (bat_priv->bla.bcast_duplist_curr + i);
> curr %= BATADV_DUPLIST_SIZE;
> entry = &bat_priv->bla.bcast_duplist[curr];
> @@ -1626,7 +1629,24 @@ 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))
> + /* 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
> + */
> + if (batadv_compare_eth(entry->orig, orig))
> + is_from_same_orig = true;
> + }
> +
> + /* 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 (is_from_same_orig)
> continue;
>
I think this "is_from_same_orig" variable is redundant, it's not used again so
you could continue directly above.
The rest looks good.
Cheers,
Simon
> /* this entry seems to match: same crc, not too old,
> @@ -1643,7 +1663,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:
> @@ -1652,6 +1679,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.
> @@ -1866,6 +1935,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);
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
prev parent reply other threads:[~2020-09-15 7:18 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-14 19:53 [PATCH maint v5 0/3] batman-adv: mcast: BLA fixes Linus Lüssing
2020-09-14 19:53 ` [PATCH maint v5 1/3] batman-adv: mcast: fix duplicate mcast packets in BLA backbone from LAN Linus Lüssing
2020-09-15 7:11 ` Simon Wunderlich
2020-09-14 19:53 ` [PATCH maint v5 2/3] batman-adv: mcast: fix duplicate mcast packets in BLA backbone from mesh Linus Lüssing
2020-09-15 7:12 ` Simon Wunderlich
2020-09-14 19:53 ` [PATCH maint v5 3/3] batman-adv: mcast: fix duplicate mcast packets from BLA backbone to mesh Linus Lüssing
2020-09-15 7:18 ` Simon Wunderlich [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3934010.JrcoLyHp49@prime \
--to=sw@simonwunderlich.de \
--cc=b.a.t.m.a.n@lists.open-mesh.org \
--cc=linus.luessing@c0d3.blue \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.