All of lore.kernel.org
 help / color / mirror / Atom feed
* [B.A.T.M.A.N.] Basic Multicast Optimizations
@ 2013-08-13  8:23 Linus Lüssing
  2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 1/5] batman-adv: Multicast Listener Announcements via Translation Table Linus Lüssing
                   ` (5 more replies)
  0 siblings, 6 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-08-13  8:23 UTC (permalink / raw)
  To: b.a.t.m.a.n

This is the eighth revision of the basic multicast optimization patches.

It adds many style + functional changes and fixes some bugs.

It also adds a new, important fifth patch, which addresses an issue
that I would have overlooked if it weren't for the extensive offline
talks with Simon about the interaction of batman-adv and various
multicast related RFCs.


# Changelog v7 -> v8

## Style improvements

* renamed batadv_mcast_tt_clean() tobatadv_mcast_tt_retract()
* renamed batadv_mcast_tvlv_update_flag_counter() to batadv_mcast_update_counter()
* renamed batadv_mcast_mla_tt_update() to batadv_mcast_mla_update()
* renamed batadv_mcast_update_counter() to batadv_mcast_counter_update()

* renamed BATADV_MCAST_HAS_NO_BRIDGE to BATADV_MCAST_WANT_ALL_UNSNOOPABLES (and reverse its logic)
* change value of BATADV_UNINIT_FLAGS from -1 to an unused bit, BIT(15)
  -> no more need to check BATADV_UNINIT_FLAGS in batadv_mcast_counter_update()

* moved code from batadv_mcast_mla_tt_update() to newly introduced batadv_mcast_mla_tvlv_update
* moved introduction of multicast_mode sysfs file to the third patch
* added kernel doc for struct batadv_priv_mcast and enum batadv_mcast_flag

## Functional improvements

* changed a '== -EINVAL' to '< 0'
* check for a bridge anywhere on top of bat0 (like br0 on bond0 on bat0, not just br0 on bat0)
  (as discussed on IRC we don't need to check for bridges on top of vlans yet as multicast
  optimizations are only enabled for non-VLAN packets at the moment)
* removed sysfs file control over multicast TT+TVLV announcements, moved sysfs file introduction to the third patch
* removed BATADV_MCAST_LISTENER_ANNOUNCEMENT flag: its purpose is now provided by checking the existence of the multicast tvlv instead
* made the tvlv value length check in the multicast tvlv handler to not only accept a length of one byte but anything greater, too
* New Patch: batman-adv: Send multicast packets to nodes with a WANT_ALL flag

## Bugs

* converted the static 'enabled' variable in batadv_mcast_mla_tt_update() to a per bat_priv variable, using bat_priv->mcast.flags (fixes a bug when using multiple batX interfaces)
* the announced tvlv was missing the BATADV_MCAST_HAS_NO_BRIDGE flag (not needed anymore with the reversed logic)
* batadv_mcast_update_counter() was missing a case which would have needed a BATADV_UNINIT_FLAGS check (not needed anymore with reversed logic and new value for BATADV_UNINIT_FLAGS)
* added missing update for num_want_all_unsnoopables (former num_has_bridge) counter in batadv_mcast_purge_orig()


Cheers, Linus


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] [PATCHv8 1/5] batman-adv: Multicast Listener Announcements via Translation Table
  2013-08-13  8:23 [B.A.T.M.A.N.] Basic Multicast Optimizations Linus Lüssing
@ 2013-08-13  8:23 ` Linus Lüssing
  2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 2/5] batman-adv: Announce new capability via multicast TVLV Linus Lüssing
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-08-13  8:23 UTC (permalink / raw)
  To: b.a.t.m.a.n

With this patch a node which has no bridge interface on top of its soft
interface announces its local multicast listeners via the translation
table.

Signed-off-by: Linus Lüssing <linus.luessing@web.de>
---
 Makefile               |    2 +
 Makefile.kbuild        |    1 +
 compat.h               |   41 ++++++++
 gen-compat-autoconf.sh |    1 +
 main.c                 |    6 ++
 main.h                 |    1 +
 multicast.c            |  243 ++++++++++++++++++++++++++++++++++++++++++++++++
 multicast.h            |   43 +++++++++
 translation-table.c    |   22 ++++-
 types.h                |   23 +++++
 10 files changed, 379 insertions(+), 4 deletions(-)
 create mode 100644 multicast.c
 create mode 100644 multicast.h

diff --git a/Makefile b/Makefile
index 407cdc4..ce9bf32 100644
--- a/Makefile
+++ b/Makefile
@@ -27,6 +27,8 @@ export CONFIG_BATMAN_ADV_BLA=y
 export CONFIG_BATMAN_ADV_DAT=y
 # B.A.T.M.A.N network coding (catwoman):
 export CONFIG_BATMAN_ADV_NC=n
+# B.A.T.M.A.N. multicast optimizations:
+export CONFIG_BATMAN_ADV_MCAST=y
 
 PWD:=$(shell pwd)
 KERNELPATH ?= /lib/modules/$(shell uname -r)/build
diff --git a/Makefile.kbuild b/Makefile.kbuild
index 4f4aabb..66d1cbe 100644
--- a/Makefile.kbuild
+++ b/Makefile.kbuild
@@ -38,3 +38,4 @@ batman-adv-y += send.o
 batman-adv-y += soft-interface.o
 batman-adv-y += sysfs.o
 batman-adv-y += translation-table.o
+batman-adv-$(CONFIG_BATMAN_ADV_MCAST) += multicast.o
diff --git a/compat.h b/compat.h
index 7687229..00ee042 100644
--- a/compat.h
+++ b/compat.h
@@ -106,6 +106,24 @@ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
 
 #define pr_warn pr_warning
 
+#undef  netdev_for_each_mc_addr
+#define netdev_for_each_mc_addr(mclist, dev) \
+	for (mclist = (struct bat_dev_addr_list *)dev->mc_list; mclist; \
+	     mclist = (struct bat_dev_addr_list *)mclist->next)
+
+/* Note, that this breaks the usage of the normal 'struct netdev_hw_addr'
+ * for kernels < 2.6.35 in batman-adv!
+ */
+#define netdev_hw_addr batadv_dev_addr_list
+struct batadv_dev_addr_list {
+	struct dev_addr_list *next;
+	u8  addr[MAX_ADDR_LEN];
+	u8  da_addrlen;
+	u8  da_synced;
+	int da_users;
+	int da_gusers;
+};
+
 #endif /* < KERNEL_VERSION(2, 6, 35) */
 
 
@@ -146,6 +164,16 @@ static inline int batadv_param_set_copystring(const char *val,
 #define addr_assign_type ifindex
 #define NET_ADDR_RANDOM 0
 
+#define netdev_master_upper_dev_get_rcu(dev) \
+	upper; \
+	rcu_read_unlock(); \
+	if (dev->br_port ? 1 : 0) { \
+		dev_hold(dev); \
+		return dev; \
+	} \
+\
+	return NULL\
+
 #endif /* < KERNEL_VERSION(2, 6, 36) */
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
@@ -317,6 +345,19 @@ static int __batadv_interface_set_mac_addr(x, y)
 	pos && ({ n = pos->member.next; 1; }); \
 	pos = hlist_entry_safe(n, typeof(*pos), member))
 
+#ifndef netdev_master_upper_dev_get_rcu
+#define netdev_master_upper_dev_get_rcu(dev) \
+	upper; \
+	rcu_read_unlock(); \
+	if (dev->priv_flags & IFF_BRIDGE_PORT) { \
+		dev_hold(dev); \
+		return dev; \
+	} \
+\
+	return NULL\
+
+#endif /* netdev_master_upper_dev_get_rcu */
+
 #endif /* < KERNEL_VERSION(3, 9, 0) */
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
diff --git a/gen-compat-autoconf.sh b/gen-compat-autoconf.sh
index 78573e4..f625b6f 100755
--- a/gen-compat-autoconf.sh
+++ b/gen-compat-autoconf.sh
@@ -39,6 +39,7 @@ gen_config() {
 gen_config 'CONFIG_BATMAN_ADV_DEBUG' ${CONFIG_BATMAN_ADV_DEBUG:="n"} >> "${TMP}"
 gen_config 'CONFIG_BATMAN_ADV_BLA' ${CONFIG_BATMAN_ADV_BLA:="y"} >> "${TMP}"
 gen_config 'CONFIG_BATMAN_ADV_DAT' ${CONFIG_BATMAN_ADV_DAT:="y"} >> "${TMP}"
+gen_config 'CONFIG_BATMAN_ADV_MCAST' ${CONFIG_BATMAN_ADV_MCAST:="y"} >> "${TMP}"
 gen_config 'CONFIG_BATMAN_ADV_NC' ${CONFIG_BATMAN_ADV_NC:="n"} >> "${TMP}"
 
 # only regenerate compat-autoconf.h when config was changed
diff --git a/main.c b/main.c
index 1066889..cc1d426 100644
--- a/main.c
+++ b/main.c
@@ -36,6 +36,7 @@
 #include "gateway_client.h"
 #include "bridge_loop_avoidance.h"
 #include "distributed-arp-table.h"
+#include "multicast.h"
 #include "gateway_common.h"
 #include "hash.h"
 #include "bat_algo.h"
@@ -121,6 +122,9 @@ int batadv_mesh_init(struct net_device *soft_iface)
 	INIT_LIST_HEAD(&bat_priv->tt.changes_list);
 	INIT_LIST_HEAD(&bat_priv->tt.req_list);
 	INIT_LIST_HEAD(&bat_priv->tt.roam_list);
+#ifdef CONFIG_BATMAN_ADV_MCAST
+	INIT_HLIST_HEAD(&bat_priv->mcast.mla_list);
+#endif
 	INIT_HLIST_HEAD(&bat_priv->tvlv.container_list);
 	INIT_HLIST_HEAD(&bat_priv->tvlv.handler_list);
 	INIT_HLIST_HEAD(&bat_priv->softif_vlan_list);
@@ -172,6 +176,8 @@ void batadv_mesh_free(struct net_device *soft_iface)
 	batadv_dat_free(bat_priv);
 	batadv_bla_free(bat_priv);
 
+	batadv_mcast_free(bat_priv);
+
 	/* Free the TT and the originator tables only after having terminated
 	 * all the other depending components which may use these structures for
 	 * their purposes.
diff --git a/main.h b/main.h
index e860f1e..142228e 100644
--- a/main.h
+++ b/main.h
@@ -164,6 +164,7 @@ enum batadv_uev_type {
 #include <linux/percpu.h>
 #include <linux/slab.h>
 #include <net/sock.h>		/* struct sock */
+#include <net/addrconf.h>	/* ipv6 address stuff */
 #include <net/rtnetlink.h>
 #include <linux/jiffies.h>
 #include <linux/seq_file.h>
diff --git a/multicast.c b/multicast.c
new file mode 100644
index 0000000..e46df5b
--- /dev/null
+++ b/multicast.c
@@ -0,0 +1,243 @@
+/* Copyright (C) 2013 B.A.T.M.A.N. contributors:
+ *
+ * Linus Lüssing
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#include "main.h"
+#include "originator.h"
+#include "hard-interface.h"
+#include "translation-table.h"
+
+/**
+ * batadv_mcast_mla_softif_get - get softif multicast listeners
+ * @dev: the device to collect multicast addresses from
+ * @mcast_list: a list to put found addresses into
+ *
+ * Collect multicast addresses of the local multicast listeners
+ * on the given soft interface, dev, in the given mcast_list.
+ *
+ * Return -ENOMEM on memory allocation error or the number of
+ * items added to the mcast_list otherwise.
+ */
+static int batadv_mcast_mla_softif_get(struct net_device *dev,
+				       struct hlist_head *mcast_list)
+{
+	struct netdev_hw_addr *mc_list_entry;
+	struct batadv_hw_addr *new;
+	int ret = 0;
+
+	netif_addr_lock_bh(dev);
+	netdev_for_each_mc_addr(mc_list_entry, dev) {
+		new = kmalloc(sizeof(*new), GFP_ATOMIC);
+		if (!new) {
+			ret = -ENOMEM;
+			break;
+		}
+
+		memcpy(&new->addr, &mc_list_entry->addr, ETH_ALEN);
+		hlist_add_head(&new->list, mcast_list);
+		ret++;
+	}
+	netif_addr_unlock_bh(dev);
+
+	return ret;
+}
+
+/**
+ * batadv_mcast_mla_is_duplicate - check whether an address is in a list
+ * @mcast_addr: the multicast address to check
+ * @mcast_list: the list with multicast addresses to search in
+ *
+ * Return true if the given address is already in the given list.
+ * Otherwise returns false.
+ */
+static bool batadv_mcast_mla_is_duplicate(uint8_t *mcast_addr,
+					  struct hlist_head *mcast_list)
+{
+	struct batadv_hw_addr *mcast_entry;
+
+	hlist_for_each_entry(mcast_entry, mcast_list, list)
+		if (batadv_compare_eth(mcast_entry->addr, mcast_addr))
+			return true;
+
+	return false;
+}
+
+/**
+ * batadv_mcast_mla_list_free - free a list of multicast addresses
+ * @mcast_list: the list to free
+ *
+ * Remove and free all items in the given mcast_list.
+ */
+static void batadv_mcast_mla_list_free(struct hlist_head *mcast_list)
+{
+	struct batadv_hw_addr *mcast_entry;
+	struct hlist_node *tmp;
+
+	hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
+		hlist_del(&mcast_entry->list);
+		kfree(mcast_entry);
+	}
+}
+
+/**
+ * batadv_mcast_mla_tt_retract - clean up multicast listener announcements
+ * @bat_priv: the bat priv with all the soft interface information
+ * @mcast_list: a list of addresses which should _not_ be removed
+ *
+ * Retract the announcement of any multicast listener from the
+ * translation table except the ones listed in the given mcast_list.
+ *
+ * If mcast_list is NULL then all are retracted.
+ */
+static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
+					struct hlist_head *mcast_list)
+{
+	struct batadv_hw_addr *mcast_entry;
+	struct hlist_node *tmp;
+
+	hlist_for_each_entry_safe(mcast_entry, tmp, &bat_priv->mcast.mla_list,
+				  list) {
+		if (mcast_list &&
+		    batadv_mcast_mla_is_duplicate(mcast_entry->addr,
+						  mcast_list))
+			continue;
+
+		batadv_tt_local_remove(bat_priv, mcast_entry->addr,
+				       BATADV_NO_FLAGS,
+				       "mcast TT outdated", false);
+
+		hlist_del(&mcast_entry->list);
+		kfree(mcast_entry);
+	}
+}
+
+/**
+ * batadv_mcast_mla_tt_add - add multicast listener announcements
+ * @bat_priv: the bat priv with all the soft interface information
+ * @mcast_list: a list of addresses which are going to get added
+ *
+ * Add multicast listener announcements from the given mcast_list to the
+ * translation table if they have not been added yet.
+ */
+static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv,
+				    struct hlist_head *mcast_list)
+{
+	struct batadv_hw_addr *mcast_entry;
+	struct hlist_node *tmp;
+
+	if (!mcast_list)
+		return;
+
+	hlist_for_each_entry_safe(mcast_entry, tmp, mcast_list, list) {
+		if (batadv_mcast_mla_is_duplicate(mcast_entry->addr,
+						  &bat_priv->mcast.mla_list))
+			continue;
+
+		batadv_tt_local_add(bat_priv->soft_iface, mcast_entry->addr,
+				    BATADV_NO_FLAGS, BATADV_NULL_IFINDEX);
+		hlist_del(&mcast_entry->list);
+		hlist_add_head(&mcast_entry->list, &bat_priv->mcast.mla_list);
+	}
+}
+
+/**
+ * batadv_mcast_get_bridge - get the bridge interface on our soft interface
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Return the next bridge interface on top of our soft interface and increase
+ * its refcount. If no such bridge interface exists, then return NULL.
+ */
+static struct net_device *
+batadv_mcast_get_bridge(struct batadv_priv *bat_priv)
+{
+	struct net_device *upper = bat_priv->soft_iface;
+
+	rcu_read_lock();
+
+	do {
+		upper = netdev_master_upper_dev_get_rcu(upper);
+	} while (upper && !(upper->priv_flags & IFF_EBRIDGE));
+
+	if (upper)
+		dev_hold(upper);
+
+	rcu_read_unlock();
+
+	return upper;
+}
+
+/**
+ * batadv_mcast_has_bridge - check whether the soft-iface is bridged
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Check whether there is a bridge on top of our soft interface. Return
+ * true if so, false otherwise.
+ */
+static bool batadv_mcast_has_bridge(struct batadv_priv *bat_priv)
+{
+	struct net_device *bridge;
+
+	bridge = batadv_mcast_get_bridge(bat_priv);
+	if (!bridge)
+		goto out;
+
+	dev_put(bridge);
+	return true;
+out:
+	return false;
+}
+
+/**
+ * batadv_mcast_mla_update - update the own MLAs
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Update the own multicast listener announcements in the translation
+ * table.
+ */
+void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
+{
+	struct net_device *soft_iface = bat_priv->soft_iface;
+	struct hlist_head mcast_list = HLIST_HEAD_INIT;
+	int ret;
+
+	/* Avoid attaching MLAs, if there is a bridge on top of our soft
+	 * interface, we don't support that yet (TODO)
+	 */
+	if (batadv_mcast_has_bridge(bat_priv))
+		goto update;
+
+	ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list);
+	if (ret < 0)
+		goto out;
+
+update:
+	batadv_mcast_mla_tt_retract(bat_priv, &mcast_list);
+	batadv_mcast_mla_tt_add(bat_priv, &mcast_list);
+
+out:
+	batadv_mcast_mla_list_free(&mcast_list);
+}
+
+/**
+ * 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_mcast_mla_tt_retract(bat_priv, NULL);
+}
diff --git a/multicast.h b/multicast.h
new file mode 100644
index 0000000..3509b37
--- /dev/null
+++ b/multicast.h
@@ -0,0 +1,43 @@
+/* Copyright (C) 2013 B.A.T.M.A.N. contributors:
+ *
+ * Linus Lüssing
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#ifndef _NET_BATMAN_ADV_MULTICAST_H_
+#define _NET_BATMAN_ADV_MULTICAST_H_
+
+#ifdef CONFIG_BATMAN_ADV_MCAST
+
+void batadv_mcast_mla_update(struct batadv_priv *bat_priv);
+
+void batadv_mcast_free(struct batadv_priv *bat_priv);
+
+#else
+
+static inline void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
+{
+	return;
+}
+
+static inline void batadv_mcast_free(struct batadv_priv *bat_priv)
+{
+	return;
+}
+
+#endif /* CONFIG_BATMAN_ADV_MCAST */
+
+#endif /* _NET_BATMAN_ADV_MULTICAST_H_ */
diff --git a/translation-table.c b/translation-table.c
index 2b4d9ed..5055bde 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -26,6 +26,7 @@
 #include "originator.h"
 #include "routing.h"
 #include "bridge_loop_avoidance.h"
+#include "multicast.h"
 
 #include <linux/crc32c.h>
 
@@ -445,14 +446,16 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
 {
 	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
 	struct batadv_tt_local_entry *tt_local;
-	struct batadv_tt_global_entry *tt_global;
+	struct batadv_tt_global_entry *tt_global = NULL;
 	struct hlist_head *head;
 	struct batadv_tt_orig_list_entry *orig_entry;
 	int hash_added;
 	bool roamed_back = false;
 
 	tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
-	tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
+
+	if (!is_multicast_ether_addr(addr))
+		tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
 
 	if (tt_local) {
 		tt_local->last_seen = jiffies;
@@ -506,8 +509,11 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
 	tt_local->last_seen = jiffies;
 	tt_local->common.added_at = tt_local->last_seen;
 
-	/* the batman interface mac address should never be purged */
-	if (batadv_compare_eth(addr, soft_iface->dev_addr))
+	/* the batman interface mac and multicast addresses should never be
+	 * purged
+	 */
+	if (batadv_compare_eth(addr, soft_iface->dev_addr) ||
+	    is_multicast_ether_addr(addr))
 		tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
 
 	hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
@@ -1258,6 +1264,11 @@ add_orig_entry:
 	ret = true;
 
 out_remove:
+	/* Do not remove multicast addresses from the local hash on
+	 * global additions
+	 */
+	if (is_multicast_ether_addr(tt_addr))
+		goto out;
 
 	/* remove address from local hash if present */
 	local_flags = batadv_tt_local_remove(bat_priv, tt_addr, vid,
@@ -2967,6 +2978,9 @@ void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
 {
 	spin_lock_bh(&bat_priv->tt.commit_lock);
 
+	/* Update multicast addresses in local translation table */
+	batadv_mcast_mla_update(bat_priv);
+
 	if (atomic_read(&bat_priv->tt.local_changes) < 1) {
 		if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
 			batadv_tt_tvlv_container_update(bat_priv);
diff --git a/types.h b/types.h
index 0f938c2..53d1d6c 100644
--- a/types.h
+++ b/types.h
@@ -537,6 +537,16 @@ struct batadv_priv_dat {
 };
 #endif
 
+#ifdef CONFIG_BATMAN_ADV_MCAST
+/**
+ * struct batadv_priv_mcast - per mesh interface mcast data
+ * @mla_list: list of multicast addresses we are currently announcing via TT
+ */
+struct batadv_priv_mcast {
+	struct hlist_head mla_list;
+};
+#endif
+
 /**
  * struct batadv_priv_nc - per mesh interface network coding private data
  * @work: work queue callback item for cleanup
@@ -684,6 +694,9 @@ struct batadv_priv {
 #ifdef CONFIG_BATMAN_ADV_DAT
 	struct batadv_priv_dat dat;
 #endif
+#ifdef CONFIG_BATMAN_ADV_MCAST
+	struct batadv_priv_mcast mcast;
+#endif
 #ifdef CONFIG_BATMAN_ADV_NC
 	atomic_t network_coding;
 	struct batadv_priv_nc nc;
@@ -1009,6 +1022,16 @@ struct batadv_dat_entry {
 };
 
 /**
+ * struct batadv_hw_addr - a list entry for a MAC address
+ * @list: list node for the linking of entries
+ * @addr: the MAC address of this list entry
+ */
+struct batadv_hw_addr {
+	struct hlist_node list;
+	unsigned char addr[ETH_ALEN];
+};
+
+/**
  * struct batadv_dat_candidate - candidate destination for DAT operations
  * @type: the type of the selected candidate. It can one of the following:
  *	  - BATADV_DAT_CANDIDATE_NOT_FOUND
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] [PATCHv8 2/5] batman-adv: Announce new capability via multicast TVLV
  2013-08-13  8:23 [B.A.T.M.A.N.] Basic Multicast Optimizations Linus Lüssing
  2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 1/5] batman-adv: Multicast Listener Announcements via Translation Table Linus Lüssing
@ 2013-08-13  8:23 ` Linus Lüssing
  2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 3/5] batman-adv: Modified forwarding behaviour for multicast packets Linus Lüssing
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-08-13  8:23 UTC (permalink / raw)
  To: b.a.t.m.a.n

If the soft interface of a node is not part of a bridge then a node
announces a new multicast TVLV: The existence of this TVLV
signalizes that this node is announcing all of its multicast listeners
via the translation table infrastructure.

Signed-off-by: Linus Lüssing <linus.luessing@web.de>
---
 main.c           |    4 ++
 main.h           |    1 +
 multicast.c      |  125 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 multicast.h      |   14 ++++++
 originator.c     |    6 +++
 packet.h         |    2 +
 soft-interface.c |    4 ++
 types.h          |   11 +++++
 8 files changed, 162 insertions(+), 5 deletions(-)

diff --git a/main.c b/main.c
index cc1d426..69dbb75 100644
--- a/main.c
+++ b/main.c
@@ -149,6 +149,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/main.h b/main.h
index 142228e..7225f63 100644
--- a/main.h
+++ b/main.h
@@ -68,6 +68,7 @@
 #define BATADV_ROAMING_MAX_TIME 20000
 #define BATADV_ROAMING_MAX_COUNT 5
 
+#define BATADV_UNINIT_FLAGS BIT(15)
 #define BATADV_NO_FLAGS 0
 
 #define BATADV_NULL_IFINDEX 0 /* dummy ifindex used to avoid iface checks */
diff --git a/multicast.c b/multicast.c
index e46df5b..5211b63 100644
--- a/multicast.c
+++ b/multicast.c
@@ -203,11 +203,45 @@ out:
 }
 
 /**
+ * batadv_mcast_mla_tvlv_update - update multicast tvlv
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Update the own multicast tvlv with our current multicast related settings,
+ * capabilities and inabilities.
+ */
+static bool batadv_mcast_mla_tvlv_update(struct batadv_priv *bat_priv)
+{
+	uint8_t mcast_flags = BATADV_NO_FLAGS;
+
+	/* Avoid attaching MLAs, if there is a bridge on top of our soft
+	 * interface, we don't support that yet (TODO)
+	 */
+	if (batadv_mcast_has_bridge(bat_priv)) {
+		if (bat_priv->mcast.flags != BATADV_UNINIT_FLAGS) {
+			batadv_tvlv_container_unregister(bat_priv,
+							 BATADV_TVLV_MCAST, 1);
+			bat_priv->mcast.flags = BATADV_UNINIT_FLAGS;
+		}
+
+		return false;
+	}
+
+	if (mcast_flags != bat_priv->mcast.flags) {
+		batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 1,
+					       &mcast_flags,
+					       sizeof(mcast_flags));
+		bat_priv->mcast.flags = mcast_flags;
+	}
+
+	return true;
+}
+
+/**
  * batadv_mcast_mla_update - update the own MLAs
  * @bat_priv: the bat priv with all the soft interface information
  *
  * Update the own multicast listener announcements in the translation
- * table.
+ * table as well as the own, announced multicast tvlv container.
  */
 void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
 {
@@ -215,10 +249,7 @@ void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
 	struct hlist_head mcast_list = HLIST_HEAD_INIT;
 	int ret;
 
-	/* Avoid attaching MLAs, if there is a bridge on top of our soft
-	 * interface, we don't support that yet (TODO)
-	 */
-	if (batadv_mcast_has_bridge(bat_priv))
+	if (!batadv_mcast_mla_tvlv_update(bat_priv))
 		goto update;
 
 	ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list);
@@ -234,10 +265,94 @@ out:
 }
 
 /**
+ * batadv_mcast_counter_update - update the counter of a flag
+ * @flag: the flag we want to update counters for
+ * @flag_counter: the counter we might update
+ * @new_flags: the new capability bitset of a node
+ * @old_flags: the current, to be updated bitset of a node
+ *
+ * Update the given flag_counter with the help of the new flag information
+ * of a node to reflect how many nodes have the given flag set.
+ */
+static void batadv_mcast_counter_update(uint8_t flag, atomic_t *flag_counter,
+					uint8_t new_flags, int old_flags)
+{
+	if (new_flags & flag && !(old_flags & flag))
+		atomic_inc(flag_counter);
+	else if (!(new_flags & flag) && old_flags & flag)
+		atomic_dec(flag_counter);
+}
+
+/**
+ * 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)
+{
+	bool mcast_enabled = !(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
+	int old_capabilities = orig->capabilities;
+	uint8_t mcast_flags = BATADV_NO_FLAGS;
+
+	if (mcast_enabled)
+		orig->capabilities |= BATADV_ORIG_CAPA_HAS_MCAST;
+	else
+		orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_MCAST;
+
+	if (orig->mcast_flags == BATADV_UNINIT_FLAGS)
+		old_capabilities |= BATADV_ORIG_CAPA_HAS_MCAST;
+
+	if (mcast_enabled && tvlv_value &&
+	    (tvlv_value_len >= sizeof(mcast_flags)))
+		mcast_flags = *(uint8_t *)tvlv_value;
+
+	batadv_mcast_counter_update(BATADV_ORIG_CAPA_HAS_MCAST,
+				    &bat_priv->mcast.num_disabled,
+				    ~orig->capabilities, ~old_capabilities);
+
+	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_retract(bat_priv, NULL);
 }
+
+/**
+ * batadv_mcast_purge_orig - reset originator global mcast state modifications
+ * @orig: the originator which is going to get purged
+ */
+void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
+{
+	struct batadv_priv *bat_priv = orig->bat_priv;
+
+	batadv_mcast_counter_update(BATADV_ORIG_CAPA_HAS_MCAST,
+				    &bat_priv->mcast.num_disabled,
+				    ~BATADV_NO_FLAGS, ~orig->capabilities);
+}
diff --git a/multicast.h b/multicast.h
index 3509b37..fca066e 100644
--- a/multicast.h
+++ b/multicast.h
@@ -24,8 +24,12 @@
 
 void batadv_mcast_mla_update(struct batadv_priv *bat_priv);
 
+int batadv_mcast_init(struct batadv_priv *bat_priv);
+
 void batadv_mcast_free(struct batadv_priv *bat_priv);
 
+void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node);
+
 #else
 
 static inline void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
@@ -33,11 +37,21 @@ static inline void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
 	return;
 }
 
+static inline int batadv_mcast_init(struct batadv_priv *bat_priv)
+{
+	return 0;
+}
+
 static inline void batadv_mcast_free(struct batadv_priv *bat_priv)
 {
 	return;
 }
 
+static inline void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node)
+{
+	return;
+}
+
 #endif /* CONFIG_BATMAN_ADV_MCAST */
 
 #endif /* _NET_BATMAN_ADV_MULTICAST_H_ */
diff --git a/originator.c b/originator.c
index ee1d847..5b889a3 100644
--- a/originator.c
+++ b/originator.c
@@ -29,6 +29,7 @@
 #include "bridge_loop_avoidance.h"
 #include "network-coding.h"
 #include "fragmentation.h"
+#include "multicast.h"
 
 /* hash class keys */
 static struct lock_class_key batadv_orig_hash_lock_class_key;
@@ -225,6 +226,8 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
 
 	spin_unlock_bh(&orig_node->neigh_list_lock);
 
+	batadv_mcast_purge_orig(orig_node);
+
 	/* Free nc_nodes */
 	batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL);
 
@@ -342,6 +345,9 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
 	reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
 	orig_node->bcast_seqno_reset = reset_time;
 	orig_node->batman_seqno_reset = reset_time;
+#ifdef CONFIG_BATMAN_ADV_MCAST
+	orig_node->mcast_flags = BATADV_UNINIT_FLAGS;
+#endif
 
 	atomic_set(&orig_node->bond_candidates, 0);
 
diff --git a/packet.h b/packet.h
index f4bbb05..c8cc1b2 100644
--- a/packet.h
+++ b/packet.h
@@ -145,6 +145,7 @@ enum batadv_bla_claimframe {
  * @BATADV_TVLV_NC: network coding tvlv
  * @BATADV_TVLV_TT: translation table tvlv
  * @BATADV_TVLV_ROAM: roaming advertisement tvlv
+ * @BATADV_TVLV_MCAST: multicast capability tvlv
  */
 enum batadv_tvlv_type {
 	BATADV_TVLV_GW		= 0x01,
@@ -152,6 +153,7 @@ enum batadv_tvlv_type {
 	BATADV_TVLV_NC		= 0x03,
 	BATADV_TVLV_TT		= 0x04,
 	BATADV_TVLV_ROAM	= 0x05,
+	BATADV_TVLV_MCAST	= 0x06,
 };
 
 /* the destination hardware field in the ARP frame is used to
diff --git a/soft-interface.c b/soft-interface.c
index d018c49..aa19502 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -658,6 +658,10 @@ static int batadv_softif_init_late(struct net_device *dev)
 #ifdef CONFIG_BATMAN_ADV_DAT
 	atomic_set(&bat_priv->distributed_arp_table, 1);
 #endif
+#ifdef CONFIG_BATMAN_ADV_MCAST
+	bat_priv->mcast.flags = BATADV_UNINIT_FLAGS;
+	atomic_set(&bat_priv->mcast.num_disabled, 0);
+#endif
 	atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
 	atomic_set(&bat_priv->gw_sel_class, 20);
 	atomic_set(&bat_priv->gw.bandwidth_down, 100);
diff --git a/types.h b/types.h
index 53d1d6c..7ea9631 100644
--- a/types.h
+++ b/types.h
@@ -144,6 +144,7 @@ struct batadv_orig_node_vlan {
  * @last_seen: time when last packet from this node was received
  * @bcast_seqno_reset: time when the broadcast seqno window was reset
  * @batman_seqno_reset: time when the batman seqno window was reset
+ * @mcast_flags: multicast flags announced by the orig node
  * @capabilities: announced capabilities of this originator
  * @last_ttvn: last seen translation table version number
  * @tt_buff: last tt changeset this node received from the orig node
@@ -194,6 +195,9 @@ struct batadv_orig_node {
 	unsigned long last_seen;
 	unsigned long bcast_seqno_reset;
 	unsigned long batman_seqno_reset;
+#ifdef CONFIG_BATMAN_ADV_MCAST
+	int mcast_flags;
+#endif
 	uint8_t capabilities;
 	atomic_t last_ttvn;
 	unsigned char *tt_buff;
@@ -236,10 +240,13 @@ struct batadv_orig_node {
  * enum batadv_orig_capabilities - orig node capabilities
  * @BATADV_ORIG_CAPA_HAS_DAT: orig node has distributed arp table enabled
  * @BATADV_ORIG_CAPA_HAS_NC: orig node has network coding enabled
+ * @BATADV_ORIG_CAPA_HAS_MCAST: orig node has some multicast capability
+ *  (= orig node announces a tvlv of type BATADV_TVLV_MCAST)
  */
 enum batadv_orig_capabilities {
 	BATADV_ORIG_CAPA_HAS_DAT = BIT(1),
 	BATADV_ORIG_CAPA_HAS_NC = BIT(2),
+	BATADV_ORIG_CAPA_HAS_MCAST = BIT(3),
 };
 
 /**
@@ -541,9 +548,13 @@ struct batadv_priv_dat {
 /**
  * struct batadv_priv_mcast - per mesh interface mcast data
  * @mla_list: list of multicast addresses we are currently announcing via TT
+ * @flags: the flags we have last sent in our mcast tvlv
+ * @num_disabled: number of nodes that have no mcast tvlv
  */
 struct batadv_priv_mcast {
 	struct hlist_head mla_list;
+	int flags;
+	atomic_t num_disabled;
 };
 #endif
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] [PATCHv8 3/5] batman-adv: Modified forwarding behaviour for multicast packets
  2013-08-13  8:23 [B.A.T.M.A.N.] Basic Multicast Optimizations Linus Lüssing
  2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 1/5] batman-adv: Multicast Listener Announcements via Translation Table Linus Lüssing
  2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 2/5] batman-adv: Announce new capability via multicast TVLV Linus Lüssing
@ 2013-08-13  8:23 ` Linus Lüssing
  2013-08-15 13:45   ` Simon Wunderlich
  2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 4/5] batman-adv: Add IPv4 link-local/IPv6-ll-all-nodes multicast support Linus Lüssing
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 37+ messages in thread
From: Linus Lüssing @ 2013-08-13  8:23 UTC (permalink / raw)
  To: b.a.t.m.a.n

With this patch a multicast packet is not always simply flooded anymore,
the bevahiour for the following cases is changed to reduce
unnecessary overhead:

If all nodes within the horizon of a certain node have signalized
multicast listener announcement capability then an IPv6 multicast packet
with a destination of IPv6 link-local scope (excluding ff02::1) coming
from the upstream of this node...

* ...is dropped if there is no according multicast listener in the
  translation table,
* ...is forwarded via unicast if there is a single node with interested
  multicast listeners
* ...and otherwise still gets flooded.

Signed-off-by: Linus Lüssing <linus.luessing@web.de>
---
 multicast.c          |  102 ++++++++++++++++++++++++++++++++++++++++++++++++++
 multicast.h          |   23 ++++++++++++
 soft-interface.c     |   24 ++++++++++--
 sysfs-class-net-mesh |    9 +++++
 sysfs.c              |    6 +++
 translation-table.c  |   91 ++++++++++++++++++++++++++++++++++----------
 translation-table.h  |    2 +
 types.h              |    5 +++
 8 files changed, 238 insertions(+), 24 deletions(-)

diff --git a/multicast.c b/multicast.c
index 5211b63..29cb929 100644
--- a/multicast.c
+++ b/multicast.c
@@ -21,6 +21,7 @@
 #include "originator.h"
 #include "hard-interface.h"
 #include "translation-table.h"
+#include "multicast.h"
 
 /**
  * batadv_mcast_mla_softif_get - get softif multicast listeners
@@ -265,6 +266,107 @@ out:
 }
 
 /**
+ * batadv_mcast_forw_mode_check_ipv6 - check for optimized forwarding potential
+ * @skb: the IPv6 packet to check
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Check whether the given IPv6 packet has the potential to
+ * be forwarded with a mode more optimal than classic flooding.
+ *
+ * If so then return 0. Otherwise -EINVAL is returned or -ENOMEM if we are
+ * out of memory.
+ */
+static int batadv_mcast_forw_mode_check_ipv6(struct sk_buff *skb,
+					     struct batadv_priv *bat_priv)
+{
+	struct ipv6hdr *ip6hdr;
+
+	/* We might fail due to out-of-memory -> drop it */
+	if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr)))
+		return -ENOMEM;
+
+	ip6hdr = ipv6_hdr(skb);
+
+	/* TODO: Implement Multicast Router Discovery (RFC4286),
+	 * then allow scope > link local, too
+	 */
+	if (IPV6_ADDR_MC_SCOPE(&ip6hdr->daddr) !=
+	    IPV6_ADDR_SCOPE_LINKLOCAL)
+		return -EINVAL;
+
+	/* With one bridge involved, we cannot be certain about
+	 * link-local-all-nodes multicast listener announcements anymore
+	 * (see RFC4541, section 3, paragraph 3)
+	 */
+	if (ipv6_addr_is_ll_all_nodes(&ip6hdr->daddr))
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * batadv_mcast_forw_mode_check - check for optimized forwarding potential
+ * @skb: the multicast frame to check
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Check whether the given multicast ethernet frame has the potential to
+ * be forwarded with a mode more optimal than classic flooding.
+ *
+ * If so then return 0. Otherwise -EINVAL is returned or -ENOMEM if we are
+ * out of memory.
+ */
+static int batadv_mcast_forw_mode_check(struct sk_buff *skb,
+					struct batadv_priv *bat_priv)
+{
+	struct ethhdr *ethhdr = (struct ethhdr *)(skb->data);
+
+	if (!atomic_read(&bat_priv->multicast_mode))
+		return -EINVAL;
+
+	if (atomic_read(&bat_priv->mcast.num_disabled))
+		return -EINVAL;
+
+	switch (ntohs(ethhdr->h_proto)) {
+	case ETH_P_IPV6:
+		return batadv_mcast_forw_mode_check_ipv6(skb, bat_priv);
+	default:
+		return -EINVAL;
+	}
+}
+
+/**
+ * batadv_mcast_forw_mode - check on how to forward a multicast packet
+ * @skb: The multicast packet to check
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Return the forwarding mode as enum batadv_forw_mode.
+ */
+enum batadv_forw_mode
+batadv_mcast_forw_mode(struct sk_buff *skb, struct batadv_priv *bat_priv)
+{
+	struct ethhdr *ethhdr = (struct ethhdr *)(skb->data);
+	int ret;
+
+	ret = batadv_mcast_forw_mode_check(skb, bat_priv);
+	if (ret == -ENOMEM)
+		return BATADV_FORW_NONE;
+	else if (ret < 0)
+		return BATADV_FORW_ALL;
+
+	ret = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest,
+					  BATADV_NO_FLAGS);
+
+	switch (ret) {
+	case 0:
+		return BATADV_FORW_NONE;
+	case 1:
+		return BATADV_FORW_SINGLE;
+	default:
+		return BATADV_FORW_ALL;
+	}
+}
+
+/**
  * batadv_mcast_counter_update - update the counter of a flag
  * @flag: the flag we want to update counters for
  * @flag_counter: the counter we might update
diff --git a/multicast.h b/multicast.h
index fca066e..e26f146 100644
--- a/multicast.h
+++ b/multicast.h
@@ -20,10 +20,27 @@
 #ifndef _NET_BATMAN_ADV_MULTICAST_H_
 #define _NET_BATMAN_ADV_MULTICAST_H_
 
+/**
+ * batadv_forw_mode - the way a packet should be forwarded as
+ * @BATADV_FORW_ALL: forward the packet to all nodes
+ *  (currently via classic flooding)
+ * @BATADV_FORW_SINGLE: forward the packet to a single node
+ *  (currently via the BATMAN_IV unicast routing protocol)
+ * @BATADV_FORW_NONE: don't forward, drop it
+ */
+enum batadv_forw_mode {
+	BATADV_FORW_ALL,
+	BATADV_FORW_SINGLE,
+	BATADV_FORW_NONE,
+};
+
 #ifdef CONFIG_BATMAN_ADV_MCAST
 
 void batadv_mcast_mla_update(struct batadv_priv *bat_priv);
 
+enum batadv_forw_mode
+batadv_mcast_forw_mode(struct sk_buff *skb, struct batadv_priv *bat_priv);
+
 int batadv_mcast_init(struct batadv_priv *bat_priv);
 
 void batadv_mcast_free(struct batadv_priv *bat_priv);
@@ -37,6 +54,12 @@ static inline void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
 	return;
 }
 
+static inline enum batadv_forw_mode
+batadv_mcast_forw_mode(struct sk_buff *skb, struct batadv_priv *bat_priv)
+{
+	return BATADV_FORW_ALL;
+}
+
 static inline int batadv_mcast_init(struct batadv_priv *bat_priv)
 {
 	return 0;
diff --git a/soft-interface.c b/soft-interface.c
index aa19502..2ecf9a5 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -34,6 +34,7 @@
 #include <linux/ethtool.h>
 #include <linux/etherdevice.h>
 #include <linux/if_vlan.h>
+#include "multicast.h"
 #include "bridge_loop_avoidance.h"
 #include "network-coding.h"
 
@@ -169,6 +170,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
 	bool do_bcast = false;
 	unsigned short vid;
 	uint32_t seqno;
+	enum batadv_forw_mode mode;
+	bool forw_to_gw = false;
 
 	if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
 		goto dropped;
@@ -229,17 +232,29 @@ static int batadv_interface_tx(struct sk_buff *skb,
 			 * via unicast to their gateway
 			 */
 			ret = batadv_gw_is_dhcp_target(skb, &header_len);
-			if (ret)
+			if (ret) {
 				do_bcast = false;
+				forw_to_gw = true;
+			}
 			break;
 		case BATADV_GW_MODE_OFF:
 		default:
 			break;
 		}
 
-		/* reminder: ethhdr might have become unusable from here on
-		 * (batadv_gw_is_dhcp_target() might have reallocated skb data)
+		/* skb->data might have been reallocated by
+		 * batadv_gw_is_dhcp_target()
 		 */
+		ethhdr = (struct ethhdr *)skb->data;
+
+		if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) {
+			mode = batadv_mcast_forw_mode(skb, bat_priv);
+			if (mode == BATADV_FORW_NONE)
+				goto dropped;
+
+			if (mode == BATADV_FORW_SINGLE)
+				do_bcast = false;
+		}
 	}
 
 	batadv_skb_set_priority(skb, 0);
@@ -298,7 +313,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
 
 		batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);
 
-		if (is_multicast_ether_addr(ethhdr->h_dest))
+		if (forw_to_gw)
 			ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
 		else
 			ret = batadv_send_skb_via_tt(bat_priv, skb, vid);
@@ -660,6 +675,7 @@ static int batadv_softif_init_late(struct net_device *dev)
 #endif
 #ifdef CONFIG_BATMAN_ADV_MCAST
 	bat_priv->mcast.flags = BATADV_UNINIT_FLAGS;
+	atomic_set(&bat_priv->multicast_mode, 1);
 	atomic_set(&bat_priv->mcast.num_disabled, 0);
 #endif
 	atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
diff --git a/sysfs-class-net-mesh b/sysfs-class-net-mesh
index ee4a479..ac1b561 100644
--- a/sysfs-class-net-mesh
+++ b/sysfs-class-net-mesh
@@ -68,6 +68,15 @@ Description:
                 Defines the penalty which will be applied to an
                 originator message's tq-field on every hop.
 
+What:           /sys/class/net/<mesh_iface>/mesh/multicast_mode
+Date:           June 2013
+Contact:        Linus Lüssing <linus.luessing@web.de>
+Description:
+                Indicates whether multicast optimizations are enabled
+                or disabled. If set to zero then all nodes in the
+                mesh are going to use classic flooding for any
+                multicast packet with no optimizations.
+
 What:           /sys/class/net/<mesh_iface>/mesh/network_coding
 Date:           Nov 2012
 Contact:        Martin Hundeboll <martin@hundeboll.net>
diff --git a/sysfs.c b/sysfs.c
index 096b511..9e161df 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -464,6 +464,9 @@ BATADV_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, BATADV_TQ_MAX_VALUE,
 		     batadv_post_gw_deselect);
 static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth,
 		   batadv_store_gw_bwidth);
+#ifdef CONFIG_BATMAN_ADV_MCAST
+BATADV_ATTR_SIF_BOOL(multicast_mode, S_IRUGO | S_IWUSR, NULL);
+#endif
 #ifdef CONFIG_BATMAN_ADV_DEBUG
 BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL);
 #endif
@@ -481,6 +484,9 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
 #ifdef CONFIG_BATMAN_ADV_DAT
 	&batadv_attr_distributed_arp_table,
 #endif
+#ifdef CONFIG_BATMAN_ADV_MCAST
+	&batadv_attr_multicast_mode,
+#endif
 	&batadv_attr_fragmentation,
 	&batadv_attr_routing_algo,
 	&batadv_attr_gw_mode,
diff --git a/translation-table.c b/translation-table.c
index 5055bde..b06ce4e 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -195,6 +195,32 @@ batadv_tt_global_entry_free_ref(struct batadv_tt_global_entry *tt_global_entry)
 	}
 }
 
+/**
+ * batadv_tt_global_hash_count - count the number of orig entries
+ * @hash: hash table containing the tt entries
+ * @addr: the mac address of the client to count entries for
+ * @vid: VLAN identifier
+ *
+ * Return the number of originators advertising the given address/data
+ * (excluding ourself).
+ */
+int batadv_tt_global_hash_count(struct batadv_priv *bat_priv,
+				const uint8_t *addr, unsigned short vid)
+{
+	struct batadv_tt_global_entry *tt_global_entry;
+	int count = 0;
+
+	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
+	if (!tt_global_entry)
+		goto out;
+
+	count = atomic_read(&tt_global_entry->orig_list_count);
+	batadv_tt_global_entry_free_ref(tt_global_entry);
+
+out:
+	return count;
+}
+
 static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
 {
 	struct batadv_tt_orig_list_entry *orig_entry;
@@ -1122,6 +1148,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
 	hlist_add_head_rcu(&orig_entry->list,
 			   &tt_global->orig_list);
 	spin_unlock_bh(&tt_global->list_lock);
+	atomic_inc(&tt_global->orig_list_count);
+
 out:
 	if (orig_entry)
 		batadv_tt_orig_list_entry_free_ref(orig_entry);
@@ -1195,6 +1223,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
 		common->added_at = jiffies;
 
 		INIT_HLIST_HEAD(&tt_global_entry->orig_list);
+		atomic_set(&tt_global_entry->orig_list_count, 0);
 		spin_lock_init(&tt_global_entry->list_lock);
 
 		hash_added = batadv_hash_add(bat_priv->tt.global_hash,
@@ -1441,6 +1470,24 @@ out:
 	return 0;
 }
 
+/**
+ * batadv_tt_global_del_orig_entry - remove and free an orig_entry
+ * @tt_global_entry: the global entry to remove the orig_entry from
+ * @orig_entry: the orig entry to remove and free
+ *
+ * Remove an orig_entry from its list in the given tt_global_entry and
+ * free this orig_entry afterwards.
+ */
+static void
+batadv_tt_global_del_orig_entry(struct batadv_tt_global_entry *tt_global_entry,
+				struct batadv_tt_orig_list_entry *orig_entry)
+{
+	batadv_tt_global_size_dec(orig_entry->orig_node,
+				  tt_global_entry->common.vid);
+	hlist_del_rcu(&orig_entry->list);
+	batadv_tt_orig_list_entry_free_ref(orig_entry);
+}
+
 /* deletes the orig list of a tt_global_entry */
 static void
 batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry)
@@ -1451,20 +1498,26 @@ batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry)
 
 	spin_lock_bh(&tt_global_entry->list_lock);
 	head = &tt_global_entry->orig_list;
-	hlist_for_each_entry_safe(orig_entry, safe, head, list) {
-		hlist_del_rcu(&orig_entry->list);
-		batadv_tt_global_size_dec(orig_entry->orig_node,
-					  tt_global_entry->common.vid);
-		batadv_tt_orig_list_entry_free_ref(orig_entry);
-	}
+	hlist_for_each_entry_safe(orig_entry, safe, head, list)
+		batadv_tt_global_del_orig_entry(tt_global_entry, orig_entry);
 	spin_unlock_bh(&tt_global_entry->list_lock);
 }
 
+/**
+ * batadv_tt_global_del_orig_node - remove orig_node from a global tt entry
+ * @bat_priv: the bat priv with all the soft interface information
+ * @tt_global_entry: the global entry to remove the orig_node from
+ * @orig_node: the originator announcing the client
+ * @message: message to append to the log on deletion
+ *
+ * Remove the given orig_node and its according orig_entry from the given
+ * global tt entry.
+ */
 static void
-batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
-				struct batadv_tt_global_entry *tt_global_entry,
-				struct batadv_orig_node *orig_node,
-				const char *message)
+batadv_tt_global_del_orig_node(struct batadv_priv *bat_priv,
+			       struct batadv_tt_global_entry *tt_global_entry,
+			       struct batadv_orig_node *orig_node,
+			       const char *message)
 {
 	struct hlist_head *head;
 	struct hlist_node *safe;
@@ -1481,10 +1534,8 @@ batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
 				   orig_node->orig,
 				   tt_global_entry->common.addr,
 				   BATADV_PRINT_VID(vid), message);
-			hlist_del_rcu(&orig_entry->list);
-			batadv_tt_global_size_dec(orig_node,
-						  tt_global_entry->common.vid);
-			batadv_tt_orig_list_entry_free_ref(orig_entry);
+			batadv_tt_global_del_orig_entry(tt_global_entry,
+							orig_entry);
 		}
 	}
 	spin_unlock_bh(&tt_global_entry->list_lock);
@@ -1526,8 +1577,8 @@ batadv_tt_global_del_roaming(struct batadv_priv *bat_priv,
 		/* there is another entry, we can simply delete this
 		 * one and can still use the other one.
 		 */
-		batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry,
-						orig_node, message);
+		batadv_tt_global_del_orig_node(bat_priv, tt_global_entry,
+					       orig_node, message);
 }
 
 /**
@@ -1553,8 +1604,8 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
 		goto out;
 
 	if (!roaming) {
-		batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry,
-						orig_node, message);
+		batadv_tt_global_del_orig_node(bat_priv, tt_global_entry,
+					       orig_node, message);
 
 		if (hlist_empty(&tt_global_entry->orig_list))
 			batadv_tt_global_free(bat_priv, tt_global_entry,
@@ -1637,8 +1688,8 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
 						 struct batadv_tt_global_entry,
 						 common);
 
-			batadv_tt_global_del_orig_entry(bat_priv, tt_global,
-							orig_node, message);
+			batadv_tt_global_del_orig_node(bat_priv, tt_global,
+						       orig_node, message);
 
 			if (hlist_empty(&tt_global->orig_list)) {
 				vid = tt_global->common.vid;
diff --git a/translation-table.h b/translation-table.h
index dc6db4e..cc5d6f0 100644
--- a/translation-table.h
+++ b/translation-table.h
@@ -31,6 +31,8 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset);
 void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
 			       struct batadv_orig_node *orig_node,
 			       int32_t match_vid, const char *message);
+int batadv_tt_global_hash_count(struct batadv_priv *bat_priv,
+				const uint8_t *addr, unsigned short vid);
 struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
 						  const uint8_t *src,
 						  const uint8_t *addr,
diff --git a/types.h b/types.h
index 7ea9631..aa17d09 100644
--- a/types.h
+++ b/types.h
@@ -669,6 +669,9 @@ struct batadv_priv {
 #ifdef CONFIG_BATMAN_ADV_DAT
 	atomic_t distributed_arp_table;
 #endif
+#ifdef CONFIG_BATMAN_ADV_MCAST
+	atomic_t multicast_mode;
+#endif
 	atomic_t gw_mode;
 	atomic_t gw_sel_class;
 	atomic_t orig_interval;
@@ -830,12 +833,14 @@ struct batadv_tt_local_entry {
  * struct batadv_tt_global_entry - translation table global entry data
  * @common: general translation table data
  * @orig_list: list of orig nodes announcing this non-mesh client
+ * @orig_list_count: number of items in the orig_list
  * @list_lock: lock protecting orig_list
  * @roam_at: time at which TT_GLOBAL_ROAM was set
  */
 struct batadv_tt_global_entry {
 	struct batadv_tt_common_entry common;
 	struct hlist_head orig_list;
+	atomic_t orig_list_count;
 	spinlock_t list_lock;	/* protects orig_list */
 	unsigned long roam_at;
 };
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] [PATCHv8 4/5] batman-adv: Add IPv4 link-local/IPv6-ll-all-nodes multicast support
  2013-08-13  8:23 [B.A.T.M.A.N.] Basic Multicast Optimizations Linus Lüssing
                   ` (2 preceding siblings ...)
  2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 3/5] batman-adv: Modified forwarding behaviour for multicast packets Linus Lüssing
@ 2013-08-13  8:23 ` Linus Lüssing
  2013-08-13  8:24 ` [B.A.T.M.A.N.] [PATCHv8 5/5] batman-adv: Send multicast packets to nodes with a WANT_ALL flag Linus Lüssing
  2013-08-15 13:56 ` [B.A.T.M.A.N.] Basic Multicast Optimizations Simon Wunderlich
  5 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-08-13  8:23 UTC (permalink / raw)
  To: b.a.t.m.a.n

With this patch a node may additionally perform the dropping or
unicasting behaviour for a link-local IPv4 and link-local-all-nodes
IPv6 multicast packet, too.

The extra counter and BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag is needed
because with a future bridge snooping support integration a node with a
bridge on top of its soft interface is not able to reliably detect its
multicast listeners for IPv4 link-local and the IPv6
link-local-all-nodes addresses anymore (see RFC4541, section 2.1.2.2
and section 3).

Even though this new flag does make "no difference" now, it'll ensure
a seamless integration of multicast bridge support without needing to
break compatibility later.

Also note, that even with multicast bridge support it will need only
one node with a bridge to disable optimizations for link-local IPv4
and IPv6-link-local-all-nodes multicast, resulting in flooding all
these packets again. So the 224.0.0.x address range and the ff02::1
address will never be a safe choice for multicast streaming etc. if
you do not control every node.

Signed-off-by: Linus Lüssing <linus.luessing@web.de>
---
 main.h           |    1 +
 multicast.c      |   49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 packet.h         |    9 +++++++++
 soft-interface.c |    1 +
 types.h          |    2 ++
 5 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/main.h b/main.h
index 7225f63..0640dce 100644
--- a/main.h
+++ b/main.h
@@ -166,6 +166,7 @@ enum batadv_uev_type {
 #include <linux/slab.h>
 #include <net/sock.h>		/* struct sock */
 #include <net/addrconf.h>	/* ipv6 address stuff */
+#include <linux/ip.h>
 #include <net/rtnetlink.h>
 #include <linux/jiffies.h>
 #include <linux/seq_file.h>
diff --git a/multicast.c b/multicast.c
index 29cb929..ae7992a 100644
--- a/multicast.c
+++ b/multicast.c
@@ -266,6 +266,44 @@ out:
 }
 
 /**
+ * batadv_mcast_forw_mode_check_ipv4 - check for optimized forwarding potential
+ * @skb: the IPv4 packet to check
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Check whether the given IPv4 packet has the potential to
+ * be forwarded with a mode more optimal than classic flooding.
+ *
+ * If so then return 0. Otherwise -EINVAL is returned or -ENOMEM if we are
+ * out of memory.
+ */
+static int batadv_mcast_forw_mode_check_ipv4(struct sk_buff *skb,
+					     struct batadv_priv *bat_priv)
+{
+	struct iphdr *iphdr;
+
+	/* We might fail due to out-of-memory -> drop it */
+	if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr)))
+		return -ENOMEM;
+
+	iphdr = ip_hdr(skb);
+
+	/* TODO: Implement Multicast Router Discovery (RFC4286),
+	 * then allow scope > link local, too
+	 */
+	if (!ipv4_is_local_multicast(iphdr->daddr))
+		return -EINVAL;
+
+	/* With one bridge involved, we cannot be certain about
+	 * link-local multicast listener announcements anymore
+	 * (see RFC4541, section 2.1.2.2)
+	 */
+	if (atomic_read(&bat_priv->mcast.num_want_all_unsnoopables))
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
  * batadv_mcast_forw_mode_check_ipv6 - check for optimized forwarding potential
  * @skb: the IPv6 packet to check
  * @bat_priv: the bat priv with all the soft interface information
@@ -298,7 +336,8 @@ static int batadv_mcast_forw_mode_check_ipv6(struct sk_buff *skb,
 	 * link-local-all-nodes multicast listener announcements anymore
 	 * (see RFC4541, section 3, paragraph 3)
 	 */
-	if (ipv6_addr_is_ll_all_nodes(&ip6hdr->daddr))
+	if (ipv6_addr_is_ll_all_nodes(&ip6hdr->daddr) &&
+	    atomic_read(&bat_priv->mcast.num_want_all_unsnoopables))
 		return -EINVAL;
 
 	return 0;
@@ -327,6 +366,8 @@ static int batadv_mcast_forw_mode_check(struct sk_buff *skb,
 		return -EINVAL;
 
 	switch (ntohs(ethhdr->h_proto)) {
+	case ETH_P_IP:
+		return batadv_mcast_forw_mode_check_ipv4(skb, bat_priv);
 	case ETH_P_IPV6:
 		return batadv_mcast_forw_mode_check_ipv6(skb, bat_priv);
 	default:
@@ -418,6 +459,9 @@ static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
 	batadv_mcast_counter_update(BATADV_ORIG_CAPA_HAS_MCAST,
 				    &bat_priv->mcast.num_disabled,
 				    ~orig->capabilities, ~old_capabilities);
+	batadv_mcast_counter_update(BATADV_MCAST_WANT_ALL_UNSNOOPABLES,
+				    &bat_priv->mcast.num_want_all_unsnoopables,
+				    mcast_flags, orig->mcast_flags);
 
 	orig->mcast_flags = mcast_flags;
 }
@@ -457,4 +501,7 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
 	batadv_mcast_counter_update(BATADV_ORIG_CAPA_HAS_MCAST,
 				    &bat_priv->mcast.num_disabled,
 				    ~BATADV_NO_FLAGS, ~orig->capabilities);
+	batadv_mcast_counter_update(BATADV_MCAST_WANT_ALL_UNSNOOPABLES,
+				    &bat_priv->mcast.num_want_all_unsnoopables,
+				    BATADV_NO_FLAGS, orig->mcast_flags);
 }
diff --git a/packet.h b/packet.h
index c8cc1b2..5fc795f 100644
--- a/packet.h
+++ b/packet.h
@@ -91,6 +91,15 @@ enum batadv_icmp_packettype {
 	BATADV_PARAMETER_PROBLEM       = 12,
 };
 
+/**
+ * enum batadv_mcast_flags - flags for multicast capabilities and settings
+ * @BATADV_MCAST_WANT_ALL_UNSNOOPABLES: we want all packets destined for
+ *  224.0.0.0/24 or ff02::1
+ */
+enum batadv_mcast_flags {
+	BATADV_MCAST_WANT_ALL_UNSNOOPABLES = BIT(0),
+};
+
 /* tt data subtypes */
 #define BATADV_TT_DATA_TYPE_MASK 0x0F
 
diff --git a/soft-interface.c b/soft-interface.c
index 2ecf9a5..2967a43 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -677,6 +677,7 @@ static int batadv_softif_init_late(struct net_device *dev)
 	bat_priv->mcast.flags = BATADV_UNINIT_FLAGS;
 	atomic_set(&bat_priv->multicast_mode, 1);
 	atomic_set(&bat_priv->mcast.num_disabled, 0);
+	atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0);
 #endif
 	atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
 	atomic_set(&bat_priv->gw_sel_class, 20);
diff --git a/types.h b/types.h
index aa17d09..1ce1793 100644
--- a/types.h
+++ b/types.h
@@ -550,11 +550,13 @@ struct batadv_priv_dat {
  * @mla_list: list of multicast addresses we are currently announcing via TT
  * @flags: the flags we have last sent in our mcast tvlv
  * @num_disabled: number of nodes that have no mcast tvlv
+ * @num_want_all_unsnoopables: number of nodes wanting unsnoopable IP traffic
  */
 struct batadv_priv_mcast {
 	struct hlist_head mla_list;
 	int flags;
 	atomic_t num_disabled;
+	atomic_t num_want_all_unsnoopables;
 };
 #endif
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] [PATCHv8 5/5] batman-adv: Send multicast packets to nodes with a WANT_ALL flag
  2013-08-13  8:23 [B.A.T.M.A.N.] Basic Multicast Optimizations Linus Lüssing
                   ` (3 preceding siblings ...)
  2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 4/5] batman-adv: Add IPv4 link-local/IPv6-ll-all-nodes multicast support Linus Lüssing
@ 2013-08-13  8:24 ` Linus Lüssing
  2013-08-15 13:56 ` [B.A.T.M.A.N.] Basic Multicast Optimizations Simon Wunderlich
  5 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-08-13  8:24 UTC (permalink / raw)
  To: b.a.t.m.a.n

With this patch a node sends IPv4 multicast packets to nodes which
have a BATADV_MCAST_WANT_ALL_IPV4 flag set and IPv6 multicast packets
to nodes which have a BATADV_MCAST_WANT_ALL_IPV6 flag set, too.

Why is this needed? There are scenarios involving bridges where
multicast report snooping and multicast TT announcements are not
sufficient, which would lead to packet loss for some nodes otherwise:

MLDv1 and IGMPv1/IGMPv2 have a suppression mechanism
for multicast listener reports. When we have an MLDv1/IGMPv1/IGMPv2
querier behind a bridge then our snooping bridge is potentially not
going to see any reports even though listeners exist because according
to RFC4541 such reports are only forwarded to multicast routers:

-----------------------------------------------------------
            ---------------
{Querier}---|Snoop. Switch|----{Listener}
            ---------------
                       \           ^
                      -------
                      | br0 |  <  ???
                      -------
                          \
                     _-~---~_
                 _-~/        ~-_
                ~   batman-adv  \-----{Sender}
                \~_   cloud    ~/
                   -~~__-__-~_/

I)  MLDv1 Query:  {Querier}  -> flooded
II) MLDv1 Report: {Listener} -> {Querier}

-> br0 cannot detect the {Listener}
=> Packets from {Sender} need to be forwarded to all
   detected listeners and MLDv1/IGMPv1/IGMPv2 queriers.

-----------------------------------------------------------

Note that we do not need to explicitly forward to MLDv2/IGMPv3 queriers,
because these protocols have no report suppression: A bridge has no
trouble detecting MLDv2/IGMPv3 listeners.

Even though we do not support bridges yet we need to provide the
according infrastructure already to not break compatibility later.

Signed-off-by: Linus Lüssing <linus.luessing@web.de>
---
 main.c           |    7 ++
 multicast.c      |  194 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 multicast.h      |   15 ++++-
 packet.h         |    4 ++
 send.c           |   23 +++++++
 send.h           |    3 +
 soft-interface.c |    9 ++-
 types.h          |   16 +++++
 8 files changed, 267 insertions(+), 4 deletions(-)

diff --git a/main.c b/main.c
index 69dbb75..7e122d0 100644
--- a/main.c
+++ b/main.c
@@ -112,6 +112,9 @@ int batadv_mesh_init(struct net_device *soft_iface)
 	spin_lock_init(&bat_priv->tt.last_changeset_lock);
 	spin_lock_init(&bat_priv->tt.commit_lock);
 	spin_lock_init(&bat_priv->gw.list_lock);
+#ifdef CONFIG_BATMAN_ADV_MCAST
+	spin_lock_init(&bat_priv->mcast.want_lists_lock);
+#endif
 	spin_lock_init(&bat_priv->tvlv.container_list_lock);
 	spin_lock_init(&bat_priv->tvlv.handler_list_lock);
 	spin_lock_init(&bat_priv->softif_vlan_list_lock);
@@ -119,6 +122,10 @@ int batadv_mesh_init(struct net_device *soft_iface)
 	INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
 	INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
 	INIT_HLIST_HEAD(&bat_priv->gw.list);
+#ifdef CONFIG_BATMAN_ADV_MCAST
+	INIT_HLIST_HEAD(&bat_priv->mcast.want_all_ipv4_list);
+	INIT_HLIST_HEAD(&bat_priv->mcast.want_all_ipv6_list);
+#endif
 	INIT_LIST_HEAD(&bat_priv->tt.changes_list);
 	INIT_LIST_HEAD(&bat_priv->tt.req_list);
 	INIT_LIST_HEAD(&bat_priv->tt.roam_list);
diff --git a/multicast.c b/multicast.c
index ae7992a..892a3ce 100644
--- a/multicast.c
+++ b/multicast.c
@@ -376,14 +376,53 @@ static int batadv_mcast_forw_mode_check(struct sk_buff *skb,
 }
 
 /**
+ * batadv_mcast_want_all_count - number of nodes with unspecific mcast interest
+ * @bat_priv: the bat priv with all the soft interface information
+ * @ethhdr: ethernet header of a packet
+ * @want_all_list: pointer to a mcast want list in our bat_priv
+ *
+ * Return the number of nodes which want all IPv4 multicast traffic if
+ * the given ethhdr is from an IPv4 packet or the number of nodes which want
+ * all IPv6 traffic if it matches an IPv6 packet and set the want_list to the
+ * according one in our bat_priv. For other frame types leave the want_list
+ * untouched and return zero.
+ */
+static int batadv_mcast_want_all_count(struct batadv_priv *bat_priv,
+				       struct ethhdr *ethhdr,
+				       struct hlist_head **want_all_list)
+{
+	int ret;
+
+	switch (ntohs(ethhdr->h_proto)) {
+	case ETH_P_IP:
+		ret = atomic_read(&bat_priv->mcast.num_want_all_ipv4);
+		if (ret)
+			*want_all_list = &bat_priv->mcast.want_all_ipv4_list;
+		break;
+	case ETH_P_IPV6:
+		ret = atomic_read(&bat_priv->mcast.num_want_all_ipv6);
+		if (ret)
+			*want_all_list = &bat_priv->mcast.want_all_ipv6_list;
+		break;
+	default:
+		/* we shouldn't be here... */
+		ret = 0;
+	}
+
+	return ret;
+}
+
+/**
  * batadv_mcast_forw_mode - check on how to forward a multicast packet
  * @skb: The multicast packet to check
  * @bat_priv: the bat priv with all the soft interface information
+ * @want_all_list: pointer to a mcast want list in our bat_priv
  *
  * Return the forwarding mode as enum batadv_forw_mode.
  */
 enum batadv_forw_mode
-batadv_mcast_forw_mode(struct sk_buff *skb, struct batadv_priv *bat_priv)
+batadv_mcast_forw_mode(struct sk_buff *skb, struct batadv_priv *bat_priv,
+		       struct hlist_head **want_all_list)
 {
 	struct ethhdr *ethhdr = (struct ethhdr *)(skb->data);
 	int ret;
@@ -396,6 +435,7 @@ batadv_mcast_forw_mode(struct sk_buff *skb, struct batadv_priv *bat_priv)
 
 	ret = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest,
 					  BATADV_NO_FLAGS);
+	ret += batadv_mcast_want_all_count(bat_priv, ethhdr, want_all_list);
 
 	switch (ret) {
 	case 0:
@@ -408,6 +448,72 @@ batadv_mcast_forw_mode(struct sk_buff *skb, struct batadv_priv *bat_priv)
 }
 
 /**
+ * batadv_mcast_want_all_ipv4_node_get - get an orig_node with want_all_ipv4
+ * @head: list of originators that want all IPv4 multicast traffic
+ *
+ * Return the first orig_node from the given want_all_ipv4 list. Increases
+ * the refcount of the returned orig_node.
+ */
+static struct batadv_orig_node *
+batadv_mcast_want_all_ipv4_node_get(struct hlist_head *head)
+{
+	struct batadv_orig_node *orig_node = NULL;
+
+	rcu_read_lock();
+	hlist_for_each_entry_rcu(orig_node, head,
+				 mcast_want_all_ipv4_node) {
+		if (atomic_inc_not_zero(&orig_node->refcount))
+			break;
+	}
+	rcu_read_unlock();
+
+	return orig_node;
+}
+
+/**
+ * batadv_mcast_want_all_ipv6_node_get - get an orig_node with want_all_ipv6
+ * @head: list of originators that want all IPv6 multicast traffic
+ *
+ * Return the first orig_node from the given want_all_ipv6 list. Increases
+ * the refcount of the returned orig_node.
+ */
+static struct batadv_orig_node *
+batadv_mcast_want_all_ipv6_node_get(struct hlist_head *head)
+{
+	struct batadv_orig_node *orig_node = NULL;
+
+	rcu_read_lock();
+	hlist_for_each_entry_rcu(orig_node, head,
+				 mcast_want_all_ipv6_node) {
+		if (atomic_inc_not_zero(&orig_node->refcount))
+			break;
+	}
+	rcu_read_unlock();
+
+	return orig_node;
+}
+
+/**
+ * batadv_mcast_want_all_node_get - get an orig_node with an mcast want list
+ * @want_all_list: list of originators that want all IPv4 or IPv6 mcast traffic
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Return the first orig_node from the given want_all list. Increases the
+ * refcount of the returned orig_node.
+ */
+struct batadv_orig_node *
+batadv_mcast_want_all_node_get(struct hlist_head *want_all_list,
+			       struct batadv_priv *bat_priv)
+{
+	if (want_all_list == &bat_priv->mcast.want_all_ipv4_list)
+		return batadv_mcast_want_all_ipv4_node_get(want_all_list);
+	else if (want_all_list == &bat_priv->mcast.want_all_ipv6_list)
+		return batadv_mcast_want_all_ipv6_node_get(want_all_list);
+	else
+		return NULL;
+}
+
+/**
  * batadv_mcast_counter_update - update the counter of a flag
  * @flag: the flag we want to update counters for
  * @flag_counter: the counter we might update
@@ -427,6 +533,58 @@ static void batadv_mcast_counter_update(uint8_t flag, atomic_t *flag_counter,
 }
 
 /**
+ * batadv_mcast_list_add - grab a lock and add a node to a head
+ * @node: the node to add
+ * @head: the head to add the node to
+ * @lock: the lock to grab while adding the node to the head
+ */
+static void batadv_mcast_list_add(struct hlist_node *node,
+				  struct hlist_head *head,
+				  spinlock_t *lock)
+{
+	spin_lock_bh(lock);
+	hlist_add_head_rcu(node, head);
+	spin_unlock_bh(lock);
+}
+
+/**
+ * batadv_mcast_list_del - grab a lock and delete a node from its list
+ * @node: the node to delete from its list
+ * @lock: the lock to grab while deleting the node from its list
+ */
+static void batadv_mcast_list_del(struct hlist_node *node, spinlock_t *lock)
+{
+	spin_lock_bh(lock);
+	hlist_del_rcu(node);
+	spin_unlock_bh(lock);
+}
+
+/**
+ * batadv_mcast_list_update - update the list of a flag
+ * @flag: the flag we want to update the list for
+ * @node: a list node of an originator
+ * @head: the list head the node might be added to
+ * @lock: the lock that synchronizes list modifications
+ * @new_flags: the new capability bitset of a node
+ * @old_flags: the current, to be updated bitset of a node
+ *
+ * Update the list of the given node/head with the help of the new flag
+ * information of an originator to contain the nodes which have the given
+ * flag set.
+ */
+static void batadv_mcast_list_update(uint8_t flag,
+				     struct hlist_node *node,
+				     struct hlist_head *head,
+				     spinlock_t *lock,
+				     uint8_t new_flags, int old_flags)
+{
+	if (new_flags & flag && !(old_flags & flag))
+		batadv_mcast_list_add(node, head, lock);
+	else if (!(new_flags & flag) && old_flags & flag)
+		batadv_mcast_list_del(node, lock);
+}
+
+/**
  * 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
@@ -462,6 +620,23 @@ static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
 	batadv_mcast_counter_update(BATADV_MCAST_WANT_ALL_UNSNOOPABLES,
 				    &bat_priv->mcast.num_want_all_unsnoopables,
 				    mcast_flags, orig->mcast_flags);
+	batadv_mcast_counter_update(BATADV_MCAST_WANT_ALL_IPV4,
+				    &bat_priv->mcast.num_want_all_ipv4,
+				    mcast_flags, orig->mcast_flags);
+	batadv_mcast_counter_update(BATADV_MCAST_WANT_ALL_IPV6,
+				    &bat_priv->mcast.num_want_all_ipv6,
+				    mcast_flags, orig->mcast_flags);
+
+	batadv_mcast_list_update(BATADV_MCAST_WANT_ALL_IPV4,
+				 &orig->mcast_want_all_ipv4_node,
+				 &bat_priv->mcast.want_all_ipv4_list,
+				 &bat_priv->mcast.want_lists_lock,
+				 mcast_flags, orig->mcast_flags);
+	batadv_mcast_list_update(BATADV_MCAST_WANT_ALL_IPV6,
+				 &orig->mcast_want_all_ipv6_node,
+				 &bat_priv->mcast.want_all_ipv6_list,
+				 &bat_priv->mcast.want_lists_lock,
+				 mcast_flags, orig->mcast_flags);
 
 	orig->mcast_flags = mcast_flags;
 }
@@ -504,4 +679,21 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
 	batadv_mcast_counter_update(BATADV_MCAST_WANT_ALL_UNSNOOPABLES,
 				    &bat_priv->mcast.num_want_all_unsnoopables,
 				    BATADV_NO_FLAGS, orig->mcast_flags);
+	batadv_mcast_counter_update(BATADV_MCAST_WANT_ALL_IPV4,
+				    &bat_priv->mcast.num_want_all_ipv4,
+				    BATADV_NO_FLAGS, orig->mcast_flags);
+	batadv_mcast_counter_update(BATADV_MCAST_WANT_ALL_IPV6,
+				    &bat_priv->mcast.num_want_all_ipv6,
+				    BATADV_NO_FLAGS, orig->mcast_flags);
+
+	batadv_mcast_list_update(BATADV_MCAST_WANT_ALL_IPV4,
+				 &orig->mcast_want_all_ipv4_node,
+				 &bat_priv->mcast.want_all_ipv4_list,
+				 &bat_priv->mcast.want_lists_lock,
+				 BATADV_NO_FLAGS, orig->mcast_flags);
+	batadv_mcast_list_update(BATADV_MCAST_WANT_ALL_IPV6,
+				 &orig->mcast_want_all_ipv6_node,
+				 &bat_priv->mcast.want_all_ipv6_list,
+				 &bat_priv->mcast.want_lists_lock,
+				 BATADV_NO_FLAGS, orig->mcast_flags);
 }
diff --git a/multicast.h b/multicast.h
index e26f146..3452077 100644
--- a/multicast.h
+++ b/multicast.h
@@ -39,7 +39,8 @@ enum batadv_forw_mode {
 void batadv_mcast_mla_update(struct batadv_priv *bat_priv);
 
 enum batadv_forw_mode
-batadv_mcast_forw_mode(struct sk_buff *skb, struct batadv_priv *bat_priv);
+batadv_mcast_forw_mode(struct sk_buff *skb, struct batadv_priv *bat_priv,
+		       struct hlist_head **want_all_list);
 
 int batadv_mcast_init(struct batadv_priv *bat_priv);
 
@@ -47,6 +48,9 @@ void batadv_mcast_free(struct batadv_priv *bat_priv);
 
 void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node);
 
+struct batadv_orig_node *
+batadv_mcast_want_all_node_get(struct hlist_head *want_all_list,
+			       struct batadv_priv *bat_priv);
 #else
 
 static inline void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
@@ -55,7 +59,8 @@ static inline void batadv_mcast_mla_update(struct batadv_priv *bat_priv)
 }
 
 static inline enum batadv_forw_mode
-batadv_mcast_forw_mode(struct sk_buff *skb, struct batadv_priv *bat_priv)
+batadv_mcast_forw_mode(struct sk_buff *skb, struct batadv_priv *bat_priv,
+		       struct hlist_head **want_all_list)
 {
 	return BATADV_FORW_ALL;
 }
@@ -75,6 +80,12 @@ static inline void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node)
 	return;
 }
 
+static inline struct batadv_orig_node *
+batadv_mcast_want_all_node_get(struct hlist_head *want_all_list,
+			       struct batadv_priv *bat_priv)
+{
+	return NULL;
+}
 #endif /* CONFIG_BATMAN_ADV_MCAST */
 
 #endif /* _NET_BATMAN_ADV_MULTICAST_H_ */
diff --git a/packet.h b/packet.h
index 5fc795f..9a7919d 100644
--- a/packet.h
+++ b/packet.h
@@ -95,9 +95,13 @@ enum batadv_icmp_packettype {
  * enum batadv_mcast_flags - flags for multicast capabilities and settings
  * @BATADV_MCAST_WANT_ALL_UNSNOOPABLES: we want all packets destined for
  *  224.0.0.0/24 or ff02::1
+ * @BATADV_MCAST_WANT_ALL_IPV4: we want all IPv4 multicast packets
+ * @BATADV_MCAST_WANT_ALL_IPV6: we want all IPv6 multicast packets
  */
 enum batadv_mcast_flags {
 	BATADV_MCAST_WANT_ALL_UNSNOOPABLES = BIT(0),
+	BATADV_MCAST_WANT_ALL_IPV4 = BIT(1),
+	BATADV_MCAST_WANT_ALL_IPV6 = BIT(2),
 };
 
 /* tt data subtypes */
diff --git a/send.c b/send.c
index c83be5e..3d881ba 100644
--- a/send.c
+++ b/send.c
@@ -29,6 +29,7 @@
 #include "originator.h"
 #include "network-coding.h"
 #include "fragmentation.h"
+#include "multicast.h"
 
 static void batadv_send_outstanding_bcast_packet(struct work_struct *work);
 
@@ -353,6 +354,28 @@ int batadv_send_skb_via_gw(struct batadv_priv *bat_priv, struct sk_buff *skb,
 				       orig_node, vid);
 }
 
+/**
+ * batadv_send_skb_via_mcast - send an skb to a node with a WANT_ALL flag
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: payload to send
+ * @vid: the vid to be used to search the translation table
+ * @want_all_list: a list of originators with a WANT_ALL flag
+ *
+ * Get an originator node from the want_all_list. Wrap the given skb into a
+ * batman-adv unicast header and send this frame to this node.
+ */
+int batadv_send_skb_via_mcast(struct batadv_priv *bat_priv,
+			      struct sk_buff *skb, unsigned short vid,
+			      struct hlist_head *want_all_list)
+
+{
+	struct batadv_orig_node *orig_node;
+
+	orig_node = batadv_mcast_want_all_node_get(want_all_list, bat_priv);
+	return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0,
+				       orig_node, vid);
+}
+
 void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface)
 {
 	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
diff --git a/send.h b/send.h
index aa2e253..3a6365f 100644
--- a/send.h
+++ b/send.h
@@ -43,6 +43,9 @@ int batadv_send_skb_via_tt_generic(struct batadv_priv *bat_priv,
 				   int packet_subtype, unsigned short vid);
 int batadv_send_skb_via_gw(struct batadv_priv *bat_priv, struct sk_buff *skb,
 			   unsigned short vid);
+int batadv_send_skb_via_mcast(struct batadv_priv *bat_priv,
+			      struct sk_buff *skb, unsigned short vid,
+			      struct hlist_head *want_all_list);
 
 /**
  * batadv_send_skb_via_tt - send an skb via TT lookup
diff --git a/soft-interface.c b/soft-interface.c
index 2967a43..3f1700c 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -159,6 +159,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
 	struct batadv_hard_iface *primary_if = NULL;
 	struct batadv_bcast_packet *bcast_packet;
 	__be16 ethertype = htons(ETH_P_BATMAN);
+	struct hlist_head *want_all_list = NULL;
 	static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00,
 						   0x00, 0x00};
 	static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00,
@@ -248,7 +249,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
 		ethhdr = (struct ethhdr *)skb->data;
 
 		if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) {
-			mode = batadv_mcast_forw_mode(skb, bat_priv);
+			mode = batadv_mcast_forw_mode(skb, bat_priv,
+						      &want_all_list);
 			if (mode == BATADV_FORW_NONE)
 				goto dropped;
 
@@ -315,6 +317,9 @@ static int batadv_interface_tx(struct sk_buff *skb,
 
 		if (forw_to_gw)
 			ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
+		else if (want_all_list)
+			ret = batadv_send_skb_via_mcast(bat_priv, skb, vid,
+							want_all_list);
 		else
 			ret = batadv_send_skb_via_tt(bat_priv, skb, vid);
 
@@ -678,6 +683,8 @@ static int batadv_softif_init_late(struct net_device *dev)
 	atomic_set(&bat_priv->multicast_mode, 1);
 	atomic_set(&bat_priv->mcast.num_disabled, 0);
 	atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0);
+	atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0);
+	atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0);
 #endif
 	atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
 	atomic_set(&bat_priv->gw_sel_class, 20);
diff --git a/types.h b/types.h
index 1ce1793..9625d93 100644
--- a/types.h
+++ b/types.h
@@ -145,6 +145,8 @@ struct batadv_orig_node_vlan {
  * @bcast_seqno_reset: time when the broadcast seqno window was reset
  * @batman_seqno_reset: time when the batman seqno window was reset
  * @mcast_flags: multicast flags announced by the orig node
+ * @mcast_want_all_ipv4_node: a list node for the mcast.want_all_ipv4 list
+ * @mcast_want_all_ipv6_node: a list node for the mcast.want_all_ipv6 list
  * @capabilities: announced capabilities of this originator
  * @last_ttvn: last seen translation table version number
  * @tt_buff: last tt changeset this node received from the orig node
@@ -197,6 +199,8 @@ struct batadv_orig_node {
 	unsigned long batman_seqno_reset;
 #ifdef CONFIG_BATMAN_ADV_MCAST
 	int mcast_flags;
+	struct hlist_node mcast_want_all_ipv4_node;
+	struct hlist_node mcast_want_all_ipv6_node;
 #endif
 	uint8_t capabilities;
 	atomic_t last_ttvn;
@@ -548,15 +552,27 @@ struct batadv_priv_dat {
 /**
  * struct batadv_priv_mcast - per mesh interface mcast data
  * @mla_list: list of multicast addresses we are currently announcing via TT
+ * @want_all_ipv4_list: a list of orig_nodes wanting all IPv4 multicast traffic
+ * @want_all_ipv6_list: a list of orig_nodes wanting all IPv6 multicast traffic
  * @flags: the flags we have last sent in our mcast tvlv
  * @num_disabled: number of nodes that have no mcast tvlv
  * @num_want_all_unsnoopables: number of nodes wanting unsnoopable IP traffic
+ * @num_want_all_ipv4: counter for items in want_all_ipv4_list
+ * @num_want_all_ipv6: counter for items in want_all_ipv6_list
+ * @want_lists_lock: lock for protecting modifications to mcast want lists
+ *  (traversals are rcu-locked)
  */
 struct batadv_priv_mcast {
 	struct hlist_head mla_list;
+	struct hlist_head want_all_ipv4_list;
+	struct hlist_head want_all_ipv6_list;
 	int flags;
 	atomic_t num_disabled;
 	atomic_t num_want_all_unsnoopables;
+	atomic_t num_want_all_ipv4;
+	atomic_t num_want_all_ipv6;
+	/* protects want_all_ipv4_list & want_all_ipv6_list */
+	spinlock_t want_lists_lock;
 };
 #endif
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] [PATCHv8 3/5] batman-adv: Modified forwarding behaviour for multicast packets
  2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 3/5] batman-adv: Modified forwarding behaviour for multicast packets Linus Lüssing
@ 2013-08-15 13:45   ` Simon Wunderlich
  2013-08-15 18:02     ` Linus Lüssing
  0 siblings, 1 reply; 37+ messages in thread
From: Simon Wunderlich @ 2013-08-15 13:45 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

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

Hey Linus,

I'm currently playing a little with this patchset ...

On Tue, Aug 13, 2013 at 10:23:58AM +0200, Linus Lüssing wrote:
> [...]
> +	count = atomic_read(&tt_global_entry->orig_list_count);
> [...]
> +	atomic_inc(&tt_global->orig_list_count);
> [...]
> +		atomic_set(&tt_global_entry->orig_list_count, 0);
> [...]
> @@ -830,12 +833,14 @@ struct batadv_tt_local_entry {
>   * struct batadv_tt_global_entry - translation table global entry data
>   * @common: general translation table data
>   * @orig_list: list of orig nodes announcing this non-mesh client
> + * @orig_list_count: number of items in the orig_list
>   * @list_lock: lock protecting orig_list
>   * @roam_at: time at which TT_GLOBAL_ROAM was set
>   */
>  struct batadv_tt_global_entry {
>  	struct batadv_tt_common_entry common;
>  	struct hlist_head orig_list;
> +	atomic_t orig_list_count;
>  	spinlock_t list_lock;	/* protects orig_list */
>  	unsigned long roam_at;

You never decrease this orig_list_count, do you? But actually you should
when a node leaves the group. What I've tried is:

Node 1 pings a multicast address
 -> no group member, nothing is sent
Node 2 is added to the group
 -> multicast is now sent as unicast
Node 3 is added to the group
 -> multicast is now sent as broadcast
Node 2 is removed from the group
 -> multicast is still sent as broadcast (should be unicast!)
Node 3 is removed from the group
 -> nothing is sent (as to be expected).

Could you please check the removal case?

Thanks,
	Simon

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-08-13  8:23 [B.A.T.M.A.N.] Basic Multicast Optimizations Linus Lüssing
                   ` (4 preceding siblings ...)
  2013-08-13  8:24 ` [B.A.T.M.A.N.] [PATCHv8 5/5] batman-adv: Send multicast packets to nodes with a WANT_ALL flag Linus Lüssing
@ 2013-08-15 13:56 ` Simon Wunderlich
  2013-08-15 18:25   ` Linus Lüssing
  5 siblings, 1 reply; 37+ messages in thread
From: Simon Wunderlich @ 2013-08-15 13:56 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

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

Hey Linus,

I've tested the patchset, and it looks good from my testcases (testing
multicast to IPv4 and IPv6 addresses). I've not tested the MLD stuff
though, but from our discussions your implementation looks reasonable.
Did you get to test it somehow?

From my perspective, if you fix the orig list stuff we could integrate
your patchset. I'd like to ask others to review the patchset too. :)

Thanks,
	Simon

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] [PATCHv8 3/5] batman-adv: Modified forwarding behaviour for multicast packets
  2013-08-15 13:45   ` Simon Wunderlich
@ 2013-08-15 18:02     ` Linus Lüssing
  0 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-08-15 18:02 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Thu, Aug 15, 2013 at 03:45:49PM +0200, Simon Wunderlich wrote:
> Hey Linus,
> 
> I'm currently playing a little with this patchset ...
> 
> On Tue, Aug 13, 2013 at 10:23:58AM +0200, Linus Lüssing wrote:
> > [...]
> > +	count = atomic_read(&tt_global_entry->orig_list_count);
> > [...]
> > +	atomic_inc(&tt_global->orig_list_count);
> > [...]
> > +		atomic_set(&tt_global_entry->orig_list_count, 0);
> > [...]
> > @@ -830,12 +833,14 @@ struct batadv_tt_local_entry {
> >   * struct batadv_tt_global_entry - translation table global entry data
> >   * @common: general translation table data
> >   * @orig_list: list of orig nodes announcing this non-mesh client
> > + * @orig_list_count: number of items in the orig_list
> >   * @list_lock: lock protecting orig_list
> >   * @roam_at: time at which TT_GLOBAL_ROAM was set
> >   */
> >  struct batadv_tt_global_entry {
> >  	struct batadv_tt_common_entry common;
> >  	struct hlist_head orig_list;
> > +	atomic_t orig_list_count;
> >  	spinlock_t list_lock;	/* protects orig_list */
> >  	unsigned long roam_at;
> 
> You never decrease this orig_list_count, do you? But actually you should
> when a node leaves the group. What I've tried is:
> 
> Node 1 pings a multicast address
>  -> no group member, nothing is sent
> Node 2 is added to the group
>  -> multicast is now sent as unicast
> Node 3 is added to the group
>  -> multicast is now sent as broadcast
> Node 2 is removed from the group
>  -> multicast is still sent as broadcast (should be unicast!)
> Node 3 is removed from the group
>  -> nothing is sent (as to be expected).
> 
> Could you please check the removal case?
> 
> Thanks,
> 	Simon

Hrm, stupid regression introduced with v8 while rebasing...
Sorry and thanks for spotting it! Going to send v9 in a minute.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-08-15 13:56 ` [B.A.T.M.A.N.] Basic Multicast Optimizations Simon Wunderlich
@ 2013-08-15 18:25   ` Linus Lüssing
  0 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-08-15 18:25 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Thu, Aug 15, 2013 at 03:56:47PM +0200, Simon Wunderlich wrote:
> Hey Linus,
> 
> I've tested the patchset, and it looks good from my testcases (testing
> multicast to IPv4 and IPv6 addresses). I've not tested the MLD stuff
> though, but from our discussions your implementation looks reasonable.
> Did you get to test it somehow?

Yes, I was testing it with the following patch from the branch
linus/multicast-bridge:

"debug: batman-adv: manual querier flag sysfs switch" (e947548bf)


> 
> From my perspective, if you fix the orig list stuff we could integrate
> your patchset. I'd like to ask others to review the patchset too. :)
> 
> Thanks,
> 	Simon



^ permalink raw reply	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] Basic Multicast Optimizations
@ 2014-01-27  9:48 Linus Lüssing
  0 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2014-01-27  9:48 UTC (permalink / raw)
  To: b.a.t.m.a.n

This is the twelfth revision of the basic multicast optimization patches.

Changes in v12 include (thanks for the feedback again, Marek and Simon):

* added three reserved bytes to the mcast TVLV container to have a four bytes
  alignment (thanks Simon)
* Return value description in kernel docs for batadv_mcast_mla_tvlv_update
  added (thanks Marek)
* Using eth_hdr() instead of skb->data in various places (thanks Marek)
* Switched order of function parameters bat_priv and skb in various places
  for style consistency reasons (thanks Marek)
* renamed one occurence of "BATMAN_IV" to "BATMAN" (thanks Marek)
* kerneldoc for multicast_mode added (thanks Marek)
* rebased on top of master
* now that batadv_tt_local_add() has a potential failure case, a check for
  its return value was added

For Marek's question on gateway code interoperability, I reread that part
and couldn't find any issues with it either. Moreover, any additional
dhcp_rcp variable check seemed redundant to me, so I left that part as is.

Cheers, Linus


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] Basic Multicast Optimizations
@ 2013-11-14  6:26 Linus Lüssing
  0 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-11-14  6:26 UTC (permalink / raw)
  To: b.a.t.m.a.n

This is the eleventh revision of the basic multicast optimization patches.

Changes:

* two non-critical compat code fixes (fixes sparse/smatch warnings):
  * typo: 'struct dev_addr_list' vs. 'struct batadv_dev_addr_list'
  * (unreachable code with netdev_master_upper_dev_get_rcu() compat code,
     patch provided by Simon)
* included multicast.h in multicast.c (fixes an sparse warning)
* substituted BATADV_UNINIT_FLAGS with a orig->capa_initialized and
  bat_priv->mcast.enabled as suggested by Marek
  (this adds patch 2/6)
* removed batadv_mcast_counter_update() to increase readability as
  suggested and provided by Marek
* rebased on top of the latest gateway code modifications:
  "batman-adv: send every DHCP packet as bat-unicast"
  (2d5b555644b22e171f3e0486abc0c2e627452d14)
  

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] Basic Multicast Optimizations
@ 2013-10-26 19:16 Linus Lüssing
  0 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-10-26 19:16 UTC (permalink / raw)
  To: b.a.t.m.a.n

This is the tenth revision of the basic multicast optimization patches.

No changes were made except dealing with two or three rebase conflicts
while rebasing on top of 24c51de20.

Cheers, Linus


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-08-15 19:21 Linus Lüssing
@ 2013-08-19 20:12 ` Simon Wunderlich
  0 siblings, 0 replies; 37+ messages in thread
From: Simon Wunderlich @ 2013-08-19 20:12 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

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

I think this looks good now! Thanks :)

Reviewed/Tested-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>

Cheers,
	Simon

On Thu, Aug 15, 2013 at 09:21:14PM +0200, Linus Lüssing wrote:
> This is the ninth revision of the basic multicast optimization patches.
> 
> It fixes a regression in Patch 3/5, introduced in v8 while rebasing:
> An atomic_dec() for the orig_list_count got lost.
> 
> Cheers, Linus
> 

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] Basic Multicast Optimizations
@ 2013-08-15 19:21 Linus Lüssing
  2013-08-19 20:12 ` Simon Wunderlich
  0 siblings, 1 reply; 37+ messages in thread
From: Linus Lüssing @ 2013-08-15 19:21 UTC (permalink / raw)
  To: b.a.t.m.a.n

This is the ninth revision of the basic multicast optimization patches.

It fixes a regression in Patch 3/5, introduced in v8 while rebasing:
An atomic_dec() for the orig_list_count got lost.

Cheers, Linus


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-07-03 22:03 Linus Lüssing
@ 2013-07-04  5:06 ` Linus Lüssing
  0 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-07-04  5:06 UTC (permalink / raw)
  To: b.a.t.m.a.n

And the sysfs file 'mcast_group_awareness' got renamed to
'multicast_mode'. The missing ABI documentation for this file was
added, too.

On Thu, Jul 04, 2013 at 12:03:18AM +0200, Linus Lüssing wrote:
> This is the seventh revision of the basic multicast optimization patches.
> 
> It adds the style changes as suggested by Marek via eMail.
> 
> It also adds various suggestion from IRC (for instance adding kerneldoc for the
> functions touched in translation-table.c, making the counter an atomic
> one to be on the safe side for some "exotic" targets).
> 
> 
> PATCHv7 4/4 is a new one and the result of a longer discussion on IRC:
> Whether to add some support for some IPv4 addresses already for the cost of
> a slightly larger complexity both code and documentation wise
> - for a case which is uncommon for most mesh networks anyway: a mesh
> with no bridges on any node involved.
> 
> So the fourth patch is sort of an RFC patch one, too (although the consense/
> tendency on IRC so far was to add and support this case).
> 
> If everyone is fine with that concept, then I can also easily merge it
> into patches 2/4 and 3/4 (if that is desired).
> 
> Cheers, Linus

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] Basic Multicast Optimizations
@ 2013-07-03 22:03 Linus Lüssing
  2013-07-04  5:06 ` Linus Lüssing
  0 siblings, 1 reply; 37+ messages in thread
From: Linus Lüssing @ 2013-07-03 22:03 UTC (permalink / raw)
  To: b.a.t.m.a.n

This is the seventh revision of the basic multicast optimization patches.

It adds the style changes as suggested by Marek via eMail.

It also adds various suggestion from IRC (for instance adding kerneldoc for the
functions touched in translation-table.c, making the counter an atomic
one to be on the safe side for some "exotic" targets).


PATCHv7 4/4 is a new one and the result of a longer discussion on IRC:
Whether to add some support for some IPv4 addresses already for the cost of
a slightly larger complexity both code and documentation wise
- for a case which is uncommon for most mesh networks anyway: a mesh
with no bridges on any node involved.

So the fourth patch is sort of an RFC patch one, too (although the consense/
tendency on IRC so far was to add and support this case).

If everyone is fine with that concept, then I can also easily merge it
into patches 2/4 and 3/4 (if that is desired).

Cheers, Linus

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-06-14 17:50 Linus Lüssing
@ 2013-06-16 14:08 ` Simon Wunderlich
  0 siblings, 0 replies; 37+ messages in thread
From: Simon Wunderlich @ 2013-06-16 14:08 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

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

Looks good, Tested/Acked-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>

Thanks,
	Simon

On Fri, Jun 14, 2013 at 07:50:06PM +0200, Linus Lüssing wrote:
> This is the sixth revision of the basic multicast optimization patches.
> 
> It simplifies and speeds-up the new batadv_tt_global_hash_count():
> 
> * We now use batadv_tt_global_hash_find() instead of our custom look-up.
> * A counter for the orig_list was added, so that we won't need to recount
>   with every multicast packet.
> 
> Cheers, Linus

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] Basic Multicast Optimizations
@ 2013-06-14 17:50 Linus Lüssing
  2013-06-16 14:08 ` Simon Wunderlich
  0 siblings, 1 reply; 37+ messages in thread
From: Linus Lüssing @ 2013-06-14 17:50 UTC (permalink / raw)
  To: b.a.t.m.a.n

This is the sixth revision of the basic multicast optimization patches.

It simplifies and speeds-up the new batadv_tt_global_hash_count():

* We now use batadv_tt_global_hash_find() instead of our custom look-up.
* A counter for the orig_list was added, so that we won't need to recount
  with every multicast packet.

Cheers, Linus

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] Basic Multicast Optimizations
@ 2013-06-14  9:02 Linus Lüssing
  0 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-06-14  9:02 UTC (permalink / raw)
  To: b.a.t.m.a.n

This is the fifth revision of the basic multicast optimization patches.

It fixes two bugs:

For one thing packets to the IPv6 all-hosts-link-scope multicast address
(ff02::1) were optimized, too. However this is the one link local address
which we should not never optimize (see RFC4541, section 3 [1]).

For another since commit 87d4a282 ("batman-adv: remove useless find_router look up"
the unicast-forwarding of multicast packets was broken and I had
only runtime tested the patches based on an older commit
(before 87d4a282 such unicast-forwarding was "only" broken if
a gateway-server was present).


Also note that rebasing on top of the TT-VLAN patches wasn't trivial:
Simply resolving the rebase complaints resulted in subtle runtime
bugs. A few lines in the counting methods added to translation-table.c
needed changes.

Cheers, Linus


[1]: Considerations for Internet Group Management Protocol (IGMP)
     and Multicast Listener Discovery (MLD) Snooping Switches
     -> "Packets with the all hosts link-scope address should be forwarded
         on all ports."
     https://tools.ietf.org/html/rfc4541

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-06-12 12:44     ` Simon Wunderlich
@ 2013-06-12 20:33       ` Linus Lüssing
  0 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-06-12 20:33 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Wed, Jun 12, 2013 at 02:44:38PM +0200, Simon Wunderlich wrote:
> On Wed, Jun 12, 2013 at 02:27:14PM +0200, Linus Lüssing wrote:
> > On Wed, Jun 12, 2013 at 12:14:11PM +0200, Simon Wunderlich wrote:
> > > Hello Linus,
> > > 
> > > I gave it a try - but there seems something off. What I did is:
> > >  * apply your patches on 3b38a80 - multicast was enabled by default
> > >  * start 2 VMs directly connected
> > >  * ping6 -I bat0 ff02::1
> > > 
> > > I only got a reply locally, but not from the peer. When I disabled
> > > multicast, I got two replies from the local host and the peer.
> > > 
> > > As far as I have tracked the problem down, it appears that
> > > batadv_mcast_forw_mode() returns 1 correctly, but the packet is dropped
> > 
> > Ok, found a bug - the return 1 is actually incorrect. You've
> > chosen the one multicast address where no optimization is
> > conceptually possible. ff02::1 is the only link-local IPv6
> > multicast address which should return a BATADV_FORW_ALL (0)
> > instead.
> 
> Ah, wonderful, and I thought I found a testcase. :D

Well, it was a testcase I hadn't used and you found a bug by that
;).

> 
> Can you advise how the feature can be tested then, practically?
> I guess I'll need to add some routes and ping6 another address?

I was usually using 'ip maddr show' to check which address isn't
in use yet, then I use something like 'ping6 ff02::3%bat0' which should
by default result in no reply.

Then I'd start adding listeners with this tiny C code snippet:
http://pastebin.com/fg9z8z5b on various nodes
(because I didn't find any simple, tiny command line program to do
just that yet).

You'd then get ICMP replies from the according nodes and I checked
via tcpdump that the ICMP packets were forwarded correctly via
unicast or broadcast.


And since "batman-adv: Add dummy soft-interface rx mode handler"
I'm not using that C code snippet that much anymore, but just
adding listeners via "ip maddr add 33:33:00:00:00:03 dev bat0"
for instance. And just checking via tcpdump (since you won't get
any ICMP replies) and the 'batctl tg' output.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-06-12 12:27   ` Linus Lüssing
@ 2013-06-12 12:44     ` Simon Wunderlich
  2013-06-12 20:33       ` Linus Lüssing
  0 siblings, 1 reply; 37+ messages in thread
From: Simon Wunderlich @ 2013-06-12 12:44 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

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

On Wed, Jun 12, 2013 at 02:27:14PM +0200, Linus Lüssing wrote:
> On Wed, Jun 12, 2013 at 12:14:11PM +0200, Simon Wunderlich wrote:
> > Hello Linus,
> > 
> > I gave it a try - but there seems something off. What I did is:
> >  * apply your patches on 3b38a80 - multicast was enabled by default
> >  * start 2 VMs directly connected
> >  * ping6 -I bat0 ff02::1
> > 
> > I only got a reply locally, but not from the peer. When I disabled
> > multicast, I got two replies from the local host and the peer.
> > 
> > As far as I have tracked the problem down, it appears that
> > batadv_mcast_forw_mode() returns 1 correctly, but the packet is dropped
> 
> Ok, found a bug - the return 1 is actually incorrect. You've
> chosen the one multicast address where no optimization is
> conceptually possible. ff02::1 is the only link-local IPv6
> multicast address which should return a BATADV_FORW_ALL (0)
> instead.

Ah, wonderful, and I thought I found a testcase. :D

Can you advise how the feature can be tested then, practically?
I guess I'll need to add some routes and ping6 another address?

> 
> (Conceptually impossible because for ff02::1 is the one multicast
> address which by the IPv6 standard every host listens to, without
> performing any MLD.)
> 
> I'll add another check next to the scope check in
> mcast_forw_mode().
> 
> > later in the process - I would guess that this happens in
> > batadv_send_generic_unicast_skb() where we try to select the gateway
> > when the destination mac is multicast instead of looking it up in the
> > tt table. But I leave the details to you. :)
> 
> Hm, but still, you're right, with this single destination, the
> other VM, the ICMPv6 request and reply should have arrived because
> the according MAC (33:33:00:00:00:01) is in the global translation table.

Yeah, it was, that is what puzzled me.
> 
> I didn't have that issue in my tests so far, I'll try to reproduce
> that issue.

OK.

Thanks,
	Simon

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-06-12 10:14 ` Simon Wunderlich
@ 2013-06-12 12:27   ` Linus Lüssing
  2013-06-12 12:44     ` Simon Wunderlich
  0 siblings, 1 reply; 37+ messages in thread
From: Linus Lüssing @ 2013-06-12 12:27 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Wed, Jun 12, 2013 at 12:14:11PM +0200, Simon Wunderlich wrote:
> Hello Linus,
> 
> I gave it a try - but there seems something off. What I did is:
>  * apply your patches on 3b38a80 - multicast was enabled by default
>  * start 2 VMs directly connected
>  * ping6 -I bat0 ff02::1
> 
> I only got a reply locally, but not from the peer. When I disabled
> multicast, I got two replies from the local host and the peer.
> 
> As far as I have tracked the problem down, it appears that
> batadv_mcast_forw_mode() returns 1 correctly, but the packet is dropped

Ok, found a bug - the return 1 is actually incorrect. You've
chosen the one multicast address where no optimization is
conceptually possible. ff02::1 is the only link-local IPv6
multicast address which should return a BATADV_FORW_ALL (0)
instead.

(Conceptually impossible because for ff02::1 is the one multicast
address which by the IPv6 standard every host listens to, without
performing any MLD.)

I'll add another check next to the scope check in
mcast_forw_mode().

> later in the process - I would guess that this happens in
> batadv_send_generic_unicast_skb() where we try to select the gateway
> when the destination mac is multicast instead of looking it up in the
> tt table. But I leave the details to you. :)

Hm, but still, you're right, with this single destination, the
other VM, the ICMPv6 request and reply should have arrived because
the according MAC (33:33:00:00:00:01) is in the global translation table.

I didn't have that issue in my tests so far, I'll try to reproduce
that issue.

> 
> The rest looks good, but I'll review more deeply again when it's
> actually working. It does compile without problems now.
> 
> Cheers,
> 	Simon
> 

Thanks for the feedback again!

Cheers, Linus

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-06-10  7:11 Linus Lüssing
@ 2013-06-12 10:14 ` Simon Wunderlich
  2013-06-12 12:27   ` Linus Lüssing
  0 siblings, 1 reply; 37+ messages in thread
From: Simon Wunderlich @ 2013-06-12 10:14 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

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

Hello Linus,

I gave it a try - but there seems something off. What I did is:
 * apply your patches on 3b38a80 - multicast was enabled by default
 * start 2 VMs directly connected
 * ping6 -I bat0 ff02::1

I only got a reply locally, but not from the peer. When I disabled
multicast, I got two replies from the local host and the peer.

As far as I have tracked the problem down, it appears that
batadv_mcast_forw_mode() returns 1 correctly, but the packet is dropped
later in the process - I would guess that this happens in
batadv_send_generic_unicast_skb() where we try to select the gateway
when the destination mac is multicast instead of looking it up in the
tt table. But I leave the details to you. :)

The rest looks good, but I'll review more deeply again when it's
actually working. It does compile without problems now.

Cheers,
	Simon

On Mon, Jun 10, 2013 at 09:11:55AM +0200, Linus Lüssing wrote:
> This is the fourth revision of the basic multicast optimization patches.
> 
> It adds a missing enum keyword to the return type of a mcast_forw_mode().
> 
> Cheers, Linus

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] Basic Multicast Optimizations
@ 2013-06-10  7:11 Linus Lüssing
  2013-06-12 10:14 ` Simon Wunderlich
  0 siblings, 1 reply; 37+ messages in thread
From: Linus Lüssing @ 2013-06-10  7:11 UTC (permalink / raw)
  To: b.a.t.m.a.n

This is the fourth revision of the basic multicast optimization patches.

It adds a missing enum keyword to the return type of a mcast_forw_mode().

Cheers, Linus

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-06-10  6:28 Linus Lüssing
@ 2013-06-10  7:06 ` Linus Lüssing
  0 siblings, 0 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-06-10  7:06 UTC (permalink / raw)
  To: b.a.t.m.a.n

Hrm, forgot to add the v3 an the patch naming. And forgot to
actually add
-static inline batadv_forw_mode
+static inline enum batadv_forw_mode
to the according commit.

Will send a v4 in a sec.

Cheers, Linus

On Mon, Jun 10, 2013 at 08:28:18AM +0200, Linus Lüssing wrote:
> This is the third revision of the basic multicast optimization patches.
> It includes one functional and some compat fixes, and some style improvements,
> thanks to Simons feedback:
> 
> PATCHv3 1/3:
> * the pmc_rcu functions got removed - they weren't actually used in the
>   submitted revision - so there's no more patch for net to export
>   for_each_pmc_rcu() needed anymore. Should also fix Simon's compat error.
> * Compat code for netdev_for_each_mc_addr() added.
>   (I needed to introduce a batadv_hw_addr because I wasn't able to achieve
>   backwards compatibility with a netdev_hw_addr - my "official reasoning" will
>   be that netdev_hw_addr is unnecessarily bloated, struct batadv_hw_addr
>   has just the right size to do the job)
> * Compat fix for IFF_BRIDGE_PORT
> * Removed primary_if->soft_iface in batadv_mcast_mla_tt_update() as we
>   can always use bat_priv->soft_iface instead.
> 
> PATCHv3 2/3
> * Renamed num_non_aware to a more specific num_no_mla - because we will need
>   things like a num_no_tracker for instance with the multicast tracker feature
>   in the future.
> * Fixed removal of orig_node's without BATADV_MCAST_LISTENER_ANNOUNCEMENT
>   flag, update num_no_mla properly now.
> 
> PATCHv3 3/3
> * Renamed batadv_mcast_flood() to batadv_mcast_forw_mode() because it does not
>   only show whether to flood or not (=drop), but also whether to forward via
>   unicast. In the future with the multicast tracker feature a fourth return value
>   is going to be added, making the name "batadv_mcast_flood()" even less fitting.
> * Simon's style suggestions for batadv_mcast_forw_mode() and
>   batadv_interface_tx().
> * batadv_mcast_forw_mode() now returns an enum (thanks to Marek and Antonio for
>   the suggestion).
> 
> I did not change:
> > I don't quite understand why you return -1, maybe the packet could still
> > be forwarded even if it could not be pulled?
> 
> Because if it returns -1 then something is wrong, for instance we could be
> out of memory. If we are out of memory then we probably won't be able to
> forward any packet. Also we shouldn't allocate any more memory for one thing
> but I think it is also better to drop/free packets to save some memory
> to increase the possibility of the system to recover without crashing.
> 
> Cheers, Linus
> 

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] Basic Multicast Optimizations
@ 2013-06-10  6:28 Linus Lüssing
  2013-06-10  7:06 ` Linus Lüssing
  0 siblings, 1 reply; 37+ messages in thread
From: Linus Lüssing @ 2013-06-10  6:28 UTC (permalink / raw)
  To: b.a.t.m.a.n

This is the third revision of the basic multicast optimization patches.
It includes one functional and some compat fixes, and some style improvements,
thanks to Simons feedback:

PATCHv3 1/3:
* the pmc_rcu functions got removed - they weren't actually used in the
  submitted revision - so there's no more patch for net to export
  for_each_pmc_rcu() needed anymore. Should also fix Simon's compat error.
* Compat code for netdev_for_each_mc_addr() added.
  (I needed to introduce a batadv_hw_addr because I wasn't able to achieve
  backwards compatibility with a netdev_hw_addr - my "official reasoning" will
  be that netdev_hw_addr is unnecessarily bloated, struct batadv_hw_addr
  has just the right size to do the job)
* Compat fix for IFF_BRIDGE_PORT
* Removed primary_if->soft_iface in batadv_mcast_mla_tt_update() as we
  can always use bat_priv->soft_iface instead.

PATCHv3 2/3
* Renamed num_non_aware to a more specific num_no_mla - because we will need
  things like a num_no_tracker for instance with the multicast tracker feature
  in the future.
* Fixed removal of orig_node's without BATADV_MCAST_LISTENER_ANNOUNCEMENT
  flag, update num_no_mla properly now.

PATCHv3 3/3
* Renamed batadv_mcast_flood() to batadv_mcast_forw_mode() because it does not
  only show whether to flood or not (=drop), but also whether to forward via
  unicast. In the future with the multicast tracker feature a fourth return value
  is going to be added, making the name "batadv_mcast_flood()" even less fitting.
* Simon's style suggestions for batadv_mcast_forw_mode() and
  batadv_interface_tx().
* batadv_mcast_forw_mode() now returns an enum (thanks to Marek and Antonio for
  the suggestion).

I did not change:
> I don't quite understand why you return -1, maybe the packet could still
> be forwarded even if it could not be pulled?

Because if it returns -1 then something is wrong, for instance we could be
out of memory. If we are out of memory then we probably won't be able to
forward any packet. Also we shouldn't allocate any more memory for one thing
but I think it is also better to drop/free packets to save some memory
to increase the possibility of the system to recover without crashing.

Cheers, Linus


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-05-24  8:02 Linus Lüssing
  2013-05-24  9:00 ` Linus Lüssing
@ 2013-05-24  9:33 ` Marek Lindner
  1 sibling, 0 replies; 37+ messages in thread
From: Marek Lindner @ 2013-05-24  9:33 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking


Hi,

On Friday, May 24, 2013 16:02:25 Linus Lüssing wrote:
> * for_each_pmc_rcu() was not moved to a commen net header file,
> only a TODO was added. Will do that after this code might have
> landed in net.

we discussed this further and concluded that we can't simply make that 
decision. The order in which patches are going to be merged into net has to be 
decided by David Miller. So, please prepare a patch destined for net, send it 
to netdev (cc the batman ml if you like) to explain what we are planning to do 
and ask for advice.

Cheers,
Marek

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-05-24  9:00 ` Linus Lüssing
@ 2013-05-24  9:06   ` Antonio Quartulli
  0 siblings, 0 replies; 37+ messages in thread
From: Antonio Quartulli @ 2013-05-24  9:06 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

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

On Fri, May 24, 2013 at 11:00:50AM +0200, Linus Lüssing wrote:
> On Fri, May 24, 2013 at 10:02:25AM +0200, Linus Lüssing wrote:
> > This is the second revision of the basic multicast optimization patches.
> > It includes one functional fix and many style fixes, thanks to Antonios
> > feedback.
> > 
> > Three things were not included from these suggestions:
> > 
> > * The default mcast TVLV flags were left as it is not as easy to
> > switch. (see answer/explanation to [PATCH 2/3])
> > * for_each_pmc_rcu() was not moved to a commen net header file,
> > only a TODO was added. Will do that after this code might have
> > landed in net.
> * VLAN support was not added yet as this will be some more work. Any
> vlan frames with a multicast destination will still get flooded
> for now so at least these patches shouldn't introduce any
> regressions for those. However I have to admit that I didn't think
> of VLANs yet and Marek suggested to check how much extra work it
> might create later compared to adding that right from the start.
> I'll have a look at that.

I think (but I am not sure) that the TT-VLAN feature that I just sent to the ml
(I have to send v3..) could probably help in this direction, because a TT entry
is not defined by its MAC address only anymore, but by the couple {MAC, vid}.

Since your code uses the TT to store the multicast addresses, I think that VLAN
support can be added "easily"[tm] after the TT-VLAN code will be in.


Cheers,


-- 
Antonio Quartulli

..each of us alone is worth nothing..
Ernesto "Che" Guevara

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-05-24  8:02 Linus Lüssing
@ 2013-05-24  9:00 ` Linus Lüssing
  2013-05-24  9:06   ` Antonio Quartulli
  2013-05-24  9:33 ` Marek Lindner
  1 sibling, 1 reply; 37+ messages in thread
From: Linus Lüssing @ 2013-05-24  9:00 UTC (permalink / raw)
  To: b.a.t.m.a.n

On Fri, May 24, 2013 at 10:02:25AM +0200, Linus Lüssing wrote:
> This is the second revision of the basic multicast optimization patches.
> It includes one functional fix and many style fixes, thanks to Antonios
> feedback.
> 
> Three things were not included from these suggestions:
> 
> * The default mcast TVLV flags were left as it is not as easy to
> switch. (see answer/explanation to [PATCH 2/3])
> * for_each_pmc_rcu() was not moved to a commen net header file,
> only a TODO was added. Will do that after this code might have
> landed in net.
* VLAN support was not added yet as this will be some more work. Any
vlan frames with a multicast destination will still get flooded
for now so at least these patches shouldn't introduce any
regressions for those. However I have to admit that I didn't think
of VLANs yet and Marek suggested to check how much extra work it
might create later compared to adding that right from the start.
I'll have a look at that.

> 
> 
> Additionally the limitation of 255 multicast listeners per originator
> was removed (it was more a relic of the pre-TT announcement mechanism
> and such limitations should be taken care of by the current TT
> infrastructure instead).
> 
> Cheers, Linus

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] Basic Multicast Optimizations
@ 2013-05-24  8:02 Linus Lüssing
  2013-05-24  9:00 ` Linus Lüssing
  2013-05-24  9:33 ` Marek Lindner
  0 siblings, 2 replies; 37+ messages in thread
From: Linus Lüssing @ 2013-05-24  8:02 UTC (permalink / raw)
  To: b.a.t.m.a.n

This is the second revision of the basic multicast optimization patches.
It includes one functional fix and many style fixes, thanks to Antonios
feedback.

Three things were not included from these suggestions:

* The default mcast TVLV flags were left as it is not as easy to
switch. (see answer/explanation to [PATCH 2/3])
* for_each_pmc_rcu() was not moved to a commen net header file,
only a TODO was added. Will do that after this code might have
landed in net.


Additionally the limitation of 255 multicast listeners per originator
was removed (it was more a relic of the pre-TT announcement mechanism
and such limitations should be taken care of by the current TT
infrastructure instead).

Cheers, Linus

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-05-17  1:38       ` Linus Lüssing
@ 2013-05-17 10:24         ` Simon Wunderlich
  0 siblings, 0 replies; 37+ messages in thread
From: Simon Wunderlich @ 2013-05-17 10:24 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

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

Hey Linus,

On Fri, May 17, 2013 at 03:38:56AM +0200, Linus Lüssing wrote:
> > 
> > For the non-link-local IPv4 multicast addresses, could we use the
> > current mechanism (drop/unicast/broadcast) by getting the assigned
> > multicast addresses? (of course, assuming we have no bridge)
> 
> We could - after implementing MRD. The thing is we might have one
> or more IPv4 multicast routers in our network. If we are having
> two multicast listeners on our link, then everything will be fine,
> we will broadcast, multicast routers receive the multicast
> packets, too and the multicast data gets routed further. However
> with no MRD and if there is just one or no multicast listener
> then we'd do the unicast/drop and the multicast router on the link
> and any listener more than one hop away would not receive that data
> anymore.
> 
OK, I see. Well, then we should save that for later ...

> > > For MRD I was thinking about taking a short-cut for now as
> > > implementing would need a few more lines of code. Instead I think
> > > I go for detecting whether a querier is on the link both in
> > > batman-adv and the bridge code for IPv4 or IPv6 and if not disabling
> > > optimizations accordingly and issuing a warning. That way
> > > non-link-local IPv6 multicast traffic could be optimized already
> > > for instance if running an mrd6 instance in userspace which
> > > already performs both MLD querying and MRD.
> > > 
> 
> Sorry, I ment: "For MLD querying I was...". mrd6 does perform MRD,
> so sending things like multicast router advertisements. But
> bridges or batman-adv would still need to parse these
> advertisements and should send multicast router solicitations
> (e.g. when an interface comes up) to be able to quickly determine
> which bridge ports or nodes have multicast routers and want the
> non-link-local multicast traffic.
> 

OK

> > 
> > Hmm, sorry I still get a little confused in that MRD/MLD/IGMP terminology.
> > So as I understand there might be a userspace component which does the MLD/MRD
> > instead of the kernel?
> 
> Yes, the layer 3 multicast routing table is in the kernel, but it
> is configured from userspace from daemons like mrd6. And mrd6 also
> does some non-performance critical protocol stuff like the MLD
> Querier protocol and the MRD multicast router advertisements like
> I said above.
> 

OK

> > Also, is it required to get implement MRD/MLD specifically
> > in batman-adv or bridges, or would it be possible to use a "general" approach
> > which could be used for any interface to emit/exchange these kind of messages?
> 
> The MLD querier is something which only makes sense to me in case
> of multicast snooping bridges and I don't see any benefit in having
> it anywhere else. If there are just the plain interfaces with no
> multicast router then you don't need an MLD querier (and in fact
> no MLD reports from the listeners either). If there's just
> batman-adv with no bridges, then you don't need it either.
> Although...
> 
> There is one use-case where a more general approach might be of
> interest: Wireless interfaces - it might be of interest for the
> mac80211 to know whether there is a listener (or router) behind
> the link provided by your wlan0 device. The wifi driver could then
> decide to refrain from broadcasting a multicast packet or to use
> the (minimum) bitrate of just the(se) listener(s) (/router(s)).

Actually that might be interesting for both batman-adv and "regular"
WiFi setups. I think some commercial vendors already do exactly that
to optimize Multicast. My setup at home is a good example how this
could benefit: 
 * I have 6 APs having mesh and ap bridged
 * Right now, when I multicast stream from my LAN, first batman-adv
   floods all the broadcast through the mesh, then every AP sends the
   broadcast again - all on the lowest rate (at least on the AP).
 --> so if we listen to music using multicast only in the kitchen, 
   the WiFi becomes really slow. :D

With the multicast optimization in batman-adv, we could solve the
broadcast storm in the batman-adv network (only send to the APs where
listener registered). Then still the AP would broadcast these packets
on the lowest rate (1 MBit/s). Not all APs at least, but still the
one where the client is connected. If mac80211 could detect that
and send it via unicast, we could use even HT rates (e.g. 300 Mbit/s)
here. I could enjoy wireless multicast HD video streams - yay. ;)

Probably not the most typical example/use case, but still we can see
how this scenario would benefit from the optimization.

> Or maybe a drop/unicast/flood on an eth0 itself might be nice, too,
> especially if there is a large switch/hub connected to it.
> 
> Although that'd probably be awesome to have, I think it's easier
> to just have the MLD querier in the bridge code for now (especilly
> as there already is some MLD querier code in the bridge - though
> it is so incomplete that it got disabled in April 2012 because of
> causing issues).

Actually I'm not sure about the technical implementation of such
a general approach. Maybe it would be possible to query the bridge
from the various components as well.

> 
> Hm, for the MRD RA parsing and MRD RS I thought about implementing
> that both in the bridge and batman-adv code (it's about 300
> lines of C++ code in mrd6). Not sure how easy it'd be to implement
> a more general approach on top of a Linux netdev for instance.
> Would need to check that.
> 
> > 
> > Sorry if I ask stupid questions. :)
> > 
> > Maybe some example or architecture overview (could be put on the wiki page) would
> > help?
> 
> I guess you mean some visualizaton with things like simple
> devices, bridge, batman-adv, maybe various kinds of multicast
> types (e.g. scope == link-local vs. scope > link-local, IPv6 transient
> vs. IPv6 well-known) and the according RFCs? Hm, not quite sure
> how that could look like would need to think about it - or maybe
> you have some idea about how you think that could/should look
> like?
> 

Hmm, not sure either. Maybe we choose the typical examples (bat0 only,
bat0 + ap + bridge), and show which component sends what. Like having
"blocks" for batman, bridge, userspace mrd, etc, and show which component
sends/querys who for which information.

I know that's pretty vague, but maybe there is a way to bring light in
that for others which are not so experienced in that (me included).

Multicast types (IPv4, IPv6) and their mac-address and RFC recommendations
should probably better go in an extra section. We could make a table of
what types exist, how we handle them (optimize, just broadcast) and why
(RFC, design decisions).

> > OK. We could also increase the version number of the TVLV and interpret
> > both versions in newer multicast implementations, but if we already know
> > that we can define this information in the current implementation.
> 
> But a newer TVLV version would break compatibility for older
> batman-adv versions, they wouldn't recognize the newer TVLV
> version. Or a node would need to add TVLVs for both versions to
> its OGM. But that'd be some more overhead compared to just adding
> another flag.
> 

Yeah you are right. Maybe just add the flag. :D

> > 
> > > > 
> > > > Would you consider Antonios comments and update your patchset? I would like to
> > > > test it in the next days ...
> > > 
> > > Yes, I will. I had written some comments for the comments on IRC,
> > > but I guess it'll be better to write them here on the list again.
> > > 
> > 
> > Mailing list would be better, yes. Thanks. :)
> 
> Done :).
> 

Thanks!

> > 
> > > > 
> > > > Thanks,
> > > > 	Simon
> > > 
> > > Another thing I was thinking about conceptually yesterday was
> > > whether we should use more refined flags instead of just
> > > MULTICAST_LISTENER_ANNOUNCEMENTS for everything (non-link-local
> > > IPv4, all IPv6 except the all-nodes address).
> > > 
> > > That way we could for instance already add some cases for when to
> > > use the multicast optimizations when having a bridge, for
> > > instance:
> > > 
> > > When batman-adv detects that there is an MLD querier and if all
> > > nodes have a MULTICAST_LISTENER_ANNOUNCEMENTS or
> > > MLA_IPV6_TRANSIENT_LINK_LOCAL flag it could  already
> > > optimize link-local, transient IPv6 multicast traffic
> > > without needing to modify anything in the bridge code except the
> > > addition of the export which was already posted as an RFC on the
> > > bridge mailing list.
> > > 
> > > Hm, again will need to think about that. Whether the extra
> > > conceptual complexity is okay because of being able to add some
> > > more use-cases with less code in small chunks already.
> > 
> > Hmm, again I'm not completely sure to follow, but the idea here is
> > to enable functionality when having a userspace MLD instead of
> > the (planned) bridge MLD stuff?
> 
> Yes, that would be the idea.
> 
> > 
> > If we need the bridge MLD stuff anyway (to have the full feature set
> > etc), I'd rather not do more intermediate steps which might be
> > obsolete later. However, if the userspace MLD thing is equivalent
> > feature-wise than this might be interesting to do.
> 
> Hm, don't know. I was thinking that most setups I know of involve
> bridges on top of bat0 and to be able to make use of any multicast
> optimizations in batman-adv in case of such bridging we need an
> MLD querier on the link. Implementing a proper MLD querier might
> need several iterations over the bridge / netdev mailing lists and
> might therefore need quite some time. During that time those
> setups won't be able to make any use of these optimizations.
> 
> Unless taking the suggested short-cut which shouldn't be that
> difficult to implement, I think, then these bat0+bridge setups
> could already enjoy some multicast optimizations and such mesh
> networks might already be able to play with multicast streams as I
> think updating and merging the tracker packet patches will be done
> some time before getting MLD querier bridge code upstream.
> (but maybe I'm estimating all this wrong, dunno)

Actually I did not hear much screaming to have multicast support so far,
so I don't think we "need" an intermediate solution. If you want to it
anyway or need it for something, go ahead, but I'd prefer aiming for
the final implementation from the start without taking detours. :)

Thanks,
	Simon

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-05-16 18:31     ` Simon Wunderlich
@ 2013-05-17  1:38       ` Linus Lüssing
  2013-05-17 10:24         ` Simon Wunderlich
  0 siblings, 1 reply; 37+ messages in thread
From: Linus Lüssing @ 2013-05-17  1:38 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

Hi,

On Thu, May 16, 2013 at 08:31:32PM +0200, Simon Wunderlich wrote:
> On Thu, May 16, 2013 at 07:42:00PM +0200, Linus Lüssing wrote:
> > Hi Simon,
> > 
> > On Thu, May 16, 2013 at 01:51:29PM +0200, Simon Wunderlich wrote:
> > > Hey Linus,
> > > 
> > > thanks for working and integrating this patchset!
> > > 
> > > On Sat, May 11, 2013 at 07:23:24PM +0200, Linus Lüssing wrote:
> > > > This set of patches is the first one for a more efficient, group aware
> > > > multicast forwarding infrastructure in batman-adv.
> > > > 
> > > > This initial set mainly consists of the integration of announcing the
> > > > location of multicast listeners via the translation table mechanism to
> > > > be able to find out which batman-adv nodes are actually interested in
> > > > certain multicast traffic. As well as the signalizing of this
> > > > announcement capability via a new multicast TVLV.
> > > > 
> > > > Finally some basic multicast forwarding opitimizations are introduced:
> > > > If all nodes signalized the MLA capability then link-local IPv6 traffic
> > > > will be dropped if there is no interested listener or gets forwarded
> > > > via a batman-adv unicast packet if there is just one node interested
> > > > in the data.
> > > 
> > > I've seen that you've only implemented that for IPv6, would it be possible
> > > to use it for IPv4 too in the current state? (I use some media streaming
> > > thingy at home where I could test ;])
> > 
> > Hmm, I need to think about it. The thing is it looks like IPv4 does
> > not seem to require IGMP. And according to RFC4541, an
> > informational one, link-local IPv4 multicast shoud be excluded as
> > there might be some applications not issuing IGMP reports.
> > 
> > For non-link-local addresses we'd need MRD first, as we'd
> > otherwise miss to forward things to multicast routers.
> > 
> > However when using no bridge, like it is the case now, RFC4541
> > does not apply and we can in fact reliably get and distribute
> > link-local IPv4 multicast addresses as we do not rely on IGMP
> > here... 
> > 
> > One option would be to introduce another flag. But that might
> > become confusing for users, it might not be easy to explain to
> > users why their 224.0.0.123 would be working on raw bat0 but not
> > when they add a bridge and why this would never work. Instead we
> > could wait for the MRD implementation and tell people that
> > 224.0.0.0/24 won't work.
> > 
> 
> Hmm, as far as I read the RFC 4541) (2.1.2, point 2) we should just
> treat 224.0.0.0/24 (which would translate to 01:00:5e:00:00:xx) as
> broadcast - we should do that in any state of the multicast implementation
> IMHO, and are then on the safe side. For all other IPv4 multicast
> addresses we can assume that IGMP is used.

Ok, yes, that's what I thought, too (although like I said before
technically there is the possibility to safely optimize 224.0.0.0/24, too
if there are no bridges involved - but ok, let's forget that thought).

> 
> For the non-link-local IPv4 multicast addresses, could we use the
> current mechanism (drop/unicast/broadcast) by getting the assigned
> multicast addresses? (of course, assuming we have no bridge)

We could - after implementing MRD. The thing is we might have one
or more IPv4 multicast routers in our network. If we are having
two multicast listeners on our link, then everything will be fine,
we will broadcast, multicast routers receive the multicast
packets, too and the multicast data gets routed further. However
with no MRD and if there is just one or no multicast listener
then we'd do the unicast/drop and the multicast router on the link
and any listener more than one hop away would not receive that data
anymore.

> > > 
> > > > 
> > > > For now, these optimizations only apply if all nodes in the mesh have
> > > > no bridge interface on top their bat0 interface. However making it
> > > > possible with bridges, too, and other features are on the roadmap. See
> > > > the according wiki page for details [1].
> > > 
> > > So from what I understand this means:
> > > 
> > >  * multicast support is working for non-bridged interfaces for now, because
> > >    we lack proper multicast router discovery support (MRD) in the bridge code
> > >  --> you told me someone is working on that, or you'll pick up to get this done?
> > 
> > Yes, I had been exchanging some emails with a group of people a
> > few months ago who wanted to implement MRD and a proper IGMP/MLD
> > querier protocol in the bridge code but didn't hear from them again.
> > So yes, I guess I'll pick up on that.
> 
> OK, cool.
> > 
> > 
> > For MRD I was thinking about taking a short-cut for now as
> > implementing would need a few more lines of code. Instead I think
> > I go for detecting whether a querier is on the link both in
> > batman-adv and the bridge code for IPv4 or IPv6 and if not disabling
> > optimizations accordingly and issuing a warning. That way
> > non-link-local IPv6 multicast traffic could be optimized already
> > for instance if running an mrd6 instance in userspace which
> > already performs both MLD querying and MRD.
> > 

Sorry, I ment: "For MLD querying I was...". mrd6 does perform MRD,
so sending things like multicast router advertisements. But
bridges or batman-adv would still need to parse these
advertisements and should send multicast router solicitations
(e.g. when an interface comes up) to be able to quickly determine
which bridge ports or nodes have multicast routers and want the
non-link-local multicast traffic.

> 
> Hmm, sorry I still get a little confused in that MRD/MLD/IGMP terminology.
> So as I understand there might be a userspace component which does the MLD/MRD
> instead of the kernel?

Yes, the layer 3 multicast routing table is in the kernel, but it
is configured from userspace from daemons like mrd6. And mrd6 also
does some non-performance critical protocol stuff like the MLD
Querier protocol and the MRD multicast router advertisements like
I said above.

> Also, is it required to get implement MRD/MLD specifically
> in batman-adv or bridges, or would it be possible to use a "general" approach
> which could be used for any interface to emit/exchange these kind of messages?

The MLD querier is something which only makes sense to me in case
of multicast snooping bridges and I don't see any benefit in having
it anywhere else. If there are just the plain interfaces with no
multicast router then you don't need an MLD querier (and in fact
no MLD reports from the listeners either). If there's just
batman-adv with no bridges, then you don't need it either.
Although...

There is one use-case where a more general approach might be of
interest: Wireless interfaces - it might be of interest for the
mac80211 to know whether there is a listener (or router) behind
the link provided by your wlan0 device. The wifi driver could then
decide to refrain from broadcasting a multicast packet or to use
the (minimum) bitrate of just the(se) listener(s) (/router(s)).
Or maybe a drop/unicast/flood on an eth0 itself might be nice, too,
especially if there is a large switch/hub connected to it.

Although that'd probably be awesome to have, I think it's easier
to just have the MLD querier in the bridge code for now (especilly
as there already is some MLD querier code in the bridge - though
it is so incomplete that it got disabled in April 2012 because of
causing issues).

Hm, for the MRD RA parsing and MRD RS I thought about implementing
that both in the bridge and batman-adv code (it's about 300
lines of C++ code in mrd6). Not sure how easy it'd be to implement
a more general approach on top of a Linux netdev for instance.
Would need to check that.

> 
> Sorry if I ask stupid questions. :)
> 
> Maybe some example or architecture overview (could be put on the wiki page) would
> help?

I guess you mean some visualizaton with things like simple
devices, bridge, batman-adv, maybe various kinds of multicast
types (e.g. scope == link-local vs. scope > link-local, IPv6 transient
vs. IPv6 well-known) and the according RFCs? Hm, not quite sure
how that could look like would need to think about it - or maybe
you have some idea about how you think that could/should look
like?

> 
> > > 
> > >  * the current optimization is to handle multicast like:
> > >    * no listener - drop
> > >    * one listener - unicast
> > >    * more listener - broadcast
> > >  --> I think that is a good and simple optimization. :) The "tracker" packets
> > >      can come later (as shown in your roadmap). This might require to announce
> > >      that tracker packets are supported in the TVLV?
> > 
> > Yes, we'll probably need to add another capability flag to the
> > multicast TVLV.
> > 
> 
> OK. We could also increase the version number of the TVLV and interpret
> both versions in newer multicast implementations, but if we already know
> that we can define this information in the current implementation.

But a newer TVLV version would break compatibility for older
batman-adv versions, they wouldn't recognize the newer TVLV
version. Or a node would need to add TVLVs for both versions to
its OGM. But that'd be some more overhead compared to just adding
another flag.

> 
> > > 
> > > Would you consider Antonios comments and update your patchset? I would like to
> > > test it in the next days ...
> > 
> > Yes, I will. I had written some comments for the comments on IRC,
> > but I guess it'll be better to write them here on the list again.
> > 
> 
> Mailing list would be better, yes. Thanks. :)

Done :).

> 
> > > 
> > > Thanks,
> > > 	Simon
> > 
> > Another thing I was thinking about conceptually yesterday was
> > whether we should use more refined flags instead of just
> > MULTICAST_LISTENER_ANNOUNCEMENTS for everything (non-link-local
> > IPv4, all IPv6 except the all-nodes address).
> > 
> > That way we could for instance already add some cases for when to
> > use the multicast optimizations when having a bridge, for
> > instance:
> > 
> > When batman-adv detects that there is an MLD querier and if all
> > nodes have a MULTICAST_LISTENER_ANNOUNCEMENTS or
> > MLA_IPV6_TRANSIENT_LINK_LOCAL flag it could  already
> > optimize link-local, transient IPv6 multicast traffic
> > without needing to modify anything in the bridge code except the
> > addition of the export which was already posted as an RFC on the
> > bridge mailing list.
> > 
> > Hm, again will need to think about that. Whether the extra
> > conceptual complexity is okay because of being able to add some
> > more use-cases with less code in small chunks already.
> 
> Hmm, again I'm not completely sure to follow, but the idea here is
> to enable functionality when having a userspace MLD instead of
> the (planned) bridge MLD stuff?

Yes, that would be the idea.

> 
> If we need the bridge MLD stuff anyway (to have the full feature set
> etc), I'd rather not do more intermediate steps which might be
> obsolete later. However, if the userspace MLD thing is equivalent
> feature-wise than this might be interesting to do.

Hm, don't know. I was thinking that most setups I know of involve
bridges on top of bat0 and to be able to make use of any multicast
optimizations in batman-adv in case of such bridging we need an
MLD querier on the link. Implementing a proper MLD querier might
need several iterations over the bridge / netdev mailing lists and
might therefore need quite some time. During that time those
setups won't be able to make any use of these optimizations.

Unless taking the suggested short-cut which shouldn't be that
difficult to implement, I think, then these bat0+bridge setups
could already enjoy some multicast optimizations and such mesh
networks might already be able to play with multicast streams as I
think updating and merging the tracker packet patches will be done
some time before getting MLD querier bridge code upstream.
(but maybe I'm estimating all this wrong, dunno)

> 
> Cheers,
> 	Simon

Cheers, Linus

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-05-16 17:42   ` Linus Lüssing
@ 2013-05-16 18:31     ` Simon Wunderlich
  2013-05-17  1:38       ` Linus Lüssing
  0 siblings, 1 reply; 37+ messages in thread
From: Simon Wunderlich @ 2013-05-16 18:31 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

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

On Thu, May 16, 2013 at 07:42:00PM +0200, Linus Lüssing wrote:
> Hi Simon,
> 
> On Thu, May 16, 2013 at 01:51:29PM +0200, Simon Wunderlich wrote:
> > Hey Linus,
> > 
> > thanks for working and integrating this patchset!
> > 
> > On Sat, May 11, 2013 at 07:23:24PM +0200, Linus Lüssing wrote:
> > > This set of patches is the first one for a more efficient, group aware
> > > multicast forwarding infrastructure in batman-adv.
> > > 
> > > This initial set mainly consists of the integration of announcing the
> > > location of multicast listeners via the translation table mechanism to
> > > be able to find out which batman-adv nodes are actually interested in
> > > certain multicast traffic. As well as the signalizing of this
> > > announcement capability via a new multicast TVLV.
> > > 
> > > Finally some basic multicast forwarding opitimizations are introduced:
> > > If all nodes signalized the MLA capability then link-local IPv6 traffic
> > > will be dropped if there is no interested listener or gets forwarded
> > > via a batman-adv unicast packet if there is just one node interested
> > > in the data.
> > 
> > I've seen that you've only implemented that for IPv6, would it be possible
> > to use it for IPv4 too in the current state? (I use some media streaming
> > thingy at home where I could test ;])
> 
> Hmm, I need to think about it. The thing is it looks like IPv4 does
> not seem to require IGMP. And according to RFC4541, an
> informational one, link-local IPv4 multicast shoud be excluded as
> there might be some applications not issuing IGMP reports.
> 
> For non-link-local addresses we'd need MRD first, as we'd
> otherwise miss to forward things to multicast routers.
> 
> However when using no bridge, like it is the case now, RFC4541
> does not apply and we can in fact reliably get and distribute
> link-local IPv4 multicast addresses as we do not rely on IGMP
> here... 
> 
> One option would be to introduce another flag. But that might
> become confusing for users, it might not be easy to explain to
> users why their 224.0.0.123 would be working on raw bat0 but not
> when they add a bridge and why this would never work. Instead we
> could wait for the MRD implementation and tell people that
> 224.0.0.0/24 won't work.
> 

Hmm, as far as I read the RFC 4541) (2.1.2, point 2) we should just
treat 224.0.0.0/24 (which would translate to 01:00:5e:00:00:xx) as
broadcast - we should do that in any state of the multicast implementation
IMHO, and are then on the safe side. For all other IPv4 multicast
addresses we can assume that IGMP is used.

For the non-link-local IPv4 multicast addresses, could we use the
current mechanism (drop/unicast/broadcast) by getting the assigned
multicast addresses? (of course, assuming we have no bridge)
> > 
> > > 
> > > For now, these optimizations only apply if all nodes in the mesh have
> > > no bridge interface on top their bat0 interface. However making it
> > > possible with bridges, too, and other features are on the roadmap. See
> > > the according wiki page for details [1].
> > 
> > So from what I understand this means:
> > 
> >  * multicast support is working for non-bridged interfaces for now, because
> >    we lack proper multicast router discovery support (MRD) in the bridge code
> >  --> you told me someone is working on that, or you'll pick up to get this done?
> 
> Yes, I had been exchanging some emails with a group of people a
> few months ago who wanted to implement MRD and a proper IGMP/MLD
> querier protocol in the bridge code but didn't hear from them again.
> So yes, I guess I'll pick up on that.

OK, cool.
> 
> 
> For MRD I was thinking about taking a short-cut for now as
> implementing would need a few more lines of code. Instead I think
> I go for detecting whether a querier is on the link both in
> batman-adv and the bridge code for IPv4 or IPv6 and if not disabling
> optimizations accordingly and issuing a warning. That way
> non-link-local IPv6 multicast traffic could be optimized already
> for instance if running an mrd6 instance in userspace which
> already performs both MLD querying and MRD.
> 

Hmm, sorry I still get a little confused in that MRD/MLD/IGMP terminology.
So as I understand there might be a userspace component which does the MLD/MRD
instead of the kernel? Also, is it required to get implement MRD/MLD specifically
in batman-adv or bridges, or would it be possible to use a "general" approach
which could be used for any interface to emit/exchange these kind of messages?

Sorry if I ask stupid questions. :)

Maybe some example or architecture overview (could be put on the wiki page) would
help?

> > 
> >  * the current optimization is to handle multicast like:
> >    * no listener - drop
> >    * one listener - unicast
> >    * more listener - broadcast
> >  --> I think that is a good and simple optimization. :) The "tracker" packets
> >      can come later (as shown in your roadmap). This might require to announce
> >      that tracker packets are supported in the TVLV?
> 
> Yes, we'll probably need to add another capability flag to the
> multicast TVLV.
> 

OK. We could also increase the version number of the TVLV and interpret
both versions in newer multicast implementations, but if we already know
that we can define this information in the current implementation.

> > 
> > Would you consider Antonios comments and update your patchset? I would like to
> > test it in the next days ...
> 
> Yes, I will. I had written some comments for the comments on IRC,
> but I guess it'll be better to write them here on the list again.
> 

Mailing list would be better, yes. Thanks. :)

> > 
> > Thanks,
> > 	Simon
> 
> Another thing I was thinking about conceptually yesterday was
> whether we should use more refined flags instead of just
> MULTICAST_LISTENER_ANNOUNCEMENTS for everything (non-link-local
> IPv4, all IPv6 except the all-nodes address).
> 
> That way we could for instance already add some cases for when to
> use the multicast optimizations when having a bridge, for
> instance:
> 
> When batman-adv detects that there is an MLD querier and if all
> nodes have a MULTICAST_LISTENER_ANNOUNCEMENTS or
> MLA_IPV6_TRANSIENT_LINK_LOCAL flag it could  already
> optimize link-local, transient IPv6 multicast traffic
> without needing to modify anything in the bridge code except the
> addition of the export which was already posted as an RFC on the
> bridge mailing list.
> 
> Hm, again will need to think about that. Whether the extra
> conceptual complexity is okay because of being able to add some
> more use-cases with less code in small chunks already.

Hmm, again I'm not completely sure to follow, but the idea here is
to enable functionality when having a userspace MLD instead of
the (planned) bridge MLD stuff?

If we need the bridge MLD stuff anyway (to have the full feature set
etc), I'd rather not do more intermediate steps which might be
obsolete later. However, if the userspace MLD thing is equivalent
feature-wise than this might be interesting to do.

Cheers,
	Simon

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-05-16 11:51 ` Simon Wunderlich
@ 2013-05-16 17:42   ` Linus Lüssing
  2013-05-16 18:31     ` Simon Wunderlich
  0 siblings, 1 reply; 37+ messages in thread
From: Linus Lüssing @ 2013-05-16 17:42 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

Hi Simon,

On Thu, May 16, 2013 at 01:51:29PM +0200, Simon Wunderlich wrote:
> Hey Linus,
> 
> thanks for working and integrating this patchset!
> 
> On Sat, May 11, 2013 at 07:23:24PM +0200, Linus Lüssing wrote:
> > This set of patches is the first one for a more efficient, group aware
> > multicast forwarding infrastructure in batman-adv.
> > 
> > This initial set mainly consists of the integration of announcing the
> > location of multicast listeners via the translation table mechanism to
> > be able to find out which batman-adv nodes are actually interested in
> > certain multicast traffic. As well as the signalizing of this
> > announcement capability via a new multicast TVLV.
> > 
> > Finally some basic multicast forwarding opitimizations are introduced:
> > If all nodes signalized the MLA capability then link-local IPv6 traffic
> > will be dropped if there is no interested listener or gets forwarded
> > via a batman-adv unicast packet if there is just one node interested
> > in the data.
> 
> I've seen that you've only implemented that for IPv6, would it be possible
> to use it for IPv4 too in the current state? (I use some media streaming
> thingy at home where I could test ;])

Hmm, I need to think about it. The thing is it looks like IPv4 does
not seem to require IGMP. And according to RFC4541, an
informational one, link-local IPv4 multicast shoud be excluded as
there might be some applications not issuing IGMP reports.

For non-link-local addresses we'd need MRD first, as we'd
otherwise miss to forward things to multicast routers.

However when using no bridge, like it is the case now, RFC4541
does not apply and we can in fact reliably get and distribute
link-local IPv4 multicast addresses as we do not rely on IGMP
here... 

One option would be to introduce another flag. But that might
become confusing for users, it might not be easy to explain to
users why their 224.0.0.123 would be working on raw bat0 but not
when they add a bridge and why this would never work. Instead we
could wait for the MRD implementation and tell people that
224.0.0.0/24 won't work.

> 
> > 
> > For now, these optimizations only apply if all nodes in the mesh have
> > no bridge interface on top their bat0 interface. However making it
> > possible with bridges, too, and other features are on the roadmap. See
> > the according wiki page for details [1].
> 
> So from what I understand this means:
> 
>  * multicast support is working for non-bridged interfaces for now, because
>    we lack proper multicast router discovery support (MRD) in the bridge code
>  --> you told me someone is working on that, or you'll pick up to get this done?

Yes, I had been exchanging some emails with a group of people a
few months ago who wanted to implement MRD and a proper IGMP/MLD
querier protocol in the bridge code but didn't hear from them again.
So yes, I guess I'll pick up on that.


For MRD I was thinking about taking a short-cut for now as
implementing would need a few more lines of code. Instead I think
I go for detecting whether a querier is on the link both in
batman-adv and the bridge code for IPv4 or IPv6 and if not disabling
optimizations accordingly and issuing a warning. That way
non-link-local IPv6 multicast traffic could be optimized already
for instance if running an mrd6 instance in userspace which
already performs both MLD querying and MRD.

> 
>  * the current optimization is to handle multicast like:
>    * no listener - drop
>    * one listener - unicast
>    * more listener - broadcast
>  --> I think that is a good and simple optimization. :) The "tracker" packets
>      can come later (as shown in your roadmap). This might require to announce
>      that tracker packets are supported in the TVLV?

Yes, we'll probably need to add another capability flag to the
multicast TVLV.

> 
> Would you consider Antonios comments and update your patchset? I would like to
> test it in the next days ...

Yes, I will. I had written some comments for the comments on IRC,
but I guess it'll be better to write them here on the list again.

> 
> Thanks,
> 	Simon

Another thing I was thinking about conceptually yesterday was
whether we should use more refined flags instead of just
MULTICAST_LISTENER_ANNOUNCEMENTS for everything (non-link-local
IPv4, all IPv6 except the all-nodes address).

That way we could for instance already add some cases for when to
use the multicast optimizations when having a bridge, for
instance:

When batman-adv detects that there is an MLD querier and if all
nodes have a MULTICAST_LISTENER_ANNOUNCEMENTS or
MLA_IPV6_TRANSIENT_LINK_LOCAL flag it could  already
optimize link-local, transient IPv6 multicast traffic
without needing to modify anything in the bridge code except the
addition of the export which was already posted as an RFC on the
bridge mailing list.

Hm, again will need to think about that. Whether the extra
conceptual complexity is okay because of being able to add some
more use-cases with less code in small chunks already.


Cheers, Linus

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [B.A.T.M.A.N.] Basic Multicast Optimizations
  2013-05-11 17:23 Linus Lüssing
@ 2013-05-16 11:51 ` Simon Wunderlich
  2013-05-16 17:42   ` Linus Lüssing
  0 siblings, 1 reply; 37+ messages in thread
From: Simon Wunderlich @ 2013-05-16 11:51 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

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

Hey Linus,

thanks for working and integrating this patchset!

On Sat, May 11, 2013 at 07:23:24PM +0200, Linus Lüssing wrote:
> This set of patches is the first one for a more efficient, group aware
> multicast forwarding infrastructure in batman-adv.
> 
> This initial set mainly consists of the integration of announcing the
> location of multicast listeners via the translation table mechanism to
> be able to find out which batman-adv nodes are actually interested in
> certain multicast traffic. As well as the signalizing of this
> announcement capability via a new multicast TVLV.
> 
> Finally some basic multicast forwarding opitimizations are introduced:
> If all nodes signalized the MLA capability then link-local IPv6 traffic
> will be dropped if there is no interested listener or gets forwarded
> via a batman-adv unicast packet if there is just one node interested
> in the data.

I've seen that you've only implemented that for IPv6, would it be possible
to use it for IPv4 too in the current state? (I use some media streaming
thingy at home where I could test ;])

> 
> For now, these optimizations only apply if all nodes in the mesh have
> no bridge interface on top their bat0 interface. However making it
> possible with bridges, too, and other features are on the roadmap. See
> the according wiki page for details [1].

So from what I understand this means:

 * multicast support is working for non-bridged interfaces for now, because
   we lack proper multicast router discovery support (MRD) in the bridge code
 --> you told me someone is working on that, or you'll pick up to get this done?

 * the current optimization is to handle multicast like:
   * no listener - drop
   * one listener - unicast
   * more listener - broadcast
 --> I think that is a good and simple optimization. :) The "tracker" packets
     can come later (as shown in your roadmap). This might require to announce
     that tracker packets are supported in the TVLV?

Would you consider Antonios comments and update your patchset? I would like to
test it in the next days ...

Thanks,
	Simon

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [B.A.T.M.A.N.] Basic Multicast Optimizations
@ 2013-05-11 17:23 Linus Lüssing
  2013-05-16 11:51 ` Simon Wunderlich
  0 siblings, 1 reply; 37+ messages in thread
From: Linus Lüssing @ 2013-05-11 17:23 UTC (permalink / raw)
  To: b.a.t.m.a.n

This set of patches is the first one for a more efficient, group aware
multicast forwarding infrastructure in batman-adv.

This initial set mainly consists of the integration of announcing the
location of multicast listeners via the translation table mechanism to
be able to find out which batman-adv nodes are actually interested in
certain multicast traffic. As well as the signalizing of this
announcement capability via a new multicast TVLV.

Finally some basic multicast forwarding opitimizations are introduced:
If all nodes signalized the MLA capability then link-local IPv6 traffic
will be dropped if there is no interested listener or gets forwarded
via a batman-adv unicast packet if there is just one node interested
in the data.


For now, these optimizations only apply if all nodes in the mesh have
no bridge interface on top their bat0 interface. However making it
possible with bridges, too, and other features are on the roadmap. See
the according wiki page for details [1].


[1]: http://www.open-mesh.org/projects/batman-adv/wiki/Multicast-ideas-updated#Roadmap


^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2014-01-27  9:48 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-13  8:23 [B.A.T.M.A.N.] Basic Multicast Optimizations Linus Lüssing
2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 1/5] batman-adv: Multicast Listener Announcements via Translation Table Linus Lüssing
2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 2/5] batman-adv: Announce new capability via multicast TVLV Linus Lüssing
2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 3/5] batman-adv: Modified forwarding behaviour for multicast packets Linus Lüssing
2013-08-15 13:45   ` Simon Wunderlich
2013-08-15 18:02     ` Linus Lüssing
2013-08-13  8:23 ` [B.A.T.M.A.N.] [PATCHv8 4/5] batman-adv: Add IPv4 link-local/IPv6-ll-all-nodes multicast support Linus Lüssing
2013-08-13  8:24 ` [B.A.T.M.A.N.] [PATCHv8 5/5] batman-adv: Send multicast packets to nodes with a WANT_ALL flag Linus Lüssing
2013-08-15 13:56 ` [B.A.T.M.A.N.] Basic Multicast Optimizations Simon Wunderlich
2013-08-15 18:25   ` Linus Lüssing
  -- strict thread matches above, loose matches on Subject: below --
2014-01-27  9:48 Linus Lüssing
2013-11-14  6:26 Linus Lüssing
2013-10-26 19:16 Linus Lüssing
2013-08-15 19:21 Linus Lüssing
2013-08-19 20:12 ` Simon Wunderlich
2013-07-03 22:03 Linus Lüssing
2013-07-04  5:06 ` Linus Lüssing
2013-06-14 17:50 Linus Lüssing
2013-06-16 14:08 ` Simon Wunderlich
2013-06-14  9:02 Linus Lüssing
2013-06-10  7:11 Linus Lüssing
2013-06-12 10:14 ` Simon Wunderlich
2013-06-12 12:27   ` Linus Lüssing
2013-06-12 12:44     ` Simon Wunderlich
2013-06-12 20:33       ` Linus Lüssing
2013-06-10  6:28 Linus Lüssing
2013-06-10  7:06 ` Linus Lüssing
2013-05-24  8:02 Linus Lüssing
2013-05-24  9:00 ` Linus Lüssing
2013-05-24  9:06   ` Antonio Quartulli
2013-05-24  9:33 ` Marek Lindner
2013-05-11 17:23 Linus Lüssing
2013-05-16 11:51 ` Simon Wunderlich
2013-05-16 17:42   ` Linus Lüssing
2013-05-16 18:31     ` Simon Wunderlich
2013-05-17  1:38       ` Linus Lüssing
2013-05-17 10:24         ` Simon Wunderlich

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.