All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Wunderlich <sw@simonwunderlich.de>
To: b.a.t.m.a.n@lists.open-mesh.org
Subject: Re: [PATCH v6 1/3] batman-adv: mcast: implement multicast packet reception and forwarding
Date: Mon, 14 Aug 2023 17:35:28 +0200	[thread overview]
Message-ID: <2296108.bB369e8A3T@prime> (raw)
In-Reply-To: <20230720043556.12163-2-linus.luessing@c0d3.blue>

[-- Attachment #1: Type: text/plain, Size: 7478 bytes --]

On Thursday, July 20, 2023 6:35:53 AM CEST Linus Lüssing wrote:
> [...]
> +
> +/**
> + * batadv_mcast_forw_orig_to_neigh() - get next hop neighbor to an orig
> address + * @bat_priv: the bat priv with all the soft interface information
> + * @orig_addr: the originator MAC address to search the best next hop
> router for + *
> + * Return: A neighbor node which is the best router towards the given
> originator + * address.
> + */
> +static struct batadv_neigh_node *
> +batadv_mcast_forw_orig_to_neigh(struct batadv_priv *bat_priv, u8
> *orig_addr) +{
> +	struct batadv_neigh_node *neigh_node;
> +	struct batadv_orig_node *orig_node;
> +
> +	orig_node = batadv_orig_hash_find(bat_priv, orig_addr);
> +	if (!orig_node)
> +		return NULL;
> +
> +	neigh_node = batadv_find_router(bat_priv, orig_node, NULL);
> +	batadv_orig_node_put(orig_node);
> +
> +	return neigh_node;
> +}

I was wondering if this shouldn't be a generic function rather than a multicast-specific function. It doesn't do anything multicast specific. I couldn't find something similar in other code though.

> +
> +/**
> + * batadv_mcast_forw_scrub_dests() - scrub destinations in a tracker TVLV
> + * @bat_priv: the bat priv with all the soft interface information
> + * @comp_neigh: next hop neighbor to scrub+collect destinations for
> + * @dest: start MAC entry in original skb's tracker TVLV
> + * @next_dest: start MAC entry in to be sent skb's tracker TVLV
> + * @num_dests: number of remaining destination MAC entries to iterate over
> + *
> + * This sorts destination entries into either the original batman-adv
> + * multicast packet or the skb (copy) that is going to be sent to
> comp_neigh + * next.
> + *
> + * In preparation for the next, to be (unicast) transmitted batman-adv
> multicast + * packet skb to be sent to the given neighbor node, tries to
> collect all + * originator MAC addresses that have the given neighbor node
> as their next hop + * in the to be transmitted skb (copy), which next_dest
> points into. That is we + * zero all destination entries in next_dest which
> do not have comp_neigh as + * their next hop. And zero all destination
> entries in the original skb that + * would have comp_neigh as their next
> hop (to avoid redundant transmissions and + * duplicated payload later).
> + */
> +static void
> +batadv_mcast_forw_scrub_dests(struct batadv_priv *bat_priv,
> +			      struct batadv_neigh_node *comp_neigh, u8 *dest,
> +			      u8 *next_dest, u16 num_dests)
> +{
> +	struct batadv_neigh_node *next_neigh;
> +
> +	/* skip first entry, this is what we are comparing with */
> +	eth_zero_addr(dest);
> +	dest += ETH_ALEN;
> +	next_dest += ETH_ALEN;
> +	num_dests--;
> +
> +	batadv_mcast_forw_tracker_for_each_dest(next_dest, num_dests) {
> +		if (is_zero_ether_addr(next_dest))
> +			goto scrub_next;
> +
> +		if (is_multicast_ether_addr(next_dest)) {
> +			eth_zero_addr(dest);
> +			eth_zero_addr(next_dest);
> +			goto scrub_next;
> +		}
> +
> +		next_neigh = batadv_mcast_forw_orig_to_neigh(bat_priv,
> +							     next_dest);
> +		if (!next_neigh) {
> +			eth_zero_addr(next_dest);
> +			goto scrub_next;
> +		}
> +
> +		/* Is this for our next packet to transmit? */
> +		if (batadv_compare_eth(next_neigh->addr, comp_neigh->addr))
> +			eth_zero_addr(dest);
> +		else
> +			eth_zero_addr(next_dest);
> +
> +		batadv_neigh_node_put(next_neigh);
> +scrub_next:
> +		dest += ETH_ALEN;

I've read through that multiple times now, and I don't understand why next_dest isn't getting incremented within each iteration in the same way as dest. Is this a bug or am I missing something? Might be nicer to use one counter which is increased instead of two pointeres, e.g. &dest[counter] and &next_dest[counter] or similar to avoid those kind of bugs.

> [...]
> +/**
> + * batadv_mcast_forw_tracker_tvlv_handler() - handle an mcast tracker tvlv
> + * @bat_priv: the bat priv with all the soft interface information
> + * @skb: the received batman-adv multicast packet
> + *
> + * Parses the tracker TVLV of an incoming batman-adv multicast packet and
> + * forwards the packet as indicated in this TVLV.
> + *
> + * Caller needs to set the skb network header to the start of the multicast
> + * tracker TVLV (excluding the generic TVLV header) and the skb transport
> header + * to the next byte after this multicast tracker TVLV.
> + *
> + * Caller needs to free the skb.
> + *
> + * Return: NET_RX_SUCCESS or NET_RX_DROP on success or a negative error
> + * code on failure. NET_RX_SUCCESS if the received packet is supposed to be
> + * decapsulated and forwarded to the own soft interface, NET_RX_DROP
> otherwise. + */
> +int batadv_mcast_forw_tracker_tvlv_handler(struct batadv_priv *bat_priv,
> +					   struct sk_buff *skb)
> +{
> +	return batadv_mcast_forw_packet(bat_priv, skb, false);
> +}
> diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
> index 34903df4fe93..e46ce83c516a 100644
> --- a/net/batman-adv/originator.c
> +++ b/net/batman-adv/originator.c
> @@ -942,6 +942,7 @@ struct batadv_orig_node *batadv_orig_node_new(struct
> batadv_priv *bat_priv, #ifdef CONFIG_BATMAN_ADV_MCAST
>  	orig_node->mcast_flags = BATADV_MCAST_WANT_NO_RTR4;
>  	orig_node->mcast_flags |= BATADV_MCAST_WANT_NO_RTR6;
> +	orig_node->mcast_flags |= BATADV_MCAST_HAVE_MC_PTYPE_CAPA;
>  	INIT_HLIST_NODE(&orig_node->mcast_want_all_unsnoopables_node);
>  	INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv4_node);
>  	INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv6_node);
> diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
> index 163cd43c4821..f1061985149f 100644
> --- a/net/batman-adv/routing.c
> +++ b/net/batman-adv/routing.c
> @@ -1270,3 +1270,73 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
>  	batadv_orig_node_put(orig_node);
>  	return ret;
>  }
> +
> +#ifdef CONFIG_BATMAN_ADV_MCAST
> +/**
> + * batadv_recv_mcast_packet() - process received batman-adv multicast
> packet + * @skb: the received batman-adv multicast packet
> + * @recv_if: interface that the skb is received on
> + *
> + * Parses the given, received batman-adv multicast packet. Depending on the
> + * contents of its TVLV forwards it and/or decapsulates it to hand it to
> the + * soft interface.
> + *
> + * Return: NET_RX_DROP if the skb is not consumed, NET_RX_SUCCESS
> otherwise. + */
> +int batadv_recv_mcast_packet(struct sk_buff *skb,
> +			     struct batadv_hard_iface *recv_if)
> +{
> +	struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
> +	struct batadv_mcast_packet *mcast_packet;
> +	int hdr_size = sizeof(*mcast_packet);
> +	unsigned char *tvlv_buff;
> +	int ret = NET_RX_DROP;
> +	u16 tvlv_buff_len;
> +
> +	if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
> +		goto free_skb;
> +
> +	/* create a copy of the skb, if needed, to modify it. */
> +	if (skb_cow(skb, ETH_HLEN) < 0)
> +		goto free_skb;
> +
> +	/* packet needs to be linearized to access the tvlv content */
> +	if (skb_linearize(skb) < 0)
> +		goto free_skb;
> +
> +	mcast_packet = (struct batadv_mcast_packet *)skb->data;
> +	if (mcast_packet->ttl-- < 2)
> +		goto free_skb;

More of a nit (since we do the same check in broadcasts), but if ttl == 0 on the incoming packet, then we will actually forward it with ttl =255 and that's a bit stupid ...

Cheers,
      Simon

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  parent reply	other threads:[~2023-08-14 15:36 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-20  4:35 [PATCH v6 0/3] Implementation of a Stateless Multicast Packet Type Linus Lüssing
2023-07-20  4:35 ` [PATCH v6 1/3] batman-adv: mcast: implement multicast packet reception and forwarding Linus Lüssing
2023-07-28 17:52   ` Sven Eckelmann
2023-08-14 15:35   ` Simon Wunderlich [this message]
2023-08-14 15:53     ` Simon Wunderlich
2023-07-20  4:35 ` [PATCH v6 2/3] batman-adv: mcast: implement multicast packet generation Linus Lüssing
2023-07-29 10:49   ` Sven Eckelmann
2023-07-20  4:35 ` [PATCH v6 3/3] batman-adv: mcast: shrink tracker packet after scrubbing Linus Lüssing
2023-07-29 11:11   ` Sven Eckelmann
2023-08-14 15:56   ` Simon Wunderlich
2023-07-29 11:11 ` [PATCH v6 0/3] Implementation of a Stateless Multicast Packet Type Sven Eckelmann
2023-08-14 16:05   ` Sven Eckelmann

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=2296108.bB369e8A3T@prime \
    --to=sw@simonwunderlich.de \
    --cc=b.a.t.m.a.n@lists.open-mesh.org \
    /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.