On Fri, May 24, 2013 at 10:02:27AM +0200, Linus Lüssing wrote: > If the soft interface of a node is not part of a bridge then a node > announces a new multicast TVLV: The according flag > (BATADV_MCAST_LISTENER_ANNOUNCEMENT) signalizes that this node is > announcing all of its multicast listeners via the translation table > infrastructure. More precisely, all multicast listeners of scope greater > than link-local for IPv4 and of scope greater > or equal to link-local for IPv6. > > Signed-off-by: Linus Lüssing <[email protected]> > --- > main.c | 4 ++++ > multicast.c | 62 > ++++++++++++++++++++++++++++++++++++++++++++++++++++-- > multicast.h | 7 ++++++ > originator.c | 3 +++ > packet.h | 7 ++++++ > soft-interface.c | 1 + > types.h | 4 ++++ > 7 files changed, 86 insertions(+), 2 deletions(-) > > diff --git a/main.c b/main.c > index 1c82c18..6ab5b2d 100644 > --- a/main.c > +++ b/main.c > @@ -145,6 +145,10 @@ int batadv_mesh_init(struct net_device *soft_iface) > if (ret < 0) > goto err; > > + ret = batadv_mcast_init(bat_priv); > + if (ret < 0) > + goto err; > + > ret = batadv_gw_init(bat_priv); > if (ret < 0) > goto err; > diff --git a/multicast.c b/multicast.c > index 56a1128..36e4c59 100644 > --- a/multicast.c > +++ b/multicast.c > @@ -204,10 +213,59 @@ out: > } > > /** > + * batadv_mcast_tvlv_ogm_handler_v1 - process incoming multicast tvlv > container > + * @bat_priv: the bat priv with all the soft interface information > + * @orig: the orig_node of the ogm > + * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags) > + * @tvlv_value: tvlv buffer containing the multicast data > + * @tvlv_value_len: tvlv buffer length > + */ > +static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, > + struct batadv_orig_node *orig, > + uint8_t flags, > + void *tvlv_value, > + uint16_t tvlv_value_len) > +{ > + uint8_t mcast_flags = BATADV_NO_FLAGS; > + > + /* only fetch the tvlv value if the handler wasn't called via the > + * CIFNOTFND flag and if there is data to fetch > + */ > + if (!(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) && > + (tvlv_value) && (tvlv_value_len == sizeof(mcast_flags))) > + mcast_flags = *(uint8_t *)tvlv_value; > + > + if (!(mcast_flags & BATADV_MCAST_LISTENER_ANNOUNCEMENT) && > + orig->mcast_flags & BATADV_MCAST_LISTENER_ANNOUNCEMENT) { > + atomic_inc(&bat_priv->mcast.num_non_aware); > + } else if (mcast_flags & BATADV_MCAST_LISTENER_ANNOUNCEMENT && > + !(orig->mcast_flags & BATADV_MCAST_LISTENER_ANNOUNCEMENT)) { > + atomic_dec(&bat_priv->mcast.num_non_aware); > + }
What happens if the orig_node is removed/times out? I can't see where
num_non_aware
is updated in this case.
We do have a work struct touch every orig every second anyway
(batadv_purge_orig), maybe
put counting multicast aware routers there? Then you don't have to care about
synchronizing stuff ...
> +
> + orig->mcast_flags = mcast_flags;
> +}
> +
> +/**
> + * batadv_mcast_init - initialize the multicast optimizations structures
> + * @bat_priv: the bat priv with all the soft interface information
> + */
> +int batadv_mcast_init(struct batadv_priv *bat_priv)
> +{
> + batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler_v1,
> + NULL, BATADV_TVLV_MCAST, 1,
> + BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
> + return 0;
> +}
> +
> +/**
> * batadv_mcast_free - free the multicast optimizations structures
> * @bat_priv: the bat priv with all the soft interface information
> */
> void batadv_mcast_free(struct batadv_priv *bat_priv)
> {
> + batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 1);
> + batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 1);
> +
> batadv_mcast_mla_tt_clean(bat_priv, NULL);
> }
signature.asc
Description: Digital signature
