batman-adv: network coding - add the initial infrastructure code
authorMartin Hundebøll <martin@hundeboll.net>
Fri, 25 Jan 2013 10:12:38 +0000 (11:12 +0100)
committerAntonio Quartulli <ordex@autistici.org>
Wed, 13 Mar 2013 21:53:48 +0000 (22:53 +0100)
Network coding exploits the 802.11 shared medium to allow multiple
packets to be sent in a single transmission. In brief, a relay can XOR
two packets, and send the coded packet to two destinations. The
receivers can decode one of the original packets by XOR'ing the coded
packet with the other original packet. This will lead to increased
throughput in topologies where two packets cross one relay.

In a simple topology with three nodes, it takes four transmissions
without network coding to get one packet from Node A to Node B and one
from Node B to Node A:

 1.  Node A  ---- p1 --->  Node R                Node B
 2.  Node A                Node R  <--- p2 ----  Node B
 3.  Node A  <--- p2 ----  Node R                Node B
 4.  Node A                Node R  ---- p1 --->  Node B

With network coding, the relay only needs one transmission, which saves
us one slot of valuable airtime:

 1.  Node A  ---- p1 --->  Node R                Node B
 2.  Node A                Node R  <--- p2 ----  Node B
 3.  Node A  <- p1 x p2 -  Node R  - p1 x p2 ->  Node B

The same principle holds for a topology including five nodes. Here the
packets from Node A and Node B are overheard by Node C and Node D,
respectively. This allows Node R to send a network coded packet to save
one transmission:

   Node A                  Node B

    |     \              /    |
    |      p1          p2     |
    |       \          /      |
    p1       > Node R <       p2
    |                         |
    |         /      \        |
    |    p1 x p2    p1 x p2   |
    v       /          \      v
           /            \
   Node C <              > Node D

More information is available on the open-mesh.org wiki[1].

This patch adds the initial code to support network coding in
batman-adv. It sets up a worker thread to do house keeping and adds a
sysfs file to enable/disable network coding. The feature is disabled by
default, as it requires a wifi-driver with working promiscuous mode, and
also because it adds a small delay at each hop.

[1] http://www.open-mesh.org/projects/batman-adv/wiki/Catwoman

Signed-off-by: Martin Hundebøll <martin@hundeboll.net>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Documentation/ABI/testing/sysfs-class-net-mesh
net/batman-adv/Kconfig
net/batman-adv/Makefile
net/batman-adv/main.c
net/batman-adv/main.h
net/batman-adv/network-coding.c [new file with mode: 0644]
net/batman-adv/network-coding.h [new file with mode: 0644]
net/batman-adv/soft-interface.c
net/batman-adv/sysfs.c
net/batman-adv/types.h

index bc41da61608d5dfc22e0c2836aa00c56499c9d98..bdcd8b4e38f2dd404acdc36bcd123f72ff5d2ed3 100644 (file)
@@ -67,6 +67,14 @@ Description:
                 Defines the penalty which will be applied to an
                 originator message's tq-field on every hop.
 
+What:           /sys/class/net/<mesh_iface>/mesh/network_coding
+Date:           Nov 2012
+Contact:        Martin Hundeboll <martin@hundeboll.net>
+Description:
+                Controls whether Network Coding (using some magic
+                to send fewer wifi packets but still the same
+                content) is enabled or not.
+
 What:           /sys/class/net/<mesh_iface>/mesh/orig_interval
 Date:           May 2010
 Contact:        Marek Lindner <lindner_marek@yahoo.de>
index 8d8afb134b3ac016799be9ab43d6fe45f40962bb..fa780b76630e4def219fc5f464554a4361721229 100644 (file)
@@ -36,6 +36,20 @@ config BATMAN_ADV_DAT
          mesh networks. If you think that your network does not need
          this option you can safely remove it and save some space.
 
+config BATMAN_ADV_NC
+       bool "Network Coding"
+       depends on BATMAN_ADV
+       default n
+       help
+         This option enables network coding, a mechanism that aims to
+         increase the overall network throughput by fusing multiple
+         packets in one transmission.
+         Note that interfaces controlled by batman-adv must be manually
+         configured to have promiscuous mode enabled in order to make
+         network coding work.
+         If you think that your network does not need this feature you
+         can safely disable it and save some space.
+
 config BATMAN_ADV_DEBUG
        bool "B.A.T.M.A.N. debugging"
        depends on BATMAN_ADV
index e45e3b4e32e3f480b2b65d5900ff0838391bc2ec..4b8f192a9e433d747cb316685374cd7c3ebfad70 100644 (file)
@@ -30,6 +30,7 @@ batman-adv-y += hard-interface.o
 batman-adv-y += hash.o
 batman-adv-y += icmp_socket.o
 batman-adv-y += main.o
+batman-adv-$(CONFIG_BATMAN_ADV_NC) += network-coding.o
 batman-adv-y += originator.o
 batman-adv-y += ring_buffer.o
 batman-adv-y += routing.o
index 0488d70c8c3512bef0311f1611d0a4a362b9057e..0495a7dc7505ef74c1f91775b72c460d7a7bf031 100644 (file)
@@ -35,6 +35,7 @@
 #include "vis.h"
 #include "hash.h"
 #include "bat_algo.h"
+#include "network-coding.h"
 
 
 /* List manipulations on hardif_list have to be rtnl_lock()'ed,
@@ -135,6 +136,10 @@ int batadv_mesh_init(struct net_device *soft_iface)
        if (ret < 0)
                goto err;
 
+       ret = batadv_nc_init(bat_priv);
+       if (ret < 0)
+               goto err;
+
        atomic_set(&bat_priv->gw.reselect, 0);
        atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
 
@@ -157,6 +162,7 @@ void batadv_mesh_free(struct net_device *soft_iface)
 
        batadv_gw_node_purge(bat_priv);
        batadv_originator_free(bat_priv);
+       batadv_nc_free(bat_priv);
 
        batadv_tt_free(bat_priv);
 
index ced08b936a9690a6f7d01af7f7eb8a31f3e1f29d..59ba2ff8e25235a410a7b3966d01778c20c223f2 100644 (file)
@@ -185,6 +185,7 @@ __be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr);
  * @BATADV_DBG_TT: translation table messages
  * @BATADV_DBG_BLA: bridge loop avoidance messages
  * @BATADV_DBG_DAT: ARP snooping and DAT related messages
+ * @BATADV_DBG_NC: network coding related messages
  * @BATADV_DBG_ALL: the union of all the above log levels
  */
 enum batadv_dbg_level {
@@ -193,7 +194,8 @@ enum batadv_dbg_level {
        BATADV_DBG_TT     = BIT(2),
        BATADV_DBG_BLA    = BIT(3),
        BATADV_DBG_DAT    = BIT(4),
-       BATADV_DBG_ALL    = 31,
+       BATADV_DBG_NC     = BIT(5),
+       BATADV_DBG_ALL    = 63,
 };
 
 #ifdef CONFIG_BATMAN_ADV_DEBUG
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
new file mode 100644 (file)
index 0000000..9c2d54b
--- /dev/null
@@ -0,0 +1,81 @@
+/* Copyright (C) 2012-2013 B.A.T.M.A.N. contributors:
+ *
+ * Martin Hundebøll, Jeppe Ledet-Pedersen
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#include "main.h"
+#include "network-coding.h"
+
+static void batadv_nc_worker(struct work_struct *work);
+
+/**
+ * batadv_nc_start_timer - initialise the nc periodic worker
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+static void batadv_nc_start_timer(struct batadv_priv *bat_priv)
+{
+       queue_delayed_work(batadv_event_workqueue, &bat_priv->nc.work,
+                          msecs_to_jiffies(10));
+}
+
+/**
+ * batadv_nc_init - initialise coding hash table and start house keeping
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+int batadv_nc_init(struct batadv_priv *bat_priv)
+{
+       INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker);
+       batadv_nc_start_timer(bat_priv);
+
+       return 0;
+}
+
+/**
+ * batadv_nc_init_bat_priv - initialise the nc specific bat_priv variables
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv)
+{
+       atomic_set(&bat_priv->network_coding, 1);
+}
+
+/**
+ * batadv_nc_worker - periodic task for house keeping related to network coding
+ * @work: kernel work struct
+ */
+static void batadv_nc_worker(struct work_struct *work)
+{
+       struct delayed_work *delayed_work;
+       struct batadv_priv_nc *priv_nc;
+       struct batadv_priv *bat_priv;
+
+       delayed_work = container_of(work, struct delayed_work, work);
+       priv_nc = container_of(delayed_work, struct batadv_priv_nc, work);
+       bat_priv = container_of(priv_nc, struct batadv_priv, nc);
+
+       /* Schedule a new check */
+       batadv_nc_start_timer(bat_priv);
+}
+
+/**
+ * batadv_nc_free - clean up network coding memory
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+void batadv_nc_free(struct batadv_priv *bat_priv)
+{
+       cancel_delayed_work_sync(&bat_priv->nc.work);
+}
diff --git a/net/batman-adv/network-coding.h b/net/batman-adv/network-coding.h
new file mode 100644 (file)
index 0000000..7483cba
--- /dev/null
@@ -0,0 +1,48 @@
+/* Copyright (C) 2012-2013 B.A.T.M.A.N. contributors:
+ *
+ * Martin Hundebøll, Jeppe Ledet-Pedersen
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#ifndef _NET_BATMAN_ADV_NETWORK_CODING_H_
+#define _NET_BATMAN_ADV_NETWORK_CODING_H_
+
+#ifdef CONFIG_BATMAN_ADV_NC
+
+int batadv_nc_init(struct batadv_priv *bat_priv);
+void batadv_nc_free(struct batadv_priv *bat_priv);
+void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv);
+
+#else /* ifdef CONFIG_BATMAN_ADV_NC */
+
+static inline int batadv_nc_init(struct batadv_priv *bat_priv)
+{
+       return 0;
+}
+
+static inline void batadv_nc_free(struct batadv_priv *bat_priv)
+{
+       return;
+}
+
+static inline void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv)
+{
+       return;
+}
+
+#endif /* ifdef CONFIG_BATMAN_ADV_NC */
+
+#endif /* _NET_BATMAN_ADV_NETWORK_CODING_H_ */
index 2711e870f557d43ac6bbd4180a7f239a27fb850a..7188e07dfc6fd40c031d7544dff3e7006f019ffa 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/if_ether.h>
 #include "unicast.h"
 #include "bridge_loop_avoidance.h"
+#include "network-coding.h"
 
 
 static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
@@ -544,6 +545,8 @@ struct net_device *batadv_softif_create(const char *name)
        if (ret < 0)
                goto unreg_soft_iface;
 
+       batadv_nc_init_bat_priv(bat_priv);
+
        ret = batadv_sysfs_add_meshif(soft_iface);
        if (ret < 0)
                goto unreg_soft_iface;
index 6a44fed128377dc3b0286d3890f0ac3a00a0d2da..ce39f62f751e10cd9feef5e70e0529e09f09b6cc 100644 (file)
@@ -442,6 +442,9 @@ static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth,
 #ifdef CONFIG_BATMAN_ADV_DEBUG
 BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL);
 #endif
+#ifdef CONFIG_BATMAN_ADV_NC
+BATADV_ATTR_SIF_BOOL(network_coding, S_IRUGO | S_IWUSR, NULL);
+#endif
 
 static struct batadv_attribute *batadv_mesh_attrs[] = {
        &batadv_attr_aggregated_ogms,
@@ -463,6 +466,9 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
        &batadv_attr_gw_bandwidth,
 #ifdef CONFIG_BATMAN_ADV_DEBUG
        &batadv_attr_log_level,
+#endif
+#ifdef CONFIG_BATMAN_ADV_NC
+       &batadv_attr_network_coding,
 #endif
        NULL,
 };
index 4cd87a0b5b8037d12c9af6ed1d78d515b598af0f..83bfe7c38f81f541b9129dc10f8ad9f0348a2849 100644 (file)
@@ -427,6 +427,14 @@ struct batadv_priv_dat {
 };
 #endif
 
+/**
+ * struct batadv_priv_nc - per mesh interface network coding private data
+ * @work: work queue callback item for cleanup
+ */
+struct batadv_priv_nc {
+       struct delayed_work work;
+};
+
 /**
  * struct batadv_priv - per mesh interface data
  * @mesh_state: current status of the mesh (inactive/active/deactivating)
@@ -470,6 +478,8 @@ struct batadv_priv_dat {
  * @tt: translation table data
  * @vis: vis data
  * @dat: distributed arp table data
+ * @network_coding: bool indicating whether network coding is enabled
+ * @batadv_priv_nc: network coding data
  */
 struct batadv_priv {
        atomic_t mesh_state;
@@ -522,6 +532,10 @@ struct batadv_priv {
 #ifdef CONFIG_BATMAN_ADV_DAT
        struct batadv_priv_dat dat;
 #endif
+#ifdef CONFIG_BATMAN_ADV_NC
+       atomic_t network_coding;
+       struct batadv_priv_nc nc;
+#endif /* CONFIG_BATMAN_ADV_NC */
 };
 
 /**