Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

batman-adv: network coding - add the initial infrastructure code

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>

authored by

Martin Hundebøll and committed by
Antonio Quartulli
d353d8d4 c1d07431

+184 -1
+8
Documentation/ABI/testing/sysfs-class-net-mesh
··· 67 67 Defines the penalty which will be applied to an 68 68 originator message's tq-field on every hop. 69 69 70 + What: /sys/class/net/<mesh_iface>/mesh/network_coding 71 + Date: Nov 2012 72 + Contact: Martin Hundeboll <martin@hundeboll.net> 73 + Description: 74 + Controls whether Network Coding (using some magic 75 + to send fewer wifi packets but still the same 76 + content) is enabled or not. 77 + 70 78 What: /sys/class/net/<mesh_iface>/mesh/orig_interval 71 79 Date: May 2010 72 80 Contact: Marek Lindner <lindner_marek@yahoo.de>
+14
net/batman-adv/Kconfig
··· 36 36 mesh networks. If you think that your network does not need 37 37 this option you can safely remove it and save some space. 38 38 39 + config BATMAN_ADV_NC 40 + bool "Network Coding" 41 + depends on BATMAN_ADV 42 + default n 43 + help 44 + This option enables network coding, a mechanism that aims to 45 + increase the overall network throughput by fusing multiple 46 + packets in one transmission. 47 + Note that interfaces controlled by batman-adv must be manually 48 + configured to have promiscuous mode enabled in order to make 49 + network coding work. 50 + If you think that your network does not need this feature you 51 + can safely disable it and save some space. 52 + 39 53 config BATMAN_ADV_DEBUG 40 54 bool "B.A.T.M.A.N. debugging" 41 55 depends on BATMAN_ADV
+1
net/batman-adv/Makefile
··· 30 30 batman-adv-y += hash.o 31 31 batman-adv-y += icmp_socket.o 32 32 batman-adv-y += main.o 33 + batman-adv-$(CONFIG_BATMAN_ADV_NC) += network-coding.o 33 34 batman-adv-y += originator.o 34 35 batman-adv-y += ring_buffer.o 35 36 batman-adv-y += routing.o
+6
net/batman-adv/main.c
··· 35 35 #include "vis.h" 36 36 #include "hash.h" 37 37 #include "bat_algo.h" 38 + #include "network-coding.h" 38 39 39 40 40 41 /* List manipulations on hardif_list have to be rtnl_lock()'ed, ··· 136 135 if (ret < 0) 137 136 goto err; 138 137 138 + ret = batadv_nc_init(bat_priv); 139 + if (ret < 0) 140 + goto err; 141 + 139 142 atomic_set(&bat_priv->gw.reselect, 0); 140 143 atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE); 141 144 ··· 162 157 163 158 batadv_gw_node_purge(bat_priv); 164 159 batadv_originator_free(bat_priv); 160 + batadv_nc_free(bat_priv); 165 161 166 162 batadv_tt_free(bat_priv); 167 163
+3 -1
net/batman-adv/main.h
··· 185 185 * @BATADV_DBG_TT: translation table messages 186 186 * @BATADV_DBG_BLA: bridge loop avoidance messages 187 187 * @BATADV_DBG_DAT: ARP snooping and DAT related messages 188 + * @BATADV_DBG_NC: network coding related messages 188 189 * @BATADV_DBG_ALL: the union of all the above log levels 189 190 */ 190 191 enum batadv_dbg_level { ··· 194 193 BATADV_DBG_TT = BIT(2), 195 194 BATADV_DBG_BLA = BIT(3), 196 195 BATADV_DBG_DAT = BIT(4), 197 - BATADV_DBG_ALL = 31, 196 + BATADV_DBG_NC = BIT(5), 197 + BATADV_DBG_ALL = 63, 198 198 }; 199 199 200 200 #ifdef CONFIG_BATMAN_ADV_DEBUG
+81
net/batman-adv/network-coding.c
··· 1 + /* Copyright (C) 2012-2013 B.A.T.M.A.N. contributors: 2 + * 3 + * Martin Hundebøll, Jeppe Ledet-Pedersen 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of version 2 of the GNU General Public 7 + * License as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but 10 + * WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 + * General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program; if not, write to the Free Software 16 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 + * 02110-1301, USA 18 + */ 19 + 20 + #include "main.h" 21 + #include "network-coding.h" 22 + 23 + static void batadv_nc_worker(struct work_struct *work); 24 + 25 + /** 26 + * batadv_nc_start_timer - initialise the nc periodic worker 27 + * @bat_priv: the bat priv with all the soft interface information 28 + */ 29 + static void batadv_nc_start_timer(struct batadv_priv *bat_priv) 30 + { 31 + queue_delayed_work(batadv_event_workqueue, &bat_priv->nc.work, 32 + msecs_to_jiffies(10)); 33 + } 34 + 35 + /** 36 + * batadv_nc_init - initialise coding hash table and start house keeping 37 + * @bat_priv: the bat priv with all the soft interface information 38 + */ 39 + int batadv_nc_init(struct batadv_priv *bat_priv) 40 + { 41 + INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker); 42 + batadv_nc_start_timer(bat_priv); 43 + 44 + return 0; 45 + } 46 + 47 + /** 48 + * batadv_nc_init_bat_priv - initialise the nc specific bat_priv variables 49 + * @bat_priv: the bat priv with all the soft interface information 50 + */ 51 + void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv) 52 + { 53 + atomic_set(&bat_priv->network_coding, 1); 54 + } 55 + 56 + /** 57 + * batadv_nc_worker - periodic task for house keeping related to network coding 58 + * @work: kernel work struct 59 + */ 60 + static void batadv_nc_worker(struct work_struct *work) 61 + { 62 + struct delayed_work *delayed_work; 63 + struct batadv_priv_nc *priv_nc; 64 + struct batadv_priv *bat_priv; 65 + 66 + delayed_work = container_of(work, struct delayed_work, work); 67 + priv_nc = container_of(delayed_work, struct batadv_priv_nc, work); 68 + bat_priv = container_of(priv_nc, struct batadv_priv, nc); 69 + 70 + /* Schedule a new check */ 71 + batadv_nc_start_timer(bat_priv); 72 + } 73 + 74 + /** 75 + * batadv_nc_free - clean up network coding memory 76 + * @bat_priv: the bat priv with all the soft interface information 77 + */ 78 + void batadv_nc_free(struct batadv_priv *bat_priv) 79 + { 80 + cancel_delayed_work_sync(&bat_priv->nc.work); 81 + }
+48
net/batman-adv/network-coding.h
··· 1 + /* Copyright (C) 2012-2013 B.A.T.M.A.N. contributors: 2 + * 3 + * Martin Hundebøll, Jeppe Ledet-Pedersen 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of version 2 of the GNU General Public 7 + * License as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but 10 + * WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 + * General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program; if not, write to the Free Software 16 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 + * 02110-1301, USA 18 + */ 19 + 20 + #ifndef _NET_BATMAN_ADV_NETWORK_CODING_H_ 21 + #define _NET_BATMAN_ADV_NETWORK_CODING_H_ 22 + 23 + #ifdef CONFIG_BATMAN_ADV_NC 24 + 25 + int batadv_nc_init(struct batadv_priv *bat_priv); 26 + void batadv_nc_free(struct batadv_priv *bat_priv); 27 + void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv); 28 + 29 + #else /* ifdef CONFIG_BATMAN_ADV_NC */ 30 + 31 + static inline int batadv_nc_init(struct batadv_priv *bat_priv) 32 + { 33 + return 0; 34 + } 35 + 36 + static inline void batadv_nc_free(struct batadv_priv *bat_priv) 37 + { 38 + return; 39 + } 40 + 41 + static inline void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv) 42 + { 43 + return; 44 + } 45 + 46 + #endif /* ifdef CONFIG_BATMAN_ADV_NC */ 47 + 48 + #endif /* _NET_BATMAN_ADV_NETWORK_CODING_H_ */
+3
net/batman-adv/soft-interface.c
··· 37 37 #include <linux/if_ether.h> 38 38 #include "unicast.h" 39 39 #include "bridge_loop_avoidance.h" 40 + #include "network-coding.h" 40 41 41 42 42 43 static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); ··· 544 543 ret = batadv_algo_select(bat_priv, batadv_routing_algo); 545 544 if (ret < 0) 546 545 goto unreg_soft_iface; 546 + 547 + batadv_nc_init_bat_priv(bat_priv); 547 548 548 549 ret = batadv_sysfs_add_meshif(soft_iface); 549 550 if (ret < 0)
+6
net/batman-adv/sysfs.c
··· 442 442 #ifdef CONFIG_BATMAN_ADV_DEBUG 443 443 BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL); 444 444 #endif 445 + #ifdef CONFIG_BATMAN_ADV_NC 446 + BATADV_ATTR_SIF_BOOL(network_coding, S_IRUGO | S_IWUSR, NULL); 447 + #endif 445 448 446 449 static struct batadv_attribute *batadv_mesh_attrs[] = { 447 450 &batadv_attr_aggregated_ogms, ··· 466 463 &batadv_attr_gw_bandwidth, 467 464 #ifdef CONFIG_BATMAN_ADV_DEBUG 468 465 &batadv_attr_log_level, 466 + #endif 467 + #ifdef CONFIG_BATMAN_ADV_NC 468 + &batadv_attr_network_coding, 469 469 #endif 470 470 NULL, 471 471 };
+14
net/batman-adv/types.h
··· 428 428 #endif 429 429 430 430 /** 431 + * struct batadv_priv_nc - per mesh interface network coding private data 432 + * @work: work queue callback item for cleanup 433 + */ 434 + struct batadv_priv_nc { 435 + struct delayed_work work; 436 + }; 437 + 438 + /** 431 439 * struct batadv_priv - per mesh interface data 432 440 * @mesh_state: current status of the mesh (inactive/active/deactivating) 433 441 * @soft_iface: net device which holds this struct as private data ··· 478 470 * @tt: translation table data 479 471 * @vis: vis data 480 472 * @dat: distributed arp table data 473 + * @network_coding: bool indicating whether network coding is enabled 474 + * @batadv_priv_nc: network coding data 481 475 */ 482 476 struct batadv_priv { 483 477 atomic_t mesh_state; ··· 532 522 #ifdef CONFIG_BATMAN_ADV_DAT 533 523 struct batadv_priv_dat dat; 534 524 #endif 525 + #ifdef CONFIG_BATMAN_ADV_NC 526 + atomic_t network_coding; 527 + struct batadv_priv_nc nc; 528 + #endif /* CONFIG_BATMAN_ADV_NC */ 535 529 }; 536 530 537 531 /**