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 linus.luessing@web.de
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);
}