b.a.t.m.a.n.lists.open-mesh.org archive mirror
 help / color / mirror / Atom feed
* [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2
@ 2016-01-16  8:39 Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 01/12] batman-adv: Add hard_iface specific sysfs wrapper macros for UINT Marek Lindner
                   ` (12 more replies)
  0 siblings, 13 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:39 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

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

Hi,

after several rounds of code & documentation reviews a number of improvements 
found their way into the patchset. The changelog is as follows:

v2:

 - rebroadcast packet immediately after best neighbor timeout
 - add a flag to avoid forwarding the same OGMs multiple times
 - move TVLV processing out of update_route() and into 
batadv_v_ogm_process_per_outif()
 - code comments improvements (typ0s, clarifications, etc)
 - mark OGM packet as new when protection window is started
 - remove redundant throughput checks
 - simplify/fix best neighbor check


Happy routing,
The B.A.T.M.A.N. team

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

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

* [B.A.T.M.A.N.] [PATCH v2 01/12] batman-adv: Add hard_iface specific sysfs wrapper macros for UINT
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
@ 2016-01-16  8:40 ` Marek Lindner
  2016-01-19 15:08   ` Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 02/12] batman-adv: ELP - adding basic infrastructure Marek Lindner
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:40 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner, Antonio Quartulli

From: Linus Luessing <linus.luessing@web.de>

This allows us to easily add a sysfs parameter for an
unsigned int later, which is not for a batman mesh interface
(e.g. bat0), but for a common interface instead. It allows
reading and writing an atomic_t in hard_iface (instead of
bat_priv compared to the mesh variant).

Developed by Linus during a 6 months trainee study period in
Ascom (Switzerland) AG.

Signed-off-by: Linus Luessing <linus.luessing@web.de>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
[antonio@open-mesh.com: rename functions and move macros]
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 net/batman-adv/sysfs.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index 4d70d44..d3f69d5 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -242,6 +242,55 @@ ssize_t batadv_show_vlan_##_name(struct kobject *kobj,			\
 	static BATADV_ATTR_VLAN(_name, _mode, batadv_show_vlan_##_name,	\
 				batadv_store_vlan_##_name)
 
+#define BATADV_ATTR_HIF_STORE_UINT(_name, _var, _min, _max, _post_func)	\
+ssize_t batadv_store_##_name(struct kobject *kobj,			\
+			     struct attribute *attr, char *buff,	\
+			     size_t count)				\
+{									\
+	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);	\
+	struct batadv_hard_iface *hard_iface;				\
+	ssize_t length;							\
+									\
+	hard_iface = batadv_hardif_get_by_netdev(net_dev);		\
+	if (!hard_iface)						\
+		return 0;						\
+									\
+	length = __batadv_store_uint_attr(buff, count, _min, _max,	\
+					  _post_func, attr,		\
+					  &hard_iface->_var, net_dev);	\
+									\
+	batadv_hardif_put(hard_iface);				\
+	return length;							\
+}
+
+#define BATADV_ATTR_HIF_SHOW_UINT(_name, _var)				\
+ssize_t batadv_show_##_name(struct kobject *kobj,			\
+			    struct attribute *attr, char *buff)		\
+{									\
+	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);	\
+	struct batadv_hard_iface *hard_iface;				\
+	ssize_t length;							\
+									\
+	hard_iface = batadv_hardif_get_by_netdev(net_dev);		\
+	if (!hard_iface)						\
+		return 0;						\
+									\
+	length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_var));	\
+									\
+	batadv_hardif_put(hard_iface);				\
+	return length;							\
+}
+
+/* Use this, if you are going to set [name] in hard_iface to an
+ * unsigned integer value
+ */
+#define BATADV_ATTR_HIF_UINT(_name, _var, _mode, _min, _max, _post_func)\
+	static BATADV_ATTR_HIF_STORE_UINT(_name, _var, _min,		\
+					  _max, _post_func)		\
+	static BATADV_ATTR_HIF_SHOW_UINT(_name, _var)			\
+	static BATADV_ATTR(_name, _mode, batadv_show_##_name,		\
+			   batadv_store_##_name)
+
 static int batadv_store_bool_attr(char *buff, size_t count,
 				  struct net_device *net_dev,
 				  const char *attr_name, atomic_t *attr,
-- 
2.7.0.rc3


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

* [B.A.T.M.A.N.] [PATCH v2 02/12] batman-adv: ELP - adding basic infrastructure
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 01/12] batman-adv: Add hard_iface specific sysfs wrapper macros for UINT Marek Lindner
@ 2016-01-16  8:40 ` Marek Lindner
  2016-01-19 15:10   ` Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 03/12] batman-adv: ELP - creating neighbor structures Marek Lindner
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:40 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner, Antonio Quartulli

From: Linus Luessing <linus.luessing@web.de>

The B.A.T.M.A.N. protocol originally only used a single
message type (called OGM) to determine the link qualities to
the direct neighbors and spreading these link quality
information through the whole mesh. This procedure is
summarized on the BATMAN concept page and explained in
details in the RFC draft published in 2008.

This approach was chosen for its simplicity during the
protocol design phase and the implementation. However, it
also bears some drawbacks:

 *  Wireless interfaces usually come with some packet loss,
    therefore a higher broadcast rate is desirable to allow
    a fast reaction on flaky connections.
    Other interfaces of the same host might be connected to
    Ethernet LANs / VPNs / etc which rarely exhibit packet
    loss would benefit from a lower broadcast rate to reduce
    overhead.
 *  It generally is more desirable to detect local link
    quality changes at a faster rate than propagating all
    these changes through the entire mesh (the far end of
    the mesh does not need to care about local link quality
    changes that much). Other optimizations strategies, like
    reducing overhead, might be possible if OGMs weren't
    used for all tasks in the mesh at the same time.

As a result detecting local link qualities shall be handled
by an independent message type, ELP, whereas the OGM message
type remains responsible for flooding the mesh with these
link quality information and determining the overall path
transmit qualities.

Developed by Linus during a 6 months trainee study period in
Ascom (Switzerland) AG.

Signed-off-by: Linus Luessing <linus.luessing@web.de>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 Makefile                   |   3 +
 README.external            |   1 +
 gen-compat-autoconf.sh     |   1 +
 net/batman-adv/Kconfig     |  14 ++++
 net/batman-adv/Makefile    |   2 +
 net/batman-adv/bat_algo.h  |  15 +++-
 net/batman-adv/bat_v.c     |  74 +++++++++++++++++
 net/batman-adv/bat_v_elp.c | 193 +++++++++++++++++++++++++++++++++++++++++++++
 net/batman-adv/bat_v_elp.h |  27 +++++++
 net/batman-adv/main.c      |   1 +
 net/batman-adv/packet.h    |  20 +++++
 net/batman-adv/types.h     |  18 +++++
 12 files changed, 368 insertions(+), 1 deletion(-)
 create mode 100644 net/batman-adv/bat_v.c
 create mode 100644 net/batman-adv/bat_v_elp.c
 create mode 100644 net/batman-adv/bat_v_elp.h

diff --git a/Makefile b/Makefile
index 5865f89..5d2c058 100644
--- a/Makefile
+++ b/Makefile
@@ -27,6 +27,8 @@ export CONFIG_BATMAN_ADV_DAT=y
 export CONFIG_BATMAN_ADV_NC=n
 # B.A.T.M.A.N. multicast optimizations:
 export CONFIG_BATMAN_ADV_MCAST=y
+# B.A.T.M.A.N. V routing algorithm (experimental):
+export CONFIG_BATMAN_ADV_BATMAN_V=n
 
 PWD:=$(shell pwd)
 KERNELPATH ?= /lib/modules/$(shell uname -r)/build
@@ -58,6 +60,7 @@ BUILD_FLAGS := \
 	CONFIG_BATMAN_ADV_DAT=$(CONFIG_BATMAN_ADV_DAT) \
 	CONFIG_BATMAN_ADV_NC=$(CONFIG_BATMAN_ADV_NC) \
 	CONFIG_BATMAN_ADV_MCAST=$(CONFIG_BATMAN_ADV_MCAST) \
+	CONFIG_BATMAN_ADV_BATMAN_V=$(CONFIG_BATMAN_ADV_BATMAN_V) \
 	INSTALL_MOD_DIR=updates/net/batman-adv/
 
 all: config
diff --git a/README.external b/README.external
index 9793c11..963343e 100644
--- a/README.external
+++ b/README.external
@@ -40,6 +40,7 @@ module).  Available  options  and  their    possible   values are
  * CONFIG_BATMAN_ADV_DAT=[y*|n] (B.A.T.M.A.N. Distributed ARP Table)
  * CONFIG_BATMAN_ADV_MCAST=[y*|n] (B.A.T.M.A.N. multicast optimizations)
  * CONFIG_BATMAN_ADV_NC=[y|n*] (B.A.T.M.A.N. Network Coding)
+ * CONFIG_BATMAN_ADV_BATMAN_V=[y|n*] (B.A.T.M.A.N. V routing algorithm)
 
 e.g., debugging can be enabled by
 
diff --git a/gen-compat-autoconf.sh b/gen-compat-autoconf.sh
index 5a9a4e4..396357a 100755
--- a/gen-compat-autoconf.sh
+++ b/gen-compat-autoconf.sh
@@ -41,6 +41,7 @@ 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}"
+gen_config 'CONFIG_BATMAN_ADV_BATMAN_V' ${CONFIG_BATMAN_ADV_BATMAN_V:="n"} >> "${TMP}"
 
 # only regenerate compat-autoconf.h when config was changed
 diff "${TMP}" "${TARGET}" > /dev/null 2>&1 || cp "${TMP}" "${TARGET}"
diff --git a/net/batman-adv/Kconfig b/net/batman-adv/Kconfig
index 2dd40e5..5c148a8 100644
--- a/net/batman-adv/Kconfig
+++ b/net/batman-adv/Kconfig
@@ -15,6 +15,20 @@ config BATMAN_ADV
           https://www.open-mesh.org/ for more information and user space
           tools.
 
+config BATMAN_ADV_BATMAN_V
+	bool "B.A.T.M.A.N. V protocol (experimental)"
+	depends on BATMAN_ADV
+	default n
+	help
+	  This option enables the B.A.T.M.A.N. V protocol, the successor
+	  of the currently used B.A.T.M.A.N. IV protocol. The main
+	  changes include splitting of the OGM protocol into a neighbor
+	  discovery protocol (Echo Location Protocol, ELP) and a new OGM
+	  Protocol OGMv2 for flooding protocol information through the
+	  network, as well as a throughput based metric.
+	  B.A.T.M.A.N. V is currently considered experimental and not
+	  compatible to B.A.T.M.A.N. IV networks.
+
 config BATMAN_ADV_BLA
 	bool "Bridge Loop Avoidance"
 	depends on BATMAN_ADV && INET
diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile
index 207e2af..ca51686 100644
--- a/net/batman-adv/Makefile
+++ b/net/batman-adv/Makefile
@@ -18,6 +18,8 @@
 
 obj-$(CONFIG_BATMAN_ADV) += batman-adv.o
 batman-adv-y += bat_iv_ogm.o
+batman-adv-$(CONFIG_BATMAN_ADV_BATMAN_V) += bat_v.o
+batman-adv-$(CONFIG_BATMAN_ADV_BATMAN_V) += bat_v_elp.o
 batman-adv-y += bitarray.o
 batman-adv-$(CONFIG_BATMAN_ADV_BLA) += bridge_loop_avoidance.o
 batman-adv-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h
index a7485d6..a4e994e 100644
--- a/net/batman-adv/bat_algo.h
+++ b/net/batman-adv/bat_algo.h
@@ -1,6 +1,6 @@
 /* Copyright (C) 2011-2016  B.A.T.M.A.N. contributors:
  *
- * Marek Lindner
+ * Marek Lindner, 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
@@ -20,4 +20,17 @@
 
 int batadv_iv_init(void);
 
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+
+int batadv_v_init(void);
+
+#else
+
+static inline int batadv_v_init(void)
+{
+	return 0;
+}
+
+#endif /* CONFIG_BATMAN_ADV_BATMAN_V */
+
 #endif /* _NET_BATMAN_ADV_BAT_ALGO_H_ */
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
new file mode 100644
index 0000000..01327f6
--- /dev/null
+++ b/net/batman-adv/bat_v.c
@@ -0,0 +1,74 @@
+/* Copyright (C) 2013-2016 B.A.T.M.A.N. contributors:
+ *
+ * Linus Lüssing, Marek Lindner
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bat_algo.h"
+#include "main.h"
+
+#include <linux/cache.h>
+#include <linux/init.h>
+
+#include "bat_v_elp.h"
+
+static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface)
+{
+	return batadv_v_elp_iface_enable(hard_iface);
+}
+
+static void batadv_v_iface_disable(struct batadv_hard_iface *hard_iface)
+{
+	batadv_v_elp_iface_disable(hard_iface);
+}
+
+static void batadv_v_iface_update_mac(struct batadv_hard_iface *hard_iface)
+{
+}
+
+static void batadv_v_primary_iface_set(struct batadv_hard_iface *hard_iface)
+{
+	batadv_v_elp_primary_iface_set(hard_iface);
+}
+
+static void batadv_v_ogm_schedule(struct batadv_hard_iface *hard_iface)
+{
+}
+
+static void batadv_v_ogm_emit(struct batadv_forw_packet *forw_packet)
+{
+}
+
+static struct batadv_algo_ops batadv_batman_v __read_mostly = {
+	.name = "BATMAN_V",
+	.bat_iface_enable = batadv_v_iface_enable,
+	.bat_iface_disable = batadv_v_iface_disable,
+	.bat_iface_update_mac = batadv_v_iface_update_mac,
+	.bat_primary_iface_set = batadv_v_primary_iface_set,
+	.bat_ogm_emit = batadv_v_ogm_emit,
+	.bat_ogm_schedule = batadv_v_ogm_schedule,
+};
+
+/**
+ * batadv_v_init - B.A.T.M.A.N. V initialization function
+ *
+ * Description: Takes care of initializing all the subcomponents.
+ * It is invoked upon module load only.
+ *
+ * Return: 0 on success or a negative error code otherwise
+ */
+int __init batadv_v_init(void)
+{
+	return batadv_algo_register(&batadv_batman_v);
+}
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
new file mode 100644
index 0000000..bc6e046
--- /dev/null
+++ b/net/batman-adv/bat_v_elp.c
@@ -0,0 +1,193 @@
+/* Copyright (C) 2011-2016 B.A.T.M.A.N. contributors:
+ *
+ * Linus Lüssing, Marek Lindner
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bat_v_elp.h"
+#include "main.h"
+
+#include <linux/atomic.h>
+#include <linux/byteorder/generic.h>
+#include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/fs.h>
+#include <linux/if_ether.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/random.h>
+#include <linux/rculist.h>
+#include <linux/rcupdate.h>
+#include <linux/skbuff.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+#include "bat_algo.h"
+#include "hard-interface.h"
+#include "packet.h"
+#include "send.h"
+
+/**
+ * batadv_v_elp_start_timer - restart timer for ELP periodic work
+ * @hard_iface: the interface for which the timer has to be reset
+ */
+static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface)
+{
+	unsigned int msecs;
+
+	msecs = atomic_read(&hard_iface->bat_v.elp_interval) - BATADV_JITTER;
+	msecs += prandom_u32() % (2 * BATADV_JITTER);
+
+	queue_delayed_work(batadv_event_workqueue, &hard_iface->bat_v.elp_wq,
+			   msecs_to_jiffies(msecs));
+}
+
+/**
+ * batadv_v_elp_periodic_work - ELP periodic task per interface
+ * @work: work queue item
+ *
+ * Emits broadcast ELP message in regular intervals.
+ */
+static void batadv_v_elp_periodic_work(struct work_struct *work)
+{
+	struct batadv_hard_iface *hard_iface;
+	struct batadv_hard_iface_bat_v *bat_v;
+	struct batadv_elp_packet *elp_packet;
+	struct batadv_priv *bat_priv;
+	struct sk_buff *skb;
+	u32 elp_interval;
+
+	bat_v = container_of(work, struct batadv_hard_iface_bat_v, elp_wq.work);
+	hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v);
+	bat_priv = netdev_priv(hard_iface->soft_iface);
+
+	if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
+		goto out;
+
+	/* we are in the process of shutting this interface down */
+	if ((hard_iface->if_status == BATADV_IF_NOT_IN_USE) ||
+	    (hard_iface->if_status == BATADV_IF_TO_BE_REMOVED))
+		goto out;
+
+	/* the interface was enabled but may not be ready yet */
+	if (hard_iface->if_status != BATADV_IF_ACTIVE)
+		goto restart_timer;
+
+	skb = skb_copy(hard_iface->bat_v.elp_skb, GFP_ATOMIC);
+	if (!skb)
+		goto restart_timer;
+
+	elp_packet = (struct batadv_elp_packet *)skb->data;
+	elp_packet->seqno = htonl(atomic_read(&hard_iface->bat_v.elp_seqno));
+	elp_interval = atomic_read(&hard_iface->bat_v.elp_interval);
+	elp_packet->elp_interval = htonl(elp_interval);
+
+	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+		   "Sending broadcast ELP packet on interface %s, seqno %u\n",
+		   hard_iface->net_dev->name,
+		   atomic_read(&hard_iface->bat_v.elp_seqno));
+
+	batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr);
+
+	atomic_inc(&hard_iface->bat_v.elp_seqno);
+
+restart_timer:
+	batadv_v_elp_start_timer(hard_iface);
+out:
+	return;
+}
+
+/**
+ * batadv_v_elp_iface_enable - setup the ELP interface private resources
+ * @hard_iface: interface for which the data has to be prepared
+ *
+ * Return: 0 on success or a -ENOMEM in case of failure.
+ */
+int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface)
+{
+	struct batadv_elp_packet *elp_packet;
+	unsigned char *elp_buff;
+	u32 random_seqno;
+	size_t size;
+	int res = -ENOMEM;
+
+	size = ETH_HLEN + NET_IP_ALIGN + BATADV_ELP_HLEN;
+	hard_iface->bat_v.elp_skb = dev_alloc_skb(size);
+	if (!hard_iface->bat_v.elp_skb)
+		goto out;
+
+	skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN);
+	elp_buff = skb_push(hard_iface->bat_v.elp_skb, BATADV_ELP_HLEN);
+	elp_packet = (struct batadv_elp_packet *)elp_buff;
+	memset(elp_packet, 0, BATADV_ELP_HLEN);
+
+	elp_packet->packet_type = BATADV_ELP;
+	elp_packet->version = BATADV_COMPAT_VERSION;
+
+	/* randomize initial seqno to avoid collision */
+	get_random_bytes(&random_seqno, sizeof(random_seqno));
+	atomic_set(&hard_iface->bat_v.elp_seqno, random_seqno);
+	atomic_set(&hard_iface->bat_v.elp_interval, 500);
+
+	INIT_DELAYED_WORK(&hard_iface->bat_v.elp_wq,
+			  batadv_v_elp_periodic_work);
+	batadv_v_elp_start_timer(hard_iface);
+	res = 0;
+
+out:
+	return res;
+}
+
+/**
+ * batadv_v_elp_iface_disable - release ELP interface private resources
+ * @hard_iface: interface for which the resources have to be released
+ */
+void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface)
+{
+	cancel_delayed_work_sync(&hard_iface->bat_v.elp_wq);
+
+	dev_kfree_skb(hard_iface->bat_v.elp_skb);
+	hard_iface->bat_v.elp_skb = NULL;
+}
+
+/**
+ * batadv_v_elp_primary_iface_set - change internal data to reflect the new
+ *  primary interface
+ * @primary_iface: the new primary interface
+ */
+void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface)
+{
+	struct batadv_hard_iface *hard_iface;
+	struct batadv_elp_packet *elp_packet;
+	struct sk_buff *skb;
+
+	/* update orig field of every elp iface belonging to this mesh */
+	rcu_read_lock();
+	list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
+		if (primary_iface->soft_iface != hard_iface->soft_iface)
+			continue;
+
+		if (!hard_iface->bat_v.elp_skb)
+			continue;
+
+		skb = hard_iface->bat_v.elp_skb;
+		elp_packet = (struct batadv_elp_packet *)skb->data;
+		ether_addr_copy(elp_packet->orig,
+				primary_iface->net_dev->dev_addr);
+	}
+	rcu_read_unlock();
+}
diff --git a/net/batman-adv/bat_v_elp.h b/net/batman-adv/bat_v_elp.h
new file mode 100644
index 0000000..7a584d1
--- /dev/null
+++ b/net/batman-adv/bat_v_elp.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 2013-2016 B.A.T.M.A.N. contributors:
+ *
+ * Linus Lüssing, Marek Lindner
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "main.h"
+
+#ifndef _NET_BATMAN_ADV_BAT_V_ELP_H_
+#define _NET_BATMAN_ADV_BAT_V_ELP_H_
+
+int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface);
+void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface);
+void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface);
+
+#endif /* _NET_BATMAN_ADV_BAT_V_ELP_H_ */
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index e3d7051..2160572 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -87,6 +87,7 @@ static int __init batadv_init(void)
 
 	batadv_recv_handler_init();
 
+	batadv_v_init();
 	batadv_iv_init();
 	batadv_nc_init();
 
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index e7f9151..c698b64 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -26,6 +26,7 @@
  * @BATADV_IV_OGM: originator messages for B.A.T.M.A.N. IV
  * @BATADV_BCAST: broadcast packets carrying broadcast payload
  * @BATADV_CODED: network coded packets
+ * @BATADV_ELP: echo location packets for B.A.T.M.A.N. V
  *
  * @BATADV_UNICAST: unicast packets carrying unicast payload traffic
  * @BATADV_UNICAST_FRAG: unicast packets carrying a fragment of the original
@@ -40,6 +41,7 @@ enum batadv_packettype {
 	BATADV_IV_OGM           = 0x00,
 	BATADV_BCAST            = 0x01,
 	BATADV_CODED            = 0x02,
+	BATADV_ELP		= 0x03,
 	/* 0x40 - 0x7f: unicast */
 #define BATADV_UNICAST_MIN     0x40
 	BATADV_UNICAST          = 0x40,
@@ -235,6 +237,24 @@ struct batadv_ogm_packet {
 #define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet)
 
 /**
+ * struct batadv_elp_packet - elp (neighbor discovery) packet
+ * @packet_type: batman-adv packet type, part of the general header
+ * @version: batman-adv protocol version, part of the genereal header
+ * @orig: originator mac address
+ * @seqno: sequence number
+ * @elp_interval: currently used ELP sending interval in ms
+ */
+struct batadv_elp_packet {
+	u8     packet_type;
+	u8     version;
+	u8     orig[ETH_ALEN];
+	__be32 seqno;
+	__be32 elp_interval;
+};
+
+#define BATADV_ELP_HLEN sizeof(struct batadv_elp_packet)
+
+/**
  * struct batadv_icmp_header - common members among all the ICMP packets
  * @packet_type: batman-adv packet type, part of the general header
  * @version: batman-adv protocol version, part of the genereal header
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 612de23..992d5fd 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -86,6 +86,20 @@ struct batadv_hard_iface_bat_iv {
 };
 
 /**
+ * struct batadv_hard_iface_bat_v - per hard-interface B.A.T.M.A.N. V data
+ * @elp_interval: time interval between two ELP transmissions
+ * @elp_seqno: current ELP sequence number
+ * @elp_skb: base skb containing the ELP message to send
+ * @elp_wq: workqueue used to schedule ELP transmissions
+ */
+struct batadv_hard_iface_bat_v {
+	atomic_t elp_interval;
+	atomic_t elp_seqno;
+	struct sk_buff *elp_skb;
+	struct delayed_work elp_wq;
+};
+
+/**
  * struct batadv_hard_iface - network device known to batman-adv
  * @list: list node for batadv_hardif_list
  * @if_num: identificator of the interface
@@ -99,6 +113,7 @@ struct batadv_hard_iface_bat_iv {
  * @soft_iface: the batman-adv interface which uses this network interface
  * @rcu: struct used for freeing in an RCU-safe manner
  * @bat_iv: per hard-interface B.A.T.M.A.N. IV data
+ * @bat_v: per hard-interface B.A.T.M.A.N. V data
  * @cleanup_work: work queue callback item for hard-interface deinit
  * @debug_dir: dentry for nc subdir in batman-adv directory in debugfs
  * @neigh_list: list of unique single hop neighbors via this interface
@@ -116,6 +131,9 @@ struct batadv_hard_iface {
 	struct net_device *soft_iface;
 	struct rcu_head rcu;
 	struct batadv_hard_iface_bat_iv bat_iv;
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+	struct batadv_hard_iface_bat_v bat_v;
+#endif
 	struct work_struct cleanup_work;
 	struct dentry *debug_dir;
 	struct hlist_head neigh_list;
-- 
2.7.0.rc3


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

* [B.A.T.M.A.N.] [PATCH v2 03/12] batman-adv: ELP - creating neighbor structures
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 01/12] batman-adv: Add hard_iface specific sysfs wrapper macros for UINT Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 02/12] batman-adv: ELP - adding basic infrastructure Marek Lindner
@ 2016-01-16  8:40 ` Marek Lindner
  2016-01-19 15:11   ` Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 04/12] batman-adv: ELP - adding sysfs parameter for elp interval Marek Lindner
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:40 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner, Antonio Quartulli

From: Linus Luessing <linus.luessing@web.de>

Initially developed by Linus during a 6 months trainee study
period in Ascom (Switzerland) AG.

Signed-off-by: Linus Luessing <linus.luessing@web.de>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 compat-include/linux/average.h |  74 ++++++++++++++++++++
 net/batman-adv/bat_v.c         |  23 ++++++-
 net/batman-adv/bat_v_elp.c     | 152 +++++++++++++++++++++++++++++++++++++++++
 net/batman-adv/bat_v_elp.h     |   4 ++
 net/batman-adv/main.h          |   3 +
 net/batman-adv/types.h         |  33 +++++++++
 6 files changed, 288 insertions(+), 1 deletion(-)
 create mode 100644 compat-include/linux/average.h

diff --git a/compat-include/linux/average.h b/compat-include/linux/average.h
new file mode 100644
index 0000000..e5a2bf5
--- /dev/null
+++ b/compat-include/linux/average.h
@@ -0,0 +1,74 @@
+/* Copyright (C) 2007-2016 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * This file contains macros for maintaining compatibility with older versions
+ * of the Linux kernel.
+ */
+
+#ifndef _NET_BATMAN_ADV_COMPAT_LINUX_AVERAGE_H
+#define _NET_BATMAN_ADV_COMPAT_LINUX_AVERAGE_H
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+#include_next <linux/average.h>
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
+
+/* Exponentially weighted moving average (EWMA) */
+
+#define DECLARE_EWMA(name, _factor, _weight)				\
+	struct ewma_##name {						\
+		unsigned long internal;					\
+	};								\
+	static inline void ewma_##name##_init(struct ewma_##name *e)	\
+	{								\
+		BUILD_BUG_ON(!__builtin_constant_p(_factor));		\
+		BUILD_BUG_ON(!__builtin_constant_p(_weight));		\
+		BUILD_BUG_ON_NOT_POWER_OF_2(_factor);			\
+		BUILD_BUG_ON_NOT_POWER_OF_2(_weight);			\
+		e->internal = 0;					\
+	}								\
+	static inline unsigned long					\
+	ewma_##name##_read(struct ewma_##name *e)			\
+	{								\
+		BUILD_BUG_ON(!__builtin_constant_p(_factor));		\
+		BUILD_BUG_ON(!__builtin_constant_p(_weight));		\
+		BUILD_BUG_ON_NOT_POWER_OF_2(_factor);			\
+		BUILD_BUG_ON_NOT_POWER_OF_2(_weight);			\
+		return e->internal >> ilog2(_factor);			\
+	}								\
+	static inline void ewma_##name##_add(struct ewma_##name *e,	\
+					     unsigned long val)		\
+	{								\
+		unsigned long internal = ACCESS_ONCE(e->internal);	\
+		unsigned long weight = ilog2(_weight);			\
+		unsigned long factor = ilog2(_factor);			\
+									\
+		BUILD_BUG_ON(!__builtin_constant_p(_factor));		\
+		BUILD_BUG_ON(!__builtin_constant_p(_weight));		\
+		BUILD_BUG_ON_NOT_POWER_OF_2(_factor);			\
+		BUILD_BUG_ON_NOT_POWER_OF_2(_weight);			\
+									\
+		ACCESS_ONCE(e->internal) = internal ?			\
+			(((internal << weight) - internal) +		\
+				(val << factor)) >> weight :		\
+			(val << factor);				\
+	}
+
+#endif /* < KERNEL_VERSION(4, 3, 0) */
+
+#endif /* _NET_BATMAN_ADV_COMPAT_LINUX_AVERAGE_H */
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index 01327f6..0fea894 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 
 #include "bat_v_elp.h"
+#include "packet.h"
 
 static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface)
 {
@@ -42,6 +43,12 @@ static void batadv_v_primary_iface_set(struct batadv_hard_iface *hard_iface)
 	batadv_v_elp_primary_iface_set(hard_iface);
 }
 
+static void
+batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh)
+{
+	ewma_throughput_init(&hardif_neigh->bat_v.throughput);
+}
+
 static void batadv_v_ogm_schedule(struct batadv_hard_iface *hard_iface)
 {
 }
@@ -56,6 +63,7 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = {
 	.bat_iface_disable = batadv_v_iface_disable,
 	.bat_iface_update_mac = batadv_v_iface_update_mac,
 	.bat_primary_iface_set = batadv_v_primary_iface_set,
+	.bat_hardif_neigh_init = batadv_v_hardif_neigh_init,
 	.bat_ogm_emit = batadv_v_ogm_emit,
 	.bat_ogm_schedule = batadv_v_ogm_schedule,
 };
@@ -70,5 +78,18 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = {
  */
 int __init batadv_v_init(void)
 {
-	return batadv_algo_register(&batadv_batman_v);
+	int ret;
+
+	/* B.A.T.M.A.N. V echo location protocol packet  */
+	ret = batadv_recv_handler_register(BATADV_ELP,
+					   batadv_v_elp_packet_recv);
+	if (ret < 0)
+		return ret;
+
+	ret = batadv_algo_register(&batadv_batman_v);
+
+	if (ret < 0)
+		batadv_recv_handler_unregister(BATADV_ELP);
+
+	return ret;
 }
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index bc6e046..dac88fa 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -38,7 +38,10 @@
 
 #include "bat_algo.h"
 #include "hard-interface.h"
+#include "hash.h"
+#include "originator.h"
 #include "packet.h"
+#include "routing.h"
 #include "send.h"
 
 /**
@@ -191,3 +194,152 @@ void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface)
 	}
 	rcu_read_unlock();
 }
+
+/**
+ * batadv_v_ogm_orig_get - retrieve and possibly create an originator node
+ * @bat_priv: the bat priv with all the soft interface information
+ * @addr: the address of the originator
+ *
+ * Return: the orig_node corresponding to the specified address. If such object
+ * does not exist it is allocated here. In case of allocation failure returns
+ * NULL.
+ */
+static struct batadv_orig_node *
+batadv_v_ogm_orig_get(struct batadv_priv *bat_priv,
+		      const u8 *addr)
+{
+	struct batadv_orig_node *orig_node;
+	int hash_added;
+
+	orig_node = batadv_orig_hash_find(bat_priv, addr);
+	if (orig_node)
+		return orig_node;
+
+	orig_node = batadv_orig_node_new(bat_priv, addr);
+	if (!orig_node)
+		return NULL;
+
+	hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
+				     batadv_choose_orig, orig_node,
+				     &orig_node->hash_entry);
+	if (hash_added != 0) {
+		/* orig_node->refcounter is initialised to 2 by
+		 * batadv_orig_node_new()
+		 */
+		batadv_orig_node_put(orig_node);
+		batadv_orig_node_put(orig_node);
+		orig_node = NULL;
+	}
+
+	return orig_node;
+}
+
+/**
+ * batadv_v_elp_neigh_update - update an ELP neighbour node
+ * @bat_priv: the bat priv with all the soft interface information
+ * @neigh_addr: the neighbour interface address
+ * @if_incoming: the interface the packet was received through
+ * @elp_packet: the received ELP packet
+ *
+ * Updates the ELP neighbour node state with the data received within the new
+ * ELP packet.
+ */
+static void batadv_v_elp_neigh_update(struct batadv_priv *bat_priv,
+				      u8 *neigh_addr,
+				      struct batadv_hard_iface *if_incoming,
+				      struct batadv_elp_packet *elp_packet)
+
+{
+	struct batadv_neigh_node *neigh;
+	struct batadv_orig_node *orig_neigh;
+	struct batadv_hardif_neigh_node *hardif_neigh;
+	s32 seqno_diff;
+	s32 elp_latest_seqno;
+
+	orig_neigh = batadv_v_ogm_orig_get(bat_priv, elp_packet->orig);
+	if (!orig_neigh)
+		return;
+
+	neigh = batadv_neigh_node_new(orig_neigh, if_incoming, neigh_addr);
+	if (!neigh)
+		goto orig_free;
+
+	hardif_neigh = batadv_hardif_neigh_get(if_incoming, neigh_addr);
+	if (!hardif_neigh)
+		goto neigh_free;
+
+	elp_latest_seqno = hardif_neigh->bat_v.elp_latest_seqno;
+	seqno_diff = ntohl(elp_packet->seqno) - elp_latest_seqno;
+
+	/* known or older sequence numbers are ignored. However always adopt
+	 * if the router seems to have been restarted.
+	 */
+	if (seqno_diff < 1 && seqno_diff > -BATADV_ELP_MAX_AGE)
+		goto hardif_free;
+
+	neigh->last_seen = jiffies;
+	hardif_neigh->last_seen = jiffies;
+	hardif_neigh->bat_v.elp_latest_seqno = ntohl(elp_packet->seqno);
+	hardif_neigh->bat_v.elp_interval = ntohl(elp_packet->elp_interval);
+
+hardif_free:
+	if (hardif_neigh)
+		batadv_hardif_neigh_put(hardif_neigh);
+neigh_free:
+	if (neigh)
+		batadv_neigh_node_put(neigh);
+orig_free:
+	if (orig_neigh)
+		batadv_orig_node_put(orig_neigh);
+}
+
+/**
+ * batadv_v_elp_packet_recv - main ELP packet handler
+ * @skb: the received packet
+ * @if_incoming: the interface this packet was received through
+ *
+ * Return: NET_RX_SUCCESS and consumes the skb if the packet was peoperly
+ * processed or NET_RX_DROP in case of failure.
+ */
+int batadv_v_elp_packet_recv(struct sk_buff *skb,
+			     struct batadv_hard_iface *if_incoming)
+{
+	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+	struct batadv_elp_packet *elp_packet;
+	struct batadv_hard_iface *primary_if;
+	struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
+	bool ret;
+
+	ret = batadv_check_management_packet(skb, if_incoming, BATADV_ELP_HLEN);
+	if (!ret)
+		return NET_RX_DROP;
+
+	if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
+		return NET_RX_DROP;
+
+	/* did we receive a B.A.T.M.A.N. V ELP packet on an interface
+	 * that does not have B.A.T.M.A.N. V ELP enabled ?
+	 */
+	if (strcmp(bat_priv->bat_algo_ops->name, "BATMAN_V") != 0)
+		return NET_RX_DROP;
+
+	elp_packet = (struct batadv_elp_packet *)skb->data;
+
+	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+		   "Received ELP packet from %pM seqno %u ORIG: %pM\n",
+		   ethhdr->h_source, ntohl(elp_packet->seqno),
+		   elp_packet->orig);
+
+	primary_if = batadv_primary_if_get_selected(bat_priv);
+	if (!primary_if)
+		goto out;
+
+	batadv_v_elp_neigh_update(bat_priv, ethhdr->h_source, if_incoming,
+				  elp_packet);
+
+out:
+	if (primary_if)
+		batadv_hardif_put(primary_if);
+	consume_skb(skb);
+	return NET_RX_SUCCESS;
+}
diff --git a/net/batman-adv/bat_v_elp.h b/net/batman-adv/bat_v_elp.h
index 7a584d1..5a7bc39 100644
--- a/net/batman-adv/bat_v_elp.h
+++ b/net/batman-adv/bat_v_elp.h
@@ -20,8 +20,12 @@
 #ifndef _NET_BATMAN_ADV_BAT_V_ELP_H_
 #define _NET_BATMAN_ADV_BAT_V_ELP_H_
 
+struct sk_buff;
+
 int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface);
 void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface);
 void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface);
+int batadv_v_elp_packet_recv(struct sk_buff *skb,
+			     struct batadv_hard_iface *if_incoming);
 
 #endif /* _NET_BATMAN_ADV_BAT_V_ELP_H_ */
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 32dfc9e..aebc62b 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -60,6 +60,9 @@
 #define BATADV_TQ_LOCAL_BIDRECT_RECV_MINIMUM 1
 #define BATADV_TQ_TOTAL_BIDRECT_LIMIT 1
 
+/* B.A.T.M.A.N. V */
+#define BATADV_ELP_MAX_AGE 64
+
 /* number of OGMs sent with the last tt diff */
 #define BATADV_TT_OGM_APPEND_MAX 3
 
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 992d5fd..7fc82a5 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -22,6 +22,7 @@
 #error only "main.h" can be included directly
 #endif
 
+#include <linux/average.h>
 #include <linux/bitops.h>
 #include <linux/compiler.h>
 #include <linux/if_ether.h>
@@ -364,12 +365,28 @@ struct batadv_gw_node {
 	struct rcu_head rcu;
 };
 
+DECLARE_EWMA(throughput, 1024, 8)
+
+/**
+ * struct batadv_hardif_neigh_node_bat_v - B.A.T.M.A.N. V private neighbor
+ *  information
+ * @throughput: ewma link throughput towards this neighbor
+ * @elp_interval: time interval between two ELP transmissions
+ * @elp_latest_seqno: latest and best known ELP sequence number
+ */
+struct batadv_hardif_neigh_node_bat_v {
+	struct ewma_throughput throughput;
+	u32 elp_interval;
+	u32 elp_latest_seqno;
+};
+
 /**
  * struct batadv_hardif_neigh_node - unique neighbor per hard-interface
  * @list: list node for batadv_hard_iface::neigh_list
  * @addr: the MAC address of the neighboring interface
  * @if_incoming: pointer to incoming hard-interface
  * @last_seen: when last packet via this neighbor was received
+ * @bat_v: B.A.T.M.A.N. V private data
  * @refcount: number of contexts the object is used
  * @rcu: struct used for freeing in a RCU-safe manner
  */
@@ -378,6 +395,9 @@ struct batadv_hardif_neigh_node {
 	u8 addr[ETH_ALEN];
 	struct batadv_hard_iface *if_incoming;
 	unsigned long last_seen;
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+	struct batadv_hardif_neigh_node_bat_v bat_v;
+#endif
 	struct kref refcount;
 	struct rcu_head rcu;
 };
@@ -425,10 +445,20 @@ struct batadv_neigh_ifinfo_bat_iv {
 };
 
 /**
+ * struct batadv_neigh_ifinfo_bat_v - neighbor information per outgoing
+ *  interface for B.A.T.M.A.N. V
+ * @throughput: last throughput metric received from originator via this neigh
+ */
+struct batadv_neigh_ifinfo_bat_v {
+	u32 throughput;
+};
+
+/**
  * struct batadv_neigh_ifinfo - neighbor information per outgoing interface
  * @list: list node for batadv_neigh_node::ifinfo_list
  * @if_outgoing: pointer to outgoing hard-interface
  * @bat_iv: B.A.T.M.A.N. IV private structure
+ * @bat_v: B.A.T.M.A.N. V private data
  * @last_ttl: last received ttl from this neigh node
  * @refcount: number of contexts the object is used
  * @rcu: struct used for freeing in a RCU-safe manner
@@ -437,6 +467,9 @@ struct batadv_neigh_ifinfo {
 	struct hlist_node list;
 	struct batadv_hard_iface *if_outgoing;
 	struct batadv_neigh_ifinfo_bat_iv bat_iv;
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+	struct batadv_neigh_ifinfo_bat_v bat_v;
+#endif
 	u8 last_ttl;
 	struct kref refcount;
 	struct rcu_head rcu;
-- 
2.7.0.rc3


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

* [B.A.T.M.A.N.] [PATCH v2 04/12] batman-adv: ELP - adding sysfs parameter for elp interval
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
                   ` (2 preceding siblings ...)
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 03/12] batman-adv: ELP - creating neighbor structures Marek Lindner
@ 2016-01-16  8:40 ` Marek Lindner
  2016-01-19 15:12   ` Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 05/12] batman-adv: OGMv2 - add basic infrastructure Marek Lindner
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:40 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner, Antonio Quartulli

From: Linus Luessing <linus.luessing@web.de>

This parameter can be set individually on each interface and
allows the configuration of the elp interval for the link
quality measurements during runtime. Usually it is desirable
to set it to a higher (= slower) value on interfaces which
have a more static characteristic (e.g. wired interfaces)
or very dense neighbourhoods to reduce overhead.

Developed by Linus during a 6 months trainee study period in
Ascom (Switzerland) AG.

Signed-off-by: Linus Luessing <linus.luessing@web.de>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
[antonio@open-mesh.com: respin on top of the latest master]
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 Documentation/ABI/testing/sysfs-class-net-batman-adv | 8 +++++++-
 net/batman-adv/sysfs.c                               | 7 +++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-class-net-batman-adv b/Documentation/ABI/testing/sysfs-class-net-batman-adv
index 7f34a95..aea78db 100644
--- a/Documentation/ABI/testing/sysfs-class-net-batman-adv
+++ b/Documentation/ABI/testing/sysfs-class-net-batman-adv
@@ -1,4 +1,11 @@
 
+What:           /sys/class/net/<iface>/batman-adv/elp_interval
+Date:           Feb 2014
+Contact:        Linus Lüssing <linus.luessing@web.de>
+Description:
+                Defines the interval in milliseconds in which batman
+                sends its probing packets for link quality measurements.
+
 What:           /sys/class/net/<iface>/batman-adv/iface_status
 Date:           May 2010
 Contact:        Marek Lindner <mareklindner@neomailbox.ch>
@@ -12,4 +19,3 @@ Description:
                 The /sys/class/net/<iface>/batman-adv/mesh_iface file
                 displays the batman mesh interface this <iface>
                 currently is associated with.
-
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index d3f69d5..e860143 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -920,10 +920,17 @@ static ssize_t batadv_show_iface_status(struct kobject *kobj,
 static BATADV_ATTR(mesh_iface, S_IRUGO | S_IWUSR, batadv_show_mesh_iface,
 		   batadv_store_mesh_iface);
 static BATADV_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL);
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+BATADV_ATTR_HIF_UINT(elp_interval, bat_v.elp_interval, S_IRUGO | S_IWUSR,
+		     2 * BATADV_JITTER, INT_MAX, NULL);
+#endif
 
 static struct batadv_attribute *batadv_batman_attrs[] = {
 	&batadv_attr_mesh_iface,
 	&batadv_attr_iface_status,
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+	&batadv_attr_elp_interval,
+#endif
 	NULL,
 };
 
-- 
2.7.0.rc3


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

* [B.A.T.M.A.N.] [PATCH v2 05/12] batman-adv: OGMv2 - add basic infrastructure
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
                   ` (3 preceding siblings ...)
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 04/12] batman-adv: ELP - adding sysfs parameter for elp interval Marek Lindner
@ 2016-01-16  8:40 ` Marek Lindner
  2016-01-19 15:14   ` Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 06/12] batman-adv: OGMv2 - implement originators logic Marek Lindner
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:40 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

From: Antonio Quartulli <antonio@open-mesh.com>

This is the initial implementation of the new OGM protocol
(version 2). It has been designed to work on top of the
newly added ELP.

In the previous version the OGM protocol was used to both
measure link qualities and flood the network with the metric
information. In this version the protocol is in charge of
the latter task only, leaving the former to ELP.

This means being able to decouple the interval used by the
neighbor discovery from the OGM broadcasting, which revealed
to be costly in dense networks and needed to be relaxed so
leading to a less responsive routing protocol.

Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 net/batman-adv/Makefile    |   1 +
 net/batman-adv/bat_algo.h  |  13 +++
 net/batman-adv/bat_v.c     |  51 ++++++++-
 net/batman-adv/bat_v_ogm.c | 279 +++++++++++++++++++++++++++++++++++++++++++++
 net/batman-adv/bat_v_ogm.h |  32 ++++++
 net/batman-adv/main.c      |   6 +
 net/batman-adv/main.h      |   1 +
 net/batman-adv/packet.h    |  29 +++++
 net/batman-adv/types.h     |  18 +++
 9 files changed, 427 insertions(+), 3 deletions(-)
 create mode 100644 net/batman-adv/bat_v_ogm.c
 create mode 100644 net/batman-adv/bat_v_ogm.h

diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile
index ca51686..797cf2f 100644
--- a/net/batman-adv/Makefile
+++ b/net/batman-adv/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_BATMAN_ADV) += batman-adv.o
 batman-adv-y += bat_iv_ogm.o
 batman-adv-$(CONFIG_BATMAN_ADV_BATMAN_V) += bat_v.o
 batman-adv-$(CONFIG_BATMAN_ADV_BATMAN_V) += bat_v_elp.o
+batman-adv-$(CONFIG_BATMAN_ADV_BATMAN_V) += bat_v_ogm.o
 batman-adv-y += bitarray.o
 batman-adv-$(CONFIG_BATMAN_ADV_BLA) += bridge_loop_avoidance.o
 batman-adv-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h
index a4e994e..03dafd3 100644
--- a/net/batman-adv/bat_algo.h
+++ b/net/batman-adv/bat_algo.h
@@ -18,11 +18,15 @@
 #ifndef _NET_BATMAN_ADV_BAT_ALGO_H_
 #define _NET_BATMAN_ADV_BAT_ALGO_H_
 
+struct batadv_priv;
+
 int batadv_iv_init(void);
 
 #ifdef CONFIG_BATMAN_ADV_BATMAN_V
 
 int batadv_v_init(void);
+int batadv_v_mesh_init(struct batadv_priv *bat_priv);
+void batadv_v_mesh_free(struct batadv_priv *bat_priv);
 
 #else
 
@@ -31,6 +35,15 @@ static inline int batadv_v_init(void)
 	return 0;
 }
 
+static inline int batadv_v_mesh_init(struct batadv_priv *bat_priv)
+{
+	return 0;
+}
+
+static inline void batadv_v_mesh_free(struct batadv_priv *bat_priv)
+{
+}
+
 #endif /* CONFIG_BATMAN_ADV_BATMAN_V */
 
 #endif /* _NET_BATMAN_ADV_BAT_ALGO_H_ */
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index 0fea894..b90a4df 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -22,11 +22,22 @@
 #include <linux/init.h>
 
 #include "bat_v_elp.h"
+#include "bat_v_ogm.h"
 #include "packet.h"
 
 static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface)
 {
-	return batadv_v_elp_iface_enable(hard_iface);
+	int ret;
+
+	ret = batadv_v_elp_iface_enable(hard_iface);
+	if (ret < 0)
+		return ret;
+
+	ret = batadv_v_ogm_iface_enable(hard_iface);
+	if (ret < 0)
+		batadv_v_elp_iface_disable(hard_iface);
+
+	return ret;
 }
 
 static void batadv_v_iface_disable(struct batadv_hard_iface *hard_iface)
@@ -41,6 +52,7 @@ static void batadv_v_iface_update_mac(struct batadv_hard_iface *hard_iface)
 static void batadv_v_primary_iface_set(struct batadv_hard_iface *hard_iface)
 {
 	batadv_v_elp_primary_iface_set(hard_iface);
+	batadv_v_ogm_primary_iface_set(hard_iface);
 }
 
 static void
@@ -69,6 +81,27 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = {
 };
 
 /**
+ * batadv_v_mesh_init - initialize the B.A.T.M.A.N. V private resources for a
+ *  mesh
+ * @bat_priv: the object representing the mesh interface to initialise
+ *
+ * Return: 0 on success or a negative error code otherwise
+ */
+int batadv_v_mesh_init(struct batadv_priv *bat_priv)
+{
+	return batadv_v_ogm_init(bat_priv);
+}
+
+/**
+ * batadv_v_mesh_free - free the B.A.T.M.A.N. V private resources for a mesh
+ * @bat_priv: the object representing the mesh interface to free
+ */
+void batadv_v_mesh_free(struct batadv_priv *bat_priv)
+{
+	batadv_v_ogm_free(bat_priv);
+}
+
+/**
  * batadv_v_init - B.A.T.M.A.N. V initialization function
  *
  * Description: Takes care of initializing all the subcomponents.
@@ -86,10 +119,22 @@ int __init batadv_v_init(void)
 	if (ret < 0)
 		return ret;
 
-	ret = batadv_algo_register(&batadv_batman_v);
+	ret = batadv_recv_handler_register(BATADV_OGM2,
+					   batadv_v_ogm_packet_recv);
+	if (ret < 0)
+		goto elp_unregister;
 
+	ret = batadv_algo_register(&batadv_batman_v);
 	if (ret < 0)
-		batadv_recv_handler_unregister(BATADV_ELP);
+		goto ogm_unregister;
+
+	return ret;
+
+ogm_unregister:
+	batadv_recv_handler_unregister(BATADV_OGM2);
+
+elp_unregister:
+	batadv_recv_handler_unregister(BATADV_ELP);
 
 	return ret;
 }
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
new file mode 100644
index 0000000..23932f9
--- /dev/null
+++ b/net/batman-adv/bat_v_ogm.c
@@ -0,0 +1,279 @@
+/* Copyright (C) 2013-2016 B.A.T.M.A.N. contributors:
+ *
+ * Antonio Quartulli
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bat_v_ogm.h"
+#include "main.h"
+
+#include <linux/atomic.h>
+#include <linux/byteorder/generic.h>
+#include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/fs.h>
+#include <linux/if_ether.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/random.h>
+#include <linux/rculist.h>
+#include <linux/rcupdate.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+#include "hard-interface.h"
+#include "packet.h"
+#include "routing.h"
+#include "send.h"
+#include "translation-table.h"
+
+/**
+ * batadv_v_ogm_start_timer - restart the OGM sending timer
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+static void batadv_v_ogm_start_timer(struct batadv_priv *bat_priv)
+{
+	unsigned long msecs;
+	/* this function may be invoked in different contexts (ogm rescheduling
+	 * or hard_iface activation), but the work timer should not be reset
+	 */
+	if (delayed_work_pending(&bat_priv->bat_v.ogm_wq))
+		return;
+
+	msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
+	msecs += prandom_u32() % (2 * BATADV_JITTER);
+	queue_delayed_work(batadv_event_workqueue, &bat_priv->bat_v.ogm_wq,
+			   msecs_to_jiffies(msecs));
+}
+
+/**
+ * batadv_v_ogm_send_to_if - send a batman ogm using a given interface
+ * @skb: the OGM to send
+ * @hard_iface: the interface to use to send the OGM
+ */
+static void batadv_v_ogm_send_to_if(struct sk_buff *skb,
+				    struct batadv_hard_iface *hard_iface)
+{
+	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+
+	if (hard_iface->if_status != BATADV_IF_ACTIVE)
+		return;
+
+	batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
+	batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
+			   skb->len + ETH_HLEN);
+
+	batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr);
+}
+
+/**
+ * batadv_v_ogm_send - periodic worker broadcasting the own OGM
+ * @work: work queue item
+ */
+static void batadv_v_ogm_send(struct work_struct *work)
+{
+	struct batadv_hard_iface *hard_iface;
+	struct batadv_priv_bat_v *bat_v;
+	struct batadv_priv *bat_priv;
+	struct batadv_ogm2_packet *ogm_packet;
+	struct sk_buff *skb, *skb_tmp;
+	unsigned char *ogm_buff, *pkt_buff;
+	int ogm_buff_len;
+	u16 tvlv_len = 0;
+
+	bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
+	bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
+
+	if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
+		goto out;
+
+	ogm_buff = bat_priv->bat_v.ogm_buff;
+	ogm_buff_len = bat_priv->bat_v.ogm_buff_len;
+	/* tt changes have to be committed before the tvlv data is
+	 * appended as it may alter the tt tvlv container
+	 */
+	batadv_tt_local_commit_changes(bat_priv);
+	tvlv_len = batadv_tvlv_container_ogm_append(bat_priv, &ogm_buff,
+						    &ogm_buff_len,
+						    BATADV_OGM2_HLEN);
+
+	bat_priv->bat_v.ogm_buff = ogm_buff;
+	bat_priv->bat_v.ogm_buff_len = ogm_buff_len;
+
+	skb = netdev_alloc_skb_ip_align(NULL, ETH_HLEN + ogm_buff_len);
+	if (!skb)
+		goto reschedule;
+
+	skb_reserve(skb, ETH_HLEN);
+	pkt_buff = skb_put(skb, ogm_buff_len);
+	memcpy(pkt_buff, ogm_buff, ogm_buff_len);
+
+	ogm_packet = (struct batadv_ogm2_packet *)skb->data;
+	ogm_packet->seqno = htonl(atomic_read(&bat_priv->bat_v.ogm_seqno));
+	atomic_inc(&bat_priv->bat_v.ogm_seqno);
+	ogm_packet->tvlv_len = htons(tvlv_len);
+
+	/* broadcast on every interface */
+	rcu_read_lock();
+	list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
+		if (hard_iface->soft_iface != bat_priv->soft_iface)
+			continue;
+
+		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+			   "Sending own OGM2 packet (originator %pM, seqno %u, throughput %u, TTL %d) on interface %s [%pM]\n",
+			   ogm_packet->orig, ntohl(ogm_packet->seqno),
+			   ntohl(ogm_packet->throughput), ogm_packet->ttl,
+			   hard_iface->net_dev->name,
+			   hard_iface->net_dev->dev_addr);
+
+		/* this skb gets consumed by batadv_v_ogm_send_to_if() */
+		skb_tmp = skb_clone(skb, GFP_ATOMIC);
+		if (!skb_tmp)
+			break;
+
+		batadv_v_ogm_send_to_if(skb_tmp, hard_iface);
+	}
+	rcu_read_unlock();
+
+	consume_skb(skb);
+
+reschedule:
+	batadv_v_ogm_start_timer(bat_priv);
+out:
+	return;
+}
+
+/**
+ * batadv_v_ogm_iface_enable - prepare an interface for B.A.T.M.A.N. V
+ * @hard_iface: the interface to prepare
+ *
+ * Takes care of scheduling own OGM sending routine for this interface.
+ *
+ * Return: 0 on success or a negative error code otherwise
+ */
+int batadv_v_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
+{
+	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+
+	batadv_v_ogm_start_timer(bat_priv);
+
+	return 0;
+}
+
+/**
+ * batadv_v_ogm_primary_iface_set - set a new primary interface
+ * @primary_iface: the new primary interface
+ */
+void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface)
+{
+	struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface);
+	struct batadv_ogm2_packet *ogm_packet;
+
+	if (!bat_priv->bat_v.ogm_buff)
+		return;
+
+	ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff;
+	ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr);
+}
+
+/**
+ * batadv_v_ogm_packet_recv - OGM2 receiving handler
+ * @skb: the received OGM
+ * @if_incoming: the interface where this OGM has been received
+ *
+ * Return: NET_RX_SUCCESS and consume the skb on success or returns NET_RX_DROP
+ * (without freeing the skb) on failure
+ */
+int batadv_v_ogm_packet_recv(struct sk_buff *skb,
+			     struct batadv_hard_iface *if_incoming)
+{
+	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+	struct batadv_ogm2_packet *ogm_packet;
+	struct ethhdr *ethhdr = eth_hdr(skb);
+
+	/* did we receive a OGM2 packet on an interface that does not have
+	 * B.A.T.M.A.N. V enabled ?
+	 */
+	if (strcmp(bat_priv->bat_algo_ops->name, "BATMAN_V") != 0)
+		return NET_RX_DROP;
+
+	if (!batadv_check_management_packet(skb, if_incoming, BATADV_OGM2_HLEN))
+		return NET_RX_DROP;
+
+	if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
+		return NET_RX_DROP;
+
+	ogm_packet = (struct batadv_ogm2_packet *)skb->data;
+
+	if (batadv_is_my_mac(bat_priv, ogm_packet->orig))
+		return NET_RX_DROP;
+
+	batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
+	batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
+			   skb->len + ETH_HLEN);
+
+	consume_skb(skb);
+	return NET_RX_SUCCESS;
+}
+
+/**
+ * batadv_v_ogm_init - initialise the OGM2 engine
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Return: 0 on success or a negative error code in case of failure
+ */
+int batadv_v_ogm_init(struct batadv_priv *bat_priv)
+{
+	struct batadv_ogm2_packet *ogm_packet;
+	unsigned char *ogm_buff;
+	u32 random_seqno;
+
+	bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN;
+	ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC);
+	if (!ogm_buff)
+		return -ENOMEM;
+
+	bat_priv->bat_v.ogm_buff = ogm_buff;
+	ogm_packet = (struct batadv_ogm2_packet *)ogm_buff;
+	ogm_packet->packet_type = BATADV_OGM2;
+	ogm_packet->version = BATADV_COMPAT_VERSION;
+	ogm_packet->ttl = BATADV_TTL;
+	ogm_packet->flags = BATADV_NO_FLAGS;
+	ogm_packet->throughput = htonl(BATADV_THROUGHPUT_MAX_VALUE);
+
+	/* randomize initial seqno to avoid collision */
+	get_random_bytes(&random_seqno, sizeof(random_seqno));
+	atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno);
+	INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send);
+
+	return 0;
+}
+
+/**
+ * batadv_v_ogm_free - free OGM private resources
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+void batadv_v_ogm_free(struct batadv_priv *bat_priv)
+{
+	cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq);
+
+	kfree(bat_priv->bat_v.ogm_buff);
+	bat_priv->bat_v.ogm_buff = NULL;
+	bat_priv->bat_v.ogm_buff_len = 0;
+}
diff --git a/net/batman-adv/bat_v_ogm.h b/net/batman-adv/bat_v_ogm.h
new file mode 100644
index 0000000..d9f178c
--- /dev/null
+++ b/net/batman-adv/bat_v_ogm.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 2013-2016 B.A.T.M.A.N. contributors:
+ *
+ * Antonio Quartulli
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _BATMAN_ADV_BATADV_V_OGM_H_
+#define _BATMAN_ADV_BATADV_V_OGM_H_
+
+struct batadv_hard_iface;
+struct batadv_priv;
+struct sk_buff;
+
+int batadv_v_ogm_init(struct batadv_priv *bat_priv);
+void batadv_v_ogm_free(struct batadv_priv *bat_priv);
+int batadv_v_ogm_iface_enable(struct batadv_hard_iface *hard_iface);
+void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface);
+int batadv_v_ogm_packet_recv(struct sk_buff *skb,
+			     struct batadv_hard_iface *if_incoming);
+
+#endif /* _BATMAN_ADV_BATADV_V_OGM_H_ */
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 2160572..d64ddb9 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -160,6 +160,10 @@ int batadv_mesh_init(struct net_device *soft_iface)
 	INIT_HLIST_HEAD(&bat_priv->tvlv.handler_list);
 	INIT_HLIST_HEAD(&bat_priv->softif_vlan_list);
 
+	ret = batadv_v_mesh_init(bat_priv);
+	if (ret < 0)
+		goto err;
+
 	ret = batadv_originator_init(bat_priv);
 	if (ret < 0)
 		goto err;
@@ -202,6 +206,8 @@ void batadv_mesh_free(struct net_device *soft_iface)
 	batadv_purge_outstanding_packets(bat_priv, NULL);
 
 	batadv_gw_node_free(bat_priv);
+
+	batadv_v_mesh_free(bat_priv);
 	batadv_nc_mesh_free(bat_priv);
 	batadv_dat_free(bat_priv);
 	batadv_bla_free(bat_priv);
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index aebc62b..f00d4ba 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -30,6 +30,7 @@
 /* B.A.T.M.A.N. parameters */
 
 #define BATADV_TQ_MAX_VALUE 255
+#define BATADV_THROUGHPUT_MAX_VALUE 0xFFFFFFFF
 #define BATADV_JITTER 20
 
 /* Time To Live of broadcast messages */
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index c698b64..8a8d7ca 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -27,6 +27,7 @@
  * @BATADV_BCAST: broadcast packets carrying broadcast payload
  * @BATADV_CODED: network coded packets
  * @BATADV_ELP: echo location packets for B.A.T.M.A.N. V
+ * @BATADV_OGM2: originator messages for B.A.T.M.A.N. V
  *
  * @BATADV_UNICAST: unicast packets carrying unicast payload traffic
  * @BATADV_UNICAST_FRAG: unicast packets carrying a fragment of the original
@@ -42,6 +43,7 @@ enum batadv_packettype {
 	BATADV_BCAST            = 0x01,
 	BATADV_CODED            = 0x02,
 	BATADV_ELP		= 0x03,
+	BATADV_OGM2		= 0x04,
 	/* 0x40 - 0x7f: unicast */
 #define BATADV_UNICAST_MIN     0x40
 	BATADV_UNICAST          = 0x40,
@@ -237,6 +239,33 @@ struct batadv_ogm_packet {
 #define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet)
 
 /**
+ * struct batadv_ogm2_packet - ogm2 (routing protocol) packet
+ * @packet_type: batman-adv packet type, part of the general header
+ * @version: batman-adv protocol version, part of the general header
+ * @ttl: time to live for this packet, part of the general header
+ * @flags: reseved for routing relevant flags - currently always 0
+ * @seqno: sequence number
+ * @orig: originator mac address
+ * @tvlv_len: length of the appended tvlv buffer (in bytes)
+ * @throughput: the currently flooded path throughput
+ */
+struct batadv_ogm2_packet {
+	u8     packet_type;
+	u8     version;
+	u8     ttl;
+	u8     flags;
+	__be32 seqno;
+	u8     orig[ETH_ALEN];
+	__be16 tvlv_len;
+	__be32 throughput;
+	/* __packed is not needed as the struct size is divisible by 4,
+	 * and the largest data type in this struct has a size of 4.
+	 */
+};
+
+#define BATADV_OGM2_HLEN sizeof(struct batadv_ogm2_packet)
+
+/**
  * struct batadv_elp_packet - elp (neighbor discovery) packet
  * @packet_type: batman-adv packet type, part of the general header
  * @version: batman-adv protocol version, part of the genereal header
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 7fc82a5..e213ccd 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -802,6 +802,20 @@ struct batadv_softif_vlan {
 };
 
 /**
+ * struct batadv_priv_bat_v - B.A.T.M.A.N. V per soft-interface private data
+ * @ogm_buff: buffer holding the OGM packet
+ * @ogm_buff_len: length of the OGM packet buffer
+ * @ogm_seqno: OGM sequence number - used to identify each OGM
+ * @ogm_wq: workqueue used to schedule OGM transmissions
+ */
+struct batadv_priv_bat_v {
+	unsigned char *ogm_buff;
+	int ogm_buff_len;
+	atomic_t ogm_seqno;
+	struct delayed_work ogm_wq;
+};
+
+/**
  * struct batadv_priv - per mesh interface data
  * @mesh_state: current status of the mesh (inactive/active/deactivating)
  * @soft_iface: net device which holds this struct as private data
@@ -855,6 +869,7 @@ struct batadv_softif_vlan {
  * @mcast: multicast data
  * @network_coding: bool indicating whether network coding is enabled
  * @nc: network coding data
+ * @bat_v: B.A.T.M.A.N. V per soft-interface private data
  */
 struct batadv_priv {
 	atomic_t mesh_state;
@@ -920,6 +935,9 @@ struct batadv_priv {
 	atomic_t network_coding;
 	struct batadv_priv_nc nc;
 #endif /* CONFIG_BATMAN_ADV_NC */
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+	struct batadv_priv_bat_v bat_v;
+#endif
 };
 
 /**
-- 
2.7.0.rc3


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

* [B.A.T.M.A.N.] [PATCH v2 06/12] batman-adv: OGMv2 - implement originators logic
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
                   ` (4 preceding siblings ...)
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 05/12] batman-adv: OGMv2 - add basic infrastructure Marek Lindner
@ 2016-01-16  8:40 ` Marek Lindner
  2016-01-19 15:15   ` Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 07/12] batman-adv: add throughput override attribute to hard_ifaces Marek Lindner
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:40 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

From: Antonio Quartulli <antonio@open-mesh.com>

Add the support for recognising new originators in the
network and rebroadcast their OGMs.

Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
v2:

 - rebroadcast packet immediately after best neighbor timeout
 - add a flag to avoid forwarding the same OGMs multiple times
 - move TVLV processing out of update_route() and into batadv_v_ogm_process_per_outif()
 - code comments improvements (typ0s, clarifications, etc)
 - mark OGM packet as new when protection window is started
 - remove redundant throughput checks
 - simplify/fix best neighbor check

 net/batman-adv/bat_v_elp.c |  41 +---
 net/batman-adv/bat_v_ogm.c | 556 ++++++++++++++++++++++++++++++++++++++++++++-
 net/batman-adv/bat_v_ogm.h |   4 +
 net/batman-adv/main.h      |   2 +
 net/batman-adv/types.h     |   4 +
 5 files changed, 566 insertions(+), 41 deletions(-)

diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index dac88fa..fac5aee 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -37,8 +37,8 @@
 #include <linux/workqueue.h>
 
 #include "bat_algo.h"
+#include "bat_v_ogm.h"
 #include "hard-interface.h"
-#include "hash.h"
 #include "originator.h"
 #include "packet.h"
 #include "routing.h"
@@ -196,45 +196,6 @@ void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface)
 }
 
 /**
- * batadv_v_ogm_orig_get - retrieve and possibly create an originator node
- * @bat_priv: the bat priv with all the soft interface information
- * @addr: the address of the originator
- *
- * Return: the orig_node corresponding to the specified address. If such object
- * does not exist it is allocated here. In case of allocation failure returns
- * NULL.
- */
-static struct batadv_orig_node *
-batadv_v_ogm_orig_get(struct batadv_priv *bat_priv,
-		      const u8 *addr)
-{
-	struct batadv_orig_node *orig_node;
-	int hash_added;
-
-	orig_node = batadv_orig_hash_find(bat_priv, addr);
-	if (orig_node)
-		return orig_node;
-
-	orig_node = batadv_orig_node_new(bat_priv, addr);
-	if (!orig_node)
-		return NULL;
-
-	hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
-				     batadv_choose_orig, orig_node,
-				     &orig_node->hash_entry);
-	if (hash_added != 0) {
-		/* orig_node->refcounter is initialised to 2 by
-		 * batadv_orig_node_new()
-		 */
-		batadv_orig_node_put(orig_node);
-		batadv_orig_node_put(orig_node);
-		orig_node = NULL;
-	}
-
-	return orig_node;
-}
-
-/**
  * batadv_v_elp_neigh_update - update an ELP neighbour node
  * @bat_priv: the bat priv with all the soft interface information
  * @neigh_addr: the neighbour interface address
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
index 23932f9..22dda0e 100644
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -26,6 +26,7 @@
 #include <linux/if_ether.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
+#include <linux/list.h>
 #include <linux/netdevice.h>
 #include <linux/random.h>
 #include <linux/rculist.h>
@@ -38,12 +39,52 @@
 #include <linux/workqueue.h>
 
 #include "hard-interface.h"
+#include "hash.h"
+#include "originator.h"
 #include "packet.h"
 #include "routing.h"
 #include "send.h"
 #include "translation-table.h"
 
 /**
+ * batadv_v_ogm_orig_get - retrieve and possibly create an originator node
+ * @bat_priv: the bat priv with all the soft interface information
+ * @addr: the address of the originator
+ *
+ * Return: the orig_node corresponding to the specified address. If such object
+ * does not exist it is allocated here. In case of allocation failure returns
+ * NULL.
+ */
+struct batadv_orig_node *batadv_v_ogm_orig_get(struct batadv_priv *bat_priv,
+					       const u8 *addr)
+{
+	struct batadv_orig_node *orig_node;
+	int hash_added;
+
+	orig_node = batadv_orig_hash_find(bat_priv, addr);
+	if (orig_node)
+		return orig_node;
+
+	orig_node = batadv_orig_node_new(bat_priv, addr);
+	if (!orig_node)
+		return NULL;
+
+	hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
+				     batadv_choose_orig, orig_node,
+				     &orig_node->hash_entry);
+	if (hash_added != 0) {
+		/* orig_node->refcounter is initialised to 2 by
+		 * batadv_orig_node_new()
+		 */
+		batadv_orig_node_put(orig_node);
+		batadv_orig_node_put(orig_node);
+		orig_node = NULL;
+	}
+
+	return orig_node;
+}
+
+/**
  * batadv_v_ogm_start_timer - restart the OGM sending timer
  * @bat_priv: the bat priv with all the soft interface information
  */
@@ -193,6 +234,500 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface)
 }
 
 /**
+ * batadv_v_ogm_orig_update - update the originator status based on the received
+ *  OGM
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig_node: the originator to update
+ * @neigh_node: the neighbour the OGM has been received from (to update)
+ * @ogm2: the received OGM
+ * @if_outgoing: the interface where this OGM is going to be forwarded through
+ */
+static void
+batadv_v_ogm_orig_update(struct batadv_priv *bat_priv,
+			 struct batadv_orig_node *orig_node,
+			 struct batadv_neigh_node *neigh_node,
+			 const struct batadv_ogm2_packet *ogm2,
+			 struct batadv_hard_iface *if_outgoing)
+{
+	struct batadv_neigh_ifinfo *router_ifinfo = NULL, *neigh_ifinfo = NULL;
+	struct batadv_neigh_node *router = NULL;
+	s32 neigh_seq_diff;
+	u32 neigh_last_seqno;
+	u32 router_last_seqno;
+	u32 router_throughput, neigh_throughput;
+
+	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+		   "Searching and updating originator entry of received packet\n");
+
+	/* if this neighbor already is our next hop there is nothing
+	 * to change
+	 */
+	router = batadv_orig_router_get(orig_node, if_outgoing);
+	if (router == neigh_node)
+		goto out;
+
+	/* don't consider neighbours with worse throughput.
+	 * also switch route if this seqno is BATADV_V_MAX_ORIGDIFF newer than
+	 * the last received seqno from our best next hop.
+	 */
+	if (router) {
+		router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
+		neigh_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
+
+		/* if these are not allocated, something is wrong. */
+		if (!router_ifinfo || !neigh_ifinfo)
+			goto out;
+
+		neigh_last_seqno = neigh_ifinfo->bat_v.last_seqno;
+		router_last_seqno = router_ifinfo->bat_v.last_seqno;
+		neigh_seq_diff = neigh_last_seqno - router_last_seqno;
+		router_throughput = router_ifinfo->bat_v.throughput;
+		neigh_throughput = neigh_ifinfo->bat_v.throughput;
+
+		if ((neigh_seq_diff < BATADV_OGM_MAX_ORIGDIFF) &&
+		    (router_throughput >= neigh_throughput))
+			goto out;
+	}
+
+	batadv_update_route(bat_priv, orig_node, if_outgoing, neigh_node);
+
+out:
+	if (router_ifinfo)
+		batadv_neigh_ifinfo_put(router_ifinfo);
+	if (neigh_ifinfo)
+		batadv_neigh_ifinfo_put(neigh_ifinfo);
+	if (router)
+		batadv_neigh_node_put(router);
+}
+
+/**
+ * batadv_v_forward_penalty - apply a penalty to the throughput metric forwarded
+ *  with B.A.T.M.A.N. V OGMs
+ * @bat_priv: the bat priv with all the soft interface information
+ * @if_incoming: the interface where the OGM has been received
+ * @if_outgoing: the interface where the OGM has to be forwarded to
+ * @throughput: the current throughput
+ *
+ * Apply a penalty on the current throughput metric value based on the
+ * characteristic of the interface where the OGM has been received. The return
+ * value is computed as follows:
+ * - throughput * 50%          if the incoming and outgoing interface are the
+ *                             same WiFi interface and the throughput is above
+ *                             1MBit/s
+ * - throughput                if the outgoing interface is the default
+ *                             interface (i.e. this OGM is processed for the
+ *                             internal table and not forwarded)
+ * - throughput * hop penalty  otherwise
+ *
+ * Return: the penalised throughput metric.
+ */
+static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv,
+				    struct batadv_hard_iface *if_incoming,
+				    struct batadv_hard_iface *if_outgoing,
+				    u32 throughput)
+{
+	int hop_penalty = atomic_read(&bat_priv->hop_penalty);
+	int hop_penalty_max = BATADV_TQ_MAX_VALUE;
+
+	/* Don't apply hop penalty in default originator table. */
+	if (if_outgoing == BATADV_IF_DEFAULT)
+		return throughput;
+
+	/* Forwarding on the same WiFi interface cuts the throughput in half
+	 * due to the store & forward characteristics of WIFI.
+	 * Very low throughput values are the exception.
+	 */
+	if ((throughput > 10) &&
+	    (if_incoming == if_outgoing) &&
+	    (batadv_is_wifi_netdev(if_incoming->net_dev)))
+		return throughput / 2;
+
+	/* hop penalty of 255 equals 100% */
+	return throughput * (hop_penalty_max - hop_penalty) / hop_penalty_max;
+}
+
+/**
+ * batadv_v_ogm_forward - forward an OGM to the given outgoing interface
+ * @bat_priv: the bat priv with all the soft interface information
+ * @ogm_received: previously received OGM to be forwarded
+ * @throughput: throughput to announce, may vary per outgoing interface
+ * @if_incoming: the interface on which this OGM was received on
+ * @if_outgoing: the interface to which the OGM has to be forwarded to
+ *
+ * Forward an OGM to an interface after having altered the throughput metric and
+ * the TTL value contained in it. The original OGM isn't modified.
+ */
+static void batadv_v_ogm_forward(struct batadv_priv *bat_priv,
+				 const struct batadv_ogm2_packet *ogm_received,
+				 u32 throughput,
+				 struct batadv_hard_iface *if_incoming,
+				 struct batadv_hard_iface *if_outgoing)
+{
+	struct batadv_ogm2_packet *ogm_forward;
+	unsigned char *skb_buff;
+	struct sk_buff *skb;
+	size_t packet_len;
+	u16 tvlv_len;
+
+	if (ogm_received->ttl <= 1) {
+		batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n");
+		return;
+	}
+
+	tvlv_len = ntohs(ogm_received->tvlv_len);
+
+	packet_len = BATADV_OGM2_HLEN + tvlv_len;
+	skb = netdev_alloc_skb_ip_align(if_outgoing->net_dev,
+					ETH_HLEN + packet_len);
+	if (!skb)
+		return;
+
+	skb_reserve(skb, ETH_HLEN);
+	skb_buff = skb_put(skb, packet_len);
+	memcpy(skb_buff, ogm_received, packet_len);
+
+	/* apply forward penalty */
+	ogm_forward = (struct batadv_ogm2_packet *)skb_buff;
+	ogm_forward->throughput = htonl(throughput);
+	ogm_forward->ttl--;
+
+	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+		   "Forwarding OGM2 packet on %s: throughput %u, ttl %u, received via %s\n",
+		   if_outgoing->net_dev->name, throughput, ogm_forward->ttl,
+		   if_incoming->net_dev->name);
+
+	batadv_v_ogm_send_to_if(skb, if_outgoing);
+}
+
+/**
+ * batadv_v_ogm_metric_update - update route metric based on OGM
+ * @bat_priv: the bat priv with all the soft interface information
+ * @ogm2: OGM2 structure
+ * @orig_node: Originator structure for which the OGM has been received
+ * @neigh_node: the neigh_node through with the OGM has been received
+ * @if_incoming: the interface where this packet was received
+ * @if_outgoing: the interface for which the packet should be considered
+ *
+ * Return:
+ *  1  if the OGM is new,
+ *  0  if it is not new but valid,
+ *  <0 on error (e.g. old OGM)
+ */
+static int batadv_v_ogm_metric_update(struct batadv_priv *bat_priv,
+				      const struct batadv_ogm2_packet *ogm2,
+				      struct batadv_orig_node *orig_node,
+				      struct batadv_neigh_node *neigh_node,
+				      struct batadv_hard_iface *if_incoming,
+				      struct batadv_hard_iface *if_outgoing)
+{
+	struct batadv_orig_ifinfo *orig_ifinfo = NULL;
+	struct batadv_neigh_ifinfo *neigh_ifinfo = NULL;
+	bool protection_started = false;
+	int ret = -EINVAL;
+	u32 path_throughput;
+	s32 seq_diff;
+
+	orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
+	if (!orig_ifinfo)
+		goto out;
+
+	seq_diff = ntohl(ogm2->seqno) - orig_ifinfo->last_real_seqno;
+
+	if (!hlist_empty(&orig_node->neigh_list) &&
+	    batadv_window_protected(bat_priv, seq_diff,
+				    BATADV_OGM_MAX_AGE,
+				    &orig_ifinfo->batman_seqno_reset,
+				    &protection_started)) {
+		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+			   "Drop packet: packet within window protection time from %pM\n",
+			   ogm2->orig);
+		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+			   "Last reset: %ld, %ld\n",
+			   orig_ifinfo->batman_seqno_reset, jiffies);
+		goto out;
+	}
+
+	/* drop packets with old seqnos, however accept the first packet after
+	 * a host has been rebooted.
+	 */
+	if ((seq_diff < 0) && !protection_started)
+		goto out;
+
+	neigh_node->last_seen = jiffies;
+
+	orig_node->last_seen = jiffies;
+
+	orig_ifinfo->last_real_seqno = ntohl(ogm2->seqno);
+	orig_ifinfo->last_ttl = ogm2->ttl;
+
+	neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
+	if (!neigh_ifinfo)
+		goto out;
+
+	path_throughput = batadv_v_forward_penalty(bat_priv, if_incoming,
+						   if_outgoing,
+						   ntohl(ogm2->throughput));
+	neigh_ifinfo->bat_v.throughput = path_throughput;
+	neigh_ifinfo->bat_v.last_seqno = ntohl(ogm2->seqno);
+	neigh_ifinfo->last_ttl = ogm2->ttl;
+
+	if (seq_diff > 0 || protection_started)
+		ret = 1;
+	else
+		ret = 0;
+out:
+	if (orig_ifinfo)
+		batadv_orig_ifinfo_put(orig_ifinfo);
+	if (neigh_ifinfo)
+		batadv_neigh_ifinfo_put(neigh_ifinfo);
+
+	return ret;
+}
+
+/**
+ * batadv_v_ogm_route_update - update routes based on OGM
+ * @bat_priv: the bat priv with all the soft interface information
+ * @ethhdr: the Ethernet header of the OGM2
+ * @ogm2: OGM2 structure
+ * @orig_node: Originator structure for which the OGM has been received
+ * @neigh_node: the neigh_node through with the OGM has been received
+ * @if_incoming: the interface where this packet was received
+ * @if_outgoing: the interface for which the packet should be considered
+ */
+static void batadv_v_ogm_route_update(struct batadv_priv *bat_priv,
+				      const struct ethhdr *ethhdr,
+				      const struct batadv_ogm2_packet *ogm2,
+				      struct batadv_orig_node *orig_node,
+				      struct batadv_neigh_node *neigh_node,
+				      struct batadv_hard_iface *if_incoming,
+				      struct batadv_hard_iface *if_outgoing)
+{
+	struct batadv_neigh_node *router = NULL;
+	struct batadv_neigh_ifinfo *neigh_ifinfo = NULL;
+	struct batadv_orig_node *orig_neigh_node = NULL;
+	struct batadv_orig_ifinfo *orig_ifinfo = NULL;
+	struct batadv_neigh_node *orig_neigh_router = NULL;
+
+	neigh_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
+	if (!neigh_ifinfo)
+		goto out;
+
+	orig_neigh_node = batadv_v_ogm_orig_get(bat_priv, ethhdr->h_source);
+	if (!orig_neigh_node)
+		goto out;
+
+	orig_neigh_router = batadv_orig_router_get(orig_neigh_node,
+						   if_outgoing);
+
+	/* drop packet if sender is not a direct neighbor and if we
+	 * don't route towards it
+	 */
+	router = batadv_orig_router_get(orig_node, if_outgoing);
+	if (router && router->orig_node != orig_node && !orig_neigh_router) {
+		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+			   "Drop packet: OGM via unknown neighbor!\n");
+		goto out;
+	}
+
+	if (router)
+		batadv_neigh_node_put(router);
+
+	/* Update routes, and check if the OGM is from the best next hop */
+	batadv_v_ogm_orig_update(bat_priv, orig_node, neigh_node, ogm2,
+				 if_outgoing);
+
+	orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
+	if (!orig_ifinfo)
+		goto out;
+
+	/* don't forward the same seqno twice on one interface */
+	if (orig_ifinfo->last_seqno_forwarded == ntohl(ogm2->seqno))
+		goto out;
+
+	/* acquire possibly updated router */
+	router = batadv_orig_router_get(orig_node, if_outgoing);
+
+	/* strict rule: forward packets coming from the best next hop only */
+	if (neigh_node != router)
+		goto out;
+
+	/* only forward for specific interface, not for the default one. */
+	if (if_outgoing != BATADV_IF_DEFAULT) {
+		orig_ifinfo->last_seqno_forwarded = ntohl(ogm2->seqno);
+		batadv_v_ogm_forward(bat_priv, ogm2,
+				     neigh_ifinfo->bat_v.throughput,
+				     if_incoming, if_outgoing);
+	}
+
+out:
+	if (orig_ifinfo)
+		batadv_orig_ifinfo_put(orig_ifinfo);
+	if (router)
+		batadv_neigh_node_put(router);
+	if (orig_neigh_router)
+		batadv_neigh_node_put(orig_neigh_router);
+	if (orig_neigh_node)
+		batadv_orig_node_put(orig_neigh_node);
+	if (neigh_ifinfo)
+		batadv_neigh_ifinfo_put(neigh_ifinfo);
+}
+
+/**
+ * batadv_v_ogm_process_per_outif - process a batman v OGM for an outgoing if
+ * @bat_priv: the bat priv with all the soft interface information
+ * @ethhdr: the Ethernet header of the OGM2
+ * @ogm2: OGM2 structure
+ * @orig_node: Originator structure for which the OGM has been received
+ * @neigh_node: the neigh_node through with the OGM has been received
+ * @if_incoming: the interface where this packet was received
+ * @if_outgoing: the interface for which the packet should be considered
+ */
+static void
+batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv,
+			       const struct ethhdr *ethhdr,
+			       const struct batadv_ogm2_packet *ogm2,
+			       struct batadv_orig_node *orig_node,
+			       struct batadv_neigh_node *neigh_node,
+			       struct batadv_hard_iface *if_incoming,
+			       struct batadv_hard_iface *if_outgoing)
+{
+	int seqno_age;
+
+	/* first, update the metric with according sanity checks */
+	seqno_age = batadv_v_ogm_metric_update(bat_priv, ogm2, orig_node,
+					       neigh_node, if_incoming,
+					       if_outgoing);
+
+	/* outdated sequence numbers are to be discarded */
+	if (seqno_age < 0)
+		return;
+
+	/* only unknown & newer OGMs contain TVLVs we are interested in */
+	if ((seqno_age > 0) && (if_outgoing == BATADV_IF_DEFAULT))
+		batadv_tvlv_containers_process(bat_priv, true, orig_node,
+					       NULL, NULL,
+					       (unsigned char *)(ogm2 + 1),
+					       ntohs(ogm2->tvlv_len));
+
+	/* if the metric update went through, update routes if needed */
+	batadv_v_ogm_route_update(bat_priv, ethhdr, ogm2, orig_node,
+				  neigh_node, if_incoming, if_outgoing);
+}
+
+/**
+ * batadv_v_ogm_aggr_packet - checks if there is another OGM aggregated
+ * @buff_pos: current position in the skb
+ * @packet_len: total length of the skb
+ * @tvlv_len: tvlv length of the previously considered OGM
+ *
+ * Return: true if there is enough space for another OGM, false otherwise.
+ */
+static bool batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
+				     __be16 tvlv_len)
+{
+	int next_buff_pos = 0;
+
+	next_buff_pos += buff_pos + BATADV_OGM2_HLEN;
+	next_buff_pos += ntohs(tvlv_len);
+
+	return (next_buff_pos <= packet_len) &&
+	       (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
+}
+
+/**
+ * batadv_v_ogm_process - process an incoming batman v OGM
+ * @skb: the skb containing the OGM
+ * @ogm_offset: offset to the OGM which should be processed (for aggregates)
+ * @if_incoming: the interface where this packet was receved
+ */
+static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
+				 struct batadv_hard_iface *if_incoming)
+{
+	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+	struct ethhdr *ethhdr;
+	struct batadv_orig_node *orig_node = NULL;
+	struct batadv_hardif_neigh_node *hardif_neigh = NULL;
+	struct batadv_neigh_node *neigh_node = NULL;
+	struct batadv_hard_iface *hard_iface;
+	struct batadv_ogm2_packet *ogm_packet;
+	u32 ogm_throughput, link_throughput, path_throughput;
+
+	ethhdr = eth_hdr(skb);
+	ogm_packet = (struct batadv_ogm2_packet *)(skb->data + ogm_offset);
+
+	ogm_throughput = ntohl(ogm_packet->throughput);
+
+	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+		   "Received OGM2 packet via NB: %pM, IF: %s [%pM] (from OG: %pM, seqno %u, troughput %u, TTL %u, V %u, tvlv_len %u)\n",
+		   ethhdr->h_source, if_incoming->net_dev->name,
+		   if_incoming->net_dev->dev_addr, ogm_packet->orig,
+		   ntohl(ogm_packet->seqno), ogm_throughput, ogm_packet->ttl,
+		   ogm_packet->version, ntohs(ogm_packet->tvlv_len));
+
+	/* If the troughput metric is 0, immediately drop the packet. No need to
+	 * create orig_node / neigh_node for an unusable route.
+	 */
+	if (ogm_throughput == 0) {
+		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+			   "Drop packet: originator packet with troughput metric of 0\n");
+		return;
+	}
+
+	/* require ELP packets be to received from this neighbor first */
+	hardif_neigh = batadv_hardif_neigh_get(if_incoming, ethhdr->h_source);
+	if (!hardif_neigh) {
+		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+			   "Drop packet: OGM via unknown neighbor!\n");
+		goto out;
+	}
+
+	orig_node = batadv_v_ogm_orig_get(bat_priv, ogm_packet->orig);
+	if (!orig_node)
+		return;
+
+	neigh_node = batadv_neigh_node_new(orig_node, if_incoming,
+					   ethhdr->h_source);
+	if (!neigh_node)
+		goto out;
+
+	/* Update the received throughput metric to match the link
+	 * characteristic:
+	 *  - If this OGM traveled one hop so far (emitted by single hop
+	 *    neighbor) the path throughput metric equals the link throughput.
+	 *  - For OGMs traversing more than hop the path throughput metric is
+	 *    the smaller of the path throughput and the link throughput.
+	 */
+	link_throughput = ewma_throughput_read(&hardif_neigh->bat_v.throughput);
+	path_throughput = min_t(u32, link_throughput, ogm_throughput);
+	ogm_packet->throughput = htonl(path_throughput);
+
+	batadv_v_ogm_process_per_outif(bat_priv, ethhdr, ogm_packet, orig_node,
+				       neigh_node, if_incoming,
+				       BATADV_IF_DEFAULT);
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
+		if (hard_iface->if_status != BATADV_IF_ACTIVE)
+			continue;
+
+		if (hard_iface->soft_iface != bat_priv->soft_iface)
+			continue;
+
+		batadv_v_ogm_process_per_outif(bat_priv, ethhdr, ogm_packet,
+					       orig_node, neigh_node,
+					       if_incoming, hard_iface);
+	}
+	rcu_read_unlock();
+out:
+	if (orig_node)
+		batadv_orig_node_put(orig_node);
+	if (neigh_node)
+		batadv_neigh_node_put(neigh_node);
+	if (hardif_neigh)
+		batadv_hardif_neigh_put(hardif_neigh);
+}
+
+/**
  * batadv_v_ogm_packet_recv - OGM2 receiving handler
  * @skb: the received OGM
  * @if_incoming: the interface where this OGM has been received
@@ -206,6 +741,9 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb,
 	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 	struct batadv_ogm2_packet *ogm_packet;
 	struct ethhdr *ethhdr = eth_hdr(skb);
+	int ogm_offset;
+	u8 *packet_pos;
+	int ret = NET_RX_DROP;
 
 	/* did we receive a OGM2 packet on an interface that does not have
 	 * B.A.T.M.A.N. V enabled ?
@@ -228,8 +766,24 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb,
 	batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
 			   skb->len + ETH_HLEN);
 
+	ogm_offset = 0;
+	ogm_packet = (struct batadv_ogm2_packet *)skb->data;
+
+	while (batadv_v_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
+					ogm_packet->tvlv_len)) {
+		batadv_v_ogm_process(skb, ogm_offset, if_incoming);
+
+		ogm_offset += BATADV_OGM2_HLEN;
+		ogm_offset += ntohs(ogm_packet->tvlv_len);
+
+		packet_pos = skb->data + ogm_offset;
+		ogm_packet = (struct batadv_ogm2_packet *)packet_pos;
+	}
+
+	ret = NET_RX_SUCCESS;
 	consume_skb(skb);
-	return NET_RX_SUCCESS;
+
+	return ret;
 }
 
 /**
diff --git a/net/batman-adv/bat_v_ogm.h b/net/batman-adv/bat_v_ogm.h
index d9f178c..d849c75 100644
--- a/net/batman-adv/bat_v_ogm.h
+++ b/net/batman-adv/bat_v_ogm.h
@@ -18,6 +18,8 @@
 #ifndef _BATMAN_ADV_BATADV_V_OGM_H_
 #define _BATMAN_ADV_BATADV_V_OGM_H_
 
+#include <linux/types.h>
+
 struct batadv_hard_iface;
 struct batadv_priv;
 struct sk_buff;
@@ -25,6 +27,8 @@ struct sk_buff;
 int batadv_v_ogm_init(struct batadv_priv *bat_priv);
 void batadv_v_ogm_free(struct batadv_priv *bat_priv);
 int batadv_v_ogm_iface_enable(struct batadv_hard_iface *hard_iface);
+struct batadv_orig_node *batadv_v_ogm_orig_get(struct batadv_priv *bat_priv,
+					       const u8 *addr);
 void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface);
 int batadv_v_ogm_packet_recv(struct sk_buff *skb,
 			     struct batadv_hard_iface *if_incoming);
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index f00d4ba..e6cef57 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -63,6 +63,8 @@
 
 /* B.A.T.M.A.N. V */
 #define BATADV_ELP_MAX_AGE 64
+#define BATADV_OGM_MAX_ORIGDIFF 5
+#define BATADV_OGM_MAX_AGE 64
 
 /* number of OGMs sent with the last tt diff */
 #define BATADV_TT_OGM_APPEND_MAX 3
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index e213ccd..cf55cd0 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -149,6 +149,7 @@ struct batadv_hard_iface {
  * @router: router that should be used to reach this originator
  * @last_real_seqno: last and best known sequence number
  * @last_ttl: ttl of last received packet
+ * @last_seqno_forwarded: seqno of the OGM which was forwarded last
  * @batman_seqno_reset: time when the batman seqno window was reset
  * @refcount: number of contexts the object is used
  * @rcu: struct used for freeing in an RCU-safe manner
@@ -159,6 +160,7 @@ struct batadv_orig_ifinfo {
 	struct batadv_neigh_node __rcu *router; /* rcu protected pointer */
 	u32 last_real_seqno;
 	u8 last_ttl;
+	u32 last_seqno_forwarded;
 	unsigned long batman_seqno_reset;
 	struct kref refcount;
 	struct rcu_head rcu;
@@ -448,9 +450,11 @@ struct batadv_neigh_ifinfo_bat_iv {
  * struct batadv_neigh_ifinfo_bat_v - neighbor information per outgoing
  *  interface for B.A.T.M.A.N. V
  * @throughput: last throughput metric received from originator via this neigh
+ * @last_seqno: last sequence number known for this neighbor
  */
 struct batadv_neigh_ifinfo_bat_v {
 	u32 throughput;
+	u32 last_seqno;
 };
 
 /**
-- 
2.7.0.rc3


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

* [B.A.T.M.A.N.] [PATCH v2 07/12] batman-adv: add throughput override attribute to hard_ifaces
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
                   ` (5 preceding siblings ...)
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 06/12] batman-adv: OGMv2 - implement originators logic Marek Lindner
@ 2016-01-16  8:40 ` Marek Lindner
  2016-01-19 15:16   ` Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 08/12] batman-adv: keep track of when unicast packets are sent Marek Lindner
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:40 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

From: Antonio Quartulli <antonio@open-mesh.com>

This attribute is exported to user space to disable the link
throughput auto-detection by setting a fixed value.
The throughput override value is used when batman-adv is
computing the link throughput towards a neighbour.

If the value is set to 0 then batman-adv will try to detect
the throughput by itself.

Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 .../ABI/testing/sysfs-class-net-batman-adv         |  9 +++
 net/batman-adv/bat_v.c                             |  6 ++
 net/batman-adv/gateway_common.c                    |  4 +-
 net/batman-adv/gateway_common.h                    |  2 +
 net/batman-adv/sysfs.c                             | 74 ++++++++++++++++++++++
 net/batman-adv/types.h                             |  2 +
 6 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-net-batman-adv b/Documentation/ABI/testing/sysfs-class-net-batman-adv
index aea78db..518f6a1 100644
--- a/Documentation/ABI/testing/sysfs-class-net-batman-adv
+++ b/Documentation/ABI/testing/sysfs-class-net-batman-adv
@@ -1,4 +1,13 @@
 
+What:		/sys/class/net/<iface>/batman-adv/throughput_override
+Date:		Feb 2014
+Contact:	Antonio Quartulli <antonio@meshcoding.com>
+description:
+		Defines the throughput value to be used by B.A.T.M.A.N. V
+		when estimating the link throughput using this interface.
+		If the value is set to 0 then batman-adv will try to
+		estimate the throughput by itself.
+
 What:           /sys/class/net/<iface>/batman-adv/elp_interval
 Date:           Feb 2014
 Contact:        Linus Lüssing <linus.luessing@web.de>
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index b90a4df..d9cb5c4 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -18,6 +18,7 @@
 #include "bat_algo.h"
 #include "main.h"
 
+#include <linux/atomic.h>
 #include <linux/cache.h>
 #include <linux/init.h>
 
@@ -37,6 +38,11 @@ static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface)
 	if (ret < 0)
 		batadv_v_elp_iface_disable(hard_iface);
 
+	/* enable link throughput auto-detection by setting the throughput
+	 * override to zero
+	 */
+	atomic_set(&hard_iface->bat_v.throughput_override, 0);
+
 	return ret;
 }
 
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c
index 5ee04f7..4423047 100644
--- a/net/batman-adv/gateway_common.c
+++ b/net/batman-adv/gateway_common.c
@@ -40,8 +40,8 @@
  *
  * Return: false on parse error and true otherwise.
  */
-static bool batadv_parse_throughput(struct net_device *net_dev, char *buff,
-				    const char *description, u32 *throughput)
+bool batadv_parse_throughput(struct net_device *net_dev, char *buff,
+			     const char *description, u32 *throughput)
 {
 	enum batadv_bandwidth_units bw_unit_type = BATADV_BW_UNIT_KBIT;
 	u64 lthroughput;
diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h
index b583463..8a5e1dd 100644
--- a/net/batman-adv/gateway_common.h
+++ b/net/batman-adv/gateway_common.h
@@ -49,5 +49,7 @@ ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff,
 void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv);
 void batadv_gw_init(struct batadv_priv *bat_priv);
 void batadv_gw_free(struct batadv_priv *bat_priv);
+bool batadv_parse_throughput(struct net_device *net_dev, char *buff,
+			     const char *description, u32 *throughput);
 
 #endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index e860143..e7cf513 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -917,12 +917,85 @@ static ssize_t batadv_show_iface_status(struct kobject *kobj,
 	return length;
 }
 
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+
+/**
+ * batadv_store_throughput_override - parse and store throughput override
+ *  entered by the user
+ * @kobj: kobject representing the private mesh sysfs directory
+ * @attr: the batman-adv attribute the user is interacting with
+ * @buff: the buffer containing the user data
+ * @count: number of bytes in the buffer
+ *
+ * Return: 'count' on success or a negative error code in case of failure
+ */
+static ssize_t batadv_store_throughput_override(struct kobject *kobj,
+						struct attribute *attr,
+						char *buff, size_t count)
+{
+	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
+	struct batadv_hard_iface *hard_iface;
+	u32 tp_override;
+	u32 old_tp_override;
+	bool ret;
+
+	hard_iface = batadv_hardif_get_by_netdev(net_dev);
+	if (!hard_iface)
+		return -EINVAL;
+
+	if (buff[count - 1] == '\n')
+		buff[count - 1] = '\0';
+
+	ret = batadv_parse_throughput(net_dev, buff, "throughput_override",
+				      &tp_override);
+	if (!ret)
+		return count;
+
+	old_tp_override = atomic_read(&hard_iface->bat_v.throughput_override);
+	if (old_tp_override == tp_override)
+		goto out;
+
+	batadv_info(net_dev, "%s: Changing from: %u.%u MBit to: %u.%u MBit\n",
+		    "throughput_override",
+		    old_tp_override / 10, old_tp_override % 10,
+		    tp_override / 10, tp_override % 10);
+
+	atomic_set(&hard_iface->bat_v.throughput_override, tp_override);
+
+out:
+	batadv_hardif_put(hard_iface);
+	return count;
+}
+
+static ssize_t batadv_show_throughput_override(struct kobject *kobj,
+					       struct attribute *attr,
+					       char *buff)
+{
+	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
+	struct batadv_hard_iface *hard_iface;
+	u32 tp_override;
+
+	hard_iface = batadv_hardif_get_by_netdev(net_dev);
+	if (!hard_iface)
+		return -EINVAL;
+
+	tp_override = atomic_read(&hard_iface->bat_v.throughput_override);
+
+	return sprintf(buff, "%u.%u MBit\n", tp_override / 10,
+		       tp_override % 10);
+}
+
+#endif
+
 static BATADV_ATTR(mesh_iface, S_IRUGO | S_IWUSR, batadv_show_mesh_iface,
 		   batadv_store_mesh_iface);
 static BATADV_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL);
 #ifdef CONFIG_BATMAN_ADV_BATMAN_V
 BATADV_ATTR_HIF_UINT(elp_interval, bat_v.elp_interval, S_IRUGO | S_IWUSR,
 		     2 * BATADV_JITTER, INT_MAX, NULL);
+static BATADV_ATTR(throughput_override, S_IRUGO | S_IWUSR,
+		   batadv_show_throughput_override,
+		   batadv_store_throughput_override);
 #endif
 
 static struct batadv_attribute *batadv_batman_attrs[] = {
@@ -930,6 +1003,7 @@ static struct batadv_attribute *batadv_batman_attrs[] = {
 	&batadv_attr_iface_status,
 #ifdef CONFIG_BATMAN_ADV_BATMAN_V
 	&batadv_attr_elp_interval,
+	&batadv_attr_throughput_override,
 #endif
 	NULL,
 };
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index cf55cd0..a6f0952 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -92,12 +92,14 @@ struct batadv_hard_iface_bat_iv {
  * @elp_seqno: current ELP sequence number
  * @elp_skb: base skb containing the ELP message to send
  * @elp_wq: workqueue used to schedule ELP transmissions
+ * @throughput_override: throughput override to disable link auto-detection
  */
 struct batadv_hard_iface_bat_v {
 	atomic_t elp_interval;
 	atomic_t elp_seqno;
 	struct sk_buff *elp_skb;
 	struct delayed_work elp_wq;
+	atomic_t throughput_override;
 };
 
 /**
-- 
2.7.0.rc3


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

* [B.A.T.M.A.N.] [PATCH v2 08/12] batman-adv: keep track of when unicast packets are sent
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
                   ` (6 preceding siblings ...)
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 07/12] batman-adv: add throughput override attribute to hard_ifaces Marek Lindner
@ 2016-01-16  8:40 ` Marek Lindner
  2016-01-19 15:20   ` Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 09/12] batman-adv: ELP - compute the metric based on the estimated throughput Marek Lindner
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:40 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

From: Antonio Quartulli <antonio@open-mesh.com>

To enable ELP to send probing packets over wireless links
only if needed, batman-adv must keep track of the last time
it sent a unicast packet towards every neighbour.

For this purpose a 2 main changes are introduced:
1) a new member of the elp_neigh_node structure stores the
   last time a unicast packet was sent towards this neighbour;
2) a wrapper function for sending unicast packets is
   implemented. This function will simply update the member
   describe din point 1) and then forward the packet to the
   real sending routine.

Point 2) implies that any code-path leading to a unicast
sending now has to use the new wrapper.

Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 net/batman-adv/bat_iv_ogm.c            |  2 +-
 net/batman-adv/bat_v_elp.c             |  2 +-
 net/batman-adv/bat_v_ogm.c             |  2 +-
 net/batman-adv/distributed-arp-table.c |  4 +--
 net/batman-adv/fragmentation.c         |  8 ++---
 net/batman-adv/icmp_socket.c           |  2 +-
 net/batman-adv/network-coding.c        | 22 +++++++-------
 net/batman-adv/send.c                  | 55 +++++++++++++++++++++++++++++-----
 net/batman-adv/send.h                  | 10 +++++--
 net/batman-adv/types.h                 |  2 ++
 10 files changed, 75 insertions(+), 34 deletions(-)

diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 5651e33..cb2d1b9 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -478,7 +478,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
 		batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
 		batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
 				   skb->len + ETH_HLEN);
-		batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr);
+		batadv_send_broadcast_skb(skb, hard_iface);
 	}
 }
 
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index fac5aee..1e4d13c 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -104,7 +104,7 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
 		   hard_iface->net_dev->name,
 		   atomic_read(&hard_iface->bat_v.elp_seqno));
 
-	batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr);
+	batadv_send_broadcast_skb(skb, hard_iface);
 
 	atomic_inc(&hard_iface->bat_v.elp_seqno);
 
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
index 22dda0e..c800096 100644
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -120,7 +120,7 @@ static void batadv_v_ogm_send_to_if(struct sk_buff *skb,
 	batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,
 			   skb->len + ETH_HLEN);
 
-	batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr);
+	batadv_send_broadcast_skb(skb, hard_iface);
 }
 
 /**
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 4c9b69d..e96d7c7 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -654,9 +654,7 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv,
 			goto free_neigh;
 		}
 
-		send_status = batadv_send_skb_packet(tmp_skb,
-						     neigh_node->if_incoming,
-						     neigh_node->addr);
+		send_status = batadv_send_unicast_skb(tmp_skb, neigh_node);
 		if (send_status == NET_XMIT_SUCCESS) {
 			/* count the sent packet */
 			switch (packet_subtype) {
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
index adb9c39..e6956d0 100644
--- a/net/batman-adv/fragmentation.c
+++ b/net/batman-adv/fragmentation.c
@@ -378,8 +378,7 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb,
 				   skb->len + ETH_HLEN);
 
 		packet->ttl--;
-		batadv_send_skb_packet(skb, neigh_node->if_incoming,
-				       neigh_node->addr);
+		batadv_send_unicast_skb(skb, neigh_node);
 		ret = true;
 	}
 
@@ -486,8 +485,7 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
 		batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_TX);
 		batadv_add_counter(bat_priv, BATADV_CNT_FRAG_TX_BYTES,
 				   skb_fragment->len + ETH_HLEN);
-		batadv_send_skb_packet(skb_fragment, neigh_node->if_incoming,
-				       neigh_node->addr);
+		batadv_send_unicast_skb(skb_fragment, neigh_node);
 		frag_header.no++;
 
 		/* The initial check in this function should cover this case */
@@ -506,7 +504,7 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
 	batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_TX);
 	batadv_add_counter(bat_priv, BATADV_CNT_FRAG_TX_BYTES,
 			   skb->len + ETH_HLEN);
-	batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
+	batadv_send_unicast_skb(skb, neigh_node);
 
 	ret = true;
 
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 6268f08..14d0013 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -278,7 +278,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
 
 	ether_addr_copy(icmp_header->orig, primary_if->net_dev->dev_addr);
 
-	batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
+	batadv_send_unicast_skb(skb, neigh_node);
 	goto out;
 
 dst_unreach:
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
index d253bb2..b41719b 100644
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -575,9 +575,7 @@ batadv_nc_hash_find(struct batadv_hashtable *hash,
  */
 static void batadv_nc_send_packet(struct batadv_nc_packet *nc_packet)
 {
-	batadv_send_skb_packet(nc_packet->skb,
-			       nc_packet->neigh_node->if_incoming,
-			       nc_packet->nc_path->next_hop);
+	batadv_send_unicast_skb(nc_packet->skb, nc_packet->neigh_node);
 	nc_packet->skb = NULL;
 	batadv_nc_packet_free(nc_packet);
 }
@@ -1067,11 +1065,11 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
 	struct batadv_unicast_packet *packet1;
 	struct batadv_unicast_packet *packet2;
 	struct batadv_coded_packet *coded_packet;
-	struct batadv_neigh_node *neigh_tmp, *router_neigh;
-	struct batadv_neigh_node *router_coding = NULL;
+	struct batadv_neigh_node *neigh_tmp, *router_neigh, *first_dest;
+	struct batadv_neigh_node *router_coding = NULL, *second_dest;
 	struct batadv_neigh_ifinfo *router_neigh_ifinfo = NULL;
 	struct batadv_neigh_ifinfo *router_coding_ifinfo = NULL;
-	u8 *first_source, *first_dest, *second_source, *second_dest;
+	u8 *first_source, *second_source;
 	__be32 packet_id1, packet_id2;
 	size_t count;
 	bool res = false;
@@ -1114,9 +1112,9 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
 	 */
 	if (tq_weighted_neigh >= tq_weighted_coding) {
 		/* Destination from nc_packet is selected for MAC-header */
-		first_dest = nc_packet->nc_path->next_hop;
+		first_dest = nc_packet->neigh_node;
 		first_source = nc_packet->nc_path->prev_hop;
-		second_dest = neigh_node->addr;
+		second_dest = neigh_node;
 		second_source = ethhdr->h_source;
 		packet1 = (struct batadv_unicast_packet *)nc_packet->skb->data;
 		packet2 = (struct batadv_unicast_packet *)skb->data;
@@ -1125,9 +1123,9 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
 					      skb->data + sizeof(*packet2));
 	} else {
 		/* Destination for skb is selected for MAC-header */
-		first_dest = neigh_node->addr;
+		first_dest = neigh_node;
 		first_source = ethhdr->h_source;
-		second_dest = nc_packet->nc_path->next_hop;
+		second_dest = nc_packet->neigh_node;
 		second_source = nc_packet->nc_path->prev_hop;
 		packet1 = (struct batadv_unicast_packet *)skb->data;
 		packet2 = (struct batadv_unicast_packet *)nc_packet->skb->data;
@@ -1169,7 +1167,7 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
 	coded_packet->first_ttvn = packet1->ttvn;
 
 	/* Info about second unicast packet */
-	ether_addr_copy(coded_packet->second_dest, second_dest);
+	ether_addr_copy(coded_packet->second_dest, second_dest->addr);
 	ether_addr_copy(coded_packet->second_source, second_source);
 	ether_addr_copy(coded_packet->second_orig_dest, packet2->dest);
 	coded_packet->second_crc = packet_id2;
@@ -1224,7 +1222,7 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
 	batadv_nc_packet_free(nc_packet);
 
 	/* Send the coded packet and return true */
-	batadv_send_skb_packet(skb_dest, neigh_node->if_incoming, first_dest);
+	batadv_send_unicast_skb(skb_dest, first_dest);
 	res = true;
 out:
 	if (router_neigh)
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index caff32c..3ce06e0 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -49,16 +49,30 @@
 
 static void batadv_send_outstanding_bcast_packet(struct work_struct *work);
 
-/* send out an already prepared packet to the given address via the
- * specified batman interface
+/**
+ * batadv_send_skb_packet - send an already prepared packet
+ * @skb: the packet to send
+ * @hard_iface: the interface to use to send the broadcast packet
+ * @dst_addr: the payload destination
+ *
+ * Send out an already prepared packet to the given neighbor or broadcast it
+ * using the specified interface. Either hard_iface or neigh_node must be not
+ * NULL.
+ * If neigh_node is NULL, then the packet is broadcasted using hard_iface,
+ * otherwise it is sent as unicast to the given neighbor.
+ *
+ * Return: NET_TX_DROP in case of error or the result of dev_queue_xmit(skb)
+ * otherwise
  */
 int batadv_send_skb_packet(struct sk_buff *skb,
 			   struct batadv_hard_iface *hard_iface,
 			   const u8 *dst_addr)
 {
-	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+	struct batadv_priv *bat_priv;
 	struct ethhdr *ethhdr;
 
+	bat_priv = netdev_priv(hard_iface->soft_iface);
+
 	if (hard_iface->if_status != BATADV_IF_ACTIVE)
 		goto send_skb_err;
 
@@ -100,6 +114,35 @@ send_skb_err:
 	return NET_XMIT_DROP;
 }
 
+int batadv_send_broadcast_skb(struct sk_buff *skb,
+			      struct batadv_hard_iface *hard_iface)
+{
+	return batadv_send_skb_packet(skb, hard_iface, batadv_broadcast_addr);
+}
+
+int batadv_send_unicast_skb(struct sk_buff *skb,
+			    struct batadv_neigh_node *neigh)
+{
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+	struct batadv_hardif_neigh_node *hardif_neigh;
+#endif
+	int ret;
+
+	ret = batadv_send_skb_packet(skb, neigh->if_incoming, neigh->addr);
+
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+	hardif_neigh = batadv_hardif_neigh_get(neigh->if_incoming, neigh->addr);
+
+	if ((hardif_neigh) && (ret != NET_XMIT_DROP))
+		hardif_neigh->bat_v.last_unicast_tx = jiffies;
+
+	if (hardif_neigh)
+		batadv_hardif_neigh_put(hardif_neigh);
+#endif
+
+	return ret;
+}
+
 /**
  * batadv_send_skb_to_orig - Lookup next-hop and transmit skb.
  * @skb: Packet to be transmitted.
@@ -146,8 +189,7 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
 	if (recv_if && batadv_nc_skb_forward(skb, neigh_node)) {
 		ret = NET_XMIT_POLICED;
 	} else {
-		batadv_send_skb_packet(skb, neigh_node->if_incoming,
-				       neigh_node->addr);
+		batadv_send_unicast_skb(skb, neigh_node);
 		ret = NET_XMIT_SUCCESS;
 	}
 
@@ -538,8 +580,7 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
 		/* send a copy of the saved skb */
 		skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC);
 		if (skb1)
-			batadv_send_skb_packet(skb1, hard_iface,
-					       batadv_broadcast_addr);
+			batadv_send_broadcast_skb(skb1, hard_iface);
 	}
 	rcu_read_unlock();
 
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
index 7ff95ca..6fd7270 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -28,12 +28,16 @@
 struct sk_buff;
 struct work_struct;
 
-int batadv_send_skb_packet(struct sk_buff *skb,
-			   struct batadv_hard_iface *hard_iface,
-			   const u8 *dst_addr);
 int batadv_send_skb_to_orig(struct sk_buff *skb,
 			    struct batadv_orig_node *orig_node,
 			    struct batadv_hard_iface *recv_if);
+int batadv_send_skb_packet(struct sk_buff *skb,
+			   struct batadv_hard_iface *hard_iface,
+			   const u8 *dst_addr);
+int batadv_send_broadcast_skb(struct sk_buff *skb,
+			      struct batadv_hard_iface *hard_iface);
+int batadv_send_unicast_skb(struct sk_buff *skb,
+			    struct batadv_neigh_node *neigh_node);
 void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface);
 int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
 				    const struct sk_buff *skb,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index a6f0952..c56bb88 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -377,11 +377,13 @@ DECLARE_EWMA(throughput, 1024, 8)
  * @throughput: ewma link throughput towards this neighbor
  * @elp_interval: time interval between two ELP transmissions
  * @elp_latest_seqno: latest and best known ELP sequence number
+ * @last_unicast_tx: when the last unicast packet has been sent to this neighbor
  */
 struct batadv_hardif_neigh_node_bat_v {
 	struct ewma_throughput throughput;
 	u32 elp_interval;
 	u32 elp_latest_seqno;
+	unsigned long last_unicast_tx;
 };
 
 /**
-- 
2.7.0.rc3


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

* [B.A.T.M.A.N.] [PATCH v2 09/12] batman-adv: ELP - compute the metric based on the estimated throughput
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
                   ` (7 preceding siblings ...)
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 08/12] batman-adv: keep track of when unicast packets are sent Marek Lindner
@ 2016-01-16  8:40 ` Marek Lindner
  2016-01-19 15:22   ` Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 10/12] batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls Marek Lindner
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:40 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

From: Antonio Quartulli <antonio@open-mesh.com>

In case of wireless interface retrieve the throughput by
querying cfg80211. To perform this call a separate work
must be scheduled because the function may sleep and this
is not allowed within an RCU protected context (RCU in this
case is used to iterate over all the neighbours).

Use ethtool to retrieve information about an Ethernet link
like HALF/FULL_DUPLEX and advertised bandwidth (e.g.
100/10Mbps).

The metric is updated each time a new ELP packet is sent,
this way it is possible to timely react to a metric
variation which can imply (for example) a neighbour
disconnection.

Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 compat.h                   |  21 +++++
 net/batman-adv/bat_v.c     |   3 +
 net/batman-adv/bat_v_elp.c | 207 +++++++++++++++++++++++++++++++++++++++++++++
 net/batman-adv/bat_v_elp.h |   2 +
 net/batman-adv/bat_v_ogm.c |   2 +-
 net/batman-adv/main.h      |   4 +
 net/batman-adv/types.h     |  16 ++++
 7 files changed, 254 insertions(+), 1 deletion(-)

diff --git a/compat.h b/compat.h
index 7152237..454fa4c 100644
--- a/compat.h
+++ b/compat.h
@@ -170,6 +170,27 @@ static int __batadv_interface_kill_vid(struct net_device *dev, __be16 proto,\
 
 #endif /* < KERNEL_VERSION(3, 10, 0) */
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)
+
+/* the expected behaviour of this function is to return 0 on success, therefore
+ * it is possible to define it as 1 so that batman-adv thinks like something
+ * went wrong. It will then decide what to do.
+ */
+#define cfg80211_get_station(_a, _b, _c) (1)
+/* the following define substitute the expected_throughput field with a random
+ * one existing in the station_info struct. It can be random because due to the
+ * define above it will never be used. We need it only to make the code compile
+ */
+#define expected_throughput filled
+
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+
+#warning cfg80211 based throughput metric is only supported with Linux 3.15+
+
+#endif
+
+#endif /* < KERNEL_VERSION(3, 15, 0) */
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
 
 #define IFF_NO_QUEUE	0; dev->tx_queue_len = 0
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index d9cb5c4..ff31f2a 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -21,6 +21,7 @@
 #include <linux/atomic.h>
 #include <linux/cache.h>
 #include <linux/init.h>
+#include <linux/workqueue.h>
 
 #include "bat_v_elp.h"
 #include "bat_v_ogm.h"
@@ -65,6 +66,8 @@ static void
 batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh)
 {
 	ewma_throughput_init(&hardif_neigh->bat_v.throughput);
+	INIT_WORK(&hardif_neigh->bat_v.metric_work,
+		  batadv_v_elp_throughput_metric_update);
 }
 
 static void batadv_v_ogm_schedule(struct batadv_hard_iface *hard_iface)
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index 1e4d13c..f257897 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -22,19 +22,23 @@
 #include <linux/byteorder/generic.h>
 #include <linux/errno.h>
 #include <linux/etherdevice.h>
+#include <linux/ethtool.h>
 #include <linux/fs.h>
 #include <linux/if_ether.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
+#include <linux/kref.h>
 #include <linux/netdevice.h>
 #include <linux/random.h>
 #include <linux/rculist.h>
 #include <linux/rcupdate.h>
+#include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
 #include <linux/stddef.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
+#include <net/cfg80211.h>
 
 #include "bat_algo.h"
 #include "bat_v_ogm.h"
@@ -60,6 +64,168 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface)
 }
 
 /**
+ * batadv_v_elp_get_throughput - get the throughput towards a neighbour
+ * @neigh: the neighbour for which the throughput has to be obtained
+ *
+ * Return: the throughput towards the given neighbour.
+ */
+static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
+{
+	struct batadv_hard_iface *hard_iface = neigh->if_incoming;
+	struct station_info sinfo;
+	struct ethtool_cmd cmd;
+	u32 throughput;
+	int ret;
+
+	/* if the user specified a customised value for this interface, then
+	 * return it directly
+	 */
+	throughput =  atomic_read(&hard_iface->bat_v.throughput_override);
+	if (throughput != 0)
+		return throughput;
+
+	/* if this is a wireless device, then ask its throughput through
+	 * cfg80211 API
+	 */
+	if (batadv_is_wifi_netdev(hard_iface->net_dev)) {
+		if (hard_iface->net_dev->ieee80211_ptr) {
+			ret = cfg80211_get_station(hard_iface->net_dev,
+						   neigh->addr, &sinfo);
+			if (ret == -ENOENT) {
+				/* Node is not associated anymore! It would be
+				 * possible to delete this neighbor. For now set
+				 * the throughput metric to 0.
+				 */
+				return 0;
+			}
+			if (!ret)
+				return sinfo.expected_throughput / 10;
+		}
+
+		/* unsupported WiFi driver version */
+		goto default_throughput;
+	}
+
+	/* if not a wifi interface, check if this device provides data via
+	 * ethtool (e.g. an Ethernet adapter)
+	 */
+	memset(&cmd, 0, sizeof(cmd));
+	rtnl_lock();
+	ret = __ethtool_get_settings(hard_iface->net_dev, &cmd);
+	rtnl_unlock();
+	if (ret == 0) {
+		/* link characteristics might change over time */
+		if (cmd.duplex == DUPLEX_FULL)
+			hard_iface->bat_v.flags |= BATADV_FULL_DUPLEX;
+		else
+			hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX;
+
+		throughput = ethtool_cmd_speed(&cmd);
+		if (throughput && throughput != SPEED_UNKNOWN)
+			return throughput * 10;
+	}
+
+default_throughput:
+	if (!(hard_iface->bat_v.flags & BATADV_WARNING_DEFAULT)) {
+		batadv_info(hard_iface->soft_iface,
+			    "WiFi driver or ethtool info does not provide information about link speeds on interface %s, therefore defaulting to hardcoded throughput values of %d kbit/s. Consider overriding the throughput manually or checking your driver.\n",
+			    hard_iface->net_dev->name,
+			    BATADV_THROUGHPUT_DEFAULT_VALUE / 10);
+		hard_iface->bat_v.flags |= BATADV_WARNING_DEFAULT;
+	}
+
+	/* if none of the above cases apply, return the base_throughput */
+	return BATADV_THROUGHPUT_DEFAULT_VALUE;
+}
+
+/**
+ * batadv_v_elp_throughput_metric_update - worker updating the throughput metric
+ *  of a single hop neighbour
+ * @work: the work queue item
+ */
+void batadv_v_elp_throughput_metric_update(struct work_struct *work)
+{
+	struct batadv_hardif_neigh_node_bat_v *neigh_bat_v;
+	struct batadv_hardif_neigh_node *neigh;
+
+	neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v,
+				   metric_work);
+	neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node,
+			     bat_v);
+
+	ewma_throughput_add(&neigh->bat_v.throughput,
+			    batadv_v_elp_get_throughput(neigh));
+
+	/* decrement refcounter to balance increment performed before scheduling
+	 * this task
+	 */
+	batadv_hardif_neigh_put(neigh);
+}
+
+/**
+ * batadv_v_elp_wifi_neigh_probe - send link probing packets to a neighbour
+ * @neigh: the neighbour to probe
+ *
+ * Sends a predefined number of unicast wifi packets to a given neighbour in
+ * order to trigger the throughput estimation on this link by the RC algorithm.
+ * Packets are sent only if there there is not enough payload unicast traffic
+ * towards this neighbour..
+ *
+ * Return: True on success and false in case of error during skb preparation.
+ */
+static bool
+batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh)
+{
+	struct batadv_hard_iface *hard_iface = neigh->if_incoming;
+	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+	unsigned long last_tx_diff;
+	struct sk_buff *skb;
+	int probe_len, i;
+	int elp_skb_len;
+
+	/* this probing routine is for Wifi neighbours only */
+	if (!batadv_is_wifi_netdev(hard_iface->net_dev))
+		return true;
+
+	/* probe the neighbor only if no unicast packets have been sent
+	 * to it in the last 100 milliseconds: this is the rate control
+	 * algorithm sampling interval (minstrel). In this way, if not
+	 * enough traffic has been sent to the neighbor, batman-adv can
+	 * generate 2 probe packets and push the RC algorithm to perform
+	 * the sampling
+	 */
+	last_tx_diff = jiffies_to_msecs(jiffies - neigh->bat_v.last_unicast_tx);
+	if (last_tx_diff <= BATADV_ELP_PROBE_MAX_TX_DIFF)
+		return true;
+
+	probe_len = max_t(int, sizeof(struct batadv_elp_packet),
+			  BATADV_ELP_MIN_PROBE_SIZE);
+
+	for (i = 0; i < BATADV_ELP_PROBES_PER_NODE; i++) {
+		elp_skb_len = hard_iface->bat_v.elp_skb->len;
+		skb = skb_copy_expand(hard_iface->bat_v.elp_skb, 0,
+				      probe_len - elp_skb_len,
+				      GFP_ATOMIC);
+		if (!skb)
+			return false;
+
+		/* Tell the skb to get as big as the allocated space (we want
+		 * the packet to be exactly of that size to make the link
+		 * throughput estimation effective.
+		 */
+		skb_put(skb, probe_len - hard_iface->bat_v.elp_skb->len);
+
+		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
+			   "Sending unicast (probe) ELP packet on interface %s to %pM\n",
+			   hard_iface->net_dev->name, neigh->addr);
+
+		batadv_send_skb_packet(skb, hard_iface, neigh->addr);
+	}
+
+	return true;
+}
+
+/**
  * batadv_v_elp_periodic_work - ELP periodic task per interface
  * @work: work queue item
  *
@@ -67,6 +233,7 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface)
  */
 static void batadv_v_elp_periodic_work(struct work_struct *work)
 {
+	struct batadv_hardif_neigh_node *hardif_neigh;
 	struct batadv_hard_iface *hard_iface;
 	struct batadv_hard_iface_bat_v *bat_v;
 	struct batadv_elp_packet *elp_packet;
@@ -108,6 +275,37 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
 
 	atomic_inc(&hard_iface->bat_v.elp_seqno);
 
+	/* The throughput metric is updated on each sent packet. This way, if a
+	 * node is dead and no longer sends packets, batman-adv is still able to
+	 * react timely to its death.
+	 *
+	 * The throughput metric is updated by following these steps:
+	 * 1) if the hard_iface is wifi => send a number of unicast ELPs for
+	 *    probing/sampling to each neighbor
+	 * 2) update the throughput metric value of each neighbor (note that the
+	 *    value retrieved in this step might be 100ms old because the
+	 *    probing packets at point 1) could still be in the HW queue)
+	 */
+	rcu_read_lock();
+	hlist_for_each_entry_rcu(hardif_neigh, &hard_iface->neigh_list, list) {
+		if (!batadv_v_elp_wifi_neigh_probe(hardif_neigh))
+			/* if something goes wrong while probing, better to stop
+			 * sending packets immediately and reschedule the task
+			 */
+			break;
+
+		if (!kref_get_unless_zero(&hardif_neigh->refcount))
+			continue;
+
+		/* Reading the estimated throughput from cfg80211 is a task that
+		 * may sleep and that is not allowed in an rcu protected
+		 * context. Therefore schedule a task for that.
+		 */
+		queue_work(batadv_event_workqueue,
+			   &hardif_neigh->bat_v.metric_work);
+	}
+	rcu_read_unlock();
+
 restart_timer:
 	batadv_v_elp_start_timer(hard_iface);
 out:
@@ -146,6 +344,15 @@ int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface)
 	atomic_set(&hard_iface->bat_v.elp_seqno, random_seqno);
 	atomic_set(&hard_iface->bat_v.elp_interval, 500);
 
+	/* assume full-duplex by default */
+	hard_iface->bat_v.flags |= BATADV_FULL_DUPLEX;
+
+	/* warn the user (again) if there is no throughput data is available */
+	hard_iface->bat_v.flags &= ~BATADV_WARNING_DEFAULT;
+
+	if (batadv_is_wifi_netdev(hard_iface->net_dev))
+		hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX;
+
 	INIT_DELAYED_WORK(&hard_iface->bat_v.elp_wq,
 			  batadv_v_elp_periodic_work);
 	batadv_v_elp_start_timer(hard_iface);
diff --git a/net/batman-adv/bat_v_elp.h b/net/batman-adv/bat_v_elp.h
index 5a7bc39..e95f1bc 100644
--- a/net/batman-adv/bat_v_elp.h
+++ b/net/batman-adv/bat_v_elp.h
@@ -21,11 +21,13 @@
 #define _NET_BATMAN_ADV_BAT_V_ELP_H_
 
 struct sk_buff;
+struct work_struct;
 
 int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface);
 void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface);
 void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface);
 int batadv_v_elp_packet_recv(struct sk_buff *skb,
 			     struct batadv_hard_iface *if_incoming);
+void batadv_v_elp_throughput_metric_update(struct work_struct *work);
 
 #endif /* _NET_BATMAN_ADV_BAT_V_ELP_H_ */
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
index c800096..d9bcbe6 100644
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -339,7 +339,7 @@ static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv,
 	 */
 	if ((throughput > 10) &&
 	    (if_incoming == if_outgoing) &&
-	    (batadv_is_wifi_netdev(if_incoming->net_dev)))
+	    !(if_incoming->bat_v.flags & BATADV_FULL_DUPLEX))
 		return throughput / 2;
 
 	/* hop penalty of 255 equals 100% */
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index e6cef57..6386e45 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -62,6 +62,10 @@
 #define BATADV_TQ_TOTAL_BIDRECT_LIMIT 1
 
 /* B.A.T.M.A.N. V */
+#define BATADV_THROUGHPUT_DEFAULT_VALUE 10
+#define BATADV_ELP_PROBES_PER_NODE 2
+#define BATADV_ELP_MIN_PROBE_SIZE 200 /* bytes */
+#define BATADV_ELP_PROBE_MAX_TX_DIFF 100 /* milliseconds */
 #define BATADV_ELP_MAX_AGE 64
 #define BATADV_OGM_MAX_ORIGDIFF 5
 #define BATADV_OGM_MAX_AGE 64
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index c56bb88..9abfb3e 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -87,12 +87,25 @@ struct batadv_hard_iface_bat_iv {
 };
 
 /**
+ * enum batadv_v_hard_iface_flags - interface flags useful to B.A.T.M.A.N. V
+ * @BATADV_FULL_DUPLEX: tells if the connection over this link is full-duplex
+ * @BATADV_WARNING_DEFAULT: tells whether we have warned the user that no
+ *  throughput data is available for this interface and that default values are
+ *  assumed.
+ */
+enum batadv_v_hard_iface_flags {
+	BATADV_FULL_DUPLEX	= BIT(0),
+	BATADV_WARNING_DEFAULT	= BIT(1),
+};
+
+/**
  * struct batadv_hard_iface_bat_v - per hard-interface B.A.T.M.A.N. V data
  * @elp_interval: time interval between two ELP transmissions
  * @elp_seqno: current ELP sequence number
  * @elp_skb: base skb containing the ELP message to send
  * @elp_wq: workqueue used to schedule ELP transmissions
  * @throughput_override: throughput override to disable link auto-detection
+ * @flags: interface specific flags
  */
 struct batadv_hard_iface_bat_v {
 	atomic_t elp_interval;
@@ -100,6 +113,7 @@ struct batadv_hard_iface_bat_v {
 	struct sk_buff *elp_skb;
 	struct delayed_work elp_wq;
 	atomic_t throughput_override;
+	u8 flags;
 };
 
 /**
@@ -378,12 +392,14 @@ DECLARE_EWMA(throughput, 1024, 8)
  * @elp_interval: time interval between two ELP transmissions
  * @elp_latest_seqno: latest and best known ELP sequence number
  * @last_unicast_tx: when the last unicast packet has been sent to this neighbor
+ * @metric_work: work queue callback item for metric update
  */
 struct batadv_hardif_neigh_node_bat_v {
 	struct ewma_throughput throughput;
 	u32 elp_interval;
 	u32 elp_latest_seqno;
 	unsigned long last_unicast_tx;
+	struct work_struct metric_work;
 };
 
 /**
-- 
2.7.0.rc3


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

* [B.A.T.M.A.N.] [PATCH v2 10/12] batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
                   ` (8 preceding siblings ...)
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 09/12] batman-adv: ELP - compute the metric based on the estimated throughput Marek Lindner
@ 2016-01-16  8:40 ` Marek Lindner
  2016-01-19 15:24   ` Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 11/12] batman-adv: B.A.T.M.A.N. V - implement bat_orig_print API Marek Lindner
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:40 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

From: Antonio Quartulli <antonio@open-mesh.com>

Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 net/batman-adv/bat_v.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index ff31f2a..953c0d1 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -19,12 +19,15 @@
 #include "main.h"
 
 #include <linux/atomic.h>
+#include <linux/bug.h>
 #include <linux/cache.h>
 #include <linux/init.h>
+#include <linux/types.h>
 #include <linux/workqueue.h>
 
 #include "bat_v_elp.h"
 #include "bat_v_ogm.h"
+#include "originator.h"
 #include "packet.h"
 
 static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface)
@@ -78,6 +81,39 @@ static void batadv_v_ogm_emit(struct batadv_forw_packet *forw_packet)
 {
 }
 
+static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1,
+			      struct batadv_hard_iface *if_outgoing1,
+			      struct batadv_neigh_node *neigh2,
+			      struct batadv_hard_iface *if_outgoing2)
+{
+	struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2;
+
+	ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
+	ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
+
+	if (WARN_ON(!ifinfo1 || !ifinfo2))
+		return 0;
+
+	return ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput;
+}
+
+static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
+				  struct batadv_hard_iface *if_outgoing1,
+				  struct batadv_neigh_node *neigh2,
+				  struct batadv_hard_iface *if_outgoing2)
+{
+	struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2;
+	u32 threshold;
+
+	ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
+	ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
+
+	threshold = ifinfo1->bat_v.throughput / 4;
+	threshold = ifinfo1->bat_v.throughput - threshold;
+
+	return ifinfo2->bat_v.throughput > threshold;
+}
+
 static struct batadv_algo_ops batadv_batman_v __read_mostly = {
 	.name = "BATMAN_V",
 	.bat_iface_enable = batadv_v_iface_enable,
@@ -87,6 +123,8 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = {
 	.bat_hardif_neigh_init = batadv_v_hardif_neigh_init,
 	.bat_ogm_emit = batadv_v_ogm_emit,
 	.bat_ogm_schedule = batadv_v_ogm_schedule,
+	.bat_neigh_cmp = batadv_v_neigh_cmp,
+	.bat_neigh_is_similar_or_better = batadv_v_neigh_is_sob,
 };
 
 /**
-- 
2.7.0.rc3


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

* [B.A.T.M.A.N.] [PATCH v2 11/12] batman-adv: B.A.T.M.A.N. V - implement bat_orig_print API
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
                   ` (9 preceding siblings ...)
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 10/12] batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls Marek Lindner
@ 2016-01-16  8:40 ` Marek Lindner
  2016-01-19 15:25   ` Marek Lindner
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 12/12] batman-adv: B.A.T.M.A.N. V - implement bat_neigh_print API Marek Lindner
  2016-01-21 11:56 ` [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Sven Eckelmann
  12 siblings, 1 reply; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:40 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

From: Antonio Quartulli <antonio@open-mesh.com>

Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 net/batman-adv/bat_v.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)

diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index 953c0d1..a90117c 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -22,11 +22,17 @@
 #include <linux/bug.h>
 #include <linux/cache.h>
 #include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/netdevice.h>
+#include <linux/rculist.h>
+#include <linux/rcupdate.h>
+#include <linux/seq_file.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
 
 #include "bat_v_elp.h"
 #include "bat_v_ogm.h"
+#include "hash.h"
 #include "originator.h"
 #include "packet.h"
 
@@ -81,6 +87,104 @@ static void batadv_v_ogm_emit(struct batadv_forw_packet *forw_packet)
 {
 }
 
+/**
+ * batadv_v_orig_print_neigh - print neighbors for the originator table
+ * @orig_node: the orig_node for which the neighbors are printed
+ * @if_outgoing: outgoing interface for these entries
+ * @seq: debugfs table seq_file struct
+ *
+ * Must be called while holding an rcu lock.
+ */
+static void
+batadv_v_orig_print_neigh(struct batadv_orig_node *orig_node,
+			  struct batadv_hard_iface *if_outgoing,
+			  struct seq_file *seq)
+{
+	struct batadv_neigh_node *neigh_node;
+	struct batadv_neigh_ifinfo *n_ifinfo;
+
+	hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
+		n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
+		if (!n_ifinfo)
+			continue;
+
+		seq_printf(seq, " %pM (%9u.%1u)",
+			   neigh_node->addr,
+			   n_ifinfo->bat_v.throughput / 10,
+			   n_ifinfo->bat_v.throughput % 10);
+
+		batadv_neigh_ifinfo_put(n_ifinfo);
+	}
+}
+
+/**
+ * batadv_v_orig_print - print the originator table
+ * @bat_priv: the bat priv with all the soft interface information
+ * @seq: debugfs table seq_file struct
+ * @if_outgoing: the outgoing interface for which this should be printed
+ */
+static void batadv_v_orig_print(struct batadv_priv *bat_priv,
+				struct seq_file *seq,
+				struct batadv_hard_iface *if_outgoing)
+{
+	struct batadv_neigh_node *neigh_node;
+	struct batadv_hashtable *hash = bat_priv->orig_hash;
+	int last_seen_msecs, last_seen_secs;
+	struct batadv_orig_node *orig_node;
+	struct batadv_neigh_ifinfo *n_ifinfo;
+	unsigned long last_seen_jiffies;
+	struct hlist_head *head;
+	int batman_count = 0;
+	u32 i;
+
+	seq_printf(seq, "  %-15s %s (%11s) %17s [%10s]: %20s ...\n",
+		   "Originator", "last-seen", "throughput", "Nexthop",
+		   "outgoingIF", "Potential nexthops");
+
+	for (i = 0; i < hash->size; i++) {
+		head = &hash->table[i];
+
+		rcu_read_lock();
+		hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+			neigh_node = batadv_orig_router_get(orig_node,
+							    if_outgoing);
+			if (!neigh_node)
+				continue;
+
+			n_ifinfo = batadv_neigh_ifinfo_get(neigh_node,
+							   if_outgoing);
+			if (!n_ifinfo)
+				goto next;
+
+			last_seen_jiffies = jiffies - orig_node->last_seen;
+			last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
+			last_seen_secs = last_seen_msecs / 1000;
+			last_seen_msecs = last_seen_msecs % 1000;
+
+			seq_printf(seq, "%pM %4i.%03is (%9u.%1u) %pM [%10s]:",
+				   orig_node->orig, last_seen_secs,
+				   last_seen_msecs,
+				   n_ifinfo->bat_v.throughput / 10,
+				   n_ifinfo->bat_v.throughput % 10,
+				   neigh_node->addr,
+				   neigh_node->if_incoming->net_dev->name);
+
+			batadv_v_orig_print_neigh(orig_node, if_outgoing, seq);
+			seq_puts(seq, "\n");
+			batman_count++;
+
+next:
+			batadv_neigh_node_put(neigh_node);
+			if (n_ifinfo)
+				batadv_neigh_ifinfo_put(n_ifinfo);
+		}
+		rcu_read_unlock();
+	}
+
+	if (batman_count == 0)
+		seq_puts(seq, "No batman nodes in range ...\n");
+}
+
 static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1,
 			      struct batadv_hard_iface *if_outgoing1,
 			      struct batadv_neigh_node *neigh2,
@@ -123,6 +227,7 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = {
 	.bat_hardif_neigh_init = batadv_v_hardif_neigh_init,
 	.bat_ogm_emit = batadv_v_ogm_emit,
 	.bat_ogm_schedule = batadv_v_ogm_schedule,
+	.bat_orig_print = batadv_v_orig_print,
 	.bat_neigh_cmp = batadv_v_neigh_cmp,
 	.bat_neigh_is_similar_or_better = batadv_v_neigh_is_sob,
 };
-- 
2.7.0.rc3


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

* [B.A.T.M.A.N.] [PATCH v2 12/12] batman-adv: B.A.T.M.A.N. V - implement bat_neigh_print API
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
                   ` (10 preceding siblings ...)
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 11/12] batman-adv: B.A.T.M.A.N. V - implement bat_orig_print API Marek Lindner
@ 2016-01-16  8:40 ` Marek Lindner
  2016-01-19 15:26   ` Marek Lindner
  2016-01-21 11:56 ` [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Sven Eckelmann
  12 siblings, 1 reply; 34+ messages in thread
From: Marek Lindner @ 2016-01-16  8:40 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner, Antonio Quartulli

From: Linus Luessing <linus.luessing@web.de>

Lists all neighbours detected by the Echo Locating Protocol
(ELP) and their throughput metric.

Initially Developed by Linus during a 6 months trainee study
period in Ascom (Switzerland) AG.

Signed-off-by: Linus Luessing <linus.luessing@web.de>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 net/batman-adv/bat_v.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index a90117c..3315b9a 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -118,6 +118,60 @@ batadv_v_orig_print_neigh(struct batadv_orig_node *orig_node,
 }
 
 /**
+ * batadv_v_hardif_neigh_print - print a single ELP neighbour node
+ * @seq: neighbour table seq_file struct
+ * @hardif_neigh: hardif neighbour information
+ */
+static void
+batadv_v_hardif_neigh_print(struct seq_file *seq,
+			    struct batadv_hardif_neigh_node *hardif_neigh)
+{
+	int last_secs, last_msecs;
+	u32 throughput;
+
+	last_secs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) / 1000;
+	last_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) % 1000;
+	throughput = ewma_throughput_read(&hardif_neigh->bat_v.throughput);
+
+	seq_printf(seq, "%pM %4i.%03is (%9u.%1u) [%10s]\n",
+		   hardif_neigh->addr, last_secs, last_msecs, throughput / 10,
+		   throughput % 10, hardif_neigh->if_incoming->net_dev->name);
+}
+
+/**
+ * batadv_v_neigh_print - print the single hop neighbour list
+ * @bat_priv: the bat priv with all the soft interface information
+ * @seq: neighbour table seq_file struct
+ */
+static void batadv_v_neigh_print(struct batadv_priv *bat_priv,
+				 struct seq_file *seq)
+{
+	struct net_device *net_dev = (struct net_device *)seq->private;
+	struct batadv_hardif_neigh_node *hardif_neigh;
+	struct batadv_hard_iface *hard_iface;
+	int batman_count = 0;
+
+	seq_printf(seq, "  %-15s %s (%11s) [%10s]\n", "Neighbor",
+		   "last-seen", "throughput", "IF");
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
+		if (hard_iface->soft_iface != net_dev)
+			continue;
+
+		hlist_for_each_entry_rcu(hardif_neigh,
+					 &hard_iface->neigh_list, list) {
+			batadv_v_hardif_neigh_print(seq, hardif_neigh);
+			batman_count++;
+		}
+	}
+	rcu_read_unlock();
+
+	if (batman_count == 0)
+		seq_puts(seq, "No batman nodes in range ...\n");
+}
+
+/**
  * batadv_v_orig_print - print the originator table
  * @bat_priv: the bat priv with all the soft interface information
  * @seq: debugfs table seq_file struct
@@ -230,6 +284,7 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = {
 	.bat_orig_print = batadv_v_orig_print,
 	.bat_neigh_cmp = batadv_v_neigh_cmp,
 	.bat_neigh_is_similar_or_better = batadv_v_neigh_is_sob,
+	.bat_neigh_print = batadv_v_neigh_print,
 };
 
 /**
-- 
2.7.0.rc3


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

* Re: [B.A.T.M.A.N.] [PATCH v2 01/12] batman-adv: Add hard_iface specific sysfs wrapper macros for UINT
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 01/12] batman-adv: Add hard_iface specific sysfs wrapper macros for UINT Marek Lindner
@ 2016-01-19 15:08   ` Marek Lindner
  0 siblings, 0 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-19 15:08 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

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

On Saturday, January 16, 2016 16:40:08 Marek Lindner wrote:
> From: Linus Luessing <linus.luessing@web.de>
> 
> This allows us to easily add a sysfs parameter for an
> unsigned int later, which is not for a batman mesh interface
> (e.g. bat0), but for a common interface instead. It allows
> reading and writing an atomic_t in hard_iface (instead of
> bat_priv compared to the mesh variant).
> 
> Developed by Linus during a 6 months trainee study period in
> Ascom (Switzerland) AG.
> 
> Signed-off-by: Linus Luessing <linus.luessing@web.de>
> Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
> [antonio@open-mesh.com: rename functions and move macros]
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
>  net/batman-adv/sysfs.c | 49
> +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49
> insertions(+)

Applied in revision ec46535.

Thanks,
Marek

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

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

* Re: [B.A.T.M.A.N.] [PATCH v2 02/12] batman-adv: ELP - adding basic infrastructure
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 02/12] batman-adv: ELP - adding basic infrastructure Marek Lindner
@ 2016-01-19 15:10   ` Marek Lindner
  0 siblings, 0 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-19 15:10 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

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

On Saturday, January 16, 2016 16:40:09 Marek Lindner wrote:
> From: Linus Luessing <linus.luessing@web.de>
> 
> The B.A.T.M.A.N. protocol originally only used a single
> message type (called OGM) to determine the link qualities to
> the direct neighbors and spreading these link quality
> information through the whole mesh. This procedure is
> summarized on the BATMAN concept page and explained in
> details in the RFC draft published in 2008.
> 
> This approach was chosen for its simplicity during the
> protocol design phase and the implementation. However, it
> also bears some drawbacks:
> 
>  *  Wireless interfaces usually come with some packet loss,
>     therefore a higher broadcast rate is desirable to allow
>     a fast reaction on flaky connections.
>     Other interfaces of the same host might be connected to
>     Ethernet LANs / VPNs / etc which rarely exhibit packet
>     loss would benefit from a lower broadcast rate to reduce
>     overhead.
>  *  It generally is more desirable to detect local link
>     quality changes at a faster rate than propagating all
>     these changes through the entire mesh (the far end of
>     the mesh does not need to care about local link quality
>     changes that much). Other optimizations strategies, like
>     reducing overhead, might be possible if OGMs weren't
>     used for all tasks in the mesh at the same time.
> 
> As a result detecting local link qualities shall be handled
> by an independent message type, ELP, whereas the OGM message
> type remains responsible for flooding the mesh with these
> link quality information and determining the overall path
> transmit qualities.
> 
> Developed by Linus during a 6 months trainee study period in
> Ascom (Switzerland) AG.
> 
> Signed-off-by: Linus Luessing <linus.luessing@web.de>
> Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
>  Makefile                   |   3 +
>  README.external            |   1 +
>  gen-compat-autoconf.sh     |   1 +
>  net/batman-adv/Kconfig     |  14 ++++
>  net/batman-adv/Makefile    |   2 +
>  net/batman-adv/bat_algo.h  |  15 +++-
>  net/batman-adv/bat_v.c     |  74 +++++++++++++++++
>  net/batman-adv/bat_v_elp.c | 193
> +++++++++++++++++++++++++++++++++++++++++++++ net/batman-adv/bat_v_elp.h
> |  27 +++++++
>  net/batman-adv/main.c      |   1 +
>  net/batman-adv/packet.h    |  20 +++++
>  net/batman-adv/types.h     |  18 +++++
>  12 files changed, 368 insertions(+), 1 deletion(-)
>  create mode 100644 net/batman-adv/bat_v.c
>  create mode 100644 net/batman-adv/bat_v_elp.c
>  create mode 100644 net/batman-adv/bat_v_elp.h

Applied in revision a4b88af.

Thanks,
Marek

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

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

* Re: [B.A.T.M.A.N.] [PATCH v2 03/12] batman-adv: ELP - creating neighbor structures
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 03/12] batman-adv: ELP - creating neighbor structures Marek Lindner
@ 2016-01-19 15:11   ` Marek Lindner
  0 siblings, 0 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-19 15:11 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

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

On Saturday, January 16, 2016 16:40:10 Marek Lindner wrote:
> From: Linus Luessing <linus.luessing@web.de>
> 
> Initially developed by Linus during a 6 months trainee study
> period in Ascom (Switzerland) AG.
> 
> Signed-off-by: Linus Luessing <linus.luessing@web.de>
> Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
>  compat-include/linux/average.h |  74 ++++++++++++++++++++
>  net/batman-adv/bat_v.c         |  23 ++++++-
>  net/batman-adv/bat_v_elp.c     | 152
> +++++++++++++++++++++++++++++++++++++++++
> net/batman-adv/bat_v_elp.h     |   4 ++
>  net/batman-adv/main.h          |   3 +
>  net/batman-adv/types.h         |  33 +++++++++
>  6 files changed, 288 insertions(+), 1 deletion(-)
>  create mode 100644 compat-include/linux/average.h

Applied in revision 2c2fe0b.

Thanks,
Marek

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

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

* Re: [B.A.T.M.A.N.] [PATCH v2 04/12] batman-adv: ELP - adding sysfs parameter for elp interval
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 04/12] batman-adv: ELP - adding sysfs parameter for elp interval Marek Lindner
@ 2016-01-19 15:12   ` Marek Lindner
  0 siblings, 0 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-19 15:12 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

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

On Saturday, January 16, 2016 16:40:11 Marek Lindner wrote:
> From: Linus Luessing <linus.luessing@web.de>
> 
> This parameter can be set individually on each interface and
> allows the configuration of the elp interval for the link
> quality measurements during runtime. Usually it is desirable
> to set it to a higher (= slower) value on interfaces which
> have a more static characteristic (e.g. wired interfaces)
> or very dense neighbourhoods to reduce overhead.
> 
> Developed by Linus during a 6 months trainee study period in
> Ascom (Switzerland) AG.
> 
> Signed-off-by: Linus Luessing <linus.luessing@web.de>
> Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
> [antonio@open-mesh.com: respin on top of the latest master]
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
>  Documentation/ABI/testing/sysfs-class-net-batman-adv | 8 +++++++-
>  net/batman-adv/sysfs.c                               | 7 +++++++
>  2 files changed, 14 insertions(+), 1 deletion(-)

Applied in revision 82da7d6.

Thanks,
Marek

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

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

* Re: [B.A.T.M.A.N.] [PATCH v2 05/12] batman-adv: OGMv2 - add basic infrastructure
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 05/12] batman-adv: OGMv2 - add basic infrastructure Marek Lindner
@ 2016-01-19 15:14   ` Marek Lindner
  0 siblings, 0 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-19 15:14 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

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

On Saturday, January 16, 2016 16:40:12 Marek Lindner wrote:
> From: Antonio Quartulli <antonio@open-mesh.com>
> 
> This is the initial implementation of the new OGM protocol
> (version 2). It has been designed to work on top of the
> newly added ELP.
> 
> In the previous version the OGM protocol was used to both
> measure link qualities and flood the network with the metric
> information. In this version the protocol is in charge of
> the latter task only, leaving the former to ELP.
> 
> This means being able to decouple the interval used by the
> neighbor discovery from the OGM broadcasting, which revealed
> to be costly in dense networks and needed to be relaxed so
> leading to a less responsive routing protocol.
> 
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
>  net/batman-adv/Makefile    |   1 +
>  net/batman-adv/bat_algo.h  |  13 +++
>  net/batman-adv/bat_v.c     |  51 ++++++++-
>  net/batman-adv/bat_v_ogm.c | 279
> +++++++++++++++++++++++++++++++++++++++++++++ net/batman-adv/bat_v_ogm.h
> |  32 ++++++
>  net/batman-adv/main.c      |   6 +
>  net/batman-adv/main.h      |   1 +
>  net/batman-adv/packet.h    |  29 +++++
>  net/batman-adv/types.h     |  18 +++
>  9 files changed, 427 insertions(+), 3 deletions(-)
>  create mode 100644 net/batman-adv/bat_v_ogm.c
>  create mode 100644 net/batman-adv/bat_v_ogm.h

Applied in revision 6328353.

Thanks,
Marek

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

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

* Re: [B.A.T.M.A.N.] [PATCH v2 06/12] batman-adv: OGMv2 - implement originators logic
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 06/12] batman-adv: OGMv2 - implement originators logic Marek Lindner
@ 2016-01-19 15:15   ` Marek Lindner
  0 siblings, 0 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-19 15:15 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

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

On Saturday, January 16, 2016 16:40:13 Marek Lindner wrote:
> From: Antonio Quartulli <antonio@open-mesh.com>
> 
> Add the support for recognising new originators in the
> network and rebroadcast their OGMs.
> 
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
> v2:
> 
>  - rebroadcast packet immediately after best neighbor timeout
>  - add a flag to avoid forwarding the same OGMs multiple times
>  - move TVLV processing out of update_route() and into
> batadv_v_ogm_process_per_outif() - code comments improvements (typ0s,
> clarifications, etc)
>  - mark OGM packet as new when protection window is started
>  - remove redundant throughput checks
>  - simplify/fix best neighbor check
> 
>  net/batman-adv/bat_v_elp.c |  41 +---
>  net/batman-adv/bat_v_ogm.c | 556
> ++++++++++++++++++++++++++++++++++++++++++++- net/batman-adv/bat_v_ogm.h
> |   4 +
>  net/batman-adv/main.h      |   2 +
>  net/batman-adv/types.h     |   4 +
>  5 files changed, 566 insertions(+), 41 deletions(-)

Applied in revision 667996e.

Thanks,
Marek

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

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

* Re: [B.A.T.M.A.N.] [PATCH v2 07/12] batman-adv: add throughput override attribute to hard_ifaces
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 07/12] batman-adv: add throughput override attribute to hard_ifaces Marek Lindner
@ 2016-01-19 15:16   ` Marek Lindner
  0 siblings, 0 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-19 15:16 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

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

On Saturday, January 16, 2016 16:40:14 Marek Lindner wrote:
> From: Antonio Quartulli <antonio@open-mesh.com>
> 
> This attribute is exported to user space to disable the link
> throughput auto-detection by setting a fixed value.
> The throughput override value is used when batman-adv is
> computing the link throughput towards a neighbour.
> 
> If the value is set to 0 then batman-adv will try to detect
> the throughput by itself.
> 
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
>  .../ABI/testing/sysfs-class-net-batman-adv         |  9 +++
>  net/batman-adv/bat_v.c                             |  6 ++
>  net/batman-adv/gateway_common.c                    |  4 +-
>  net/batman-adv/gateway_common.h                    |  2 +
>  net/batman-adv/sysfs.c                             | 74
> ++++++++++++++++++++++
> net/batman-adv/types.h                             |  2 +
>  6 files changed, 95 insertions(+), 2 deletions(-)

Applied in revision c513176.

Thanks,
Marek

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

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

* Re: [B.A.T.M.A.N.] [PATCH v2 08/12] batman-adv: keep track of when unicast packets are sent
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 08/12] batman-adv: keep track of when unicast packets are sent Marek Lindner
@ 2016-01-19 15:20   ` Marek Lindner
  0 siblings, 0 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-19 15:20 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

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

On Saturday, January 16, 2016 16:40:15 Marek Lindner wrote:
> From: Antonio Quartulli <antonio@open-mesh.com>
> 
> To enable ELP to send probing packets over wireless links
> only if needed, batman-adv must keep track of the last time
> it sent a unicast packet towards every neighbour.
> 
> For this purpose a 2 main changes are introduced:
> 1) a new member of the elp_neigh_node structure stores the
>    last time a unicast packet was sent towards this neighbour;
> 2) a wrapper function for sending unicast packets is
>    implemented. This function will simply update the member
>    describe din point 1) and then forward the packet to the
>    real sending routine.
> 
> Point 2) implies that any code-path leading to a unicast
> sending now has to use the new wrapper.
> 
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
>  net/batman-adv/bat_iv_ogm.c            |  2 +-
>  net/batman-adv/bat_v_elp.c             |  2 +-
>  net/batman-adv/bat_v_ogm.c             |  2 +-
>  net/batman-adv/distributed-arp-table.c |  4 +--
>  net/batman-adv/fragmentation.c         |  8 ++---
>  net/batman-adv/icmp_socket.c           |  2 +-
>  net/batman-adv/network-coding.c        | 22 +++++++-------
>  net/batman-adv/send.c                  | 55
> +++++++++++++++++++++++++++++----- net/batman-adv/send.h                  |
> 10 +++++--
>  net/batman-adv/types.h                 |  2 ++
>  10 files changed, 75 insertions(+), 34 deletions(-)

Applied in revision cdc4545.

Thanks,
Marek

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

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

* Re: [B.A.T.M.A.N.] [PATCH v2 09/12] batman-adv: ELP - compute the metric based on the estimated throughput
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 09/12] batman-adv: ELP - compute the metric based on the estimated throughput Marek Lindner
@ 2016-01-19 15:22   ` Marek Lindner
  0 siblings, 0 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-19 15:22 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

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

On Saturday, January 16, 2016 16:40:16 Marek Lindner wrote:
> From: Antonio Quartulli <antonio@open-mesh.com>
> 
> In case of wireless interface retrieve the throughput by
> querying cfg80211. To perform this call a separate work
> must be scheduled because the function may sleep and this
> is not allowed within an RCU protected context (RCU in this
> case is used to iterate over all the neighbours).
> 
> Use ethtool to retrieve information about an Ethernet link
> like HALF/FULL_DUPLEX and advertised bandwidth (e.g.
> 100/10Mbps).
> 
> The metric is updated each time a new ELP packet is sent,
> this way it is possible to timely react to a metric
> variation which can imply (for example) a neighbour
> disconnection.
> 
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
>  compat.h                   |  21 +++++
>  net/batman-adv/bat_v.c     |   3 +
>  net/batman-adv/bat_v_elp.c | 207
> +++++++++++++++++++++++++++++++++++++++++++++ net/batman-adv/bat_v_elp.h
> |   2 +
>  net/batman-adv/bat_v_ogm.c |   2 +-
>  net/batman-adv/main.h      |   4 +
>  net/batman-adv/types.h     |  16 ++++
>  7 files changed, 254 insertions(+), 1 deletion(-)

Applied in revision 5c32451.

Thanks,
Marek

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

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

* Re: [B.A.T.M.A.N.] [PATCH v2 10/12] batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 10/12] batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls Marek Lindner
@ 2016-01-19 15:24   ` Marek Lindner
  0 siblings, 0 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-19 15:24 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

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

On Saturday, January 16, 2016 16:40:17 Marek Lindner wrote:
> From: Antonio Quartulli <antonio@open-mesh.com>
> 
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
>  net/batman-adv/bat_v.c | 38 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)

Applied in revision b05bbab.

Thanks,
Marek

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

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

* Re: [B.A.T.M.A.N.] [PATCH v2 11/12] batman-adv: B.A.T.M.A.N. V - implement bat_orig_print API
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 11/12] batman-adv: B.A.T.M.A.N. V - implement bat_orig_print API Marek Lindner
@ 2016-01-19 15:25   ` Marek Lindner
  0 siblings, 0 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-19 15:25 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

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

On Saturday, January 16, 2016 16:40:18 Marek Lindner wrote:
> From: Antonio Quartulli <antonio@open-mesh.com>
> 
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
>  net/batman-adv/bat_v.c | 105
> +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105
> insertions(+)

Applied in revision 662b7c1.

Thanks,
Marek

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

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

* Re: [B.A.T.M.A.N.] [PATCH v2 12/12] batman-adv: B.A.T.M.A.N. V - implement bat_neigh_print API
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 12/12] batman-adv: B.A.T.M.A.N. V - implement bat_neigh_print API Marek Lindner
@ 2016-01-19 15:26   ` Marek Lindner
  0 siblings, 0 replies; 34+ messages in thread
From: Marek Lindner @ 2016-01-19 15:26 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

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

On Saturday, January 16, 2016 16:40:19 Marek Lindner wrote:
> From: Linus Luessing <linus.luessing@web.de>
> 
> Lists all neighbours detected by the Echo Locating Protocol
> (ELP) and their throughput metric.
> 
> Initially Developed by Linus during a 6 months trainee study
> period in Ascom (Switzerland) AG.
> 
> Signed-off-by: Linus Luessing <linus.luessing@web.de>
> Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
>  net/batman-adv/bat_v.c | 55
> ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55
> insertions(+)

Applied in revision 342f7f3.

Thanks,
Marek

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

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

* Re: [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2
  2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
                   ` (11 preceding siblings ...)
  2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 12/12] batman-adv: B.A.T.M.A.N. V - implement bat_neigh_print API Marek Lindner
@ 2016-01-21 11:56 ` Sven Eckelmann
  2016-01-21 13:47   ` [B.A.T.M.A.N.] OpenWrt cfg80211.h station_info incompatibility with kernel+mac80211 [was: B.A.T.M.A.N. V leaves the nest v2] Sven Eckelmann
  12 siblings, 1 reply; 34+ messages in thread
From: Sven Eckelmann @ 2016-01-21 11:56 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

Just installed in on some hardware (2x OM5P + OpenWrt 44654 + compat-wireless
2015-10-26) and enabled BATMAN_V.

/etc/config/wireless:
====================

config wifi-iface 'wmesh'
        option device 'radio0'
        option ifname 'adhoc0'
        option network 'batnet'
        option mode 'adhoc'
        option ssid 'mesh'
        option 'mcast_rate' '18000'
        option bssid '02:CA:FE:CA:CA:40'


/etc/config/network
===================

config interface 'batnet'
        option mtu '1532'
        option proto 'batadv'
        option mesh 'bat0'
        option routing_algo 'BATMAN_V'

The result was:
==============

[  168.540000] CPU 0 Unable to handle kernel paging request at virtual address fffffff0, epc == 86d8301c, ra == 86d8301c
[  168.550000] Oops[#1]:
[  168.550000] CPU: 0 PID: 265 Comm: kworker/u2:2 Tainted: P               3.18.8 #1
[  168.550000] Workqueue: bat_events batadv_v_elp_throughput_metric_update [batman_adv]
[  168.550000] task: 878826c0 ti: 87a24000 task.ti: 87a24000
[  168.550000] $ 0   : 00000000 00000001 00000000 fffffffe
[  168.550000] $ 4   : 86a5cf00 00000000 00000000 00000000
[  168.550000] $ 8   : 00000011 c4653600 ffffffff 00000001
[  168.550000] $12   : 00000000 0000000c 00000000 00000000
[  168.550000] $16   : 00000000 00000000 87804a1e 868f5000
[  168.550000] $20   : 00000000 00000000 87804a10 87804a00
[  168.550000] $24   : 00000002 86d1a0e4                  
[  168.550000] $28   : 87a24000 87a25e40 00000088 86d8301c
[  168.550000] Hi    : 00000000
[  168.550000] Lo    : 00000000
[  168.550000] epc   : 86d8301c batadv_v_elp_throughput_metric_update+0x20/0x58 [batman_adv]
[  168.550000]     Tainted: P              
[  168.550000] ra    : 86d8301c batadv_v_elp_throughput_metric_update+0x20/0x58 [batman_adv]
[  168.550000] Status: 1100fc03 KERNEL EXL IE 
[  168.550000] Cause : 00800008
[  168.550000] BadVA : fffffff0
[  168.550000] PrId  : 00019750 (MIPS 74Kc)
[  168.550000] Modules linked in: iptable_nat ath9k nf_nat_pptp nf_nat_ipv4 nf_nat_amanda nf_conntrack_pptp nf_conntrack_ipv6 nf_conntrack_ipv4 nf_conntrack_amanda ipt_REJECT ipt_MASQUERADE ath9k_common xt_time xt_tcpudp xt_tcpmss xt_string xt_statistic xt_state xt_recent xt_quota xt_pkttype xt_physdev xt_owner xt_nat xt_multiport xt_mark xt_mac xt_limit xt_length xt_id xt_hl xt_helper xt_ecn xt_dscp xt_conntrack xt_connmark xt_connlimit xt_connbytes xt_comment xt_addrtype xt_TCPMSS xt_REDIRECT xt_NETMAP xt_LOG xt_HL xt_DSCP xt_CT xt_CLASSIFY ts_kmp ts_fsm ts_bm nf_reject_ipv4 nf_nat_tftp nf_nat_snmp_basic nf_nat_sip nf_nat_proto_gre nf_nat_masquerade_ipv4 nf_nat_irc nf_nat_h323 nf_nat_ftp nf_nat nf_log_ipv4 nf_defrag_ipv6 nf_defrag_ipv4 nf_conntrack_tftp nf_conntrack_snmp nf_conntrack_sip nf_conntrack_rtcache nf_conntrack_proto_gre nf_conntrack_irc nf_conntrack_h323 nf_conntrack_ftp nf_conntrack_broadcast iptable_raw iptable_mangle iptable_filter ipt_ECN ip_tables crc_ccitt ath9k_hw em_nbyte sch_codel sch_prio sch_dsmark act_ipt sch_gred em_meta sch_htb cls_basic sch_netem act_police em_text sch_tbf sch_sfq em_cmp sch_red act_skbedit act_mirred em_u32 cls_u32 cls_tcindex cls_flow cls_route cls_fw sch_hfsc sch_ingress tmp421 hwmon batman_adv libcrc32c crc16 ath10k_pci ath10k_core ath mac80211 cfg80211 compat UDSMARK udsmac i2c_dev tc_classid_mapper(P) filter_group classifier_dns(P) classifier_netblock(P) classifier_bittorrent(P) classifier_rtmp(P) classifier_ssl(P) classifier_content(P) classifier_skype(P) kernel_classifier nf_conntrack xt_set ip_set_list_set ip_set_hash_netport ip_set_hash_netiface ip_set_hash_net ip_set_hash_ipportnet ip_set_hash_ipportip ip_set_hash_ipport ip_set_hash_ip ip_set_bitmap_port ip_set_bitmap_ipmac ip_set_bitmap_ip ip_set nfnetlink ip6t_REJECT nf_reject_ipv6 nf_log_ipv6 nf_log_common ip6table_raw ip6table_mangle ip6table_filter ip6_tables x_tables ifb tun ipv6 arc4 crypto_blkcipher input_polldev gpio_button_hotplug button_hotplug input_core ag71xx crc32c_generic crypto_hash
[  168.550000] Process kworker/u2:2 (pid: 265, threadinfo=87a24000, task=878826c0, tls=00000000)
[  168.550000] Stack : 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
          803496de 800665ac 00000000 00000000 00000000 00000000 00000000 00000000
          87804a00 879cf198 8030bb3e 00000001 00000000 00000000 00000000 00000000
          00000010 80123ad4 879fa100 801232d0 879cf21e 879cf180 00000000 00000000
          00000000 00000000 00000000 00000000 00000000 00000000 fffffffe 00000002
          ...
[  168.550000] Call Trace:
[  168.550000] [<86d8301c>] batadv_v_elp_throughput_metric_update+0x20/0x58 [batman_adv]
[  168.550000] 
[  168.550000]

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

* [B.A.T.M.A.N.] OpenWrt cfg80211.h station_info incompatibility with kernel+mac80211 [was: B.A.T.M.A.N. V leaves the nest v2]
  2016-01-21 11:56 ` [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Sven Eckelmann
@ 2016-01-21 13:47   ` Sven Eckelmann
  2016-01-21 13:55     ` Felix Fietkau
  0 siblings, 1 reply; 34+ messages in thread
From: Sven Eckelmann @ 2016-01-21 13:47 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Felix Fietkau, openwrt-devel, Marek Lindner

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

On Thursday 21 January 2016 12:56:01 Sven Eckelmann wrote:
> Just installed in on some hardware (2x OM5P + OpenWrt 44654 + compat-wireless
> 2015-10-26) and enabled BATMAN_V.
>
> [  168.540000] CPU 0 Unable to handle kernel paging request at virtual address fffffff0, epc == 86d8301c, ra == 86d8301c
> [  168.550000] Oops[#1]:
> [  168.550000] CPU: 0 PID: 265 Comm: kworker/u2:2 Tainted: P               3.18.8 #1
> [  168.550000] Workqueue: bat_events batadv_v_elp_throughput_metric_update [batman_adv]
[..]
> [  168.550000] epc   : 86d8301c batadv_v_elp_throughput_metric_update+0x20/0x58 [batman_adv]
> [  168.550000]     Tainted: P              
> [  168.550000] ra    : 86d8301c batadv_v_elp_throughput_metric_update+0x20/0x58 [batman_adv]

Who knew that struct station_info changed in v3.18-6219-g6de3980,
v3.18-6235-gb51f3be and v3.18-6217-ga76b194? Wieder keiner!? :)

So what basically happened was a stack corruption causing the return address
to be bogus. This only happened because the kernel version of cfg80211.h (which
is used to compile batman-adv) is different than the version in the mac80211
package (which is used at runtime) I have now synced that structure between the
OpenWrt kernel and the used compat-wireless, rebuild my OpenWrt and tried again.
I hope this helps anyone trying to use B.A.T.M.A.N. V on OpenWrt.

@Felix, would it be ok for you when I propose a
"*-sync-cfg80211-station_info.patch" for the 3.18 generic kernel patches?
Or do you have a good idea how to force the openwrt-routing batman-adv package
against the cfg80211.h of compat-wireless?

Kind regards,
	Sven

[-- Attachment #2: 999-sync-cfg80211-station_info.patch --]
[-- Type: text/x-patch, Size: 4610 bytes --]

From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 21 Jan 2016 14:07:32 +0100
Subject: [PATCH] sync cfg80211 station_info

batman-adv v2016.0 with B.A.T.M.A.N. V enabled will query the cfg80211
module for wireless station information. But the module is compiled against
the OpenWrt kernel but will be with the cfg80211 module from the mac80211
package. The result is a stack corruption when the definition of these two
headers are different.

But the cfg80211.h from the kernel can be synced easily against the
compat-wireless patch because it should not be used by the OpenWrt kernel.

This problem happens for example with the kernel v3.18 and compat-wireless
generated from 3.19 or later. The patch tries to avoid this by synching the
structure against mac80211 2016-01-10.
---
 include/net/cfg80211.h | 47 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index a2ddcf2..60c91cf 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -945,12 +945,14 @@ enum rate_info_flags {
  * @mcs: mcs index if struct describes a 802.11n bitrate
  * @legacy: bitrate in 100kbit/s for 802.11abg
  * @nss: number of streams (VHT only)
+ * @bw: bandwidth (from &enum rate_info_bw)
  */
 struct rate_info {
 	u8 flags;
 	u8 mcs;
 	u16 legacy;
 	u8 nss;
+	u8 bw;
 };
 
 /**
@@ -984,6 +986,24 @@ struct sta_bss_parameters {
 	u16 beacon_interval;
 };
 
+/**
+ * struct cfg80211_tid_stats - per-TID statistics
+ * @filled: bitmap of flags using the bits of &enum nl80211_tid_stats to
+ *	indicate the relevant values in this struct are filled
+ * @rx_msdu: number of received MSDUs
+ * @tx_msdu: number of (attempted) transmitted MSDUs
+ * @tx_msdu_retries: number of retries (not counting the first) for
+ *	transmitted MSDUs
+ * @tx_msdu_failed: number of failed transmitted MSDUs
+ */
+struct cfg80211_tid_stats {
+	u32 filled;
+	u64 rx_msdu;
+	u64 tx_msdu;
+	u64 tx_msdu_retries;
+	u64 tx_msdu_failed;
+};
+
 #define IEEE80211_MAX_CHAINS	4
 
 /**
@@ -991,11 +1011,12 @@ struct sta_bss_parameters {
  *
  * Station information filled by driver for get_station() and dump_station.
  *
- * @filled: bitflag of flags from &enum station_info_flags
+ * @filled: bitflag of flags using the bits of &enum nl80211_sta_info to
+ *	indicate the relevant values in this struct for them
  * @connected_time: time(in secs) since a station is last connected
  * @inactive_time: time since last station activity (tx/rx) in milliseconds
- * @rx_bytes: bytes received from this station
- * @tx_bytes: bytes transmitted to this station
+ * @rx_bytes: bytes (size of MPDUs) received from this station
+ * @tx_bytes: bytes (size of MPDUs) transmitted to this station
  * @llid: mesh local link id
  * @plid: mesh peer link id
  * @plink_state: mesh peer link state
@@ -1008,10 +1029,10 @@ struct sta_bss_parameters {
  * @chain_signal_avg: per-chain signal strength average in dBm
  * @txrate: current unicast bitrate from this station
  * @rxrate: current unicast bitrate to this station
- * @rx_packets: packets received from this station
- * @tx_packets: packets transmitted to this station
- * @tx_retries: cumulative retry counts
- * @tx_failed: number of failed transmissions (retries exceeded, no ACK)
+ * @rx_packets: packets (MSDUs & MMPDUs) received from this station
+ * @tx_packets: packets (MSDUs & MMPDUs) transmitted to this station
+ * @tx_retries: cumulative retry counts (MPDUs)
+ * @tx_failed: number of failed transmissions (MPDUs) (retries exceeded, no ACK)
  * @rx_dropped_misc:  Dropped for un-specified reason.
  * @bss_param: current BSS parameters
  * @generation: generation number for nl80211 dumps.
@@ -1031,6 +1052,11 @@ struct sta_bss_parameters {
  * @nonpeer_pm: non-peer mesh STA power save mode
  * @expected_throughput: expected throughput in kbps (including 802.11 headers)
  *	towards this station.
+ * @rx_beacon: number of beacons received from this peer
+ * @rx_beacon_signal_avg: signal strength average (in dBm) for beacons received
+ *	from this peer
+ * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last
+ *	(IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs.
  */
 struct station_info {
 	u32 filled;
@@ -1071,10 +1097,9 @@ struct station_info {
 
 	u32 expected_throughput;
 
-	/*
-	 * Note: Add a new enum station_info_flags value for each new field and
-	 * use it to check which fields are initialized.
-	 */
+	u64 rx_beacon;
+	u8 rx_beacon_signal_avg;
+	struct cfg80211_tid_stats pertid[IEEE80211_NUM_TIDS + 1];
 };
 
 /**

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

* Re: [B.A.T.M.A.N.] OpenWrt cfg80211.h station_info incompatibility with kernel+mac80211 [was: B.A.T.M.A.N. V leaves the nest v2]
  2016-01-21 13:47   ` [B.A.T.M.A.N.] OpenWrt cfg80211.h station_info incompatibility with kernel+mac80211 [was: B.A.T.M.A.N. V leaves the nest v2] Sven Eckelmann
@ 2016-01-21 13:55     ` Felix Fietkau
  2016-01-21 14:03       ` Sven Eckelmann
  0 siblings, 1 reply; 34+ messages in thread
From: Felix Fietkau @ 2016-01-21 13:55 UTC (permalink / raw)
  To: Sven Eckelmann, b.a.t.m.a.n; +Cc: openwrt-devel, Marek Lindner

On 2016-01-21 14:47, Sven Eckelmann wrote:
> On Thursday 21 January 2016 12:56:01 Sven Eckelmann wrote:
>> Just installed in on some hardware (2x OM5P + OpenWrt 44654 + compat-wireless
>> 2015-10-26) and enabled BATMAN_V.
>>
>> [  168.540000] CPU 0 Unable to handle kernel paging request at virtual address fffffff0, epc == 86d8301c, ra == 86d8301c
>> [  168.550000] Oops[#1]:
>> [  168.550000] CPU: 0 PID: 265 Comm: kworker/u2:2 Tainted: P               3.18.8 #1
>> [  168.550000] Workqueue: bat_events batadv_v_elp_throughput_metric_update [batman_adv]
> [..]
>> [  168.550000] epc   : 86d8301c batadv_v_elp_throughput_metric_update+0x20/0x58 [batman_adv]
>> [  168.550000]     Tainted: P              
>> [  168.550000] ra    : 86d8301c batadv_v_elp_throughput_metric_update+0x20/0x58 [batman_adv]
> 
> Who knew that struct station_info changed in v3.18-6219-g6de3980,
> v3.18-6235-gb51f3be and v3.18-6217-ga76b194? Wieder keiner!? :)
> 
> So what basically happened was a stack corruption causing the return address
> to be bogus. This only happened because the kernel version of cfg80211.h (which
> is used to compile batman-adv) is different than the version in the mac80211
> package (which is used at runtime) I have now synced that structure between the
> OpenWrt kernel and the used compat-wireless, rebuild my OpenWrt and tried again.
> I hope this helps anyone trying to use B.A.T.M.A.N. V on OpenWrt.
> 
> @Felix, would it be ok for you when I propose a
> "*-sync-cfg80211-station_info.patch" for the 3.18 generic kernel patches?
> Or do you have a good idea how to force the openwrt-routing batman-adv package
> against the cfg80211.h of compat-wireless?
The openwrt mac80211 package exports its headers to
$(STAGING_DIR)/usr/include/mac80211

You could just make the batman-adv package use those includes.

- Felix

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

* Re: [B.A.T.M.A.N.] OpenWrt cfg80211.h station_info incompatibility with kernel+mac80211 [was: B.A.T.M.A.N. V leaves the nest v2]
  2016-01-21 14:03       ` Sven Eckelmann
@ 2016-01-21 14:02         ` Antonio Quartulli
  2016-01-21 14:34           ` Sven Eckelmann
  2016-01-21 14:26         ` Sven Eckelmann
  1 sibling, 1 reply; 34+ messages in thread
From: Antonio Quartulli @ 2016-01-21 14:02 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking,
	Felix Fietkau
  Cc: openwrt-devel, Marek Lindner

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



On 21/01/16 22:03, Sven Eckelmann wrote:
> On Thursday 21 January 2016 14:55:01 Felix Fietkau wrote:
>>> @Felix, would it be ok for you when I propose a
>>> "*-sync-cfg80211-station_info.patch" for the 3.18 generic kernel patches?
>>> Or do you have a good idea how to force the openwrt-routing batman-adv package
>>> against the cfg80211.h of compat-wireless?
>> The openwrt mac80211 package exports its headers to
>> $(STAGING_DIR)/usr/include/mac80211
>>
>> You could just make the batman-adv package use those includes.
> 
> Thanks, missed that. I will prepare a pull request for openwrt-routing.

In case this was missed: we also need to make sure that batman-adv
depends on mac80211 and that it gets compiled first.


Cheers,

-- 
Antonio Quartulli


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [B.A.T.M.A.N.] OpenWrt cfg80211.h station_info incompatibility with kernel+mac80211 [was: B.A.T.M.A.N. V leaves the nest v2]
  2016-01-21 13:55     ` Felix Fietkau
@ 2016-01-21 14:03       ` Sven Eckelmann
  2016-01-21 14:02         ` Antonio Quartulli
  2016-01-21 14:26         ` Sven Eckelmann
  0 siblings, 2 replies; 34+ messages in thread
From: Sven Eckelmann @ 2016-01-21 14:03 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: openwrt-devel, b.a.t.m.a.n, Marek Lindner

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

On Thursday 21 January 2016 14:55:01 Felix Fietkau wrote:
> > @Felix, would it be ok for you when I propose a
> > "*-sync-cfg80211-station_info.patch" for the 3.18 generic kernel patches?
> > Or do you have a good idea how to force the openwrt-routing batman-adv package
> > against the cfg80211.h of compat-wireless?
> The openwrt mac80211 package exports its headers to
> $(STAGING_DIR)/usr/include/mac80211
> 
> You could just make the batman-adv package use those includes.

Thanks, missed that. I will prepare a pull request for openwrt-routing.

Regards,
	Sven

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

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

* Re: [B.A.T.M.A.N.] OpenWrt cfg80211.h station_info incompatibility with kernel+mac80211 [was: B.A.T.M.A.N. V leaves the nest v2]
  2016-01-21 14:03       ` Sven Eckelmann
  2016-01-21 14:02         ` Antonio Quartulli
@ 2016-01-21 14:26         ` Sven Eckelmann
  2016-01-21 14:47           ` Felix Fietkau
  1 sibling, 1 reply; 34+ messages in thread
From: Sven Eckelmann @ 2016-01-21 14:26 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: openwrt-devel, b.a.t.m.a.n, Marek Lindner

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

On Thursday 21 January 2016 15:03:10 Sven Eckelmann wrote:
> On Thursday 21 January 2016 14:55:01 Felix Fietkau wrote:
> > > @Felix, would it be ok for you when I propose a
> > > "*-sync-cfg80211-station_info.patch" for the 3.18 generic kernel 
patches?
> > > Or do you have a good idea how to force the openwrt-routing batman-adv 
package
> > > against the cfg80211.h of compat-wireless?
> > The openwrt mac80211 package exports its headers to
> > $(STAGING_DIR)/usr/include/mac80211
> > 
> > You could just make the batman-adv package use those includes.
> 
> Thanks, missed that. I will prepare a pull request for openwrt-routing.

Hm, didn't work out so well. It basically explodes right away because 
possible_net_t, possible_read_pnet, possible_write_pnet is not defined on 
v3.18 when not using the mac80211 backporting headers. And when usign the 
backporting headers then it will explode because it conflicts with batman-
adv's own backporting stuff. And without the batman-adv's backporting headers 
it will also not compile due to missing backporting hacks.

Kind regards,
	Sven

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

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

* Re: [B.A.T.M.A.N.] OpenWrt cfg80211.h station_info incompatibility with kernel+mac80211 [was: B.A.T.M.A.N. V leaves the nest v2]
  2016-01-21 14:02         ` Antonio Quartulli
@ 2016-01-21 14:34           ` Sven Eckelmann
  0 siblings, 0 replies; 34+ messages in thread
From: Sven Eckelmann @ 2016-01-21 14:34 UTC (permalink / raw)
  To: b.a.t.m.a.n
  Cc: Felix Fietkau, openwrt-devel, Antonio Quartulli, Marek Lindner

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

On Thursday 21 January 2016 22:02:50 Antonio Quartulli wrote:
> 
> On 21/01/16 22:03, Sven Eckelmann wrote:
> > On Thursday 21 January 2016 14:55:01 Felix Fietkau wrote:
> >>> @Felix, would it be ok for you when I propose a
> >>> "*-sync-cfg80211-station_info.patch" for the 3.18 generic kernel 
patches?
> >>> Or do you have a good idea how to force the openwrt-routing batman-adv 
package
> >>> against the cfg80211.h of compat-wireless?
> >> The openwrt mac80211 package exports its headers to
> >> $(STAGING_DIR)/usr/include/mac80211
> >>
> >> You could just make the batman-adv package use those includes.
> > 
> > Thanks, missed that. I will prepare a pull request for openwrt-routing.
> 
> In case this was missed: we also need to make sure that batman-adv
> depends on mac80211 and that it gets compiled first.

You are right. But the B.A.T.M.A.N. V patches cannot be build with the 
official openwrt-routing package - so no need to get too eager. All we are 
doing right now is to prepare the integration (for the next release which will 
include B.A.T.M.A.N. V).

But if anyone is willing to prepare the changes for the internal branch...

Kind regards,
	Sven

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

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

* Re: [B.A.T.M.A.N.] OpenWrt cfg80211.h station_info incompatibility with kernel+mac80211 [was: B.A.T.M.A.N. V leaves the nest v2]
  2016-01-21 14:26         ` Sven Eckelmann
@ 2016-01-21 14:47           ` Felix Fietkau
  2016-01-21 15:16             ` Sven Eckelmann
  0 siblings, 1 reply; 34+ messages in thread
From: Felix Fietkau @ 2016-01-21 14:47 UTC (permalink / raw)
  To: Sven Eckelmann; +Cc: openwrt-devel, b.a.t.m.a.n, Marek Lindner

On 2016-01-21 15:26, Sven Eckelmann wrote:
> On Thursday 21 January 2016 15:03:10 Sven Eckelmann wrote:
>> On Thursday 21 January 2016 14:55:01 Felix Fietkau wrote:
>> > > @Felix, would it be ok for you when I propose a
>> > > "*-sync-cfg80211-station_info.patch" for the 3.18 generic kernel 
> patches?
>> > > Or do you have a good idea how to force the openwrt-routing batman-adv 
> package
>> > > against the cfg80211.h of compat-wireless?
>> > The openwrt mac80211 package exports its headers to
>> > $(STAGING_DIR)/usr/include/mac80211
>> > 
>> > You could just make the batman-adv package use those includes.
>> 
>> Thanks, missed that. I will prepare a pull request for openwrt-routing.
> 
> Hm, didn't work out so well. It basically explodes right away because 
> possible_net_t, possible_read_pnet, possible_write_pnet is not defined on 
> v3.18 when not using the mac80211 backporting headers. And when usign the 
> backporting headers then it will explode because it conflicts with batman-
> adv's own backporting stuff. And without the batman-adv's backporting headers 
> it will also not compile due to missing backporting hacks.
I think in the short term it would be a good idea to identify what's
missing in the mac80211 backport support and make patches for it.
You should also rebase those on top of backports.git and submit them
upstream.

For a long term solution, you guys should probably start pushing for
full batman-adv integration in kernel backports. Might be useful for
increasing adoption of the latest stuff even outside of OpenWrt.

- Felix

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

* Re: [B.A.T.M.A.N.] OpenWrt cfg80211.h station_info incompatibility with kernel+mac80211 [was: B.A.T.M.A.N. V leaves the nest v2]
  2016-01-21 14:47           ` Felix Fietkau
@ 2016-01-21 15:16             ` Sven Eckelmann
  0 siblings, 0 replies; 34+ messages in thread
From: Sven Eckelmann @ 2016-01-21 15:16 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: openwrt-devel, b.a.t.m.a.n, Marek Lindner

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

On Thursday 21 January 2016 15:47:02 Felix Fietkau wrote:
[...]
> > Hm, didn't work out so well. It basically explodes right away because 
> > possible_net_t, possible_read_pnet, possible_write_pnet is not defined on 
> > v3.18 when not using the mac80211 backporting headers. And when usign the 
> > backporting headers then it will explode because it conflicts with batman-
> > adv's own backporting stuff. And without the batman-adv's backporting headers 
> > it will also not compile due to missing backporting hacks.
> I think in the short term it would be a good idea to identify what's
> missing in the mac80211 backport support and make patches for it.
> You should also rebase those on top of backports.git and submit them
> upstream.

Yes, this was already started after/during the linux plumbers conf 2014 [1]. But
it died the horrible death of being ignored and neglected - especially after the
multicast optimization was integrated.

Someone who want to use the mac80211 stuff with the batman-adv package can use
the attached patch as starting point.

Kind regards,
	Sven

[1] https://github.com/ordex/batman-adv-backport/commits/TODO-compat

[-- Attachment #2: 0001-batman-adv-Use-the-mac80211-compat-layer.patch --]
[-- Type: text/x-patch, Size: 2854 bytes --]

From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 21 Jan 2016 16:04:20 +0100
Subject: [PATCH] batman-adv: Use the mac80211 compat layer
---
 batman-adv/Makefile | 41 +++++++++++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 14 deletions(-)

diff --git a/batman-adv/Makefile b/batman-adv/Makefile
index 1eb6bbe..0b2637d 100644
--- a/batman-adv/Makefile
+++ b/batman-adv/Makefile
@@ -27,7 +27,7 @@ define KernelPackage/batman-adv
   URL:=https://www.open-mesh.org/
   MAINTAINER:=Marek Lindner <mareklindner@neomailbox.ch>
   SUBMENU:=Network Support
-  DEPENDS:=+KMOD_BATMAN_ADV_BLA:kmod-lib-crc16 +kmod-crypto-core +kmod-crypto-crc32c +kmod-lib-crc32c
+  DEPENDS:=+KMOD_BATMAN_ADV_BLA:kmod-lib-crc16 +kmod-crypto-core +kmod-crypto-crc32c +kmod-lib-crc32c +kmod-cfg80211
   TITLE:=B.A.T.M.A.N. Adv
   FILES:=$(PKG_BUILD_DIR)/net/batman-adv/batman-adv.$(LINUX_KMOD_SUFFIX)
   AUTOLOAD:=$(call AutoLoad,50,batman-adv)
@@ -47,20 +47,37 @@ define Package/kmod-batman-adv/conffiles
 /etc/config/batman-adv
 endef
 
-MAKE_BATMAN_ADV_ARGS += \
-	CROSS_COMPILE="$(TARGET_CROSS)" \
-	KERNELPATH="$(LINUX_DIR)" \
-	ARCH="$(LINUX_KARCH)" \
-	PATH="$(TARGET_PATH)" \
-	SUBDIRS="$(PKG_BUILD_DIR)" \
-	PWD="$(PKG_BUILD_DIR)" \
-	LINUX_VERSION="$(LINUX_VERSION)" \
+PKG_EXTRA_KCONFIG:= \
+	CONFIG_BATMAN_ADV=m \
 	CONFIG_BATMAN_ADV_DEBUG=$(if $(CONFIG_KMOD_BATMAN_ADV_DEBUG_LOG),y,n) \
 	CONFIG_BATMAN_ADV_BLA=$(if $(CONFIG_KMOD_BATMAN_ADV_BLA),y,n) \
 	CONFIG_BATMAN_ADV_DAT=$(if $(CONFIG_KMOD_BATMAN_ADV_DAT),y,n) \
 	CONFIG_BATMAN_ADV_MCAST=$(if $(CONFIG_KMOD_BATMAN_ADV_MCAST),y,n) \
 	CONFIG_BATMAN_ADV_NC=$(if $(CONFIG_KMOD_BATMAN_ADV_NC),y,n) \
-	REVISION="" all
+	CONFIG_BATMAN_ADV_BATMAN_V=$(if $(CONFIG_KMOD_BATMAN_ADV_BATMAN_V),y,n) \
+
+PKG_EXTRA_CFLAGS:= \
+	$(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(PKG_EXTRA_KCONFIG)))) \
+	$(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(PKG_EXTRA_KCONFIG)))) \
+
+NOSTDINC_FLAGS = \
+	-I$(PKG_BUILD_DIR)/net/batman-adv \
+	-I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \
+	-I$(STAGING_DIR)/usr/include/mac80211-backport \
+	-I$(STAGING_DIR)/usr/include/mac80211/uapi \
+	-I$(STAGING_DIR)/usr/include/mac80211 \
+	-include backport/backport.h
+
+define Build/Compile
+	+$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
+		ARCH="$(LINUX_KARCH)" \
+		CROSS_COMPILE="$(TARGET_CROSS)" \
+		SUBDIRS="$(PKG_BUILD_DIR)/net/batman-adv" \
+		$(PKG_EXTRA_KCONFIG) \
+		EXTRA_CFLAGS="$(PKG_EXTRA_CFLAGS)" \
+		NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
+		modules
+endef
 
 define Build/Prepare
 	$(call Build/Prepare/Default)
@@ -68,10 +85,6 @@ define Build/Prepare
 		$(PKG_BUILD_DIR)/net/batman-adv/main.h
 endef
 
-define Build/Compile
-	$(MAKE) -C "$(PKG_BUILD_DIR)" $(MAKE_BATMAN_ADV_ARGS)
-endef
-
 define Build/Clean
         rm -rf $(BUILD_DIR)/$(PKG_NAME)/
 endef

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

end of thread, other threads:[~2016-01-21 15:16 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-16  8:39 [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Marek Lindner
2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 01/12] batman-adv: Add hard_iface specific sysfs wrapper macros for UINT Marek Lindner
2016-01-19 15:08   ` Marek Lindner
2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 02/12] batman-adv: ELP - adding basic infrastructure Marek Lindner
2016-01-19 15:10   ` Marek Lindner
2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 03/12] batman-adv: ELP - creating neighbor structures Marek Lindner
2016-01-19 15:11   ` Marek Lindner
2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 04/12] batman-adv: ELP - adding sysfs parameter for elp interval Marek Lindner
2016-01-19 15:12   ` Marek Lindner
2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 05/12] batman-adv: OGMv2 - add basic infrastructure Marek Lindner
2016-01-19 15:14   ` Marek Lindner
2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 06/12] batman-adv: OGMv2 - implement originators logic Marek Lindner
2016-01-19 15:15   ` Marek Lindner
2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 07/12] batman-adv: add throughput override attribute to hard_ifaces Marek Lindner
2016-01-19 15:16   ` Marek Lindner
2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 08/12] batman-adv: keep track of when unicast packets are sent Marek Lindner
2016-01-19 15:20   ` Marek Lindner
2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 09/12] batman-adv: ELP - compute the metric based on the estimated throughput Marek Lindner
2016-01-19 15:22   ` Marek Lindner
2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 10/12] batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls Marek Lindner
2016-01-19 15:24   ` Marek Lindner
2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 11/12] batman-adv: B.A.T.M.A.N. V - implement bat_orig_print API Marek Lindner
2016-01-19 15:25   ` Marek Lindner
2016-01-16  8:40 ` [B.A.T.M.A.N.] [PATCH v2 12/12] batman-adv: B.A.T.M.A.N. V - implement bat_neigh_print API Marek Lindner
2016-01-19 15:26   ` Marek Lindner
2016-01-21 11:56 ` [B.A.T.M.A.N.] B.A.T.M.A.N. V leaves the nest v2 Sven Eckelmann
2016-01-21 13:47   ` [B.A.T.M.A.N.] OpenWrt cfg80211.h station_info incompatibility with kernel+mac80211 [was: B.A.T.M.A.N. V leaves the nest v2] Sven Eckelmann
2016-01-21 13:55     ` Felix Fietkau
2016-01-21 14:03       ` Sven Eckelmann
2016-01-21 14:02         ` Antonio Quartulli
2016-01-21 14:34           ` Sven Eckelmann
2016-01-21 14:26         ` Sven Eckelmann
2016-01-21 14:47           ` Felix Fietkau
2016-01-21 15:16             ` Sven Eckelmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).