aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/hard-interface.c
diff options
context:
space:
mode:
authorSimon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de>2012-01-22 14:00:19 -0500
committerAntonio Quartulli <ordex@autistici.org>2012-04-11 08:28:58 -0400
commit23721387c409087fd3b97e274f34d3ddc0970b74 (patch)
treecf386c6f169a1b2b6e8c8ef77be5226e10046689 /net/batman-adv/hard-interface.c
parenta7f6ee9493677ba40625d810258de5bd521cc1b0 (diff)
batman-adv: add basic bridge loop avoidance code
This second version of the bridge loop avoidance for batman-adv avoids loops between the mesh and a backbone (usually a LAN). By connecting multiple batman-adv mesh nodes to the same ethernet segment a loop can be created when the soft-interface is bridged into that ethernet segment. A simple visualization of the loop involving the most common case - a LAN as ethernet segment: node1 <-- LAN --> node2 | | wifi <-- mesh --> wifi Packets from the LAN (e.g. ARP broadcasts) will circle forever from node1 or node2 over the mesh back into the LAN. With this patch, batman recognizes backbone gateways, nodes which are part of the mesh and backbone/LAN at the same time. Each backbone gateway "claims" clients from within the mesh to handle them exclusively. By restricting that only responsible backbone gateways may handle their claimed clients traffic, loops are effectively avoided. Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de> Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Diffstat (limited to 'net/batman-adv/hard-interface.c')
-rw-r--r--net/batman-adv/hard-interface.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 377897701a85..8c4b790b98be 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -28,6 +28,7 @@
28#include "bat_sysfs.h" 28#include "bat_sysfs.h"
29#include "originator.h" 29#include "originator.h"
30#include "hash.h" 30#include "hash.h"
31#include "bridge_loop_avoidance.h"
31 32
32#include <linux/if_arp.h> 33#include <linux/if_arp.h>
33 34
@@ -107,7 +108,8 @@ out:
107 return hard_iface; 108 return hard_iface;
108} 109}
109 110
110static void primary_if_update_addr(struct bat_priv *bat_priv) 111static void primary_if_update_addr(struct bat_priv *bat_priv,
112 struct hard_iface *oldif)
111{ 113{
112 struct vis_packet *vis_packet; 114 struct vis_packet *vis_packet;
113 struct hard_iface *primary_if; 115 struct hard_iface *primary_if;
@@ -122,6 +124,7 @@ static void primary_if_update_addr(struct bat_priv *bat_priv)
122 memcpy(vis_packet->sender_orig, 124 memcpy(vis_packet->sender_orig,
123 primary_if->net_dev->dev_addr, ETH_ALEN); 125 primary_if->net_dev->dev_addr, ETH_ALEN);
124 126
127 bla_update_orig_address(bat_priv, primary_if, oldif);
125out: 128out:
126 if (primary_if) 129 if (primary_if)
127 hardif_free_ref(primary_if); 130 hardif_free_ref(primary_if);
@@ -140,14 +143,15 @@ static void primary_if_select(struct bat_priv *bat_priv,
140 curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1); 143 curr_hard_iface = rcu_dereference_protected(bat_priv->primary_if, 1);
141 rcu_assign_pointer(bat_priv->primary_if, new_hard_iface); 144 rcu_assign_pointer(bat_priv->primary_if, new_hard_iface);
142 145
143 if (curr_hard_iface)
144 hardif_free_ref(curr_hard_iface);
145
146 if (!new_hard_iface) 146 if (!new_hard_iface)
147 return; 147 goto out;
148 148
149 bat_priv->bat_algo_ops->bat_ogm_init_primary(new_hard_iface); 149 bat_priv->bat_algo_ops->bat_ogm_init_primary(new_hard_iface);
150 primary_if_update_addr(bat_priv); 150 primary_if_update_addr(bat_priv, curr_hard_iface);
151
152out:
153 if (curr_hard_iface)
154 hardif_free_ref(curr_hard_iface);
151} 155}
152 156
153static bool hardif_is_iface_up(const struct hard_iface *hard_iface) 157static bool hardif_is_iface_up(const struct hard_iface *hard_iface)
@@ -531,7 +535,7 @@ static int hard_if_event(struct notifier_block *this,
531 goto hardif_put; 535 goto hardif_put;
532 536
533 if (hard_iface == primary_if) 537 if (hard_iface == primary_if)
534 primary_if_update_addr(bat_priv); 538 primary_if_update_addr(bat_priv, NULL);
535 break; 539 break;
536 default: 540 default:
537 break; 541 break;