aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/aggregation.c31
-rw-r--r--net/batman-adv/aggregation.h4
-rw-r--r--net/batman-adv/bat_debugfs.c4
-rw-r--r--net/batman-adv/bat_sysfs.c16
-rw-r--r--net/batman-adv/gateway_client.c306
-rw-r--r--net/batman-adv/gateway_client.h2
-rw-r--r--net/batman-adv/hard-interface.c107
-rw-r--r--net/batman-adv/hard-interface.h18
-rw-r--r--net/batman-adv/icmp_socket.c37
-rw-r--r--net/batman-adv/main.c20
-rw-r--r--net/batman-adv/main.h44
-rw-r--r--net/batman-adv/originator.c90
-rw-r--r--net/batman-adv/originator.h1
-rw-r--r--net/batman-adv/packet.h5
-rw-r--r--net/batman-adv/routing.c572
-rw-r--r--net/batman-adv/routing.h6
-rw-r--r--net/batman-adv/send.c72
-rw-r--r--net/batman-adv/send.h2
-rw-r--r--net/batman-adv/soft-interface.c473
-rw-r--r--net/batman-adv/translation-table.c474
-rw-r--r--net/batman-adv/translation-table.h24
-rw-r--r--net/batman-adv/types.h56
-rw-r--r--net/batman-adv/unicast.c20
-rw-r--r--net/batman-adv/vis.c146
24 files changed, 1483 insertions, 1047 deletions
diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c
index af45d6b2031f..a8c32030527c 100644
--- a/net/batman-adv/aggregation.c
+++ b/net/batman-adv/aggregation.c
@@ -23,11 +23,12 @@
23#include "aggregation.h" 23#include "aggregation.h"
24#include "send.h" 24#include "send.h"
25#include "routing.h" 25#include "routing.h"
26#include "hard-interface.h"
26 27
27/* calculate the size of the hna information for a given packet */ 28/* calculate the size of the tt information for a given packet */
28static int hna_len(struct batman_packet *batman_packet) 29static int tt_len(struct batman_packet *batman_packet)
29{ 30{
30 return batman_packet->num_hna * ETH_ALEN; 31 return batman_packet->num_tt * ETH_ALEN;
31} 32}
32 33
33/* return true if new_packet can be aggregated with forw_packet */ 34/* return true if new_packet can be aggregated with forw_packet */
@@ -95,7 +96,6 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
95 return false; 96 return false;
96} 97}
97 98
98#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
99/* create a new aggregated packet and add this packet to it */ 99/* create a new aggregated packet and add this packet to it */
100static void new_aggregated_packet(unsigned char *packet_buff, int packet_len, 100static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
101 unsigned long send_time, bool direct_link, 101 unsigned long send_time, bool direct_link,
@@ -106,12 +106,15 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
106 struct forw_packet *forw_packet_aggr; 106 struct forw_packet *forw_packet_aggr;
107 unsigned char *skb_buff; 107 unsigned char *skb_buff;
108 108
109 if (!atomic_inc_not_zero(&if_incoming->refcount))
110 return;
111
109 /* own packet should always be scheduled */ 112 /* own packet should always be scheduled */
110 if (!own_packet) { 113 if (!own_packet) {
111 if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) { 114 if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
112 bat_dbg(DBG_BATMAN, bat_priv, 115 bat_dbg(DBG_BATMAN, bat_priv,
113 "batman packet queue full\n"); 116 "batman packet queue full\n");
114 return; 117 goto out;
115 } 118 }
116 } 119 }
117 120
@@ -119,7 +122,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
119 if (!forw_packet_aggr) { 122 if (!forw_packet_aggr) {
120 if (!own_packet) 123 if (!own_packet)
121 atomic_inc(&bat_priv->batman_queue_left); 124 atomic_inc(&bat_priv->batman_queue_left);
122 return; 125 goto out;
123 } 126 }
124 127
125 if ((atomic_read(&bat_priv->aggregated_ogms)) && 128 if ((atomic_read(&bat_priv->aggregated_ogms)) &&
@@ -134,7 +137,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
134 if (!own_packet) 137 if (!own_packet)
135 atomic_inc(&bat_priv->batman_queue_left); 138 atomic_inc(&bat_priv->batman_queue_left);
136 kfree(forw_packet_aggr); 139 kfree(forw_packet_aggr);
137 return; 140 goto out;
138 } 141 }
139 skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr)); 142 skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
140 143
@@ -165,6 +168,10 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
165 queue_delayed_work(bat_event_workqueue, 168 queue_delayed_work(bat_event_workqueue,
166 &forw_packet_aggr->delayed_work, 169 &forw_packet_aggr->delayed_work,
167 send_time - jiffies); 170 send_time - jiffies);
171
172 return;
173out:
174 hardif_free_ref(if_incoming);
168} 175}
169 176
170/* aggregate a new packet into the existing aggregation */ 177/* aggregate a new packet into the existing aggregation */
@@ -251,7 +258,7 @@ void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
251{ 258{
252 struct batman_packet *batman_packet; 259 struct batman_packet *batman_packet;
253 int buff_pos = 0; 260 int buff_pos = 0;
254 unsigned char *hna_buff; 261 unsigned char *tt_buff;
255 262
256 batman_packet = (struct batman_packet *)packet_buff; 263 batman_packet = (struct batman_packet *)packet_buff;
257 264
@@ -260,14 +267,14 @@ void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
260 orig_interval. */ 267 orig_interval. */
261 batman_packet->seqno = ntohl(batman_packet->seqno); 268 batman_packet->seqno = ntohl(batman_packet->seqno);
262 269
263 hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN; 270 tt_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
264 receive_bat_packet(ethhdr, batman_packet, 271 receive_bat_packet(ethhdr, batman_packet,
265 hna_buff, hna_len(batman_packet), 272 tt_buff, tt_len(batman_packet),
266 if_incoming); 273 if_incoming);
267 274
268 buff_pos += BAT_PACKET_LEN + hna_len(batman_packet); 275 buff_pos += BAT_PACKET_LEN + tt_len(batman_packet);
269 batman_packet = (struct batman_packet *) 276 batman_packet = (struct batman_packet *)
270 (packet_buff + buff_pos); 277 (packet_buff + buff_pos);
271 } while (aggregated_packet(buff_pos, packet_len, 278 } while (aggregated_packet(buff_pos, packet_len,
272 batman_packet->num_hna)); 279 batman_packet->num_tt));
273} 280}
diff --git a/net/batman-adv/aggregation.h b/net/batman-adv/aggregation.h
index 062204289d1f..7e6d72fbf540 100644
--- a/net/batman-adv/aggregation.h
+++ b/net/batman-adv/aggregation.h
@@ -25,9 +25,9 @@
25#include "main.h" 25#include "main.h"
26 26
27/* is there another aggregated packet here? */ 27/* is there another aggregated packet here? */
28static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna) 28static inline int aggregated_packet(int buff_pos, int packet_len, int num_tt)
29{ 29{
30 int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN); 30 int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_tt * ETH_ALEN);
31 31
32 return (next_buff_pos <= packet_len) && 32 return (next_buff_pos <= packet_len) &&
33 (next_buff_pos <= MAX_AGGREGATION_BYTES); 33 (next_buff_pos <= MAX_AGGREGATION_BYTES);
diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c
index 0e9d43509935..abaeec5f6247 100644
--- a/net/batman-adv/bat_debugfs.c
+++ b/net/batman-adv/bat_debugfs.c
@@ -241,13 +241,13 @@ static int softif_neigh_open(struct inode *inode, struct file *file)
241static int transtable_global_open(struct inode *inode, struct file *file) 241static int transtable_global_open(struct inode *inode, struct file *file)
242{ 242{
243 struct net_device *net_dev = (struct net_device *)inode->i_private; 243 struct net_device *net_dev = (struct net_device *)inode->i_private;
244 return single_open(file, hna_global_seq_print_text, net_dev); 244 return single_open(file, tt_global_seq_print_text, net_dev);
245} 245}
246 246
247static int transtable_local_open(struct inode *inode, struct file *file) 247static int transtable_local_open(struct inode *inode, struct file *file)
248{ 248{
249 struct net_device *net_dev = (struct net_device *)inode->i_private; 249 struct net_device *net_dev = (struct net_device *)inode->i_private;
250 return single_open(file, hna_local_seq_print_text, net_dev); 250 return single_open(file, tt_local_seq_print_text, net_dev);
251} 251}
252 252
253static int vis_data_open(struct inode *inode, struct file *file) 253static int vis_data_open(struct inode *inode, struct file *file)
diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c
index e449bf6353e0..497a0700cc3c 100644
--- a/net/batman-adv/bat_sysfs.c
+++ b/net/batman-adv/bat_sysfs.c
@@ -488,22 +488,24 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
488 (strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0)) 488 (strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
489 goto out; 489 goto out;
490 490
491 if (!rtnl_trylock()) {
492 ret = -ERESTARTSYS;
493 goto out;
494 }
495
491 if (status_tmp == IF_NOT_IN_USE) { 496 if (status_tmp == IF_NOT_IN_USE) {
492 rtnl_lock();
493 hardif_disable_interface(hard_iface); 497 hardif_disable_interface(hard_iface);
494 rtnl_unlock(); 498 goto unlock;
495 goto out;
496 } 499 }
497 500
498 /* if the interface already is in use */ 501 /* if the interface already is in use */
499 if (hard_iface->if_status != IF_NOT_IN_USE) { 502 if (hard_iface->if_status != IF_NOT_IN_USE)
500 rtnl_lock();
501 hardif_disable_interface(hard_iface); 503 hardif_disable_interface(hard_iface);
502 rtnl_unlock();
503 }
504 504
505 ret = hardif_enable_interface(hard_iface, buff); 505 ret = hardif_enable_interface(hard_iface, buff);
506 506
507unlock:
508 rtnl_unlock();
507out: 509out:
508 hardif_free_ref(hard_iface); 510 hardif_free_ref(hard_iface);
509 return ret; 511 return ret;
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 3cc43558cf9c..61605a0f3f39 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -23,80 +23,88 @@
23#include "gateway_client.h" 23#include "gateway_client.h"
24#include "gateway_common.h" 24#include "gateway_common.h"
25#include "hard-interface.h" 25#include "hard-interface.h"
26#include "originator.h"
26#include <linux/ip.h> 27#include <linux/ip.h>
27#include <linux/ipv6.h> 28#include <linux/ipv6.h>
28#include <linux/udp.h> 29#include <linux/udp.h>
29#include <linux/if_vlan.h> 30#include <linux/if_vlan.h>
30 31
31static void gw_node_free_rcu(struct rcu_head *rcu)
32{
33 struct gw_node *gw_node;
34
35 gw_node = container_of(rcu, struct gw_node, rcu);
36 kfree(gw_node);
37}
38
39static void gw_node_free_ref(struct gw_node *gw_node) 32static void gw_node_free_ref(struct gw_node *gw_node)
40{ 33{
41 if (atomic_dec_and_test(&gw_node->refcount)) 34 if (atomic_dec_and_test(&gw_node->refcount))
42 call_rcu(&gw_node->rcu, gw_node_free_rcu); 35 kfree_rcu(gw_node, rcu);
43} 36}
44 37
45void *gw_get_selected(struct bat_priv *bat_priv) 38static struct gw_node *gw_get_selected_gw_node(struct bat_priv *bat_priv)
46{ 39{
47 struct gw_node *curr_gateway_tmp; 40 struct gw_node *gw_node;
48 struct orig_node *orig_node = NULL;
49 41
50 rcu_read_lock(); 42 rcu_read_lock();
51 curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw); 43 gw_node = rcu_dereference(bat_priv->curr_gw);
52 if (!curr_gateway_tmp) 44 if (!gw_node)
53 goto out; 45 goto out;
54 46
55 orig_node = curr_gateway_tmp->orig_node; 47 if (!atomic_inc_not_zero(&gw_node->refcount))
56 if (!orig_node) 48 gw_node = NULL;
57 goto out;
58
59 if (!atomic_inc_not_zero(&orig_node->refcount))
60 orig_node = NULL;
61 49
62out: 50out:
63 rcu_read_unlock(); 51 rcu_read_unlock();
64 return orig_node; 52 return gw_node;
65} 53}
66 54
67void gw_deselect(struct bat_priv *bat_priv) 55struct orig_node *gw_get_selected_orig(struct bat_priv *bat_priv)
68{ 56{
69 struct gw_node *gw_node; 57 struct gw_node *gw_node;
58 struct orig_node *orig_node = NULL;
70 59
71 spin_lock_bh(&bat_priv->gw_list_lock); 60 gw_node = gw_get_selected_gw_node(bat_priv);
72 gw_node = rcu_dereference(bat_priv->curr_gw); 61 if (!gw_node)
73 rcu_assign_pointer(bat_priv->curr_gw, NULL); 62 goto out;
74 spin_unlock_bh(&bat_priv->gw_list_lock); 63
64 rcu_read_lock();
65 orig_node = gw_node->orig_node;
66 if (!orig_node)
67 goto unlock;
75 68
69 if (!atomic_inc_not_zero(&orig_node->refcount))
70 orig_node = NULL;
71
72unlock:
73 rcu_read_unlock();
74out:
76 if (gw_node) 75 if (gw_node)
77 gw_node_free_ref(gw_node); 76 gw_node_free_ref(gw_node);
77 return orig_node;
78} 78}
79 79
80static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node) 80static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node)
81{ 81{
82 struct gw_node *curr_gw_node; 82 struct gw_node *curr_gw_node;
83 83
84 spin_lock_bh(&bat_priv->gw_list_lock);
85
84 if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount)) 86 if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount))
85 new_gw_node = NULL; 87 new_gw_node = NULL;
86 88
87 spin_lock_bh(&bat_priv->gw_list_lock); 89 curr_gw_node = bat_priv->curr_gw;
88 curr_gw_node = rcu_dereference(bat_priv->curr_gw);
89 rcu_assign_pointer(bat_priv->curr_gw, new_gw_node); 90 rcu_assign_pointer(bat_priv->curr_gw, new_gw_node);
90 spin_unlock_bh(&bat_priv->gw_list_lock);
91 91
92 if (curr_gw_node) 92 if (curr_gw_node)
93 gw_node_free_ref(curr_gw_node); 93 gw_node_free_ref(curr_gw_node);
94
95 spin_unlock_bh(&bat_priv->gw_list_lock);
96}
97
98void gw_deselect(struct bat_priv *bat_priv)
99{
100 gw_select(bat_priv, NULL);
94} 101}
95 102
96void gw_election(struct bat_priv *bat_priv) 103void gw_election(struct bat_priv *bat_priv)
97{ 104{
98 struct hlist_node *node; 105 struct hlist_node *node;
99 struct gw_node *gw_node, *curr_gw, *curr_gw_tmp = NULL; 106 struct gw_node *gw_node, *curr_gw = NULL, *curr_gw_tmp = NULL;
107 struct neigh_node *router;
100 uint8_t max_tq = 0; 108 uint8_t max_tq = 0;
101 uint32_t max_gw_factor = 0, tmp_gw_factor = 0; 109 uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
102 int down, up; 110 int down, up;
@@ -110,32 +118,25 @@ void gw_election(struct bat_priv *bat_priv)
110 if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT) 118 if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT)
111 return; 119 return;
112 120
113 rcu_read_lock(); 121 curr_gw = gw_get_selected_gw_node(bat_priv);
114 curr_gw = rcu_dereference(bat_priv->curr_gw); 122 if (curr_gw)
115 if (curr_gw) { 123 goto out;
116 rcu_read_unlock();
117 return;
118 }
119 124
125 rcu_read_lock();
120 if (hlist_empty(&bat_priv->gw_list)) { 126 if (hlist_empty(&bat_priv->gw_list)) {
121 127 bat_dbg(DBG_BATMAN, bat_priv,
122 if (curr_gw) { 128 "Removing selected gateway - "
123 rcu_read_unlock(); 129 "no gateway in range\n");
124 bat_dbg(DBG_BATMAN, bat_priv, 130 gw_deselect(bat_priv);
125 "Removing selected gateway - " 131 goto unlock;
126 "no gateway in range\n");
127 gw_deselect(bat_priv);
128 } else
129 rcu_read_unlock();
130
131 return;
132 } 132 }
133 133
134 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { 134 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
135 if (!gw_node->orig_node->router) 135 if (gw_node->deleted)
136 continue; 136 continue;
137 137
138 if (gw_node->deleted) 138 router = orig_node_get_router(gw_node->orig_node);
139 if (!router)
139 continue; 140 continue;
140 141
141 switch (atomic_read(&bat_priv->gw_sel_class)) { 142 switch (atomic_read(&bat_priv->gw_sel_class)) {
@@ -143,15 +144,14 @@ void gw_election(struct bat_priv *bat_priv)
143 gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, 144 gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags,
144 &down, &up); 145 &down, &up);
145 146
146 tmp_gw_factor = (gw_node->orig_node->router->tq_avg * 147 tmp_gw_factor = (router->tq_avg * router->tq_avg *
147 gw_node->orig_node->router->tq_avg *
148 down * 100 * 100) / 148 down * 100 * 100) /
149 (TQ_LOCAL_WINDOW_SIZE * 149 (TQ_LOCAL_WINDOW_SIZE *
150 TQ_LOCAL_WINDOW_SIZE * 64); 150 TQ_LOCAL_WINDOW_SIZE * 64);
151 151
152 if ((tmp_gw_factor > max_gw_factor) || 152 if ((tmp_gw_factor > max_gw_factor) ||
153 ((tmp_gw_factor == max_gw_factor) && 153 ((tmp_gw_factor == max_gw_factor) &&
154 (gw_node->orig_node->router->tq_avg > max_tq))) 154 (router->tq_avg > max_tq)))
155 curr_gw_tmp = gw_node; 155 curr_gw_tmp = gw_node;
156 break; 156 break;
157 157
@@ -163,19 +163,25 @@ void gw_election(struct bat_priv *bat_priv)
163 * soon as a better gateway appears which has 163 * soon as a better gateway appears which has
164 * $routing_class more tq points) 164 * $routing_class more tq points)
165 **/ 165 **/
166 if (gw_node->orig_node->router->tq_avg > max_tq) 166 if (router->tq_avg > max_tq)
167 curr_gw_tmp = gw_node; 167 curr_gw_tmp = gw_node;
168 break; 168 break;
169 } 169 }
170 170
171 if (gw_node->orig_node->router->tq_avg > max_tq) 171 if (router->tq_avg > max_tq)
172 max_tq = gw_node->orig_node->router->tq_avg; 172 max_tq = router->tq_avg;
173 173
174 if (tmp_gw_factor > max_gw_factor) 174 if (tmp_gw_factor > max_gw_factor)
175 max_gw_factor = tmp_gw_factor; 175 max_gw_factor = tmp_gw_factor;
176
177 neigh_node_free_ref(router);
176 } 178 }
177 179
178 if (curr_gw != curr_gw_tmp) { 180 if (curr_gw != curr_gw_tmp) {
181 router = orig_node_get_router(curr_gw_tmp->orig_node);
182 if (!router)
183 goto unlock;
184
179 if ((curr_gw) && (!curr_gw_tmp)) 185 if ((curr_gw) && (!curr_gw_tmp))
180 bat_dbg(DBG_BATMAN, bat_priv, 186 bat_dbg(DBG_BATMAN, bat_priv,
181 "Removing selected gateway - " 187 "Removing selected gateway - "
@@ -186,48 +192,50 @@ void gw_election(struct bat_priv *bat_priv)
186 "(gw_flags: %i, tq: %i)\n", 192 "(gw_flags: %i, tq: %i)\n",
187 curr_gw_tmp->orig_node->orig, 193 curr_gw_tmp->orig_node->orig,
188 curr_gw_tmp->orig_node->gw_flags, 194 curr_gw_tmp->orig_node->gw_flags,
189 curr_gw_tmp->orig_node->router->tq_avg); 195 router->tq_avg);
190 else 196 else
191 bat_dbg(DBG_BATMAN, bat_priv, 197 bat_dbg(DBG_BATMAN, bat_priv,
192 "Changing route to gateway %pM " 198 "Changing route to gateway %pM "
193 "(gw_flags: %i, tq: %i)\n", 199 "(gw_flags: %i, tq: %i)\n",
194 curr_gw_tmp->orig_node->orig, 200 curr_gw_tmp->orig_node->orig,
195 curr_gw_tmp->orig_node->gw_flags, 201 curr_gw_tmp->orig_node->gw_flags,
196 curr_gw_tmp->orig_node->router->tq_avg); 202 router->tq_avg);
197 203
204 neigh_node_free_ref(router);
198 gw_select(bat_priv, curr_gw_tmp); 205 gw_select(bat_priv, curr_gw_tmp);
199 } 206 }
200 207
208unlock:
201 rcu_read_unlock(); 209 rcu_read_unlock();
210out:
211 if (curr_gw)
212 gw_node_free_ref(curr_gw);
202} 213}
203 214
204void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) 215void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node)
205{ 216{
206 struct gw_node *curr_gateway_tmp; 217 struct orig_node *curr_gw_orig;
218 struct neigh_node *router_gw = NULL, *router_orig = NULL;
207 uint8_t gw_tq_avg, orig_tq_avg; 219 uint8_t gw_tq_avg, orig_tq_avg;
208 220
209 rcu_read_lock(); 221 curr_gw_orig = gw_get_selected_orig(bat_priv);
210 curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw); 222 if (!curr_gw_orig)
211 if (!curr_gateway_tmp) 223 goto deselect;
212 goto out_rcu;
213
214 if (!curr_gateway_tmp->orig_node)
215 goto deselect_rcu;
216 224
217 if (!curr_gateway_tmp->orig_node->router) 225 router_gw = orig_node_get_router(curr_gw_orig);
218 goto deselect_rcu; 226 if (!router_gw)
227 goto deselect;
219 228
220 /* this node already is the gateway */ 229 /* this node already is the gateway */
221 if (curr_gateway_tmp->orig_node == orig_node) 230 if (curr_gw_orig == orig_node)
222 goto out_rcu; 231 goto out;
223
224 if (!orig_node->router)
225 goto out_rcu;
226 232
227 gw_tq_avg = curr_gateway_tmp->orig_node->router->tq_avg; 233 router_orig = orig_node_get_router(orig_node);
228 rcu_read_unlock(); 234 if (!router_orig)
235 goto out;
229 236
230 orig_tq_avg = orig_node->router->tq_avg; 237 gw_tq_avg = router_gw->tq_avg;
238 orig_tq_avg = router_orig->tq_avg;
231 239
232 /* the TQ value has to be better */ 240 /* the TQ value has to be better */
233 if (orig_tq_avg < gw_tq_avg) 241 if (orig_tq_avg < gw_tq_avg)
@@ -245,16 +253,17 @@ void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node)
245 "Restarting gateway selection: better gateway found (tq curr: " 253 "Restarting gateway selection: better gateway found (tq curr: "
246 "%i, tq new: %i)\n", 254 "%i, tq new: %i)\n",
247 gw_tq_avg, orig_tq_avg); 255 gw_tq_avg, orig_tq_avg);
248 goto deselect;
249 256
250out_rcu:
251 rcu_read_unlock();
252 goto out;
253deselect_rcu:
254 rcu_read_unlock();
255deselect: 257deselect:
256 gw_deselect(bat_priv); 258 gw_deselect(bat_priv);
257out: 259out:
260 if (curr_gw_orig)
261 orig_node_free_ref(curr_gw_orig);
262 if (router_gw)
263 neigh_node_free_ref(router_gw);
264 if (router_orig)
265 neigh_node_free_ref(router_orig);
266
258 return; 267 return;
259} 268}
260 269
@@ -291,7 +300,15 @@ void gw_node_update(struct bat_priv *bat_priv,
291 struct orig_node *orig_node, uint8_t new_gwflags) 300 struct orig_node *orig_node, uint8_t new_gwflags)
292{ 301{
293 struct hlist_node *node; 302 struct hlist_node *node;
294 struct gw_node *gw_node; 303 struct gw_node *gw_node, *curr_gw;
304
305 /**
306 * Note: We don't need a NULL check here, since curr_gw never gets
307 * dereferenced. If curr_gw is NULL we also should not exit as we may
308 * have this gateway in our list (duplication check!) even though we
309 * have no currently selected gateway.
310 */
311 curr_gw = gw_get_selected_gw_node(bat_priv);
295 312
296 rcu_read_lock(); 313 rcu_read_lock();
297 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { 314 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
@@ -312,22 +329,26 @@ void gw_node_update(struct bat_priv *bat_priv,
312 "Gateway %pM removed from gateway list\n", 329 "Gateway %pM removed from gateway list\n",
313 orig_node->orig); 330 orig_node->orig);
314 331
315 if (gw_node == rcu_dereference(bat_priv->curr_gw)) { 332 if (gw_node == curr_gw)
316 rcu_read_unlock(); 333 goto deselect;
317 gw_deselect(bat_priv);
318 return;
319 }
320 } 334 }
321 335
322 rcu_read_unlock(); 336 goto unlock;
323 return;
324 } 337 }
325 rcu_read_unlock();
326 338
327 if (new_gwflags == 0) 339 if (new_gwflags == 0)
328 return; 340 goto unlock;
329 341
330 gw_node_add(bat_priv, orig_node, new_gwflags); 342 gw_node_add(bat_priv, orig_node, new_gwflags);
343 goto unlock;
344
345deselect:
346 gw_deselect(bat_priv);
347unlock:
348 rcu_read_unlock();
349
350 if (curr_gw)
351 gw_node_free_ref(curr_gw);
331} 352}
332 353
333void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node) 354void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node)
@@ -337,9 +358,12 @@ void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node)
337 358
338void gw_node_purge(struct bat_priv *bat_priv) 359void gw_node_purge(struct bat_priv *bat_priv)
339{ 360{
340 struct gw_node *gw_node; 361 struct gw_node *gw_node, *curr_gw;
341 struct hlist_node *node, *node_tmp; 362 struct hlist_node *node, *node_tmp;
342 unsigned long timeout = 2 * PURGE_TIMEOUT * HZ; 363 unsigned long timeout = 2 * PURGE_TIMEOUT * HZ;
364 char do_deselect = 0;
365
366 curr_gw = gw_get_selected_gw_node(bat_priv);
343 367
344 spin_lock_bh(&bat_priv->gw_list_lock); 368 spin_lock_bh(&bat_priv->gw_list_lock);
345 369
@@ -350,41 +374,56 @@ void gw_node_purge(struct bat_priv *bat_priv)
350 atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) 374 atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)
351 continue; 375 continue;
352 376
353 if (rcu_dereference(bat_priv->curr_gw) == gw_node) 377 if (curr_gw == gw_node)
354 gw_deselect(bat_priv); 378 do_deselect = 1;
355 379
356 hlist_del_rcu(&gw_node->list); 380 hlist_del_rcu(&gw_node->list);
357 gw_node_free_ref(gw_node); 381 gw_node_free_ref(gw_node);
358 } 382 }
359 383
360
361 spin_unlock_bh(&bat_priv->gw_list_lock); 384 spin_unlock_bh(&bat_priv->gw_list_lock);
385
386 /* gw_deselect() needs to acquire the gw_list_lock */
387 if (do_deselect)
388 gw_deselect(bat_priv);
389
390 if (curr_gw)
391 gw_node_free_ref(curr_gw);
362} 392}
363 393
394/**
395 * fails if orig_node has no router
396 */
364static int _write_buffer_text(struct bat_priv *bat_priv, 397static int _write_buffer_text(struct bat_priv *bat_priv,
365 struct seq_file *seq, struct gw_node *gw_node) 398 struct seq_file *seq, struct gw_node *gw_node)
366{ 399{
367 struct gw_node *curr_gw; 400 struct gw_node *curr_gw;
368 int down, up, ret; 401 struct neigh_node *router;
402 int down, up, ret = -1;
369 403
370 gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up); 404 gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up);
371 405
372 rcu_read_lock(); 406 router = orig_node_get_router(gw_node->orig_node);
373 curr_gw = rcu_dereference(bat_priv->curr_gw); 407 if (!router)
408 goto out;
374 409
375 ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n", 410 curr_gw = gw_get_selected_gw_node(bat_priv);
376 (curr_gw == gw_node ? "=>" : " "),
377 gw_node->orig_node->orig,
378 gw_node->orig_node->router->tq_avg,
379 gw_node->orig_node->router->addr,
380 gw_node->orig_node->router->if_incoming->net_dev->name,
381 gw_node->orig_node->gw_flags,
382 (down > 2048 ? down / 1024 : down),
383 (down > 2048 ? "MBit" : "KBit"),
384 (up > 2048 ? up / 1024 : up),
385 (up > 2048 ? "MBit" : "KBit"));
386 411
387 rcu_read_unlock(); 412 ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n",
413 (curr_gw == gw_node ? "=>" : " "),
414 gw_node->orig_node->orig,
415 router->tq_avg, router->addr,
416 router->if_incoming->net_dev->name,
417 gw_node->orig_node->gw_flags,
418 (down > 2048 ? down / 1024 : down),
419 (down > 2048 ? "MBit" : "KBit"),
420 (up > 2048 ? up / 1024 : up),
421 (up > 2048 ? "MBit" : "KBit"));
422
423 neigh_node_free_ref(router);
424 if (curr_gw)
425 gw_node_free_ref(curr_gw);
426out:
388 return ret; 427 return ret;
389} 428}
390 429
@@ -392,40 +431,42 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset)
392{ 431{
393 struct net_device *net_dev = (struct net_device *)seq->private; 432 struct net_device *net_dev = (struct net_device *)seq->private;
394 struct bat_priv *bat_priv = netdev_priv(net_dev); 433 struct bat_priv *bat_priv = netdev_priv(net_dev);
434 struct hard_iface *primary_if;
395 struct gw_node *gw_node; 435 struct gw_node *gw_node;
396 struct hlist_node *node; 436 struct hlist_node *node;
397 int gw_count = 0; 437 int gw_count = 0, ret = 0;
398
399 if (!bat_priv->primary_if) {
400 438
401 return seq_printf(seq, "BATMAN mesh %s disabled - please " 439 primary_if = primary_if_get_selected(bat_priv);
402 "specify interfaces to enable it\n", 440 if (!primary_if) {
403 net_dev->name); 441 ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
442 "specify interfaces to enable it\n",
443 net_dev->name);
444 goto out;
404 } 445 }
405 446
406 if (bat_priv->primary_if->if_status != IF_ACTIVE) { 447 if (primary_if->if_status != IF_ACTIVE) {
407 448 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
408 return seq_printf(seq, "BATMAN mesh %s disabled - " 449 "primary interface not active\n",
409 "primary interface not active\n", 450 net_dev->name);
410 net_dev->name); 451 goto out;
411 } 452 }
412 453
413 seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... " 454 seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... "
414 "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n", 455 "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
415 "Gateway", "#", TQ_MAX_VALUE, "Nexthop", 456 "Gateway", "#", TQ_MAX_VALUE, "Nexthop",
416 "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR, 457 "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR,
417 bat_priv->primary_if->net_dev->name, 458 primary_if->net_dev->name,
418 bat_priv->primary_if->net_dev->dev_addr, net_dev->name); 459 primary_if->net_dev->dev_addr, net_dev->name);
419 460
420 rcu_read_lock(); 461 rcu_read_lock();
421 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { 462 hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
422 if (gw_node->deleted) 463 if (gw_node->deleted)
423 continue; 464 continue;
424 465
425 if (!gw_node->orig_node->router) 466 /* fails if orig_node has no router */
467 if (_write_buffer_text(bat_priv, seq, gw_node) < 0)
426 continue; 468 continue;
427 469
428 _write_buffer_text(bat_priv, seq, gw_node);
429 gw_count++; 470 gw_count++;
430 } 471 }
431 rcu_read_unlock(); 472 rcu_read_unlock();
@@ -433,7 +474,10 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset)
433 if (gw_count == 0) 474 if (gw_count == 0)
434 seq_printf(seq, "No gateways in range ...\n"); 475 seq_printf(seq, "No gateways in range ...\n");
435 476
436 return 0; 477out:
478 if (primary_if)
479 hardif_free_ref(primary_if);
480 return ret;
437} 481}
438 482
439int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) 483int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
@@ -442,6 +486,7 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
442 struct iphdr *iphdr; 486 struct iphdr *iphdr;
443 struct ipv6hdr *ipv6hdr; 487 struct ipv6hdr *ipv6hdr;
444 struct udphdr *udphdr; 488 struct udphdr *udphdr;
489 struct gw_node *curr_gw;
445 unsigned int header_len = 0; 490 unsigned int header_len = 0;
446 491
447 if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF) 492 if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF)
@@ -506,12 +551,11 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
506 if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER) 551 if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)
507 return -1; 552 return -1;
508 553
509 rcu_read_lock(); 554 curr_gw = gw_get_selected_gw_node(bat_priv);
510 if (!rcu_dereference(bat_priv->curr_gw)) { 555 if (!curr_gw)
511 rcu_read_unlock();
512 return 0; 556 return 0;
513 }
514 rcu_read_unlock();
515 557
558 if (curr_gw)
559 gw_node_free_ref(curr_gw);
516 return 1; 560 return 1;
517} 561}
diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h
index 2aa439124ee3..1ce8c6066da1 100644
--- a/net/batman-adv/gateway_client.h
+++ b/net/batman-adv/gateway_client.h
@@ -24,7 +24,7 @@
24 24
25void gw_deselect(struct bat_priv *bat_priv); 25void gw_deselect(struct bat_priv *bat_priv);
26void gw_election(struct bat_priv *bat_priv); 26void gw_election(struct bat_priv *bat_priv);
27void *gw_get_selected(struct bat_priv *bat_priv); 27struct orig_node *gw_get_selected_orig(struct bat_priv *bat_priv);
28void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node); 28void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node);
29void gw_node_update(struct bat_priv *bat_priv, 29void gw_node_update(struct bat_priv *bat_priv,
30 struct orig_node *orig_node, uint8_t new_gwflags); 30 struct orig_node *orig_node, uint8_t new_gwflags);
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index b3058e46ee6b..dfbfccc9fe40 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -31,9 +31,6 @@
31 31
32#include <linux/if_arp.h> 32#include <linux/if_arp.h>
33 33
34/* protect update critical side of hardif_list - but not the content */
35static DEFINE_SPINLOCK(hardif_list_lock);
36
37 34
38static int batman_skb_recv(struct sk_buff *skb, 35static int batman_skb_recv(struct sk_buff *skb,
39 struct net_device *dev, 36 struct net_device *dev,
@@ -110,47 +107,57 @@ out:
110 return hard_iface; 107 return hard_iface;
111} 108}
112 109
113static void update_primary_addr(struct bat_priv *bat_priv) 110static void primary_if_update_addr(struct bat_priv *bat_priv)
114{ 111{
115 struct vis_packet *vis_packet; 112 struct vis_packet *vis_packet;
113 struct hard_iface *primary_if;
114
115 primary_if = primary_if_get_selected(bat_priv);
116 if (!primary_if)
117 goto out;
116 118
117 vis_packet = (struct vis_packet *) 119 vis_packet = (struct vis_packet *)
118 bat_priv->my_vis_info->skb_packet->data; 120 bat_priv->my_vis_info->skb_packet->data;
119 memcpy(vis_packet->vis_orig, 121 memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
120 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
121 memcpy(vis_packet->sender_orig, 122 memcpy(vis_packet->sender_orig,
122 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 123 primary_if->net_dev->dev_addr, ETH_ALEN);
124
125out:
126 if (primary_if)
127 hardif_free_ref(primary_if);
123} 128}
124 129
125static void set_primary_if(struct bat_priv *bat_priv, 130static void primary_if_select(struct bat_priv *bat_priv,
126 struct hard_iface *hard_iface) 131 struct hard_iface *new_hard_iface)
127{ 132{
133 struct hard_iface *curr_hard_iface;
128 struct batman_packet *batman_packet; 134 struct batman_packet *batman_packet;
129 struct hard_iface *old_if;
130 135
131 if (hard_iface && !atomic_inc_not_zero(&hard_iface->refcount)) 136 ASSERT_RTNL();
132 hard_iface = NULL; 137
138 if (new_hard_iface && !atomic_inc_not_zero(&new_hard_iface->refcount))
139 new_hard_iface = NULL;
133 140
134 old_if = bat_priv->primary_if; 141 curr_hard_iface = bat_priv->primary_if;
135 bat_priv->primary_if = hard_iface; 142 rcu_assign_pointer(bat_priv->primary_if, new_hard_iface);
136 143
137 if (old_if) 144 if (curr_hard_iface)
138 hardif_free_ref(old_if); 145 hardif_free_ref(curr_hard_iface);
139 146
140 if (!bat_priv->primary_if) 147 if (!new_hard_iface)
141 return; 148 return;
142 149
143 batman_packet = (struct batman_packet *)(hard_iface->packet_buff); 150 batman_packet = (struct batman_packet *)(new_hard_iface->packet_buff);
144 batman_packet->flags = PRIMARIES_FIRST_HOP; 151 batman_packet->flags = PRIMARIES_FIRST_HOP;
145 batman_packet->ttl = TTL; 152 batman_packet->ttl = TTL;
146 153
147 update_primary_addr(bat_priv); 154 primary_if_update_addr(bat_priv);
148 155
149 /*** 156 /***
150 * hacky trick to make sure that we send the HNA information via 157 * hacky trick to make sure that we send the TT information via
151 * our new primary interface 158 * our new primary interface
152 */ 159 */
153 atomic_set(&bat_priv->hna_local_changed, 1); 160 atomic_set(&bat_priv->tt_local_changed, 1);
154} 161}
155 162
156static bool hardif_is_iface_up(struct hard_iface *hard_iface) 163static bool hardif_is_iface_up(struct hard_iface *hard_iface)
@@ -236,9 +243,10 @@ void update_min_mtu(struct net_device *soft_iface)
236static void hardif_activate_interface(struct hard_iface *hard_iface) 243static void hardif_activate_interface(struct hard_iface *hard_iface)
237{ 244{
238 struct bat_priv *bat_priv; 245 struct bat_priv *bat_priv;
246 struct hard_iface *primary_if = NULL;
239 247
240 if (hard_iface->if_status != IF_INACTIVE) 248 if (hard_iface->if_status != IF_INACTIVE)
241 return; 249 goto out;
242 250
243 bat_priv = netdev_priv(hard_iface->soft_iface); 251 bat_priv = netdev_priv(hard_iface->soft_iface);
244 252
@@ -249,14 +257,18 @@ static void hardif_activate_interface(struct hard_iface *hard_iface)
249 * the first active interface becomes our primary interface or 257 * the first active interface becomes our primary interface or
250 * the next active interface after the old primay interface was removed 258 * the next active interface after the old primay interface was removed
251 */ 259 */
252 if (!bat_priv->primary_if) 260 primary_if = primary_if_get_selected(bat_priv);
253 set_primary_if(bat_priv, hard_iface); 261 if (!primary_if)
262 primary_if_select(bat_priv, hard_iface);
254 263
255 bat_info(hard_iface->soft_iface, "Interface activated: %s\n", 264 bat_info(hard_iface->soft_iface, "Interface activated: %s\n",
256 hard_iface->net_dev->name); 265 hard_iface->net_dev->name);
257 266
258 update_min_mtu(hard_iface->soft_iface); 267 update_min_mtu(hard_iface->soft_iface);
259 return; 268
269out:
270 if (primary_if)
271 hardif_free_ref(primary_if);
260} 272}
261 273
262static void hardif_deactivate_interface(struct hard_iface *hard_iface) 274static void hardif_deactivate_interface(struct hard_iface *hard_iface)
@@ -327,7 +339,7 @@ int hardif_enable_interface(struct hard_iface *hard_iface, char *iface_name)
327 batman_packet->flags = 0; 339 batman_packet->flags = 0;
328 batman_packet->ttl = 2; 340 batman_packet->ttl = 2;
329 batman_packet->tq = TQ_MAX_VALUE; 341 batman_packet->tq = TQ_MAX_VALUE;
330 batman_packet->num_hna = 0; 342 batman_packet->num_tt = 0;
331 343
332 hard_iface->if_num = bat_priv->num_ifaces; 344 hard_iface->if_num = bat_priv->num_ifaces;
333 bat_priv->num_ifaces++; 345 bat_priv->num_ifaces++;
@@ -386,12 +398,13 @@ err:
386void hardif_disable_interface(struct hard_iface *hard_iface) 398void hardif_disable_interface(struct hard_iface *hard_iface)
387{ 399{
388 struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 400 struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
401 struct hard_iface *primary_if = NULL;
389 402
390 if (hard_iface->if_status == IF_ACTIVE) 403 if (hard_iface->if_status == IF_ACTIVE)
391 hardif_deactivate_interface(hard_iface); 404 hardif_deactivate_interface(hard_iface);
392 405
393 if (hard_iface->if_status != IF_INACTIVE) 406 if (hard_iface->if_status != IF_INACTIVE)
394 return; 407 goto out;
395 408
396 bat_info(hard_iface->soft_iface, "Removing interface: %s\n", 409 bat_info(hard_iface->soft_iface, "Removing interface: %s\n",
397 hard_iface->net_dev->name); 410 hard_iface->net_dev->name);
@@ -400,11 +413,12 @@ void hardif_disable_interface(struct hard_iface *hard_iface)
400 bat_priv->num_ifaces--; 413 bat_priv->num_ifaces--;
401 orig_hash_del_if(hard_iface, bat_priv->num_ifaces); 414 orig_hash_del_if(hard_iface, bat_priv->num_ifaces);
402 415
403 if (hard_iface == bat_priv->primary_if) { 416 primary_if = primary_if_get_selected(bat_priv);
417 if (hard_iface == primary_if) {
404 struct hard_iface *new_if; 418 struct hard_iface *new_if;
405 419
406 new_if = hardif_get_active(hard_iface->soft_iface); 420 new_if = hardif_get_active(hard_iface->soft_iface);
407 set_primary_if(bat_priv, new_if); 421 primary_if_select(bat_priv, new_if);
408 422
409 if (new_if) 423 if (new_if)
410 hardif_free_ref(new_if); 424 hardif_free_ref(new_if);
@@ -425,6 +439,10 @@ void hardif_disable_interface(struct hard_iface *hard_iface)
425 439
426 hard_iface->soft_iface = NULL; 440 hard_iface->soft_iface = NULL;
427 hardif_free_ref(hard_iface); 441 hardif_free_ref(hard_iface);
442
443out:
444 if (primary_if)
445 hardif_free_ref(primary_if);
428} 446}
429 447
430static struct hard_iface *hardif_add_interface(struct net_device *net_dev) 448static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
@@ -432,6 +450,8 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
432 struct hard_iface *hard_iface; 450 struct hard_iface *hard_iface;
433 int ret; 451 int ret;
434 452
453 ASSERT_RTNL();
454
435 ret = is_valid_iface(net_dev); 455 ret = is_valid_iface(net_dev);
436 if (ret != 1) 456 if (ret != 1)
437 goto out; 457 goto out;
@@ -458,10 +478,7 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
458 atomic_set(&hard_iface->refcount, 2); 478 atomic_set(&hard_iface->refcount, 2);
459 479
460 check_known_mac_addr(hard_iface->net_dev); 480 check_known_mac_addr(hard_iface->net_dev);
461
462 spin_lock(&hardif_list_lock);
463 list_add_tail_rcu(&hard_iface->list, &hardif_list); 481 list_add_tail_rcu(&hard_iface->list, &hardif_list);
464 spin_unlock(&hardif_list_lock);
465 482
466 return hard_iface; 483 return hard_iface;
467 484
@@ -475,6 +492,8 @@ out:
475 492
476static void hardif_remove_interface(struct hard_iface *hard_iface) 493static void hardif_remove_interface(struct hard_iface *hard_iface)
477{ 494{
495 ASSERT_RTNL();
496
478 /* first deactivate interface */ 497 /* first deactivate interface */
479 if (hard_iface->if_status != IF_NOT_IN_USE) 498 if (hard_iface->if_status != IF_NOT_IN_USE)
480 hardif_disable_interface(hard_iface); 499 hardif_disable_interface(hard_iface);
@@ -490,20 +509,11 @@ static void hardif_remove_interface(struct hard_iface *hard_iface)
490void hardif_remove_interfaces(void) 509void hardif_remove_interfaces(void)
491{ 510{
492 struct hard_iface *hard_iface, *hard_iface_tmp; 511 struct hard_iface *hard_iface, *hard_iface_tmp;
493 struct list_head if_queue;
494
495 INIT_LIST_HEAD(&if_queue);
496 512
497 spin_lock(&hardif_list_lock); 513 rtnl_lock();
498 list_for_each_entry_safe(hard_iface, hard_iface_tmp, 514 list_for_each_entry_safe(hard_iface, hard_iface_tmp,
499 &hardif_list, list) { 515 &hardif_list, list) {
500 list_del_rcu(&hard_iface->list); 516 list_del_rcu(&hard_iface->list);
501 list_add_tail(&hard_iface->list, &if_queue);
502 }
503 spin_unlock(&hardif_list_lock);
504
505 rtnl_lock();
506 list_for_each_entry_safe(hard_iface, hard_iface_tmp, &if_queue, list) {
507 hardif_remove_interface(hard_iface); 517 hardif_remove_interface(hard_iface);
508 } 518 }
509 rtnl_unlock(); 519 rtnl_unlock();
@@ -514,6 +524,7 @@ static int hard_if_event(struct notifier_block *this,
514{ 524{
515 struct net_device *net_dev = (struct net_device *)ptr; 525 struct net_device *net_dev = (struct net_device *)ptr;
516 struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev); 526 struct hard_iface *hard_iface = hardif_get_by_netdev(net_dev);
527 struct hard_iface *primary_if = NULL;
517 struct bat_priv *bat_priv; 528 struct bat_priv *bat_priv;
518 529
519 if (!hard_iface && event == NETDEV_REGISTER) 530 if (!hard_iface && event == NETDEV_REGISTER)
@@ -531,9 +542,7 @@ static int hard_if_event(struct notifier_block *this,
531 hardif_deactivate_interface(hard_iface); 542 hardif_deactivate_interface(hard_iface);
532 break; 543 break;
533 case NETDEV_UNREGISTER: 544 case NETDEV_UNREGISTER:
534 spin_lock(&hardif_list_lock);
535 list_del_rcu(&hard_iface->list); 545 list_del_rcu(&hard_iface->list);
536 spin_unlock(&hardif_list_lock);
537 546
538 hardif_remove_interface(hard_iface); 547 hardif_remove_interface(hard_iface);
539 break; 548 break;
@@ -549,8 +558,12 @@ static int hard_if_event(struct notifier_block *this,
549 update_mac_addresses(hard_iface); 558 update_mac_addresses(hard_iface);
550 559
551 bat_priv = netdev_priv(hard_iface->soft_iface); 560 bat_priv = netdev_priv(hard_iface->soft_iface);
552 if (hard_iface == bat_priv->primary_if) 561 primary_if = primary_if_get_selected(bat_priv);
553 update_primary_addr(bat_priv); 562 if (!primary_if)
563 goto hardif_put;
564
565 if (hard_iface == primary_if)
566 primary_if_update_addr(bat_priv);
554 break; 567 break;
555 default: 568 default:
556 break; 569 break;
@@ -559,6 +572,8 @@ static int hard_if_event(struct notifier_block *this,
559hardif_put: 572hardif_put:
560 hardif_free_ref(hard_iface); 573 hardif_free_ref(hard_iface);
561out: 574out:
575 if (primary_if)
576 hardif_free_ref(primary_if);
562 return NOTIFY_DONE; 577 return NOTIFY_DONE;
563} 578}
564 579
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h
index a9ddf36e51c8..64265991460b 100644
--- a/net/batman-adv/hard-interface.h
+++ b/net/batman-adv/hard-interface.h
@@ -45,4 +45,22 @@ static inline void hardif_free_ref(struct hard_iface *hard_iface)
45 call_rcu(&hard_iface->rcu, hardif_free_rcu); 45 call_rcu(&hard_iface->rcu, hardif_free_rcu);
46} 46}
47 47
48static inline struct hard_iface *primary_if_get_selected(
49 struct bat_priv *bat_priv)
50{
51 struct hard_iface *hard_iface;
52
53 rcu_read_lock();
54 hard_iface = rcu_dereference(bat_priv->primary_if);
55 if (!hard_iface)
56 goto out;
57
58 if (!atomic_inc_not_zero(&hard_iface->refcount))
59 hard_iface = NULL;
60
61out:
62 rcu_read_unlock();
63 return hard_iface;
64}
65
48#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */ 66#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 34ce56c358e5..fa22ba2bb832 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -153,6 +153,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
153{ 153{
154 struct socket_client *socket_client = file->private_data; 154 struct socket_client *socket_client = file->private_data;
155 struct bat_priv *bat_priv = socket_client->bat_priv; 155 struct bat_priv *bat_priv = socket_client->bat_priv;
156 struct hard_iface *primary_if = NULL;
156 struct sk_buff *skb; 157 struct sk_buff *skb;
157 struct icmp_packet_rr *icmp_packet; 158 struct icmp_packet_rr *icmp_packet;
158 159
@@ -167,15 +168,21 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
167 return -EINVAL; 168 return -EINVAL;
168 } 169 }
169 170
170 if (!bat_priv->primary_if) 171 primary_if = primary_if_get_selected(bat_priv);
171 return -EFAULT; 172
173 if (!primary_if) {
174 len = -EFAULT;
175 goto out;
176 }
172 177
173 if (len >= sizeof(struct icmp_packet_rr)) 178 if (len >= sizeof(struct icmp_packet_rr))
174 packet_len = sizeof(struct icmp_packet_rr); 179 packet_len = sizeof(struct icmp_packet_rr);
175 180
176 skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr)); 181 skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr));
177 if (!skb) 182 if (!skb) {
178 return -ENOMEM; 183 len = -ENOMEM;
184 goto out;
185 }
179 186
180 skb_reserve(skb, sizeof(struct ethhdr)); 187 skb_reserve(skb, sizeof(struct ethhdr));
181 icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len); 188 icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len);
@@ -218,23 +225,13 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
218 if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) 225 if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
219 goto dst_unreach; 226 goto dst_unreach;
220 227
221 rcu_read_lock();
222 orig_node = orig_hash_find(bat_priv, icmp_packet->dst); 228 orig_node = orig_hash_find(bat_priv, icmp_packet->dst);
223
224 if (!orig_node) 229 if (!orig_node)
225 goto unlock; 230 goto dst_unreach;
226
227 neigh_node = orig_node->router;
228 231
232 neigh_node = orig_node_get_router(orig_node);
229 if (!neigh_node) 233 if (!neigh_node)
230 goto unlock; 234 goto dst_unreach;
231
232 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
233 neigh_node = NULL;
234 goto unlock;
235 }
236
237 rcu_read_unlock();
238 235
239 if (!neigh_node->if_incoming) 236 if (!neigh_node->if_incoming)
240 goto dst_unreach; 237 goto dst_unreach;
@@ -243,7 +240,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
243 goto dst_unreach; 240 goto dst_unreach;
244 241
245 memcpy(icmp_packet->orig, 242 memcpy(icmp_packet->orig,
246 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 243 primary_if->net_dev->dev_addr, ETH_ALEN);
247 244
248 if (packet_len == sizeof(struct icmp_packet_rr)) 245 if (packet_len == sizeof(struct icmp_packet_rr))
249 memcpy(icmp_packet->rr, 246 memcpy(icmp_packet->rr,
@@ -252,14 +249,14 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
252 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 249 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
253 goto out; 250 goto out;
254 251
255unlock:
256 rcu_read_unlock();
257dst_unreach: 252dst_unreach:
258 icmp_packet->msg_type = DESTINATION_UNREACHABLE; 253 icmp_packet->msg_type = DESTINATION_UNREACHABLE;
259 bat_socket_add_packet(socket_client, icmp_packet, packet_len); 254 bat_socket_add_packet(socket_client, icmp_packet, packet_len);
260free_skb: 255free_skb:
261 kfree_skb(skb); 256 kfree_skb(skb);
262out: 257out:
258 if (primary_if)
259 hardif_free_ref(primary_if);
263 if (neigh_node) 260 if (neigh_node)
264 neigh_node_free_ref(neigh_node); 261 neigh_node_free_ref(neigh_node);
265 if (orig_node) 262 if (orig_node)
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 709b33bbdf43..0a7cee0076f4 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -33,6 +33,9 @@
33#include "vis.h" 33#include "vis.h"
34#include "hash.h" 34#include "hash.h"
35 35
36
37/* List manipulations on hardif_list have to be rtnl_lock()'ed,
38 * list traversals just rcu-locked */
36struct list_head hardif_list; 39struct list_head hardif_list;
37 40
38unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 41unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -81,28 +84,29 @@ int mesh_init(struct net_device *soft_iface)
81 84
82 spin_lock_init(&bat_priv->forw_bat_list_lock); 85 spin_lock_init(&bat_priv->forw_bat_list_lock);
83 spin_lock_init(&bat_priv->forw_bcast_list_lock); 86 spin_lock_init(&bat_priv->forw_bcast_list_lock);
84 spin_lock_init(&bat_priv->hna_lhash_lock); 87 spin_lock_init(&bat_priv->tt_lhash_lock);
85 spin_lock_init(&bat_priv->hna_ghash_lock); 88 spin_lock_init(&bat_priv->tt_ghash_lock);
86 spin_lock_init(&bat_priv->gw_list_lock); 89 spin_lock_init(&bat_priv->gw_list_lock);
87 spin_lock_init(&bat_priv->vis_hash_lock); 90 spin_lock_init(&bat_priv->vis_hash_lock);
88 spin_lock_init(&bat_priv->vis_list_lock); 91 spin_lock_init(&bat_priv->vis_list_lock);
89 spin_lock_init(&bat_priv->softif_neigh_lock); 92 spin_lock_init(&bat_priv->softif_neigh_lock);
93 spin_lock_init(&bat_priv->softif_neigh_vid_lock);
90 94
91 INIT_HLIST_HEAD(&bat_priv->forw_bat_list); 95 INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
92 INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); 96 INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
93 INIT_HLIST_HEAD(&bat_priv->gw_list); 97 INIT_HLIST_HEAD(&bat_priv->gw_list);
94 INIT_HLIST_HEAD(&bat_priv->softif_neigh_list); 98 INIT_HLIST_HEAD(&bat_priv->softif_neigh_vids);
95 99
96 if (originator_init(bat_priv) < 1) 100 if (originator_init(bat_priv) < 1)
97 goto err; 101 goto err;
98 102
99 if (hna_local_init(bat_priv) < 1) 103 if (tt_local_init(bat_priv) < 1)
100 goto err; 104 goto err;
101 105
102 if (hna_global_init(bat_priv) < 1) 106 if (tt_global_init(bat_priv) < 1)
103 goto err; 107 goto err;
104 108
105 hna_local_add(soft_iface, soft_iface->dev_addr); 109 tt_local_add(soft_iface, soft_iface->dev_addr);
106 110
107 if (vis_init(bat_priv) < 1) 111 if (vis_init(bat_priv) < 1)
108 goto err; 112 goto err;
@@ -133,8 +137,8 @@ void mesh_free(struct net_device *soft_iface)
133 gw_node_purge(bat_priv); 137 gw_node_purge(bat_priv);
134 originator_free(bat_priv); 138 originator_free(bat_priv);
135 139
136 hna_local_free(bat_priv); 140 tt_local_free(bat_priv);
137 hna_global_free(bat_priv); 141 tt_global_free(bat_priv);
138 142
139 softif_neigh_purge(bat_priv); 143 softif_neigh_purge(bat_priv);
140 144
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index dc248697de71..148b49e02642 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -34,16 +34,18 @@
34 34
35#define TQ_MAX_VALUE 255 35#define TQ_MAX_VALUE 255
36#define JITTER 20 36#define JITTER 20
37#define TTL 50 /* Time To Live of broadcast messages */
38 37
39#define PURGE_TIMEOUT 200 /* purge originators after time in seconds if no 38 /* Time To Live of broadcast messages */
40 * valid packet comes in -> TODO: check 39#define TTL 50
41 * influence on TQ_LOCAL_WINDOW_SIZE */
42#define LOCAL_HNA_TIMEOUT 3600 /* in seconds */
43 40
44#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator 41/* purge originators after time in seconds if no valid packet comes in
45 * messages in squence numbers (should be a 42 * -> TODO: check influence on TQ_LOCAL_WINDOW_SIZE */
46 * multiple of our word size) */ 43#define PURGE_TIMEOUT 200
44#define TT_LOCAL_TIMEOUT 3600 /* in seconds */
45
46/* sliding packet range of received originator messages in squence numbers
47 * (should be a multiple of our word size) */
48#define TQ_LOCAL_WINDOW_SIZE 64
47#define TQ_GLOBAL_WINDOW_SIZE 5 49#define TQ_GLOBAL_WINDOW_SIZE 5
48#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1 50#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1
49#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1 51#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1
@@ -55,21 +57,20 @@
55 57
56#define VIS_INTERVAL 5000 /* 5 seconds */ 58#define VIS_INTERVAL 5000 /* 5 seconds */
57 59
58/* how much worse secondary interfaces may be to 60/* how much worse secondary interfaces may be to be considered as bonding
59 * to be considered as bonding candidates */ 61 * candidates */
60
61#define BONDING_TQ_THRESHOLD 50 62#define BONDING_TQ_THRESHOLD 50
62 63
63#define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or 64/* should not be bigger than 512 bytes or change the size of
64 * change the size of 65 * forw_packet->direct_link_flags */
65 * forw_packet->direct_link_flags */ 66#define MAX_AGGREGATION_BYTES 512
66#define MAX_AGGREGATION_MS 100 67#define MAX_AGGREGATION_MS 100
67 68
68#define SOFTIF_NEIGH_TIMEOUT 180000 /* 3 minutes */ 69#define SOFTIF_NEIGH_TIMEOUT 180000 /* 3 minutes */
69 70
71/* don't reset again within 30 seconds */
70#define RESET_PROTECTION_MS 30000 72#define RESET_PROTECTION_MS 30000
71#define EXPECTED_SEQNO_RANGE 65536 73#define EXPECTED_SEQNO_RANGE 65536
72/* don't reset again within 30 seconds */
73 74
74#define MESH_INACTIVE 0 75#define MESH_INACTIVE 0
75#define MESH_ACTIVE 1 76#define MESH_ACTIVE 1
@@ -84,12 +85,13 @@
84#ifdef pr_fmt 85#ifdef pr_fmt
85#undef pr_fmt 86#undef pr_fmt
86#endif 87#endif
87#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* Append 'batman-adv: ' before 88/* Append 'batman-adv: ' before kernel messages */
88 * kernel messages */ 89#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
89 90
90#define DBG_BATMAN 1 /* all messages related to routing / flooding / 91/* all messages related to routing / flooding / broadcasting / etc */
91 * broadcasting / etc */ 92#define DBG_BATMAN 1
92#define DBG_ROUTES 2 /* route or hna added / changed / deleted */ 93/* route or tt entry added / changed / deleted */
94#define DBG_ROUTES 2
93#define DBG_ALL 3 95#define DBG_ALL 3
94 96
95 97
@@ -175,4 +177,6 @@ static inline int compare_eth(void *data1, void *data2)
175 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 177 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
176} 178}
177 179
180#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
181
178#endif /* _NET_BATMAN_ADV_MAIN_H_ */ 182#endif /* _NET_BATMAN_ADV_MAIN_H_ */
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 0b9133022d2d..40a30bbcd147 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -19,8 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22/* increase the reference counter for this originator */
23
24#include "main.h" 22#include "main.h"
25#include "originator.h" 23#include "originator.h"
26#include "hash.h" 24#include "hash.h"
@@ -56,18 +54,25 @@ err:
56 return 0; 54 return 0;
57} 55}
58 56
59static void neigh_node_free_rcu(struct rcu_head *rcu) 57void neigh_node_free_ref(struct neigh_node *neigh_node)
60{ 58{
61 struct neigh_node *neigh_node; 59 if (atomic_dec_and_test(&neigh_node->refcount))
62 60 kfree_rcu(neigh_node, rcu);
63 neigh_node = container_of(rcu, struct neigh_node, rcu);
64 kfree(neigh_node);
65} 61}
66 62
67void neigh_node_free_ref(struct neigh_node *neigh_node) 63/* increases the refcounter of a found router */
64struct neigh_node *orig_node_get_router(struct orig_node *orig_node)
68{ 65{
69 if (atomic_dec_and_test(&neigh_node->refcount)) 66 struct neigh_node *router;
70 call_rcu(&neigh_node->rcu, neigh_node_free_rcu); 67
68 rcu_read_lock();
69 router = rcu_dereference(orig_node->router);
70
71 if (router && !atomic_inc_not_zero(&router->refcount))
72 router = NULL;
73
74 rcu_read_unlock();
75 return router;
71} 76}
72 77
73struct neigh_node *create_neighbor(struct orig_node *orig_node, 78struct neigh_node *create_neighbor(struct orig_node *orig_node,
@@ -87,6 +92,7 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node,
87 92
88 INIT_HLIST_NODE(&neigh_node->list); 93 INIT_HLIST_NODE(&neigh_node->list);
89 INIT_LIST_HEAD(&neigh_node->bonding_list); 94 INIT_LIST_HEAD(&neigh_node->bonding_list);
95 spin_lock_init(&neigh_node->tq_lock);
90 96
91 memcpy(neigh_node->addr, neigh, ETH_ALEN); 97 memcpy(neigh_node->addr, neigh, ETH_ALEN);
92 neigh_node->orig_node = orig_neigh_node; 98 neigh_node->orig_node = orig_neigh_node;
@@ -128,7 +134,7 @@ static void orig_node_free_rcu(struct rcu_head *rcu)
128 spin_unlock_bh(&orig_node->neigh_list_lock); 134 spin_unlock_bh(&orig_node->neigh_list_lock);
129 135
130 frag_list_free(&orig_node->frag_list); 136 frag_list_free(&orig_node->frag_list);
131 hna_global_del_orig(orig_node->bat_priv, orig_node, 137 tt_global_del_orig(orig_node->bat_priv, orig_node,
132 "originator timed out"); 138 "originator timed out");
133 139
134 kfree(orig_node->bcast_own); 140 kfree(orig_node->bcast_own);
@@ -206,7 +212,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
206 orig_node->bat_priv = bat_priv; 212 orig_node->bat_priv = bat_priv;
207 memcpy(orig_node->orig, addr, ETH_ALEN); 213 memcpy(orig_node->orig, addr, ETH_ALEN);
208 orig_node->router = NULL; 214 orig_node->router = NULL;
209 orig_node->hna_buff = NULL; 215 orig_node->tt_buff = NULL;
210 orig_node->bcast_seqno_reset = jiffies - 1 216 orig_node->bcast_seqno_reset = jiffies - 1
211 - msecs_to_jiffies(RESET_PROTECTION_MS); 217 - msecs_to_jiffies(RESET_PROTECTION_MS);
212 orig_node->batman_seqno_reset = jiffies - 1 218 orig_node->batman_seqno_reset = jiffies - 1
@@ -317,8 +323,8 @@ static bool purge_orig_node(struct bat_priv *bat_priv,
317 &best_neigh_node)) { 323 &best_neigh_node)) {
318 update_routes(bat_priv, orig_node, 324 update_routes(bat_priv, orig_node,
319 best_neigh_node, 325 best_neigh_node,
320 orig_node->hna_buff, 326 orig_node->tt_buff,
321 orig_node->hna_buff_len); 327 orig_node->tt_buff_len);
322 } 328 }
323 } 329 }
324 330
@@ -389,29 +395,34 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
389 struct hashtable_t *hash = bat_priv->orig_hash; 395 struct hashtable_t *hash = bat_priv->orig_hash;
390 struct hlist_node *node, *node_tmp; 396 struct hlist_node *node, *node_tmp;
391 struct hlist_head *head; 397 struct hlist_head *head;
398 struct hard_iface *primary_if;
392 struct orig_node *orig_node; 399 struct orig_node *orig_node;
393 struct neigh_node *neigh_node; 400 struct neigh_node *neigh_node, *neigh_node_tmp;
394 int batman_count = 0; 401 int batman_count = 0;
395 int last_seen_secs; 402 int last_seen_secs;
396 int last_seen_msecs; 403 int last_seen_msecs;
397 int i; 404 int i, ret = 0;
405
406 primary_if = primary_if_get_selected(bat_priv);
398 407
399 if ((!bat_priv->primary_if) || 408 if (!primary_if) {
400 (bat_priv->primary_if->if_status != IF_ACTIVE)) { 409 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
401 if (!bat_priv->primary_if) 410 "please specify interfaces to enable it\n",
402 return seq_printf(seq, "BATMAN mesh %s disabled - " 411 net_dev->name);
403 "please specify interfaces to enable it\n", 412 goto out;
404 net_dev->name); 413 }
405 414
406 return seq_printf(seq, "BATMAN mesh %s " 415 if (primary_if->if_status != IF_ACTIVE) {
407 "disabled - primary interface not active\n", 416 ret = seq_printf(seq, "BATMAN mesh %s "
408 net_dev->name); 417 "disabled - primary interface not active\n",
418 net_dev->name);
419 goto out;
409 } 420 }
410 421
411 seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n", 422 seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
412 SOURCE_VERSION, REVISION_VERSION_STR, 423 SOURCE_VERSION, REVISION_VERSION_STR,
413 bat_priv->primary_if->net_dev->name, 424 primary_if->net_dev->name,
414 bat_priv->primary_if->net_dev->dev_addr, net_dev->name); 425 primary_if->net_dev->dev_addr, net_dev->name);
415 seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n", 426 seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
416 "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop", 427 "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop",
417 "outgoingIF", "Potential nexthops"); 428 "outgoingIF", "Potential nexthops");
@@ -421,40 +432,47 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
421 432
422 rcu_read_lock(); 433 rcu_read_lock();
423 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { 434 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
424 if (!orig_node->router) 435 neigh_node = orig_node_get_router(orig_node);
436 if (!neigh_node)
425 continue; 437 continue;
426 438
427 if (orig_node->router->tq_avg == 0) 439 if (neigh_node->tq_avg == 0)
428 continue; 440 goto next;
429 441
430 last_seen_secs = jiffies_to_msecs(jiffies - 442 last_seen_secs = jiffies_to_msecs(jiffies -
431 orig_node->last_valid) / 1000; 443 orig_node->last_valid) / 1000;
432 last_seen_msecs = jiffies_to_msecs(jiffies - 444 last_seen_msecs = jiffies_to_msecs(jiffies -
433 orig_node->last_valid) % 1000; 445 orig_node->last_valid) % 1000;
434 446
435 neigh_node = orig_node->router;
436 seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:", 447 seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:",
437 orig_node->orig, last_seen_secs, 448 orig_node->orig, last_seen_secs,
438 last_seen_msecs, neigh_node->tq_avg, 449 last_seen_msecs, neigh_node->tq_avg,
439 neigh_node->addr, 450 neigh_node->addr,
440 neigh_node->if_incoming->net_dev->name); 451 neigh_node->if_incoming->net_dev->name);
441 452
442 hlist_for_each_entry_rcu(neigh_node, node_tmp, 453 hlist_for_each_entry_rcu(neigh_node_tmp, node_tmp,
443 &orig_node->neigh_list, list) { 454 &orig_node->neigh_list, list) {
444 seq_printf(seq, " %pM (%3i)", neigh_node->addr, 455 seq_printf(seq, " %pM (%3i)",
445 neigh_node->tq_avg); 456 neigh_node_tmp->addr,
457 neigh_node_tmp->tq_avg);
446 } 458 }
447 459
448 seq_printf(seq, "\n"); 460 seq_printf(seq, "\n");
449 batman_count++; 461 batman_count++;
462
463next:
464 neigh_node_free_ref(neigh_node);
450 } 465 }
451 rcu_read_unlock(); 466 rcu_read_unlock();
452 } 467 }
453 468
454 if ((batman_count == 0)) 469 if (batman_count == 0)
455 seq_printf(seq, "No batman nodes in range ...\n"); 470 seq_printf(seq, "No batman nodes in range ...\n");
456 471
457 return 0; 472out:
473 if (primary_if)
474 hardif_free_ref(primary_if);
475 return ret;
458} 476}
459 477
460static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) 478static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index 5cc011057da1..e1d641f27aa9 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -34,6 +34,7 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node,
34 uint8_t *neigh, 34 uint8_t *neigh,
35 struct hard_iface *if_incoming); 35 struct hard_iface *if_incoming);
36void neigh_node_free_ref(struct neigh_node *neigh_node); 36void neigh_node_free_ref(struct neigh_node *neigh_node);
37struct neigh_node *orig_node_get_router(struct orig_node *orig_node);
37int orig_seq_print_text(struct seq_file *seq, void *offset); 38int orig_seq_print_text(struct seq_file *seq, void *offset);
38int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num); 39int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num);
39int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num); 40int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num);
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index e7571879af3f..eda99650e9f8 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -61,7 +61,7 @@ struct batman_packet {
61 uint8_t orig[6]; 61 uint8_t orig[6];
62 uint8_t prev_sender[6]; 62 uint8_t prev_sender[6];
63 uint8_t ttl; 63 uint8_t ttl;
64 uint8_t num_hna; 64 uint8_t num_tt;
65 uint8_t gw_flags; /* flags related to gateway class */ 65 uint8_t gw_flags; /* flags related to gateway class */
66 uint8_t align; 66 uint8_t align;
67} __packed; 67} __packed;
@@ -128,8 +128,7 @@ struct vis_packet {
128 uint8_t entries; /* number of entries behind this struct */ 128 uint8_t entries; /* number of entries behind this struct */
129 uint32_t seqno; /* sequence number */ 129 uint32_t seqno; /* sequence number */
130 uint8_t ttl; /* TTL */ 130 uint8_t ttl; /* TTL */
131 uint8_t vis_orig[6]; /* originator that informs about its 131 uint8_t vis_orig[6]; /* originator that announces its neighbors */
132 * neighbors */
133 uint8_t target_orig[6]; /* who should receive this packet */ 132 uint8_t target_orig[6]; /* who should receive this packet */
134 uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */ 133 uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */
135} __packed; 134} __packed;
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index c172f5d0e05a..bb1c3ec7e3ff 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -64,80 +64,97 @@ void slide_own_bcast_window(struct hard_iface *hard_iface)
64 } 64 }
65} 65}
66 66
67static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node, 67static void update_TT(struct bat_priv *bat_priv, struct orig_node *orig_node,
68 unsigned char *hna_buff, int hna_buff_len) 68 unsigned char *tt_buff, int tt_buff_len)
69{ 69{
70 if ((hna_buff_len != orig_node->hna_buff_len) || 70 if ((tt_buff_len != orig_node->tt_buff_len) ||
71 ((hna_buff_len > 0) && 71 ((tt_buff_len > 0) &&
72 (orig_node->hna_buff_len > 0) && 72 (orig_node->tt_buff_len > 0) &&
73 (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) { 73 (memcmp(orig_node->tt_buff, tt_buff, tt_buff_len) != 0))) {
74 74
75 if (orig_node->hna_buff_len > 0) 75 if (orig_node->tt_buff_len > 0)
76 hna_global_del_orig(bat_priv, orig_node, 76 tt_global_del_orig(bat_priv, orig_node,
77 "originator changed hna"); 77 "originator changed tt");
78 78
79 if ((hna_buff_len > 0) && (hna_buff)) 79 if ((tt_buff_len > 0) && (tt_buff))
80 hna_global_add_orig(bat_priv, orig_node, 80 tt_global_add_orig(bat_priv, orig_node,
81 hna_buff, hna_buff_len); 81 tt_buff, tt_buff_len);
82 } 82 }
83} 83}
84 84
85static void update_route(struct bat_priv *bat_priv, 85static void update_route(struct bat_priv *bat_priv,
86 struct orig_node *orig_node, 86 struct orig_node *orig_node,
87 struct neigh_node *neigh_node, 87 struct neigh_node *neigh_node,
88 unsigned char *hna_buff, int hna_buff_len) 88 unsigned char *tt_buff, int tt_buff_len)
89{ 89{
90 struct neigh_node *neigh_node_tmp; 90 struct neigh_node *curr_router;
91
92 curr_router = orig_node_get_router(orig_node);
91 93
92 /* route deleted */ 94 /* route deleted */
93 if ((orig_node->router) && (!neigh_node)) { 95 if ((curr_router) && (!neigh_node)) {
94 96
95 bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n", 97 bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n",
96 orig_node->orig); 98 orig_node->orig);
97 hna_global_del_orig(bat_priv, orig_node, 99 tt_global_del_orig(bat_priv, orig_node,
98 "originator timed out"); 100 "originator timed out");
99 101
100 /* route added */ 102 /* route added */
101 } else if ((!orig_node->router) && (neigh_node)) { 103 } else if ((!curr_router) && (neigh_node)) {
102 104
103 bat_dbg(DBG_ROUTES, bat_priv, 105 bat_dbg(DBG_ROUTES, bat_priv,
104 "Adding route towards: %pM (via %pM)\n", 106 "Adding route towards: %pM (via %pM)\n",
105 orig_node->orig, neigh_node->addr); 107 orig_node->orig, neigh_node->addr);
106 hna_global_add_orig(bat_priv, orig_node, 108 tt_global_add_orig(bat_priv, orig_node,
107 hna_buff, hna_buff_len); 109 tt_buff, tt_buff_len);
108 110
109 /* route changed */ 111 /* route changed */
110 } else { 112 } else {
111 bat_dbg(DBG_ROUTES, bat_priv, 113 bat_dbg(DBG_ROUTES, bat_priv,
112 "Changing route towards: %pM " 114 "Changing route towards: %pM "
113 "(now via %pM - was via %pM)\n", 115 "(now via %pM - was via %pM)\n",
114 orig_node->orig, neigh_node->addr, 116 orig_node->orig, neigh_node->addr,
115 orig_node->router->addr); 117 curr_router->addr);
116 } 118 }
117 119
120 if (curr_router)
121 neigh_node_free_ref(curr_router);
122
123 /* increase refcount of new best neighbor */
118 if (neigh_node && !atomic_inc_not_zero(&neigh_node->refcount)) 124 if (neigh_node && !atomic_inc_not_zero(&neigh_node->refcount))
119 neigh_node = NULL; 125 neigh_node = NULL;
120 neigh_node_tmp = orig_node->router; 126
121 orig_node->router = neigh_node; 127 spin_lock_bh(&orig_node->neigh_list_lock);
122 if (neigh_node_tmp) 128 rcu_assign_pointer(orig_node->router, neigh_node);
123 neigh_node_free_ref(neigh_node_tmp); 129 spin_unlock_bh(&orig_node->neigh_list_lock);
130
131 /* decrease refcount of previous best neighbor */
132 if (curr_router)
133 neigh_node_free_ref(curr_router);
124} 134}
125 135
126 136
127void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, 137void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
128 struct neigh_node *neigh_node, unsigned char *hna_buff, 138 struct neigh_node *neigh_node, unsigned char *tt_buff,
129 int hna_buff_len) 139 int tt_buff_len)
130{ 140{
141 struct neigh_node *router = NULL;
131 142
132 if (!orig_node) 143 if (!orig_node)
133 return; 144 goto out;
145
146 router = orig_node_get_router(orig_node);
134 147
135 if (orig_node->router != neigh_node) 148 if (router != neigh_node)
136 update_route(bat_priv, orig_node, neigh_node, 149 update_route(bat_priv, orig_node, neigh_node,
137 hna_buff, hna_buff_len); 150 tt_buff, tt_buff_len);
138 /* may be just HNA changed */ 151 /* may be just TT changed */
139 else 152 else
140 update_HNA(bat_priv, orig_node, hna_buff, hna_buff_len); 153 update_TT(bat_priv, orig_node, tt_buff, tt_buff_len);
154
155out:
156 if (router)
157 neigh_node_free_ref(router);
141} 158}
142 159
143static int is_bidirectional_neigh(struct orig_node *orig_node, 160static int is_bidirectional_neigh(struct orig_node *orig_node,
@@ -152,65 +169,41 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
152 uint8_t orig_eq_count, neigh_rq_count, tq_own; 169 uint8_t orig_eq_count, neigh_rq_count, tq_own;
153 int tq_asym_penalty, ret = 0; 170 int tq_asym_penalty, ret = 0;
154 171
155 if (orig_node == orig_neigh_node) { 172 /* find corresponding one hop neighbor */
156 rcu_read_lock(); 173 rcu_read_lock();
157 hlist_for_each_entry_rcu(tmp_neigh_node, node, 174 hlist_for_each_entry_rcu(tmp_neigh_node, node,
158 &orig_node->neigh_list, list) { 175 &orig_neigh_node->neigh_list, list) {
159
160 if (!compare_eth(tmp_neigh_node->addr,
161 orig_neigh_node->orig))
162 continue;
163
164 if (tmp_neigh_node->if_incoming != if_incoming)
165 continue;
166
167 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
168 continue;
169
170 neigh_node = tmp_neigh_node;
171 }
172 rcu_read_unlock();
173 176
174 if (!neigh_node) 177 if (!compare_eth(tmp_neigh_node->addr, orig_neigh_node->orig))
175 neigh_node = create_neighbor(orig_node, 178 continue;
176 orig_neigh_node,
177 orig_neigh_node->orig,
178 if_incoming);
179 if (!neigh_node)
180 goto out;
181 179
182 neigh_node->last_valid = jiffies; 180 if (tmp_neigh_node->if_incoming != if_incoming)
183 } else { 181 continue;
184 /* find packet count of corresponding one hop neighbor */
185 rcu_read_lock();
186 hlist_for_each_entry_rcu(tmp_neigh_node, node,
187 &orig_neigh_node->neigh_list, list) {
188 182
189 if (!compare_eth(tmp_neigh_node->addr, 183 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
190 orig_neigh_node->orig)) 184 continue;
191 continue;
192 185
193 if (tmp_neigh_node->if_incoming != if_incoming) 186 neigh_node = tmp_neigh_node;
194 continue; 187 break;
188 }
189 rcu_read_unlock();
195 190
196 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) 191 if (!neigh_node)
197 continue; 192 neigh_node = create_neighbor(orig_neigh_node,
193 orig_neigh_node,
194 orig_neigh_node->orig,
195 if_incoming);
198 196
199 neigh_node = tmp_neigh_node; 197 if (!neigh_node)
200 } 198 goto out;
201 rcu_read_unlock();
202 199
203 if (!neigh_node) 200 /* if orig_node is direct neighbour update neigh_node last_valid */
204 neigh_node = create_neighbor(orig_neigh_node, 201 if (orig_node == orig_neigh_node)
205 orig_neigh_node, 202 neigh_node->last_valid = jiffies;
206 orig_neigh_node->orig,
207 if_incoming);
208 if (!neigh_node)
209 goto out;
210 }
211 203
212 orig_node->last_valid = jiffies; 204 orig_node->last_valid = jiffies;
213 205
206 /* find packet count of corresponding one hop neighbor */
214 spin_lock_bh(&orig_node->ogm_cnt_lock); 207 spin_lock_bh(&orig_node->ogm_cnt_lock);
215 orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num]; 208 orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num];
216 neigh_rq_count = neigh_node->real_packet_count; 209 neigh_rq_count = neigh_node->real_packet_count;
@@ -288,8 +281,8 @@ static void bonding_candidate_add(struct orig_node *orig_node,
288 struct neigh_node *neigh_node) 281 struct neigh_node *neigh_node)
289{ 282{
290 struct hlist_node *node; 283 struct hlist_node *node;
291 struct neigh_node *tmp_neigh_node; 284 struct neigh_node *tmp_neigh_node, *router = NULL;
292 uint8_t best_tq, interference_candidate = 0; 285 uint8_t interference_candidate = 0;
293 286
294 spin_lock_bh(&orig_node->neigh_list_lock); 287 spin_lock_bh(&orig_node->neigh_list_lock);
295 288
@@ -298,13 +291,12 @@ static void bonding_candidate_add(struct orig_node *orig_node,
298 neigh_node->orig_node->primary_addr)) 291 neigh_node->orig_node->primary_addr))
299 goto candidate_del; 292 goto candidate_del;
300 293
301 if (!orig_node->router) 294 router = orig_node_get_router(orig_node);
295 if (!router)
302 goto candidate_del; 296 goto candidate_del;
303 297
304 best_tq = orig_node->router->tq_avg;
305
306 /* ... and is good enough to be considered */ 298 /* ... and is good enough to be considered */
307 if (neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD) 299 if (neigh_node->tq_avg < router->tq_avg - BONDING_TQ_THRESHOLD)
308 goto candidate_del; 300 goto candidate_del;
309 301
310 /** 302 /**
@@ -350,7 +342,9 @@ candidate_del:
350 342
351out: 343out:
352 spin_unlock_bh(&orig_node->neigh_list_lock); 344 spin_unlock_bh(&orig_node->neigh_list_lock);
353 return; 345
346 if (router)
347 neigh_node_free_ref(router);
354} 348}
355 349
356/* copy primary address for bonding */ 350/* copy primary address for bonding */
@@ -369,13 +363,14 @@ static void update_orig(struct bat_priv *bat_priv,
369 struct ethhdr *ethhdr, 363 struct ethhdr *ethhdr,
370 struct batman_packet *batman_packet, 364 struct batman_packet *batman_packet,
371 struct hard_iface *if_incoming, 365 struct hard_iface *if_incoming,
372 unsigned char *hna_buff, int hna_buff_len, 366 unsigned char *tt_buff, int tt_buff_len,
373 char is_duplicate) 367 char is_duplicate)
374{ 368{
375 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 369 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
370 struct neigh_node *router = NULL;
376 struct orig_node *orig_node_tmp; 371 struct orig_node *orig_node_tmp;
377 struct hlist_node *node; 372 struct hlist_node *node;
378 int tmp_hna_buff_len; 373 int tmp_tt_buff_len;
379 uint8_t bcast_own_sum_orig, bcast_own_sum_neigh; 374 uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
380 375
381 bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): " 376 bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
@@ -396,10 +391,12 @@ static void update_orig(struct bat_priv *bat_priv,
396 if (is_duplicate) 391 if (is_duplicate)
397 continue; 392 continue;
398 393
394 spin_lock_bh(&tmp_neigh_node->tq_lock);
399 ring_buffer_set(tmp_neigh_node->tq_recv, 395 ring_buffer_set(tmp_neigh_node->tq_recv,
400 &tmp_neigh_node->tq_index, 0); 396 &tmp_neigh_node->tq_index, 0);
401 tmp_neigh_node->tq_avg = 397 tmp_neigh_node->tq_avg =
402 ring_buffer_avg(tmp_neigh_node->tq_recv); 398 ring_buffer_avg(tmp_neigh_node->tq_recv);
399 spin_unlock_bh(&tmp_neigh_node->tq_lock);
403 } 400 }
404 401
405 if (!neigh_node) { 402 if (!neigh_node) {
@@ -424,10 +421,12 @@ static void update_orig(struct bat_priv *bat_priv,
424 orig_node->flags = batman_packet->flags; 421 orig_node->flags = batman_packet->flags;
425 neigh_node->last_valid = jiffies; 422 neigh_node->last_valid = jiffies;
426 423
424 spin_lock_bh(&neigh_node->tq_lock);
427 ring_buffer_set(neigh_node->tq_recv, 425 ring_buffer_set(neigh_node->tq_recv,
428 &neigh_node->tq_index, 426 &neigh_node->tq_index,
429 batman_packet->tq); 427 batman_packet->tq);
430 neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); 428 neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
429 spin_unlock_bh(&neigh_node->tq_lock);
431 430
432 if (!is_duplicate) { 431 if (!is_duplicate) {
433 orig_node->last_ttl = batman_packet->ttl; 432 orig_node->last_ttl = batman_packet->ttl;
@@ -436,24 +435,23 @@ static void update_orig(struct bat_priv *bat_priv,
436 435
437 bonding_candidate_add(orig_node, neigh_node); 436 bonding_candidate_add(orig_node, neigh_node);
438 437
439 tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ? 438 tmp_tt_buff_len = (tt_buff_len > batman_packet->num_tt * ETH_ALEN ?
440 batman_packet->num_hna * ETH_ALEN : hna_buff_len); 439 batman_packet->num_tt * ETH_ALEN : tt_buff_len);
441 440
442 /* if this neighbor already is our next hop there is nothing 441 /* if this neighbor already is our next hop there is nothing
443 * to change */ 442 * to change */
444 if (orig_node->router == neigh_node) 443 router = orig_node_get_router(orig_node);
445 goto update_hna; 444 if (router == neigh_node)
445 goto update_tt;
446 446
447 /* if this neighbor does not offer a better TQ we won't consider it */ 447 /* if this neighbor does not offer a better TQ we won't consider it */
448 if ((orig_node->router) && 448 if (router && (router->tq_avg > neigh_node->tq_avg))
449 (orig_node->router->tq_avg > neigh_node->tq_avg)) 449 goto update_tt;
450 goto update_hna;
451 450
452 /* if the TQ is the same and the link not more symetric we 451 /* if the TQ is the same and the link not more symetric we
453 * won't consider it either */ 452 * won't consider it either */
454 if ((orig_node->router) && 453 if (router && (neigh_node->tq_avg == router->tq_avg)) {
455 (neigh_node->tq_avg == orig_node->router->tq_avg)) { 454 orig_node_tmp = router->orig_node;
456 orig_node_tmp = orig_node->router->orig_node;
457 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); 455 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
458 bcast_own_sum_orig = 456 bcast_own_sum_orig =
459 orig_node_tmp->bcast_own_sum[if_incoming->if_num]; 457 orig_node_tmp->bcast_own_sum[if_incoming->if_num];
@@ -466,16 +464,16 @@ static void update_orig(struct bat_priv *bat_priv,
466 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 464 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
467 465
468 if (bcast_own_sum_orig >= bcast_own_sum_neigh) 466 if (bcast_own_sum_orig >= bcast_own_sum_neigh)
469 goto update_hna; 467 goto update_tt;
470 } 468 }
471 469
472 update_routes(bat_priv, orig_node, neigh_node, 470 update_routes(bat_priv, orig_node, neigh_node,
473 hna_buff, tmp_hna_buff_len); 471 tt_buff, tmp_tt_buff_len);
474 goto update_gw; 472 goto update_gw;
475 473
476update_hna: 474update_tt:
477 update_routes(bat_priv, orig_node, orig_node->router, 475 update_routes(bat_priv, orig_node, router,
478 hna_buff, tmp_hna_buff_len); 476 tt_buff, tmp_tt_buff_len);
479 477
480update_gw: 478update_gw:
481 if (orig_node->gw_flags != batman_packet->gw_flags) 479 if (orig_node->gw_flags != batman_packet->gw_flags)
@@ -496,6 +494,8 @@ unlock:
496out: 494out:
497 if (neigh_node) 495 if (neigh_node)
498 neigh_node_free_ref(neigh_node); 496 neigh_node_free_ref(neigh_node);
497 if (router)
498 neigh_node_free_ref(router);
499} 499}
500 500
501/* checks whether the host restarted and is in the protection time. 501/* checks whether the host restarted and is in the protection time.
@@ -597,12 +597,14 @@ out:
597 597
598void receive_bat_packet(struct ethhdr *ethhdr, 598void receive_bat_packet(struct ethhdr *ethhdr,
599 struct batman_packet *batman_packet, 599 struct batman_packet *batman_packet,
600 unsigned char *hna_buff, int hna_buff_len, 600 unsigned char *tt_buff, int tt_buff_len,
601 struct hard_iface *if_incoming) 601 struct hard_iface *if_incoming)
602{ 602{
603 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 603 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
604 struct hard_iface *hard_iface; 604 struct hard_iface *hard_iface;
605 struct orig_node *orig_neigh_node, *orig_node; 605 struct orig_node *orig_neigh_node, *orig_node;
606 struct neigh_node *router = NULL, *router_router = NULL;
607 struct neigh_node *orig_neigh_router = NULL;
606 char has_directlink_flag; 608 char has_directlink_flag;
607 char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; 609 char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
608 char is_broadcast = 0, is_bidirectional, is_single_hop_neigh; 610 char is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
@@ -747,14 +749,15 @@ void receive_bat_packet(struct ethhdr *ethhdr,
747 goto out; 749 goto out;
748 } 750 }
749 751
752 router = orig_node_get_router(orig_node);
753 if (router)
754 router_router = orig_node_get_router(router->orig_node);
755
750 /* avoid temporary routing loops */ 756 /* avoid temporary routing loops */
751 if ((orig_node->router) && 757 if (router && router_router &&
752 (orig_node->router->orig_node->router) && 758 (compare_eth(router->addr, batman_packet->prev_sender)) &&
753 (compare_eth(orig_node->router->addr,
754 batman_packet->prev_sender)) &&
755 !(compare_eth(batman_packet->orig, batman_packet->prev_sender)) && 759 !(compare_eth(batman_packet->orig, batman_packet->prev_sender)) &&
756 (compare_eth(orig_node->router->addr, 760 (compare_eth(router->addr, router_router->addr))) {
757 orig_node->router->orig_node->router->addr))) {
758 bat_dbg(DBG_BATMAN, bat_priv, 761 bat_dbg(DBG_BATMAN, bat_priv,
759 "Drop packet: ignoring all rebroadcast packets that " 762 "Drop packet: ignoring all rebroadcast packets that "
760 "may make me loop (sender: %pM)\n", ethhdr->h_source); 763 "may make me loop (sender: %pM)\n", ethhdr->h_source);
@@ -769,9 +772,11 @@ void receive_bat_packet(struct ethhdr *ethhdr,
769 if (!orig_neigh_node) 772 if (!orig_neigh_node)
770 goto out; 773 goto out;
771 774
775 orig_neigh_router = orig_node_get_router(orig_neigh_node);
776
772 /* drop packet if sender is not a direct neighbor and if we 777 /* drop packet if sender is not a direct neighbor and if we
773 * don't route towards it */ 778 * don't route towards it */
774 if (!is_single_hop_neigh && (!orig_neigh_node->router)) { 779 if (!is_single_hop_neigh && (!orig_neigh_router)) {
775 bat_dbg(DBG_BATMAN, bat_priv, 780 bat_dbg(DBG_BATMAN, bat_priv,
776 "Drop packet: OGM via unknown neighbor!\n"); 781 "Drop packet: OGM via unknown neighbor!\n");
777 goto out_neigh; 782 goto out_neigh;
@@ -789,14 +794,14 @@ void receive_bat_packet(struct ethhdr *ethhdr,
789 ((orig_node->last_real_seqno == batman_packet->seqno) && 794 ((orig_node->last_real_seqno == batman_packet->seqno) &&
790 (orig_node->last_ttl - 3 <= batman_packet->ttl)))) 795 (orig_node->last_ttl - 3 <= batman_packet->ttl))))
791 update_orig(bat_priv, orig_node, ethhdr, batman_packet, 796 update_orig(bat_priv, orig_node, ethhdr, batman_packet,
792 if_incoming, hna_buff, hna_buff_len, is_duplicate); 797 if_incoming, tt_buff, tt_buff_len, is_duplicate);
793 798
794 /* is single hop (direct) neighbor */ 799 /* is single hop (direct) neighbor */
795 if (is_single_hop_neigh) { 800 if (is_single_hop_neigh) {
796 801
797 /* mark direct link on incoming interface */ 802 /* mark direct link on incoming interface */
798 schedule_forward_packet(orig_node, ethhdr, batman_packet, 803 schedule_forward_packet(orig_node, ethhdr, batman_packet,
799 1, hna_buff_len, if_incoming); 804 1, tt_buff_len, if_incoming);
800 805
801 bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: " 806 bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
802 "rebroadcast neighbor packet with direct link flag\n"); 807 "rebroadcast neighbor packet with direct link flag\n");
@@ -819,12 +824,19 @@ void receive_bat_packet(struct ethhdr *ethhdr,
819 bat_dbg(DBG_BATMAN, bat_priv, 824 bat_dbg(DBG_BATMAN, bat_priv,
820 "Forwarding packet: rebroadcast originator packet\n"); 825 "Forwarding packet: rebroadcast originator packet\n");
821 schedule_forward_packet(orig_node, ethhdr, batman_packet, 826 schedule_forward_packet(orig_node, ethhdr, batman_packet,
822 0, hna_buff_len, if_incoming); 827 0, tt_buff_len, if_incoming);
823 828
824out_neigh: 829out_neigh:
825 if ((orig_neigh_node) && (!is_single_hop_neigh)) 830 if ((orig_neigh_node) && (!is_single_hop_neigh))
826 orig_node_free_ref(orig_neigh_node); 831 orig_node_free_ref(orig_neigh_node);
827out: 832out:
833 if (router)
834 neigh_node_free_ref(router);
835 if (router_router)
836 neigh_node_free_ref(router_router);
837 if (orig_neigh_router)
838 neigh_node_free_ref(orig_neigh_router);
839
828 orig_node_free_ref(orig_node); 840 orig_node_free_ref(orig_node);
829} 841}
830 842
@@ -868,8 +880,9 @@ int recv_bat_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
868static int recv_my_icmp_packet(struct bat_priv *bat_priv, 880static int recv_my_icmp_packet(struct bat_priv *bat_priv,
869 struct sk_buff *skb, size_t icmp_len) 881 struct sk_buff *skb, size_t icmp_len)
870{ 882{
883 struct hard_iface *primary_if = NULL;
871 struct orig_node *orig_node = NULL; 884 struct orig_node *orig_node = NULL;
872 struct neigh_node *neigh_node = NULL; 885 struct neigh_node *router = NULL;
873 struct icmp_packet_rr *icmp_packet; 886 struct icmp_packet_rr *icmp_packet;
874 int ret = NET_RX_DROP; 887 int ret = NET_RX_DROP;
875 888
@@ -881,28 +894,19 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
881 goto out; 894 goto out;
882 } 895 }
883 896
884 if (!bat_priv->primary_if) 897 primary_if = primary_if_get_selected(bat_priv);
898 if (!primary_if)
885 goto out; 899 goto out;
886 900
887 /* answer echo request (ping) */ 901 /* answer echo request (ping) */
888 /* get routing information */ 902 /* get routing information */
889 rcu_read_lock();
890 orig_node = orig_hash_find(bat_priv, icmp_packet->orig); 903 orig_node = orig_hash_find(bat_priv, icmp_packet->orig);
891
892 if (!orig_node) 904 if (!orig_node)
893 goto unlock; 905 goto out;
894
895 neigh_node = orig_node->router;
896
897 if (!neigh_node)
898 goto unlock;
899
900 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
901 neigh_node = NULL;
902 goto unlock;
903 }
904 906
905 rcu_read_unlock(); 907 router = orig_node_get_router(orig_node);
908 if (!router)
909 goto out;
906 910
907 /* create a copy of the skb, if needed, to modify it. */ 911 /* create a copy of the skb, if needed, to modify it. */
908 if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 912 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
@@ -911,20 +915,18 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
911 icmp_packet = (struct icmp_packet_rr *)skb->data; 915 icmp_packet = (struct icmp_packet_rr *)skb->data;
912 916
913 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 917 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
914 memcpy(icmp_packet->orig, 918 memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
915 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
916 icmp_packet->msg_type = ECHO_REPLY; 919 icmp_packet->msg_type = ECHO_REPLY;
917 icmp_packet->ttl = TTL; 920 icmp_packet->ttl = TTL;
918 921
919 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 922 send_skb_packet(skb, router->if_incoming, router->addr);
920 ret = NET_RX_SUCCESS; 923 ret = NET_RX_SUCCESS;
921 goto out;
922 924
923unlock:
924 rcu_read_unlock();
925out: 925out:
926 if (neigh_node) 926 if (primary_if)
927 neigh_node_free_ref(neigh_node); 927 hardif_free_ref(primary_if);
928 if (router)
929 neigh_node_free_ref(router);
928 if (orig_node) 930 if (orig_node)
929 orig_node_free_ref(orig_node); 931 orig_node_free_ref(orig_node);
930 return ret; 932 return ret;
@@ -933,8 +935,9 @@ out:
933static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, 935static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
934 struct sk_buff *skb) 936 struct sk_buff *skb)
935{ 937{
938 struct hard_iface *primary_if = NULL;
936 struct orig_node *orig_node = NULL; 939 struct orig_node *orig_node = NULL;
937 struct neigh_node *neigh_node = NULL; 940 struct neigh_node *router = NULL;
938 struct icmp_packet *icmp_packet; 941 struct icmp_packet *icmp_packet;
939 int ret = NET_RX_DROP; 942 int ret = NET_RX_DROP;
940 943
@@ -948,27 +951,18 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
948 goto out; 951 goto out;
949 } 952 }
950 953
951 if (!bat_priv->primary_if) 954 primary_if = primary_if_get_selected(bat_priv);
955 if (!primary_if)
952 goto out; 956 goto out;
953 957
954 /* get routing information */ 958 /* get routing information */
955 rcu_read_lock();
956 orig_node = orig_hash_find(bat_priv, icmp_packet->orig); 959 orig_node = orig_hash_find(bat_priv, icmp_packet->orig);
957
958 if (!orig_node) 960 if (!orig_node)
959 goto unlock; 961 goto out;
960
961 neigh_node = orig_node->router;
962
963 if (!neigh_node)
964 goto unlock;
965
966 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
967 neigh_node = NULL;
968 goto unlock;
969 }
970 962
971 rcu_read_unlock(); 963 router = orig_node_get_router(orig_node);
964 if (!router)
965 goto out;
972 966
973 /* create a copy of the skb, if needed, to modify it. */ 967 /* create a copy of the skb, if needed, to modify it. */
974 if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 968 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
@@ -977,20 +971,18 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
977 icmp_packet = (struct icmp_packet *)skb->data; 971 icmp_packet = (struct icmp_packet *)skb->data;
978 972
979 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 973 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
980 memcpy(icmp_packet->orig, 974 memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
981 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
982 icmp_packet->msg_type = TTL_EXCEEDED; 975 icmp_packet->msg_type = TTL_EXCEEDED;
983 icmp_packet->ttl = TTL; 976 icmp_packet->ttl = TTL;
984 977
985 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 978 send_skb_packet(skb, router->if_incoming, router->addr);
986 ret = NET_RX_SUCCESS; 979 ret = NET_RX_SUCCESS;
987 goto out;
988 980
989unlock:
990 rcu_read_unlock();
991out: 981out:
992 if (neigh_node) 982 if (primary_if)
993 neigh_node_free_ref(neigh_node); 983 hardif_free_ref(primary_if);
984 if (router)
985 neigh_node_free_ref(router);
994 if (orig_node) 986 if (orig_node)
995 orig_node_free_ref(orig_node); 987 orig_node_free_ref(orig_node);
996 return ret; 988 return ret;
@@ -1003,7 +995,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1003 struct icmp_packet_rr *icmp_packet; 995 struct icmp_packet_rr *icmp_packet;
1004 struct ethhdr *ethhdr; 996 struct ethhdr *ethhdr;
1005 struct orig_node *orig_node = NULL; 997 struct orig_node *orig_node = NULL;
1006 struct neigh_node *neigh_node = NULL; 998 struct neigh_node *router = NULL;
1007 int hdr_size = sizeof(struct icmp_packet); 999 int hdr_size = sizeof(struct icmp_packet);
1008 int ret = NET_RX_DROP; 1000 int ret = NET_RX_DROP;
1009 1001
@@ -1050,23 +1042,13 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1050 return recv_icmp_ttl_exceeded(bat_priv, skb); 1042 return recv_icmp_ttl_exceeded(bat_priv, skb);
1051 1043
1052 /* get routing information */ 1044 /* get routing information */
1053 rcu_read_lock();
1054 orig_node = orig_hash_find(bat_priv, icmp_packet->dst); 1045 orig_node = orig_hash_find(bat_priv, icmp_packet->dst);
1055
1056 if (!orig_node) 1046 if (!orig_node)
1057 goto unlock; 1047 goto out;
1058
1059 neigh_node = orig_node->router;
1060
1061 if (!neigh_node)
1062 goto unlock;
1063
1064 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
1065 neigh_node = NULL;
1066 goto unlock;
1067 }
1068 1048
1069 rcu_read_unlock(); 1049 router = orig_node_get_router(orig_node);
1050 if (!router)
1051 goto out;
1070 1052
1071 /* create a copy of the skb, if needed, to modify it. */ 1053 /* create a copy of the skb, if needed, to modify it. */
1072 if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 1054 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
@@ -1078,20 +1060,117 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1078 icmp_packet->ttl--; 1060 icmp_packet->ttl--;
1079 1061
1080 /* route it */ 1062 /* route it */
1081 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1063 send_skb_packet(skb, router->if_incoming, router->addr);
1082 ret = NET_RX_SUCCESS; 1064 ret = NET_RX_SUCCESS;
1083 goto out;
1084 1065
1085unlock:
1086 rcu_read_unlock();
1087out: 1066out:
1088 if (neigh_node) 1067 if (router)
1089 neigh_node_free_ref(neigh_node); 1068 neigh_node_free_ref(router);
1090 if (orig_node) 1069 if (orig_node)
1091 orig_node_free_ref(orig_node); 1070 orig_node_free_ref(orig_node);
1092 return ret; 1071 return ret;
1093} 1072}
1094 1073
1074/* In the bonding case, send the packets in a round
1075 * robin fashion over the remaining interfaces.
1076 *
1077 * This method rotates the bonding list and increases the
1078 * returned router's refcount. */
1079static struct neigh_node *find_bond_router(struct orig_node *primary_orig,
1080 struct hard_iface *recv_if)
1081{
1082 struct neigh_node *tmp_neigh_node;
1083 struct neigh_node *router = NULL, *first_candidate = NULL;
1084
1085 rcu_read_lock();
1086 list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list,
1087 bonding_list) {
1088 if (!first_candidate)
1089 first_candidate = tmp_neigh_node;
1090
1091 /* recv_if == NULL on the first node. */
1092 if (tmp_neigh_node->if_incoming == recv_if)
1093 continue;
1094
1095 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
1096 continue;
1097
1098 router = tmp_neigh_node;
1099 break;
1100 }
1101
1102 /* use the first candidate if nothing was found. */
1103 if (!router && first_candidate &&
1104 atomic_inc_not_zero(&first_candidate->refcount))
1105 router = first_candidate;
1106
1107 if (!router)
1108 goto out;
1109
1110 /* selected should point to the next element
1111 * after the current router */
1112 spin_lock_bh(&primary_orig->neigh_list_lock);
1113 /* this is a list_move(), which unfortunately
1114 * does not exist as rcu version */
1115 list_del_rcu(&primary_orig->bond_list);
1116 list_add_rcu(&primary_orig->bond_list,
1117 &router->bonding_list);
1118 spin_unlock_bh(&primary_orig->neigh_list_lock);
1119
1120out:
1121 rcu_read_unlock();
1122 return router;
1123}
1124
1125/* Interface Alternating: Use the best of the
1126 * remaining candidates which are not using
1127 * this interface.
1128 *
1129 * Increases the returned router's refcount */
1130static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig,
1131 struct hard_iface *recv_if)
1132{
1133 struct neigh_node *tmp_neigh_node;
1134 struct neigh_node *router = NULL, *first_candidate = NULL;
1135
1136 rcu_read_lock();
1137 list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list,
1138 bonding_list) {
1139 if (!first_candidate)
1140 first_candidate = tmp_neigh_node;
1141
1142 /* recv_if == NULL on the first node. */
1143 if (tmp_neigh_node->if_incoming == recv_if)
1144 continue;
1145
1146 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
1147 continue;
1148
1149 /* if we don't have a router yet
1150 * or this one is better, choose it. */
1151 if ((!router) ||
1152 (tmp_neigh_node->tq_avg > router->tq_avg)) {
1153 /* decrement refcount of
1154 * previously selected router */
1155 if (router)
1156 neigh_node_free_ref(router);
1157
1158 router = tmp_neigh_node;
1159 atomic_inc_not_zero(&router->refcount);
1160 }
1161
1162 neigh_node_free_ref(tmp_neigh_node);
1163 }
1164
1165 /* use the first candidate if nothing was found. */
1166 if (!router && first_candidate &&
1167 atomic_inc_not_zero(&first_candidate->refcount))
1168 router = first_candidate;
1169
1170 rcu_read_unlock();
1171 return router;
1172}
1173
1095/* find a suitable router for this originator, and use 1174/* find a suitable router for this originator, and use
1096 * bonding if possible. increases the found neighbors 1175 * bonding if possible. increases the found neighbors
1097 * refcount.*/ 1176 * refcount.*/
@@ -1101,15 +1180,16 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
1101{ 1180{
1102 struct orig_node *primary_orig_node; 1181 struct orig_node *primary_orig_node;
1103 struct orig_node *router_orig; 1182 struct orig_node *router_orig;
1104 struct neigh_node *router, *first_candidate, *tmp_neigh_node; 1183 struct neigh_node *router;
1105 static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; 1184 static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
1106 int bonding_enabled; 1185 int bonding_enabled;
1107 1186
1108 if (!orig_node) 1187 if (!orig_node)
1109 return NULL; 1188 return NULL;
1110 1189
1111 if (!orig_node->router) 1190 router = orig_node_get_router(orig_node);
1112 return NULL; 1191 if (!router)
1192 goto err;
1113 1193
1114 /* without bonding, the first node should 1194 /* without bonding, the first node should
1115 * always choose the default router. */ 1195 * always choose the default router. */
@@ -1117,12 +1197,9 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
1117 1197
1118 rcu_read_lock(); 1198 rcu_read_lock();
1119 /* select default router to output */ 1199 /* select default router to output */
1120 router = orig_node->router; 1200 router_orig = router->orig_node;
1121 router_orig = orig_node->router->orig_node; 1201 if (!router_orig)
1122 if (!router_orig || !atomic_inc_not_zero(&router->refcount)) { 1202 goto err_unlock;
1123 rcu_read_unlock();
1124 return NULL;
1125 }
1126 1203
1127 if ((!recv_if) && (!bonding_enabled)) 1204 if ((!recv_if) && (!bonding_enabled))
1128 goto return_router; 1205 goto return_router;
@@ -1151,91 +1228,26 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
1151 if (atomic_read(&primary_orig_node->bond_candidates) < 2) 1228 if (atomic_read(&primary_orig_node->bond_candidates) < 2)
1152 goto return_router; 1229 goto return_router;
1153 1230
1154
1155 /* all nodes between should choose a candidate which 1231 /* all nodes between should choose a candidate which
1156 * is is not on the interface where the packet came 1232 * is is not on the interface where the packet came
1157 * in. */ 1233 * in. */
1158 1234
1159 neigh_node_free_ref(router); 1235 neigh_node_free_ref(router);
1160 first_candidate = NULL;
1161 router = NULL;
1162
1163 if (bonding_enabled) {
1164 /* in the bonding case, send the packets in a round
1165 * robin fashion over the remaining interfaces. */
1166
1167 list_for_each_entry_rcu(tmp_neigh_node,
1168 &primary_orig_node->bond_list, bonding_list) {
1169 if (!first_candidate)
1170 first_candidate = tmp_neigh_node;
1171 /* recv_if == NULL on the first node. */
1172 if (tmp_neigh_node->if_incoming != recv_if &&
1173 atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
1174 router = tmp_neigh_node;
1175 break;
1176 }
1177 }
1178
1179 /* use the first candidate if nothing was found. */
1180 if (!router && first_candidate &&
1181 atomic_inc_not_zero(&first_candidate->refcount))
1182 router = first_candidate;
1183 1236
1184 if (!router) { 1237 if (bonding_enabled)
1185 rcu_read_unlock(); 1238 router = find_bond_router(primary_orig_node, recv_if);
1186 return NULL; 1239 else
1187 } 1240 router = find_ifalter_router(primary_orig_node, recv_if);
1188
1189 /* selected should point to the next element
1190 * after the current router */
1191 spin_lock_bh(&primary_orig_node->neigh_list_lock);
1192 /* this is a list_move(), which unfortunately
1193 * does not exist as rcu version */
1194 list_del_rcu(&primary_orig_node->bond_list);
1195 list_add_rcu(&primary_orig_node->bond_list,
1196 &router->bonding_list);
1197 spin_unlock_bh(&primary_orig_node->neigh_list_lock);
1198
1199 } else {
1200 /* if bonding is disabled, use the best of the
1201 * remaining candidates which are not using
1202 * this interface. */
1203 list_for_each_entry_rcu(tmp_neigh_node,
1204 &primary_orig_node->bond_list, bonding_list) {
1205 if (!first_candidate)
1206 first_candidate = tmp_neigh_node;
1207
1208 /* recv_if == NULL on the first node. */
1209 if (tmp_neigh_node->if_incoming == recv_if)
1210 continue;
1211
1212 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
1213 continue;
1214
1215 /* if we don't have a router yet
1216 * or this one is better, choose it. */
1217 if ((!router) ||
1218 (tmp_neigh_node->tq_avg > router->tq_avg)) {
1219 /* decrement refcount of
1220 * previously selected router */
1221 if (router)
1222 neigh_node_free_ref(router);
1223
1224 router = tmp_neigh_node;
1225 atomic_inc_not_zero(&router->refcount);
1226 }
1227
1228 neigh_node_free_ref(tmp_neigh_node);
1229 }
1230 1241
1231 /* use the first candidate if nothing was found. */
1232 if (!router && first_candidate &&
1233 atomic_inc_not_zero(&first_candidate->refcount))
1234 router = first_candidate;
1235 }
1236return_router: 1242return_router:
1237 rcu_read_unlock(); 1243 rcu_read_unlock();
1238 return router; 1244 return router;
1245err_unlock:
1246 rcu_read_unlock();
1247err:
1248 if (router)
1249 neigh_node_free_ref(router);
1250 return NULL;
1239} 1251}
1240 1252
1241static int check_unicast_packet(struct sk_buff *skb, int hdr_size) 1253static int check_unicast_packet(struct sk_buff *skb, int hdr_size)
@@ -1284,13 +1296,10 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1284 } 1296 }
1285 1297
1286 /* get routing information */ 1298 /* get routing information */
1287 rcu_read_lock();
1288 orig_node = orig_hash_find(bat_priv, unicast_packet->dest); 1299 orig_node = orig_hash_find(bat_priv, unicast_packet->dest);
1289 1300
1290 if (!orig_node) 1301 if (!orig_node)
1291 goto unlock; 1302 goto out;
1292
1293 rcu_read_unlock();
1294 1303
1295 /* find_router() increases neigh_nodes refcount if found. */ 1304 /* find_router() increases neigh_nodes refcount if found. */
1296 neigh_node = find_router(bat_priv, orig_node, recv_if); 1305 neigh_node = find_router(bat_priv, orig_node, recv_if);
@@ -1336,10 +1345,7 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1336 /* route it */ 1345 /* route it */
1337 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1346 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1338 ret = NET_RX_SUCCESS; 1347 ret = NET_RX_SUCCESS;
1339 goto out;
1340 1348
1341unlock:
1342 rcu_read_unlock();
1343out: 1349out:
1344 if (neigh_node) 1350 if (neigh_node)
1345 neigh_node_free_ref(neigh_node); 1351 neigh_node_free_ref(neigh_node);
@@ -1438,13 +1444,10 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1438 if (bcast_packet->ttl < 2) 1444 if (bcast_packet->ttl < 2)
1439 goto out; 1445 goto out;
1440 1446
1441 rcu_read_lock();
1442 orig_node = orig_hash_find(bat_priv, bcast_packet->orig); 1447 orig_node = orig_hash_find(bat_priv, bcast_packet->orig);
1443 1448
1444 if (!orig_node) 1449 if (!orig_node)
1445 goto rcu_unlock; 1450 goto out;
1446
1447 rcu_read_unlock();
1448 1451
1449 spin_lock_bh(&orig_node->bcast_seqno_lock); 1452 spin_lock_bh(&orig_node->bcast_seqno_lock);
1450 1453
@@ -1475,9 +1478,6 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1475 ret = NET_RX_SUCCESS; 1478 ret = NET_RX_SUCCESS;
1476 goto out; 1479 goto out;
1477 1480
1478rcu_unlock:
1479 rcu_read_unlock();
1480 goto out;
1481spin_unlock: 1481spin_unlock:
1482 spin_unlock_bh(&orig_node->bcast_seqno_lock); 1482 spin_unlock_bh(&orig_node->bcast_seqno_lock);
1483out: 1483out:
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h
index b5a064c88a4f..870f29842b28 100644
--- a/net/batman-adv/routing.h
+++ b/net/batman-adv/routing.h
@@ -25,11 +25,11 @@
25void slide_own_bcast_window(struct hard_iface *hard_iface); 25void slide_own_bcast_window(struct hard_iface *hard_iface);
26void receive_bat_packet(struct ethhdr *ethhdr, 26void receive_bat_packet(struct ethhdr *ethhdr,
27 struct batman_packet *batman_packet, 27 struct batman_packet *batman_packet,
28 unsigned char *hna_buff, int hna_buff_len, 28 unsigned char *tt_buff, int tt_buff_len,
29 struct hard_iface *if_incoming); 29 struct hard_iface *if_incoming);
30void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, 30void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
31 struct neigh_node *neigh_node, unsigned char *hna_buff, 31 struct neigh_node *neigh_node, unsigned char *tt_buff,
32 int hna_buff_len); 32 int tt_buff_len);
33int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if); 33int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if);
34int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if); 34int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if);
35int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if); 35int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if);
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index d49e54d932af..33779278f1b2 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -121,7 +121,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
121 /* adjust all flags and log packets */ 121 /* adjust all flags and log packets */
122 while (aggregated_packet(buff_pos, 122 while (aggregated_packet(buff_pos,
123 forw_packet->packet_len, 123 forw_packet->packet_len,
124 batman_packet->num_hna)) { 124 batman_packet->num_tt)) {
125 125
126 /* we might have aggregated direct link packets with an 126 /* we might have aggregated direct link packets with an
127 * ordinary base packet */ 127 * ordinary base packet */
@@ -146,7 +146,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
146 hard_iface->net_dev->dev_addr); 146 hard_iface->net_dev->dev_addr);
147 147
148 buff_pos += sizeof(struct batman_packet) + 148 buff_pos += sizeof(struct batman_packet) +
149 (batman_packet->num_hna * ETH_ALEN); 149 (batman_packet->num_tt * ETH_ALEN);
150 packet_num++; 150 packet_num++;
151 batman_packet = (struct batman_packet *) 151 batman_packet = (struct batman_packet *)
152 (forw_packet->skb->data + buff_pos); 152 (forw_packet->skb->data + buff_pos);
@@ -222,7 +222,7 @@ static void rebuild_batman_packet(struct bat_priv *bat_priv,
222 struct batman_packet *batman_packet; 222 struct batman_packet *batman_packet;
223 223
224 new_len = sizeof(struct batman_packet) + 224 new_len = sizeof(struct batman_packet) +
225 (bat_priv->num_local_hna * ETH_ALEN); 225 (bat_priv->num_local_tt * ETH_ALEN);
226 new_buff = kmalloc(new_len, GFP_ATOMIC); 226 new_buff = kmalloc(new_len, GFP_ATOMIC);
227 227
228 /* keep old buffer if kmalloc should fail */ 228 /* keep old buffer if kmalloc should fail */
@@ -231,7 +231,7 @@ static void rebuild_batman_packet(struct bat_priv *bat_priv,
231 sizeof(struct batman_packet)); 231 sizeof(struct batman_packet));
232 batman_packet = (struct batman_packet *)new_buff; 232 batman_packet = (struct batman_packet *)new_buff;
233 233
234 batman_packet->num_hna = hna_local_fill_buffer(bat_priv, 234 batman_packet->num_tt = tt_local_fill_buffer(bat_priv,
235 new_buff + sizeof(struct batman_packet), 235 new_buff + sizeof(struct batman_packet),
236 new_len - sizeof(struct batman_packet)); 236 new_len - sizeof(struct batman_packet));
237 237
@@ -244,6 +244,7 @@ static void rebuild_batman_packet(struct bat_priv *bat_priv,
244void schedule_own_packet(struct hard_iface *hard_iface) 244void schedule_own_packet(struct hard_iface *hard_iface)
245{ 245{
246 struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 246 struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
247 struct hard_iface *primary_if;
247 unsigned long send_time; 248 unsigned long send_time;
248 struct batman_packet *batman_packet; 249 struct batman_packet *batman_packet;
249 int vis_server; 250 int vis_server;
@@ -253,6 +254,7 @@ void schedule_own_packet(struct hard_iface *hard_iface)
253 return; 254 return;
254 255
255 vis_server = atomic_read(&bat_priv->vis_mode); 256 vis_server = atomic_read(&bat_priv->vis_mode);
257 primary_if = primary_if_get_selected(bat_priv);
256 258
257 /** 259 /**
258 * the interface gets activated here to avoid race conditions between 260 * the interface gets activated here to avoid race conditions between
@@ -264,9 +266,9 @@ void schedule_own_packet(struct hard_iface *hard_iface)
264 if (hard_iface->if_status == IF_TO_BE_ACTIVATED) 266 if (hard_iface->if_status == IF_TO_BE_ACTIVATED)
265 hard_iface->if_status = IF_ACTIVE; 267 hard_iface->if_status = IF_ACTIVE;
266 268
267 /* if local hna has changed and interface is a primary interface */ 269 /* if local tt has changed and interface is a primary interface */
268 if ((atomic_read(&bat_priv->hna_local_changed)) && 270 if ((atomic_read(&bat_priv->tt_local_changed)) &&
269 (hard_iface == bat_priv->primary_if)) 271 (hard_iface == primary_if))
270 rebuild_batman_packet(bat_priv, hard_iface); 272 rebuild_batman_packet(bat_priv, hard_iface);
271 273
272 /** 274 /**
@@ -284,7 +286,7 @@ void schedule_own_packet(struct hard_iface *hard_iface)
284 else 286 else
285 batman_packet->flags &= ~VIS_SERVER; 287 batman_packet->flags &= ~VIS_SERVER;
286 288
287 if ((hard_iface == bat_priv->primary_if) && 289 if ((hard_iface == primary_if) &&
288 (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)) 290 (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER))
289 batman_packet->gw_flags = 291 batman_packet->gw_flags =
290 (uint8_t)atomic_read(&bat_priv->gw_bandwidth); 292 (uint8_t)atomic_read(&bat_priv->gw_bandwidth);
@@ -299,15 +301,19 @@ void schedule_own_packet(struct hard_iface *hard_iface)
299 hard_iface->packet_buff, 301 hard_iface->packet_buff,
300 hard_iface->packet_len, 302 hard_iface->packet_len,
301 hard_iface, 1, send_time); 303 hard_iface, 1, send_time);
304
305 if (primary_if)
306 hardif_free_ref(primary_if);
302} 307}
303 308
304void schedule_forward_packet(struct orig_node *orig_node, 309void schedule_forward_packet(struct orig_node *orig_node,
305 struct ethhdr *ethhdr, 310 struct ethhdr *ethhdr,
306 struct batman_packet *batman_packet, 311 struct batman_packet *batman_packet,
307 uint8_t directlink, int hna_buff_len, 312 uint8_t directlink, int tt_buff_len,
308 struct hard_iface *if_incoming) 313 struct hard_iface *if_incoming)
309{ 314{
310 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 315 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
316 struct neigh_node *router;
311 unsigned char in_tq, in_ttl, tq_avg = 0; 317 unsigned char in_tq, in_ttl, tq_avg = 0;
312 unsigned long send_time; 318 unsigned long send_time;
313 319
@@ -316,6 +322,8 @@ void schedule_forward_packet(struct orig_node *orig_node,
316 return; 322 return;
317 } 323 }
318 324
325 router = orig_node_get_router(orig_node);
326
319 in_tq = batman_packet->tq; 327 in_tq = batman_packet->tq;
320 in_ttl = batman_packet->ttl; 328 in_ttl = batman_packet->ttl;
321 329
@@ -324,20 +332,22 @@ void schedule_forward_packet(struct orig_node *orig_node,
324 332
325 /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast 333 /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
326 * of our best tq value */ 334 * of our best tq value */
327 if ((orig_node->router) && (orig_node->router->tq_avg != 0)) { 335 if (router && router->tq_avg != 0) {
328 336
329 /* rebroadcast ogm of best ranking neighbor as is */ 337 /* rebroadcast ogm of best ranking neighbor as is */
330 if (!compare_eth(orig_node->router->addr, ethhdr->h_source)) { 338 if (!compare_eth(router->addr, ethhdr->h_source)) {
331 batman_packet->tq = orig_node->router->tq_avg; 339 batman_packet->tq = router->tq_avg;
332 340
333 if (orig_node->router->last_ttl) 341 if (router->last_ttl)
334 batman_packet->ttl = orig_node->router->last_ttl 342 batman_packet->ttl = router->last_ttl - 1;
335 - 1;
336 } 343 }
337 344
338 tq_avg = orig_node->router->tq_avg; 345 tq_avg = router->tq_avg;
339 } 346 }
340 347
348 if (router)
349 neigh_node_free_ref(router);
350
341 /* apply hop penalty */ 351 /* apply hop penalty */
342 batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv); 352 batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv);
343 353
@@ -359,7 +369,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
359 send_time = forward_send_time(); 369 send_time = forward_send_time();
360 add_bat_packet_to_list(bat_priv, 370 add_bat_packet_to_list(bat_priv,
361 (unsigned char *)batman_packet, 371 (unsigned char *)batman_packet,
362 sizeof(struct batman_packet) + hna_buff_len, 372 sizeof(struct batman_packet) + tt_buff_len,
363 if_incoming, 0, send_time); 373 if_incoming, 0, send_time);
364} 374}
365 375
@@ -367,6 +377,8 @@ static void forw_packet_free(struct forw_packet *forw_packet)
367{ 377{
368 if (forw_packet->skb) 378 if (forw_packet->skb)
369 kfree_skb(forw_packet->skb); 379 kfree_skb(forw_packet->skb);
380 if (forw_packet->if_incoming)
381 hardif_free_ref(forw_packet->if_incoming);
370 kfree(forw_packet); 382 kfree(forw_packet);
371} 383}
372 384
@@ -388,7 +400,6 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
388 send_time); 400 send_time);
389} 401}
390 402
391#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
392/* add a broadcast packet to the queue and setup timers. broadcast packets 403/* add a broadcast packet to the queue and setup timers. broadcast packets
393 * are sent multiple times to increase probability for beeing received. 404 * are sent multiple times to increase probability for beeing received.
394 * 405 *
@@ -399,6 +410,7 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
399 * skb is freed. */ 410 * skb is freed. */
400int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb) 411int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
401{ 412{
413 struct hard_iface *primary_if = NULL;
402 struct forw_packet *forw_packet; 414 struct forw_packet *forw_packet;
403 struct bcast_packet *bcast_packet; 415 struct bcast_packet *bcast_packet;
404 416
@@ -407,8 +419,9 @@ int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
407 goto out; 419 goto out;
408 } 420 }
409 421
410 if (!bat_priv->primary_if) 422 primary_if = primary_if_get_selected(bat_priv);
411 goto out; 423 if (!primary_if)
424 goto out_and_inc;
412 425
413 forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); 426 forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
414 427
@@ -426,7 +439,7 @@ int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
426 skb_reset_mac_header(skb); 439 skb_reset_mac_header(skb);
427 440
428 forw_packet->skb = skb; 441 forw_packet->skb = skb;
429 forw_packet->if_incoming = bat_priv->primary_if; 442 forw_packet->if_incoming = primary_if;
430 443
431 /* how often did we send the bcast packet ? */ 444 /* how often did we send the bcast packet ? */
432 forw_packet->num_packets = 0; 445 forw_packet->num_packets = 0;
@@ -439,6 +452,8 @@ packet_free:
439out_and_inc: 452out_and_inc:
440 atomic_inc(&bat_priv->bcast_queue_left); 453 atomic_inc(&bat_priv->bcast_queue_left);
441out: 454out:
455 if (primary_if)
456 hardif_free_ref(primary_if);
442 return NETDEV_TX_BUSY; 457 return NETDEV_TX_BUSY;
443} 458}
444 459
@@ -526,6 +541,7 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
526{ 541{
527 struct forw_packet *forw_packet; 542 struct forw_packet *forw_packet;
528 struct hlist_node *tmp_node, *safe_tmp_node; 543 struct hlist_node *tmp_node, *safe_tmp_node;
544 bool pending;
529 545
530 if (hard_iface) 546 if (hard_iface)
531 bat_dbg(DBG_BATMAN, bat_priv, 547 bat_dbg(DBG_BATMAN, bat_priv,
@@ -554,8 +570,13 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
554 * send_outstanding_bcast_packet() will lock the list to 570 * send_outstanding_bcast_packet() will lock the list to
555 * delete the item from the list 571 * delete the item from the list
556 */ 572 */
557 cancel_delayed_work_sync(&forw_packet->delayed_work); 573 pending = cancel_delayed_work_sync(&forw_packet->delayed_work);
558 spin_lock_bh(&bat_priv->forw_bcast_list_lock); 574 spin_lock_bh(&bat_priv->forw_bcast_list_lock);
575
576 if (pending) {
577 hlist_del(&forw_packet->list);
578 forw_packet_free(forw_packet);
579 }
559 } 580 }
560 spin_unlock_bh(&bat_priv->forw_bcast_list_lock); 581 spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
561 582
@@ -578,8 +599,13 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
578 * send_outstanding_bat_packet() will lock the list to 599 * send_outstanding_bat_packet() will lock the list to
579 * delete the item from the list 600 * delete the item from the list
580 */ 601 */
581 cancel_delayed_work_sync(&forw_packet->delayed_work); 602 pending = cancel_delayed_work_sync(&forw_packet->delayed_work);
582 spin_lock_bh(&bat_priv->forw_bat_list_lock); 603 spin_lock_bh(&bat_priv->forw_bat_list_lock);
604
605 if (pending) {
606 hlist_del(&forw_packet->list);
607 forw_packet_free(forw_packet);
608 }
583 } 609 }
584 spin_unlock_bh(&bat_priv->forw_bat_list_lock); 610 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
585} 611}
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
index 7b2ff19c05e7..247172d71e4b 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -29,7 +29,7 @@ void schedule_own_packet(struct hard_iface *hard_iface);
29void schedule_forward_packet(struct orig_node *orig_node, 29void schedule_forward_packet(struct orig_node *orig_node,
30 struct ethhdr *ethhdr, 30 struct ethhdr *ethhdr,
31 struct batman_packet *batman_packet, 31 struct batman_packet *batman_packet,
32 uint8_t directlink, int hna_buff_len, 32 uint8_t directlink, int tt_buff_len,
33 struct hard_iface *if_outgoing); 33 struct hard_iface *if_outgoing);
34int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb); 34int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb);
35void send_outstanding_bat_packet(struct work_struct *work); 35void send_outstanding_bat_packet(struct work_struct *work);
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 824e1f6e50f2..d5aa60999e83 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -43,8 +43,6 @@ static void bat_get_drvinfo(struct net_device *dev,
43static u32 bat_get_msglevel(struct net_device *dev); 43static u32 bat_get_msglevel(struct net_device *dev);
44static void bat_set_msglevel(struct net_device *dev, u32 value); 44static void bat_set_msglevel(struct net_device *dev, u32 value);
45static u32 bat_get_link(struct net_device *dev); 45static u32 bat_get_link(struct net_device *dev);
46static u32 bat_get_rx_csum(struct net_device *dev);
47static int bat_set_rx_csum(struct net_device *dev, u32 data);
48 46
49static const struct ethtool_ops bat_ethtool_ops = { 47static const struct ethtool_ops bat_ethtool_ops = {
50 .get_settings = bat_get_settings, 48 .get_settings = bat_get_settings,
@@ -52,8 +50,6 @@ static const struct ethtool_ops bat_ethtool_ops = {
52 .get_msglevel = bat_get_msglevel, 50 .get_msglevel = bat_get_msglevel,
53 .set_msglevel = bat_set_msglevel, 51 .set_msglevel = bat_set_msglevel,
54 .get_link = bat_get_link, 52 .get_link = bat_get_link,
55 .get_rx_csum = bat_get_rx_csum,
56 .set_rx_csum = bat_set_rx_csum
57}; 53};
58 54
59int my_skb_head_push(struct sk_buff *skb, unsigned int len) 55int my_skb_head_push(struct sk_buff *skb, unsigned int len)
@@ -76,120 +72,371 @@ int my_skb_head_push(struct sk_buff *skb, unsigned int len)
76 return 0; 72 return 0;
77} 73}
78 74
79static void softif_neigh_free_rcu(struct rcu_head *rcu)
80{
81 struct softif_neigh *softif_neigh;
82
83 softif_neigh = container_of(rcu, struct softif_neigh, rcu);
84 kfree(softif_neigh);
85}
86
87static void softif_neigh_free_ref(struct softif_neigh *softif_neigh) 75static void softif_neigh_free_ref(struct softif_neigh *softif_neigh)
88{ 76{
89 if (atomic_dec_and_test(&softif_neigh->refcount)) 77 if (atomic_dec_and_test(&softif_neigh->refcount))
90 call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu); 78 kfree_rcu(softif_neigh, rcu);
91} 79}
92 80
93void softif_neigh_purge(struct bat_priv *bat_priv) 81static void softif_neigh_vid_free_rcu(struct rcu_head *rcu)
94{ 82{
95 struct softif_neigh *softif_neigh, *softif_neigh_tmp; 83 struct softif_neigh_vid *softif_neigh_vid;
84 struct softif_neigh *softif_neigh;
96 struct hlist_node *node, *node_tmp; 85 struct hlist_node *node, *node_tmp;
86 struct bat_priv *bat_priv;
97 87
98 spin_lock_bh(&bat_priv->softif_neigh_lock); 88 softif_neigh_vid = container_of(rcu, struct softif_neigh_vid, rcu);
89 bat_priv = softif_neigh_vid->bat_priv;
99 90
91 spin_lock_bh(&bat_priv->softif_neigh_lock);
100 hlist_for_each_entry_safe(softif_neigh, node, node_tmp, 92 hlist_for_each_entry_safe(softif_neigh, node, node_tmp,
101 &bat_priv->softif_neigh_list, list) { 93 &softif_neigh_vid->softif_neigh_list, list) {
94 hlist_del_rcu(&softif_neigh->list);
95 softif_neigh_free_ref(softif_neigh);
96 }
97 spin_unlock_bh(&bat_priv->softif_neigh_lock);
102 98
103 if ((!time_after(jiffies, softif_neigh->last_seen + 99 kfree(softif_neigh_vid);
104 msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) && 100}
105 (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE))
106 continue;
107 101
108 hlist_del_rcu(&softif_neigh->list); 102static void softif_neigh_vid_free_ref(struct softif_neigh_vid *softif_neigh_vid)
103{
104 if (atomic_dec_and_test(&softif_neigh_vid->refcount))
105 call_rcu(&softif_neigh_vid->rcu, softif_neigh_vid_free_rcu);
106}
109 107
110 if (bat_priv->softif_neigh == softif_neigh) { 108static struct softif_neigh_vid *softif_neigh_vid_get(struct bat_priv *bat_priv,
111 bat_dbg(DBG_ROUTES, bat_priv, 109 short vid)
112 "Current mesh exit point '%pM' vanished " 110{
113 "(vid: %d).\n", 111 struct softif_neigh_vid *softif_neigh_vid;
114 softif_neigh->addr, softif_neigh->vid); 112 struct hlist_node *node;
115 softif_neigh_tmp = bat_priv->softif_neigh;
116 bat_priv->softif_neigh = NULL;
117 softif_neigh_free_ref(softif_neigh_tmp);
118 }
119 113
120 softif_neigh_free_ref(softif_neigh); 114 rcu_read_lock();
115 hlist_for_each_entry_rcu(softif_neigh_vid, node,
116 &bat_priv->softif_neigh_vids, list) {
117 if (softif_neigh_vid->vid != vid)
118 continue;
119
120 if (!atomic_inc_not_zero(&softif_neigh_vid->refcount))
121 continue;
122
123 goto out;
121 } 124 }
122 125
123 spin_unlock_bh(&bat_priv->softif_neigh_lock); 126 softif_neigh_vid = kzalloc(sizeof(struct softif_neigh_vid),
127 GFP_ATOMIC);
128 if (!softif_neigh_vid)
129 goto out;
130
131 softif_neigh_vid->vid = vid;
132 softif_neigh_vid->bat_priv = bat_priv;
133
134 /* initialize with 2 - caller decrements counter by one */
135 atomic_set(&softif_neigh_vid->refcount, 2);
136 INIT_HLIST_HEAD(&softif_neigh_vid->softif_neigh_list);
137 INIT_HLIST_NODE(&softif_neigh_vid->list);
138 spin_lock_bh(&bat_priv->softif_neigh_vid_lock);
139 hlist_add_head_rcu(&softif_neigh_vid->list,
140 &bat_priv->softif_neigh_vids);
141 spin_unlock_bh(&bat_priv->softif_neigh_vid_lock);
142
143out:
144 rcu_read_unlock();
145 return softif_neigh_vid;
124} 146}
125 147
126static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, 148static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv,
127 uint8_t *addr, short vid) 149 uint8_t *addr, short vid)
128{ 150{
129 struct softif_neigh *softif_neigh; 151 struct softif_neigh_vid *softif_neigh_vid;
152 struct softif_neigh *softif_neigh = NULL;
130 struct hlist_node *node; 153 struct hlist_node *node;
131 154
155 softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid);
156 if (!softif_neigh_vid)
157 goto out;
158
132 rcu_read_lock(); 159 rcu_read_lock();
133 hlist_for_each_entry_rcu(softif_neigh, node, 160 hlist_for_each_entry_rcu(softif_neigh, node,
134 &bat_priv->softif_neigh_list, list) { 161 &softif_neigh_vid->softif_neigh_list,
162 list) {
135 if (!compare_eth(softif_neigh->addr, addr)) 163 if (!compare_eth(softif_neigh->addr, addr))
136 continue; 164 continue;
137 165
138 if (softif_neigh->vid != vid)
139 continue;
140
141 if (!atomic_inc_not_zero(&softif_neigh->refcount)) 166 if (!atomic_inc_not_zero(&softif_neigh->refcount))
142 continue; 167 continue;
143 168
144 softif_neigh->last_seen = jiffies; 169 softif_neigh->last_seen = jiffies;
145 goto out; 170 goto unlock;
146 } 171 }
147 172
148 softif_neigh = kzalloc(sizeof(struct softif_neigh), GFP_ATOMIC); 173 softif_neigh = kzalloc(sizeof(struct softif_neigh), GFP_ATOMIC);
149 if (!softif_neigh) 174 if (!softif_neigh)
150 goto out; 175 goto unlock;
151 176
152 memcpy(softif_neigh->addr, addr, ETH_ALEN); 177 memcpy(softif_neigh->addr, addr, ETH_ALEN);
153 softif_neigh->vid = vid;
154 softif_neigh->last_seen = jiffies; 178 softif_neigh->last_seen = jiffies;
155 /* initialize with 2 - caller decrements counter by one */ 179 /* initialize with 2 - caller decrements counter by one */
156 atomic_set(&softif_neigh->refcount, 2); 180 atomic_set(&softif_neigh->refcount, 2);
157 181
158 INIT_HLIST_NODE(&softif_neigh->list); 182 INIT_HLIST_NODE(&softif_neigh->list);
159 spin_lock_bh(&bat_priv->softif_neigh_lock); 183 spin_lock_bh(&bat_priv->softif_neigh_lock);
160 hlist_add_head_rcu(&softif_neigh->list, &bat_priv->softif_neigh_list); 184 hlist_add_head_rcu(&softif_neigh->list,
185 &softif_neigh_vid->softif_neigh_list);
161 spin_unlock_bh(&bat_priv->softif_neigh_lock); 186 spin_unlock_bh(&bat_priv->softif_neigh_lock);
162 187
188unlock:
189 rcu_read_unlock();
163out: 190out:
191 if (softif_neigh_vid)
192 softif_neigh_vid_free_ref(softif_neigh_vid);
193 return softif_neigh;
194}
195
196static struct softif_neigh *softif_neigh_get_selected(
197 struct softif_neigh_vid *softif_neigh_vid)
198{
199 struct softif_neigh *softif_neigh;
200
201 rcu_read_lock();
202 softif_neigh = rcu_dereference(softif_neigh_vid->softif_neigh);
203
204 if (softif_neigh && !atomic_inc_not_zero(&softif_neigh->refcount))
205 softif_neigh = NULL;
206
164 rcu_read_unlock(); 207 rcu_read_unlock();
165 return softif_neigh; 208 return softif_neigh;
166} 209}
167 210
211static struct softif_neigh *softif_neigh_vid_get_selected(
212 struct bat_priv *bat_priv,
213 short vid)
214{
215 struct softif_neigh_vid *softif_neigh_vid;
216 struct softif_neigh *softif_neigh = NULL;
217
218 softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid);
219 if (!softif_neigh_vid)
220 goto out;
221
222 softif_neigh = softif_neigh_get_selected(softif_neigh_vid);
223out:
224 if (softif_neigh_vid)
225 softif_neigh_vid_free_ref(softif_neigh_vid);
226 return softif_neigh;
227}
228
229static void softif_neigh_vid_select(struct bat_priv *bat_priv,
230 struct softif_neigh *new_neigh,
231 short vid)
232{
233 struct softif_neigh_vid *softif_neigh_vid;
234 struct softif_neigh *curr_neigh;
235
236 softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid);
237 if (!softif_neigh_vid)
238 goto out;
239
240 spin_lock_bh(&bat_priv->softif_neigh_lock);
241
242 if (new_neigh && !atomic_inc_not_zero(&new_neigh->refcount))
243 new_neigh = NULL;
244
245 curr_neigh = softif_neigh_vid->softif_neigh;
246 rcu_assign_pointer(softif_neigh_vid->softif_neigh, new_neigh);
247
248 if ((curr_neigh) && (!new_neigh))
249 bat_dbg(DBG_ROUTES, bat_priv,
250 "Removing mesh exit point on vid: %d (prev: %pM).\n",
251 vid, curr_neigh->addr);
252 else if ((curr_neigh) && (new_neigh))
253 bat_dbg(DBG_ROUTES, bat_priv,
254 "Changing mesh exit point on vid: %d from %pM "
255 "to %pM.\n", vid, curr_neigh->addr, new_neigh->addr);
256 else if ((!curr_neigh) && (new_neigh))
257 bat_dbg(DBG_ROUTES, bat_priv,
258 "Setting mesh exit point on vid: %d to %pM.\n",
259 vid, new_neigh->addr);
260
261 if (curr_neigh)
262 softif_neigh_free_ref(curr_neigh);
263
264 spin_unlock_bh(&bat_priv->softif_neigh_lock);
265
266out:
267 if (softif_neigh_vid)
268 softif_neigh_vid_free_ref(softif_neigh_vid);
269}
270
271static void softif_neigh_vid_deselect(struct bat_priv *bat_priv,
272 struct softif_neigh_vid *softif_neigh_vid)
273{
274 struct softif_neigh *curr_neigh;
275 struct softif_neigh *softif_neigh = NULL, *softif_neigh_tmp;
276 struct hard_iface *primary_if = NULL;
277 struct hlist_node *node;
278
279 primary_if = primary_if_get_selected(bat_priv);
280 if (!primary_if)
281 goto out;
282
283 /* find new softif_neigh immediately to avoid temporary loops */
284 rcu_read_lock();
285 curr_neigh = rcu_dereference(softif_neigh_vid->softif_neigh);
286
287 hlist_for_each_entry_rcu(softif_neigh_tmp, node,
288 &softif_neigh_vid->softif_neigh_list,
289 list) {
290 if (softif_neigh_tmp == curr_neigh)
291 continue;
292
293 /* we got a neighbor but its mac is 'bigger' than ours */
294 if (memcmp(primary_if->net_dev->dev_addr,
295 softif_neigh_tmp->addr, ETH_ALEN) < 0)
296 continue;
297
298 if (!atomic_inc_not_zero(&softif_neigh_tmp->refcount))
299 continue;
300
301 softif_neigh = softif_neigh_tmp;
302 goto unlock;
303 }
304
305unlock:
306 rcu_read_unlock();
307out:
308 softif_neigh_vid_select(bat_priv, softif_neigh, softif_neigh_vid->vid);
309
310 if (primary_if)
311 hardif_free_ref(primary_if);
312 if (softif_neigh)
313 softif_neigh_free_ref(softif_neigh);
314}
315
168int softif_neigh_seq_print_text(struct seq_file *seq, void *offset) 316int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
169{ 317{
170 struct net_device *net_dev = (struct net_device *)seq->private; 318 struct net_device *net_dev = (struct net_device *)seq->private;
171 struct bat_priv *bat_priv = netdev_priv(net_dev); 319 struct bat_priv *bat_priv = netdev_priv(net_dev);
320 struct softif_neigh_vid *softif_neigh_vid;
172 struct softif_neigh *softif_neigh; 321 struct softif_neigh *softif_neigh;
173 struct hlist_node *node; 322 struct hard_iface *primary_if;
323 struct hlist_node *node, *node_tmp;
324 struct softif_neigh *curr_softif_neigh;
325 int ret = 0, last_seen_secs, last_seen_msecs;
326
327 primary_if = primary_if_get_selected(bat_priv);
328 if (!primary_if) {
329 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
330 "please specify interfaces to enable it\n",
331 net_dev->name);
332 goto out;
333 }
174 334
175 if (!bat_priv->primary_if) { 335 if (primary_if->if_status != IF_ACTIVE) {
176 return seq_printf(seq, "BATMAN mesh %s disabled - " 336 ret = seq_printf(seq, "BATMAN mesh %s "
177 "please specify interfaces to enable it\n", 337 "disabled - primary interface not active\n",
178 net_dev->name); 338 net_dev->name);
339 goto out;
179 } 340 }
180 341
181 seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name); 342 seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name);
182 343
183 rcu_read_lock(); 344 rcu_read_lock();
184 hlist_for_each_entry_rcu(softif_neigh, node, 345 hlist_for_each_entry_rcu(softif_neigh_vid, node,
185 &bat_priv->softif_neigh_list, list) 346 &bat_priv->softif_neigh_vids, list) {
186 seq_printf(seq, "%s %pM (vid: %d)\n", 347 seq_printf(seq, " %-15s %s on vid: %d\n",
187 bat_priv->softif_neigh == softif_neigh 348 "Originator", "last-seen", softif_neigh_vid->vid);
188 ? "=>" : " ", softif_neigh->addr, 349
189 softif_neigh->vid); 350 curr_softif_neigh = softif_neigh_get_selected(softif_neigh_vid);
351
352 hlist_for_each_entry_rcu(softif_neigh, node_tmp,
353 &softif_neigh_vid->softif_neigh_list,
354 list) {
355 last_seen_secs = jiffies_to_msecs(jiffies -
356 softif_neigh->last_seen) / 1000;
357 last_seen_msecs = jiffies_to_msecs(jiffies -
358 softif_neigh->last_seen) % 1000;
359 seq_printf(seq, "%s %pM %3i.%03is\n",
360 curr_softif_neigh == softif_neigh
361 ? "=>" : " ", softif_neigh->addr,
362 last_seen_secs, last_seen_msecs);
363 }
364
365 if (curr_softif_neigh)
366 softif_neigh_free_ref(curr_softif_neigh);
367
368 seq_printf(seq, "\n");
369 }
190 rcu_read_unlock(); 370 rcu_read_unlock();
191 371
192 return 0; 372out:
373 if (primary_if)
374 hardif_free_ref(primary_if);
375 return ret;
376}
377
378void softif_neigh_purge(struct bat_priv *bat_priv)
379{
380 struct softif_neigh *softif_neigh, *curr_softif_neigh;
381 struct softif_neigh_vid *softif_neigh_vid;
382 struct hlist_node *node, *node_tmp, *node_tmp2;
383 char do_deselect;
384
385 rcu_read_lock();
386 hlist_for_each_entry_rcu(softif_neigh_vid, node,
387 &bat_priv->softif_neigh_vids, list) {
388 if (!atomic_inc_not_zero(&softif_neigh_vid->refcount))
389 continue;
390
391 curr_softif_neigh = softif_neigh_get_selected(softif_neigh_vid);
392 do_deselect = 0;
393
394 spin_lock_bh(&bat_priv->softif_neigh_lock);
395 hlist_for_each_entry_safe(softif_neigh, node_tmp, node_tmp2,
396 &softif_neigh_vid->softif_neigh_list,
397 list) {
398 if ((!time_after(jiffies, softif_neigh->last_seen +
399 msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) &&
400 (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE))
401 continue;
402
403 if (curr_softif_neigh == softif_neigh) {
404 bat_dbg(DBG_ROUTES, bat_priv,
405 "Current mesh exit point on vid: %d "
406 "'%pM' vanished.\n",
407 softif_neigh_vid->vid,
408 softif_neigh->addr);
409 do_deselect = 1;
410 }
411
412 hlist_del_rcu(&softif_neigh->list);
413 softif_neigh_free_ref(softif_neigh);
414 }
415 spin_unlock_bh(&bat_priv->softif_neigh_lock);
416
417 /* soft_neigh_vid_deselect() needs to acquire the
418 * softif_neigh_lock */
419 if (do_deselect)
420 softif_neigh_vid_deselect(bat_priv, softif_neigh_vid);
421
422 if (curr_softif_neigh)
423 softif_neigh_free_ref(curr_softif_neigh);
424
425 softif_neigh_vid_free_ref(softif_neigh_vid);
426 }
427 rcu_read_unlock();
428
429 spin_lock_bh(&bat_priv->softif_neigh_vid_lock);
430 hlist_for_each_entry_safe(softif_neigh_vid, node, node_tmp,
431 &bat_priv->softif_neigh_vids, list) {
432 if (!hlist_empty(&softif_neigh_vid->softif_neigh_list))
433 continue;
434
435 hlist_del_rcu(&softif_neigh_vid->list);
436 softif_neigh_vid_free_ref(softif_neigh_vid);
437 }
438 spin_unlock_bh(&bat_priv->softif_neigh_vid_lock);
439
193} 440}
194 441
195static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, 442static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
@@ -198,7 +445,9 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
198 struct bat_priv *bat_priv = netdev_priv(dev); 445 struct bat_priv *bat_priv = netdev_priv(dev);
199 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 446 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
200 struct batman_packet *batman_packet; 447 struct batman_packet *batman_packet;
201 struct softif_neigh *softif_neigh, *softif_neigh_tmp; 448 struct softif_neigh *softif_neigh = NULL;
449 struct hard_iface *primary_if = NULL;
450 struct softif_neigh *curr_softif_neigh = NULL;
202 451
203 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) 452 if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
204 batman_packet = (struct batman_packet *) 453 batman_packet = (struct batman_packet *)
@@ -207,63 +456,52 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
207 batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN); 456 batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN);
208 457
209 if (batman_packet->version != COMPAT_VERSION) 458 if (batman_packet->version != COMPAT_VERSION)
210 goto err; 459 goto out;
211 460
212 if (batman_packet->packet_type != BAT_PACKET) 461 if (batman_packet->packet_type != BAT_PACKET)
213 goto err; 462 goto out;
214 463
215 if (!(batman_packet->flags & PRIMARIES_FIRST_HOP)) 464 if (!(batman_packet->flags & PRIMARIES_FIRST_HOP))
216 goto err; 465 goto out;
217 466
218 if (is_my_mac(batman_packet->orig)) 467 if (is_my_mac(batman_packet->orig))
219 goto err; 468 goto out;
220 469
221 softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid); 470 softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid);
222
223 if (!softif_neigh) 471 if (!softif_neigh)
224 goto err; 472 goto out;
473
474 curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid);
475 if (curr_softif_neigh == softif_neigh)
476 goto out;
225 477
226 if (bat_priv->softif_neigh == softif_neigh) 478 primary_if = primary_if_get_selected(bat_priv);
479 if (!primary_if)
227 goto out; 480 goto out;
228 481
229 /* we got a neighbor but its mac is 'bigger' than ours */ 482 /* we got a neighbor but its mac is 'bigger' than ours */
230 if (memcmp(bat_priv->primary_if->net_dev->dev_addr, 483 if (memcmp(primary_if->net_dev->dev_addr,
231 softif_neigh->addr, ETH_ALEN) < 0) 484 softif_neigh->addr, ETH_ALEN) < 0)
232 goto out; 485 goto out;
233 486
234 /* switch to new 'smallest neighbor' */
235 if ((bat_priv->softif_neigh) &&
236 (memcmp(softif_neigh->addr, bat_priv->softif_neigh->addr,
237 ETH_ALEN) < 0)) {
238 bat_dbg(DBG_ROUTES, bat_priv,
239 "Changing mesh exit point from %pM (vid: %d) "
240 "to %pM (vid: %d).\n",
241 bat_priv->softif_neigh->addr,
242 bat_priv->softif_neigh->vid,
243 softif_neigh->addr, softif_neigh->vid);
244 softif_neigh_tmp = bat_priv->softif_neigh;
245 bat_priv->softif_neigh = softif_neigh;
246 softif_neigh_free_ref(softif_neigh_tmp);
247 /* we need to hold the additional reference */
248 goto err;
249 }
250
251 /* close own batX device and use softif_neigh as exit node */ 487 /* close own batX device and use softif_neigh as exit node */
252 if ((!bat_priv->softif_neigh) && 488 if (!curr_softif_neigh) {
253 (memcmp(softif_neigh->addr, 489 softif_neigh_vid_select(bat_priv, softif_neigh, vid);
254 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) { 490 goto out;
255 bat_dbg(DBG_ROUTES, bat_priv,
256 "Setting mesh exit point to %pM (vid: %d).\n",
257 softif_neigh->addr, softif_neigh->vid);
258 bat_priv->softif_neigh = softif_neigh;
259 /* we need to hold the additional reference */
260 goto err;
261 } 491 }
262 492
493 /* switch to new 'smallest neighbor' */
494 if (memcmp(softif_neigh->addr, curr_softif_neigh->addr, ETH_ALEN) < 0)
495 softif_neigh_vid_select(bat_priv, softif_neigh, vid);
496
263out: 497out:
264 softif_neigh_free_ref(softif_neigh);
265err:
266 kfree_skb(skb); 498 kfree_skb(skb);
499 if (softif_neigh)
500 softif_neigh_free_ref(softif_neigh);
501 if (curr_softif_neigh)
502 softif_neigh_free_ref(curr_softif_neigh);
503 if (primary_if)
504 hardif_free_ref(primary_if);
267 return; 505 return;
268} 506}
269 507
@@ -293,11 +531,11 @@ static int interface_set_mac_addr(struct net_device *dev, void *p)
293 if (!is_valid_ether_addr(addr->sa_data)) 531 if (!is_valid_ether_addr(addr->sa_data))
294 return -EADDRNOTAVAIL; 532 return -EADDRNOTAVAIL;
295 533
296 /* only modify hna-table if it has been initialised before */ 534 /* only modify transtable if it has been initialised before */
297 if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) { 535 if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) {
298 hna_local_remove(bat_priv, dev->dev_addr, 536 tt_local_remove(bat_priv, dev->dev_addr,
299 "mac address changed"); 537 "mac address changed");
300 hna_local_add(dev, addr->sa_data); 538 tt_local_add(dev, addr->sa_data);
301 } 539 }
302 540
303 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); 541 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
@@ -319,8 +557,10 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
319{ 557{
320 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 558 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
321 struct bat_priv *bat_priv = netdev_priv(soft_iface); 559 struct bat_priv *bat_priv = netdev_priv(soft_iface);
560 struct hard_iface *primary_if = NULL;
322 struct bcast_packet *bcast_packet; 561 struct bcast_packet *bcast_packet;
323 struct vlan_ethhdr *vhdr; 562 struct vlan_ethhdr *vhdr;
563 struct softif_neigh *curr_softif_neigh = NULL;
324 int data_len = skb->len, ret; 564 int data_len = skb->len, ret;
325 short vid = -1; 565 short vid = -1;
326 bool do_bcast = false; 566 bool do_bcast = false;
@@ -348,11 +588,12 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
348 * if we have a another chosen mesh exit node in range 588 * if we have a another chosen mesh exit node in range
349 * it will transport the packets to the mesh 589 * it will transport the packets to the mesh
350 */ 590 */
351 if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) 591 curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid);
592 if (curr_softif_neigh)
352 goto dropped; 593 goto dropped;
353 594
354 /* TODO: check this for locks */ 595 /* TODO: check this for locks */
355 hna_local_add(soft_iface, ethhdr->h_source); 596 tt_local_add(soft_iface, ethhdr->h_source);
356 597
357 if (is_multicast_ether_addr(ethhdr->h_dest)) { 598 if (is_multicast_ether_addr(ethhdr->h_dest)) {
358 ret = gw_is_target(bat_priv, skb); 599 ret = gw_is_target(bat_priv, skb);
@@ -366,7 +607,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
366 607
367 /* ethernet packet should be broadcasted */ 608 /* ethernet packet should be broadcasted */
368 if (do_bcast) { 609 if (do_bcast) {
369 if (!bat_priv->primary_if) 610 primary_if = primary_if_get_selected(bat_priv);
611 if (!primary_if)
370 goto dropped; 612 goto dropped;
371 613
372 if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0) 614 if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0)
@@ -382,7 +624,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
382 /* hw address of first interface is the orig mac because only 624 /* hw address of first interface is the orig mac because only
383 * this mac is known throughout the mesh */ 625 * this mac is known throughout the mesh */
384 memcpy(bcast_packet->orig, 626 memcpy(bcast_packet->orig,
385 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 627 primary_if->net_dev->dev_addr, ETH_ALEN);
386 628
387 /* set broadcast sequence number */ 629 /* set broadcast sequence number */
388 bcast_packet->seqno = 630 bcast_packet->seqno =
@@ -410,6 +652,10 @@ dropped:
410dropped_freed: 652dropped_freed:
411 bat_priv->stats.tx_dropped++; 653 bat_priv->stats.tx_dropped++;
412end: 654end:
655 if (curr_softif_neigh)
656 softif_neigh_free_ref(curr_softif_neigh);
657 if (primary_if)
658 hardif_free_ref(primary_if);
413 return NETDEV_TX_OK; 659 return NETDEV_TX_OK;
414} 660}
415 661
@@ -421,6 +667,7 @@ void interface_rx(struct net_device *soft_iface,
421 struct unicast_packet *unicast_packet; 667 struct unicast_packet *unicast_packet;
422 struct ethhdr *ethhdr; 668 struct ethhdr *ethhdr;
423 struct vlan_ethhdr *vhdr; 669 struct vlan_ethhdr *vhdr;
670 struct softif_neigh *curr_softif_neigh = NULL;
424 short vid = -1; 671 short vid = -1;
425 int ret; 672 int ret;
426 673
@@ -450,7 +697,8 @@ void interface_rx(struct net_device *soft_iface,
450 * if we have a another chosen mesh exit node in range 697 * if we have a another chosen mesh exit node in range
451 * it will transport the packets to the non-mesh network 698 * it will transport the packets to the non-mesh network
452 */ 699 */
453 if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) { 700 curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid);
701 if (curr_softif_neigh) {
454 skb_push(skb, hdr_size); 702 skb_push(skb, hdr_size);
455 unicast_packet = (struct unicast_packet *)skb->data; 703 unicast_packet = (struct unicast_packet *)skb->data;
456 704
@@ -461,7 +709,7 @@ void interface_rx(struct net_device *soft_iface,
461 skb_reset_mac_header(skb); 709 skb_reset_mac_header(skb);
462 710
463 memcpy(unicast_packet->dest, 711 memcpy(unicast_packet->dest,
464 bat_priv->softif_neigh->addr, ETH_ALEN); 712 curr_softif_neigh->addr, ETH_ALEN);
465 ret = route_unicast_packet(skb, recv_if); 713 ret = route_unicast_packet(skb, recv_if);
466 if (ret == NET_RX_DROP) 714 if (ret == NET_RX_DROP)
467 goto dropped; 715 goto dropped;
@@ -486,11 +734,13 @@ void interface_rx(struct net_device *soft_iface,
486 soft_iface->last_rx = jiffies; 734 soft_iface->last_rx = jiffies;
487 735
488 netif_rx(skb); 736 netif_rx(skb);
489 return; 737 goto out;
490 738
491dropped: 739dropped:
492 kfree_skb(skb); 740 kfree_skb(skb);
493out: 741out:
742 if (curr_softif_neigh)
743 softif_neigh_free_ref(curr_softif_neigh);
494 return; 744 return;
495} 745}
496 746
@@ -524,14 +774,15 @@ static void interface_setup(struct net_device *dev)
524 dev->hard_start_xmit = interface_tx; 774 dev->hard_start_xmit = interface_tx;
525#endif 775#endif
526 dev->destructor = free_netdev; 776 dev->destructor = free_netdev;
777 dev->tx_queue_len = 0;
527 778
528 /** 779 /**
529 * can't call min_mtu, because the needed variables 780 * can't call min_mtu, because the needed variables
530 * have not been initialized yet 781 * have not been initialized yet
531 */ 782 */
532 dev->mtu = ETH_DATA_LEN; 783 dev->mtu = ETH_DATA_LEN;
533 dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the 784 /* reserve more space in the skbuff for our header */
534 * skbuff for our header */ 785 dev->hard_header_len = BAT_HEADER_LEN;
535 786
536 /* generate random address */ 787 /* generate random address */
537 random_ether_addr(dev_addr); 788 random_ether_addr(dev_addr);
@@ -556,7 +807,7 @@ struct net_device *softif_create(char *name)
556 goto out; 807 goto out;
557 } 808 }
558 809
559 ret = register_netdev(soft_iface); 810 ret = register_netdevice(soft_iface);
560 if (ret < 0) { 811 if (ret < 0) {
561 pr_err("Unable to register the batman interface '%s': %i\n", 812 pr_err("Unable to register the batman interface '%s': %i\n",
562 name, ret); 813 name, ret);
@@ -580,11 +831,10 @@ struct net_device *softif_create(char *name)
580 831
581 atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); 832 atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
582 atomic_set(&bat_priv->bcast_seqno, 1); 833 atomic_set(&bat_priv->bcast_seqno, 1);
583 atomic_set(&bat_priv->hna_local_changed, 0); 834 atomic_set(&bat_priv->tt_local_changed, 0);
584 835
585 bat_priv->primary_if = NULL; 836 bat_priv->primary_if = NULL;
586 bat_priv->num_ifaces = 0; 837 bat_priv->num_ifaces = 0;
587 bat_priv->softif_neigh = NULL;
588 838
589 ret = sysfs_add_meshif(soft_iface); 839 ret = sysfs_add_meshif(soft_iface);
590 if (ret < 0) 840 if (ret < 0)
@@ -640,7 +890,7 @@ static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
640{ 890{
641 cmd->supported = 0; 891 cmd->supported = 0;
642 cmd->advertising = 0; 892 cmd->advertising = 0;
643 cmd->speed = SPEED_10; 893 ethtool_cmd_speed_set(cmd, SPEED_10);
644 cmd->duplex = DUPLEX_FULL; 894 cmd->duplex = DUPLEX_FULL;
645 cmd->port = PORT_TP; 895 cmd->port = PORT_TP;
646 cmd->phy_address = 0; 896 cmd->phy_address = 0;
@@ -675,12 +925,3 @@ static u32 bat_get_link(struct net_device *dev)
675 return 1; 925 return 1;
676} 926}
677 927
678static u32 bat_get_rx_csum(struct net_device *dev)
679{
680 return 0;
681}
682
683static int bat_set_rx_csum(struct net_device *dev, u32 data)
684{
685 return -EOPNOTSUPP;
686}
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 8d15b48d1692..7b729660cbfd 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -22,43 +22,44 @@
22#include "main.h" 22#include "main.h"
23#include "translation-table.h" 23#include "translation-table.h"
24#include "soft-interface.h" 24#include "soft-interface.h"
25#include "hard-interface.h"
25#include "hash.h" 26#include "hash.h"
26#include "originator.h" 27#include "originator.h"
27 28
28static void hna_local_purge(struct work_struct *work); 29static void tt_local_purge(struct work_struct *work);
29static void _hna_global_del_orig(struct bat_priv *bat_priv, 30static void _tt_global_del_orig(struct bat_priv *bat_priv,
30 struct hna_global_entry *hna_global_entry, 31 struct tt_global_entry *tt_global_entry,
31 char *message); 32 char *message);
32 33
33/* returns 1 if they are the same mac addr */ 34/* returns 1 if they are the same mac addr */
34static int compare_lhna(struct hlist_node *node, void *data2) 35static int compare_ltt(struct hlist_node *node, void *data2)
35{ 36{
36 void *data1 = container_of(node, struct hna_local_entry, hash_entry); 37 void *data1 = container_of(node, struct tt_local_entry, hash_entry);
37 38
38 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 39 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
39} 40}
40 41
41/* returns 1 if they are the same mac addr */ 42/* returns 1 if they are the same mac addr */
42static int compare_ghna(struct hlist_node *node, void *data2) 43static int compare_gtt(struct hlist_node *node, void *data2)
43{ 44{
44 void *data1 = container_of(node, struct hna_global_entry, hash_entry); 45 void *data1 = container_of(node, struct tt_global_entry, hash_entry);
45 46
46 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 47 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
47} 48}
48 49
49static void hna_local_start_timer(struct bat_priv *bat_priv) 50static void tt_local_start_timer(struct bat_priv *bat_priv)
50{ 51{
51 INIT_DELAYED_WORK(&bat_priv->hna_work, hna_local_purge); 52 INIT_DELAYED_WORK(&bat_priv->tt_work, tt_local_purge);
52 queue_delayed_work(bat_event_workqueue, &bat_priv->hna_work, 10 * HZ); 53 queue_delayed_work(bat_event_workqueue, &bat_priv->tt_work, 10 * HZ);
53} 54}
54 55
55static struct hna_local_entry *hna_local_hash_find(struct bat_priv *bat_priv, 56static struct tt_local_entry *tt_local_hash_find(struct bat_priv *bat_priv,
56 void *data) 57 void *data)
57{ 58{
58 struct hashtable_t *hash = bat_priv->hna_local_hash; 59 struct hashtable_t *hash = bat_priv->tt_local_hash;
59 struct hlist_head *head; 60 struct hlist_head *head;
60 struct hlist_node *node; 61 struct hlist_node *node;
61 struct hna_local_entry *hna_local_entry, *hna_local_entry_tmp = NULL; 62 struct tt_local_entry *tt_local_entry, *tt_local_entry_tmp = NULL;
62 int index; 63 int index;
63 64
64 if (!hash) 65 if (!hash)
@@ -68,26 +69,26 @@ static struct hna_local_entry *hna_local_hash_find(struct bat_priv *bat_priv,
68 head = &hash->table[index]; 69 head = &hash->table[index];
69 70
70 rcu_read_lock(); 71 rcu_read_lock();
71 hlist_for_each_entry_rcu(hna_local_entry, node, head, hash_entry) { 72 hlist_for_each_entry_rcu(tt_local_entry, node, head, hash_entry) {
72 if (!compare_eth(hna_local_entry, data)) 73 if (!compare_eth(tt_local_entry, data))
73 continue; 74 continue;
74 75
75 hna_local_entry_tmp = hna_local_entry; 76 tt_local_entry_tmp = tt_local_entry;
76 break; 77 break;
77 } 78 }
78 rcu_read_unlock(); 79 rcu_read_unlock();
79 80
80 return hna_local_entry_tmp; 81 return tt_local_entry_tmp;
81} 82}
82 83
83static struct hna_global_entry *hna_global_hash_find(struct bat_priv *bat_priv, 84static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv,
84 void *data) 85 void *data)
85{ 86{
86 struct hashtable_t *hash = bat_priv->hna_global_hash; 87 struct hashtable_t *hash = bat_priv->tt_global_hash;
87 struct hlist_head *head; 88 struct hlist_head *head;
88 struct hlist_node *node; 89 struct hlist_node *node;
89 struct hna_global_entry *hna_global_entry; 90 struct tt_global_entry *tt_global_entry;
90 struct hna_global_entry *hna_global_entry_tmp = NULL; 91 struct tt_global_entry *tt_global_entry_tmp = NULL;
91 int index; 92 int index;
92 93
93 if (!hash) 94 if (!hash)
@@ -97,125 +98,125 @@ static struct hna_global_entry *hna_global_hash_find(struct bat_priv *bat_priv,
97 head = &hash->table[index]; 98 head = &hash->table[index];
98 99
99 rcu_read_lock(); 100 rcu_read_lock();
100 hlist_for_each_entry_rcu(hna_global_entry, node, head, hash_entry) { 101 hlist_for_each_entry_rcu(tt_global_entry, node, head, hash_entry) {
101 if (!compare_eth(hna_global_entry, data)) 102 if (!compare_eth(tt_global_entry, data))
102 continue; 103 continue;
103 104
104 hna_global_entry_tmp = hna_global_entry; 105 tt_global_entry_tmp = tt_global_entry;
105 break; 106 break;
106 } 107 }
107 rcu_read_unlock(); 108 rcu_read_unlock();
108 109
109 return hna_global_entry_tmp; 110 return tt_global_entry_tmp;
110} 111}
111 112
112int hna_local_init(struct bat_priv *bat_priv) 113int tt_local_init(struct bat_priv *bat_priv)
113{ 114{
114 if (bat_priv->hna_local_hash) 115 if (bat_priv->tt_local_hash)
115 return 1; 116 return 1;
116 117
117 bat_priv->hna_local_hash = hash_new(1024); 118 bat_priv->tt_local_hash = hash_new(1024);
118 119
119 if (!bat_priv->hna_local_hash) 120 if (!bat_priv->tt_local_hash)
120 return 0; 121 return 0;
121 122
122 atomic_set(&bat_priv->hna_local_changed, 0); 123 atomic_set(&bat_priv->tt_local_changed, 0);
123 hna_local_start_timer(bat_priv); 124 tt_local_start_timer(bat_priv);
124 125
125 return 1; 126 return 1;
126} 127}
127 128
128void hna_local_add(struct net_device *soft_iface, uint8_t *addr) 129void tt_local_add(struct net_device *soft_iface, uint8_t *addr)
129{ 130{
130 struct bat_priv *bat_priv = netdev_priv(soft_iface); 131 struct bat_priv *bat_priv = netdev_priv(soft_iface);
131 struct hna_local_entry *hna_local_entry; 132 struct tt_local_entry *tt_local_entry;
132 struct hna_global_entry *hna_global_entry; 133 struct tt_global_entry *tt_global_entry;
133 int required_bytes; 134 int required_bytes;
134 135
135 spin_lock_bh(&bat_priv->hna_lhash_lock); 136 spin_lock_bh(&bat_priv->tt_lhash_lock);
136 hna_local_entry = hna_local_hash_find(bat_priv, addr); 137 tt_local_entry = tt_local_hash_find(bat_priv, addr);
137 spin_unlock_bh(&bat_priv->hna_lhash_lock); 138 spin_unlock_bh(&bat_priv->tt_lhash_lock);
138 139
139 if (hna_local_entry) { 140 if (tt_local_entry) {
140 hna_local_entry->last_seen = jiffies; 141 tt_local_entry->last_seen = jiffies;
141 return; 142 return;
142 } 143 }
143 144
144 /* only announce as many hosts as possible in the batman-packet and 145 /* only announce as many hosts as possible in the batman-packet and
145 space in batman_packet->num_hna That also should give a limit to 146 space in batman_packet->num_tt That also should give a limit to
146 MAC-flooding. */ 147 MAC-flooding. */
147 required_bytes = (bat_priv->num_local_hna + 1) * ETH_ALEN; 148 required_bytes = (bat_priv->num_local_tt + 1) * ETH_ALEN;
148 required_bytes += BAT_PACKET_LEN; 149 required_bytes += BAT_PACKET_LEN;
149 150
150 if ((required_bytes > ETH_DATA_LEN) || 151 if ((required_bytes > ETH_DATA_LEN) ||
151 (atomic_read(&bat_priv->aggregated_ogms) && 152 (atomic_read(&bat_priv->aggregated_ogms) &&
152 required_bytes > MAX_AGGREGATION_BYTES) || 153 required_bytes > MAX_AGGREGATION_BYTES) ||
153 (bat_priv->num_local_hna + 1 > 255)) { 154 (bat_priv->num_local_tt + 1 > 255)) {
154 bat_dbg(DBG_ROUTES, bat_priv, 155 bat_dbg(DBG_ROUTES, bat_priv,
155 "Can't add new local hna entry (%pM): " 156 "Can't add new local tt entry (%pM): "
156 "number of local hna entries exceeds packet size\n", 157 "number of local tt entries exceeds packet size\n",
157 addr); 158 addr);
158 return; 159 return;
159 } 160 }
160 161
161 bat_dbg(DBG_ROUTES, bat_priv, 162 bat_dbg(DBG_ROUTES, bat_priv,
162 "Creating new local hna entry: %pM\n", addr); 163 "Creating new local tt entry: %pM\n", addr);
163 164
164 hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC); 165 tt_local_entry = kmalloc(sizeof(struct tt_local_entry), GFP_ATOMIC);
165 if (!hna_local_entry) 166 if (!tt_local_entry)
166 return; 167 return;
167 168
168 memcpy(hna_local_entry->addr, addr, ETH_ALEN); 169 memcpy(tt_local_entry->addr, addr, ETH_ALEN);
169 hna_local_entry->last_seen = jiffies; 170 tt_local_entry->last_seen = jiffies;
170 171
171 /* the batman interface mac address should never be purged */ 172 /* the batman interface mac address should never be purged */
172 if (compare_eth(addr, soft_iface->dev_addr)) 173 if (compare_eth(addr, soft_iface->dev_addr))
173 hna_local_entry->never_purge = 1; 174 tt_local_entry->never_purge = 1;
174 else 175 else
175 hna_local_entry->never_purge = 0; 176 tt_local_entry->never_purge = 0;
176 177
177 spin_lock_bh(&bat_priv->hna_lhash_lock); 178 spin_lock_bh(&bat_priv->tt_lhash_lock);
178 179
179 hash_add(bat_priv->hna_local_hash, compare_lhna, choose_orig, 180 hash_add(bat_priv->tt_local_hash, compare_ltt, choose_orig,
180 hna_local_entry, &hna_local_entry->hash_entry); 181 tt_local_entry, &tt_local_entry->hash_entry);
181 bat_priv->num_local_hna++; 182 bat_priv->num_local_tt++;
182 atomic_set(&bat_priv->hna_local_changed, 1); 183 atomic_set(&bat_priv->tt_local_changed, 1);
183 184
184 spin_unlock_bh(&bat_priv->hna_lhash_lock); 185 spin_unlock_bh(&bat_priv->tt_lhash_lock);
185 186
186 /* remove address from global hash if present */ 187 /* remove address from global hash if present */
187 spin_lock_bh(&bat_priv->hna_ghash_lock); 188 spin_lock_bh(&bat_priv->tt_ghash_lock);
188 189
189 hna_global_entry = hna_global_hash_find(bat_priv, addr); 190 tt_global_entry = tt_global_hash_find(bat_priv, addr);
190 191
191 if (hna_global_entry) 192 if (tt_global_entry)
192 _hna_global_del_orig(bat_priv, hna_global_entry, 193 _tt_global_del_orig(bat_priv, tt_global_entry,
193 "local hna received"); 194 "local tt received");
194 195
195 spin_unlock_bh(&bat_priv->hna_ghash_lock); 196 spin_unlock_bh(&bat_priv->tt_ghash_lock);
196} 197}
197 198
198int hna_local_fill_buffer(struct bat_priv *bat_priv, 199int tt_local_fill_buffer(struct bat_priv *bat_priv,
199 unsigned char *buff, int buff_len) 200 unsigned char *buff, int buff_len)
200{ 201{
201 struct hashtable_t *hash = bat_priv->hna_local_hash; 202 struct hashtable_t *hash = bat_priv->tt_local_hash;
202 struct hna_local_entry *hna_local_entry; 203 struct tt_local_entry *tt_local_entry;
203 struct hlist_node *node; 204 struct hlist_node *node;
204 struct hlist_head *head; 205 struct hlist_head *head;
205 int i, count = 0; 206 int i, count = 0;
206 207
207 spin_lock_bh(&bat_priv->hna_lhash_lock); 208 spin_lock_bh(&bat_priv->tt_lhash_lock);
208 209
209 for (i = 0; i < hash->size; i++) { 210 for (i = 0; i < hash->size; i++) {
210 head = &hash->table[i]; 211 head = &hash->table[i];
211 212
212 rcu_read_lock(); 213 rcu_read_lock();
213 hlist_for_each_entry_rcu(hna_local_entry, node, 214 hlist_for_each_entry_rcu(tt_local_entry, node,
214 head, hash_entry) { 215 head, hash_entry) {
215 if (buff_len < (count + 1) * ETH_ALEN) 216 if (buff_len < (count + 1) * ETH_ALEN)
216 break; 217 break;
217 218
218 memcpy(buff + (count * ETH_ALEN), hna_local_entry->addr, 219 memcpy(buff + (count * ETH_ALEN), tt_local_entry->addr,
219 ETH_ALEN); 220 ETH_ALEN);
220 221
221 count++; 222 count++;
@@ -223,37 +224,47 @@ int hna_local_fill_buffer(struct bat_priv *bat_priv,
223 rcu_read_unlock(); 224 rcu_read_unlock();
224 } 225 }
225 226
226 /* if we did not get all new local hnas see you next time ;-) */ 227 /* if we did not get all new local tts see you next time ;-) */
227 if (count == bat_priv->num_local_hna) 228 if (count == bat_priv->num_local_tt)
228 atomic_set(&bat_priv->hna_local_changed, 0); 229 atomic_set(&bat_priv->tt_local_changed, 0);
229 230
230 spin_unlock_bh(&bat_priv->hna_lhash_lock); 231 spin_unlock_bh(&bat_priv->tt_lhash_lock);
231 return count; 232 return count;
232} 233}
233 234
234int hna_local_seq_print_text(struct seq_file *seq, void *offset) 235int tt_local_seq_print_text(struct seq_file *seq, void *offset)
235{ 236{
236 struct net_device *net_dev = (struct net_device *)seq->private; 237 struct net_device *net_dev = (struct net_device *)seq->private;
237 struct bat_priv *bat_priv = netdev_priv(net_dev); 238 struct bat_priv *bat_priv = netdev_priv(net_dev);
238 struct hashtable_t *hash = bat_priv->hna_local_hash; 239 struct hashtable_t *hash = bat_priv->tt_local_hash;
239 struct hna_local_entry *hna_local_entry; 240 struct tt_local_entry *tt_local_entry;
241 struct hard_iface *primary_if;
240 struct hlist_node *node; 242 struct hlist_node *node;
241 struct hlist_head *head; 243 struct hlist_head *head;
242 size_t buf_size, pos; 244 size_t buf_size, pos;
243 char *buff; 245 char *buff;
244 int i; 246 int i, ret = 0;
245 247
246 if (!bat_priv->primary_if) { 248 primary_if = primary_if_get_selected(bat_priv);
247 return seq_printf(seq, "BATMAN mesh %s disabled - " 249 if (!primary_if) {
248 "please specify interfaces to enable it\n", 250 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
249 net_dev->name); 251 "please specify interfaces to enable it\n",
252 net_dev->name);
253 goto out;
254 }
255
256 if (primary_if->if_status != IF_ACTIVE) {
257 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
258 "primary interface not active\n",
259 net_dev->name);
260 goto out;
250 } 261 }
251 262
252 seq_printf(seq, "Locally retrieved addresses (from %s) " 263 seq_printf(seq, "Locally retrieved addresses (from %s) "
253 "announced via HNA:\n", 264 "announced via TT:\n",
254 net_dev->name); 265 net_dev->name);
255 266
256 spin_lock_bh(&bat_priv->hna_lhash_lock); 267 spin_lock_bh(&bat_priv->tt_lhash_lock);
257 268
258 buf_size = 1; 269 buf_size = 1;
259 /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */ 270 /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
@@ -268,8 +279,9 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset)
268 279
269 buff = kmalloc(buf_size, GFP_ATOMIC); 280 buff = kmalloc(buf_size, GFP_ATOMIC);
270 if (!buff) { 281 if (!buff) {
271 spin_unlock_bh(&bat_priv->hna_lhash_lock); 282 spin_unlock_bh(&bat_priv->tt_lhash_lock);
272 return -ENOMEM; 283 ret = -ENOMEM;
284 goto out;
273 } 285 }
274 286
275 buff[0] = '\0'; 287 buff[0] = '\0';
@@ -279,211 +291,225 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset)
279 head = &hash->table[i]; 291 head = &hash->table[i];
280 292
281 rcu_read_lock(); 293 rcu_read_lock();
282 hlist_for_each_entry_rcu(hna_local_entry, node, 294 hlist_for_each_entry_rcu(tt_local_entry, node,
283 head, hash_entry) { 295 head, hash_entry) {
284 pos += snprintf(buff + pos, 22, " * %pM\n", 296 pos += snprintf(buff + pos, 22, " * %pM\n",
285 hna_local_entry->addr); 297 tt_local_entry->addr);
286 } 298 }
287 rcu_read_unlock(); 299 rcu_read_unlock();
288 } 300 }
289 301
290 spin_unlock_bh(&bat_priv->hna_lhash_lock); 302 spin_unlock_bh(&bat_priv->tt_lhash_lock);
291 303
292 seq_printf(seq, "%s", buff); 304 seq_printf(seq, "%s", buff);
293 kfree(buff); 305 kfree(buff);
294 return 0; 306out:
307 if (primary_if)
308 hardif_free_ref(primary_if);
309 return ret;
295} 310}
296 311
297static void _hna_local_del(struct hlist_node *node, void *arg) 312static void _tt_local_del(struct hlist_node *node, void *arg)
298{ 313{
299 struct bat_priv *bat_priv = (struct bat_priv *)arg; 314 struct bat_priv *bat_priv = (struct bat_priv *)arg;
300 void *data = container_of(node, struct hna_local_entry, hash_entry); 315 void *data = container_of(node, struct tt_local_entry, hash_entry);
301 316
302 kfree(data); 317 kfree(data);
303 bat_priv->num_local_hna--; 318 bat_priv->num_local_tt--;
304 atomic_set(&bat_priv->hna_local_changed, 1); 319 atomic_set(&bat_priv->tt_local_changed, 1);
305} 320}
306 321
307static void hna_local_del(struct bat_priv *bat_priv, 322static void tt_local_del(struct bat_priv *bat_priv,
308 struct hna_local_entry *hna_local_entry, 323 struct tt_local_entry *tt_local_entry,
309 char *message) 324 char *message)
310{ 325{
311 bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n", 326 bat_dbg(DBG_ROUTES, bat_priv, "Deleting local tt entry (%pM): %s\n",
312 hna_local_entry->addr, message); 327 tt_local_entry->addr, message);
313 328
314 hash_remove(bat_priv->hna_local_hash, compare_lhna, choose_orig, 329 hash_remove(bat_priv->tt_local_hash, compare_ltt, choose_orig,
315 hna_local_entry->addr); 330 tt_local_entry->addr);
316 _hna_local_del(&hna_local_entry->hash_entry, bat_priv); 331 _tt_local_del(&tt_local_entry->hash_entry, bat_priv);
317} 332}
318 333
319void hna_local_remove(struct bat_priv *bat_priv, 334void tt_local_remove(struct bat_priv *bat_priv,
320 uint8_t *addr, char *message) 335 uint8_t *addr, char *message)
321{ 336{
322 struct hna_local_entry *hna_local_entry; 337 struct tt_local_entry *tt_local_entry;
323 338
324 spin_lock_bh(&bat_priv->hna_lhash_lock); 339 spin_lock_bh(&bat_priv->tt_lhash_lock);
325 340
326 hna_local_entry = hna_local_hash_find(bat_priv, addr); 341 tt_local_entry = tt_local_hash_find(bat_priv, addr);
327 342
328 if (hna_local_entry) 343 if (tt_local_entry)
329 hna_local_del(bat_priv, hna_local_entry, message); 344 tt_local_del(bat_priv, tt_local_entry, message);
330 345
331 spin_unlock_bh(&bat_priv->hna_lhash_lock); 346 spin_unlock_bh(&bat_priv->tt_lhash_lock);
332} 347}
333 348
334static void hna_local_purge(struct work_struct *work) 349static void tt_local_purge(struct work_struct *work)
335{ 350{
336 struct delayed_work *delayed_work = 351 struct delayed_work *delayed_work =
337 container_of(work, struct delayed_work, work); 352 container_of(work, struct delayed_work, work);
338 struct bat_priv *bat_priv = 353 struct bat_priv *bat_priv =
339 container_of(delayed_work, struct bat_priv, hna_work); 354 container_of(delayed_work, struct bat_priv, tt_work);
340 struct hashtable_t *hash = bat_priv->hna_local_hash; 355 struct hashtable_t *hash = bat_priv->tt_local_hash;
341 struct hna_local_entry *hna_local_entry; 356 struct tt_local_entry *tt_local_entry;
342 struct hlist_node *node, *node_tmp; 357 struct hlist_node *node, *node_tmp;
343 struct hlist_head *head; 358 struct hlist_head *head;
344 unsigned long timeout; 359 unsigned long timeout;
345 int i; 360 int i;
346 361
347 spin_lock_bh(&bat_priv->hna_lhash_lock); 362 spin_lock_bh(&bat_priv->tt_lhash_lock);
348 363
349 for (i = 0; i < hash->size; i++) { 364 for (i = 0; i < hash->size; i++) {
350 head = &hash->table[i]; 365 head = &hash->table[i];
351 366
352 hlist_for_each_entry_safe(hna_local_entry, node, node_tmp, 367 hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
353 head, hash_entry) { 368 head, hash_entry) {
354 if (hna_local_entry->never_purge) 369 if (tt_local_entry->never_purge)
355 continue; 370 continue;
356 371
357 timeout = hna_local_entry->last_seen; 372 timeout = tt_local_entry->last_seen;
358 timeout += LOCAL_HNA_TIMEOUT * HZ; 373 timeout += TT_LOCAL_TIMEOUT * HZ;
359 374
360 if (time_before(jiffies, timeout)) 375 if (time_before(jiffies, timeout))
361 continue; 376 continue;
362 377
363 hna_local_del(bat_priv, hna_local_entry, 378 tt_local_del(bat_priv, tt_local_entry,
364 "address timed out"); 379 "address timed out");
365 } 380 }
366 } 381 }
367 382
368 spin_unlock_bh(&bat_priv->hna_lhash_lock); 383 spin_unlock_bh(&bat_priv->tt_lhash_lock);
369 hna_local_start_timer(bat_priv); 384 tt_local_start_timer(bat_priv);
370} 385}
371 386
372void hna_local_free(struct bat_priv *bat_priv) 387void tt_local_free(struct bat_priv *bat_priv)
373{ 388{
374 if (!bat_priv->hna_local_hash) 389 if (!bat_priv->tt_local_hash)
375 return; 390 return;
376 391
377 cancel_delayed_work_sync(&bat_priv->hna_work); 392 cancel_delayed_work_sync(&bat_priv->tt_work);
378 hash_delete(bat_priv->hna_local_hash, _hna_local_del, bat_priv); 393 hash_delete(bat_priv->tt_local_hash, _tt_local_del, bat_priv);
379 bat_priv->hna_local_hash = NULL; 394 bat_priv->tt_local_hash = NULL;
380} 395}
381 396
382int hna_global_init(struct bat_priv *bat_priv) 397int tt_global_init(struct bat_priv *bat_priv)
383{ 398{
384 if (bat_priv->hna_global_hash) 399 if (bat_priv->tt_global_hash)
385 return 1; 400 return 1;
386 401
387 bat_priv->hna_global_hash = hash_new(1024); 402 bat_priv->tt_global_hash = hash_new(1024);
388 403
389 if (!bat_priv->hna_global_hash) 404 if (!bat_priv->tt_global_hash)
390 return 0; 405 return 0;
391 406
392 return 1; 407 return 1;
393} 408}
394 409
395void hna_global_add_orig(struct bat_priv *bat_priv, 410void tt_global_add_orig(struct bat_priv *bat_priv,
396 struct orig_node *orig_node, 411 struct orig_node *orig_node,
397 unsigned char *hna_buff, int hna_buff_len) 412 unsigned char *tt_buff, int tt_buff_len)
398{ 413{
399 struct hna_global_entry *hna_global_entry; 414 struct tt_global_entry *tt_global_entry;
400 struct hna_local_entry *hna_local_entry; 415 struct tt_local_entry *tt_local_entry;
401 int hna_buff_count = 0; 416 int tt_buff_count = 0;
402 unsigned char *hna_ptr; 417 unsigned char *tt_ptr;
403 418
404 while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) { 419 while ((tt_buff_count + 1) * ETH_ALEN <= tt_buff_len) {
405 spin_lock_bh(&bat_priv->hna_ghash_lock); 420 spin_lock_bh(&bat_priv->tt_ghash_lock);
406 421
407 hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); 422 tt_ptr = tt_buff + (tt_buff_count * ETH_ALEN);
408 hna_global_entry = hna_global_hash_find(bat_priv, hna_ptr); 423 tt_global_entry = tt_global_hash_find(bat_priv, tt_ptr);
409 424
410 if (!hna_global_entry) { 425 if (!tt_global_entry) {
411 spin_unlock_bh(&bat_priv->hna_ghash_lock); 426 spin_unlock_bh(&bat_priv->tt_ghash_lock);
412 427
413 hna_global_entry = 428 tt_global_entry =
414 kmalloc(sizeof(struct hna_global_entry), 429 kmalloc(sizeof(struct tt_global_entry),
415 GFP_ATOMIC); 430 GFP_ATOMIC);
416 431
417 if (!hna_global_entry) 432 if (!tt_global_entry)
418 break; 433 break;
419 434
420 memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN); 435 memcpy(tt_global_entry->addr, tt_ptr, ETH_ALEN);
421 436
422 bat_dbg(DBG_ROUTES, bat_priv, 437 bat_dbg(DBG_ROUTES, bat_priv,
423 "Creating new global hna entry: " 438 "Creating new global tt entry: "
424 "%pM (via %pM)\n", 439 "%pM (via %pM)\n",
425 hna_global_entry->addr, orig_node->orig); 440 tt_global_entry->addr, orig_node->orig);
426 441
427 spin_lock_bh(&bat_priv->hna_ghash_lock); 442 spin_lock_bh(&bat_priv->tt_ghash_lock);
428 hash_add(bat_priv->hna_global_hash, compare_ghna, 443 hash_add(bat_priv->tt_global_hash, compare_gtt,
429 choose_orig, hna_global_entry, 444 choose_orig, tt_global_entry,
430 &hna_global_entry->hash_entry); 445 &tt_global_entry->hash_entry);
431 446
432 } 447 }
433 448
434 hna_global_entry->orig_node = orig_node; 449 tt_global_entry->orig_node = orig_node;
435 spin_unlock_bh(&bat_priv->hna_ghash_lock); 450 spin_unlock_bh(&bat_priv->tt_ghash_lock);
436 451
437 /* remove address from local hash if present */ 452 /* remove address from local hash if present */
438 spin_lock_bh(&bat_priv->hna_lhash_lock); 453 spin_lock_bh(&bat_priv->tt_lhash_lock);
439 454
440 hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); 455 tt_ptr = tt_buff + (tt_buff_count * ETH_ALEN);
441 hna_local_entry = hna_local_hash_find(bat_priv, hna_ptr); 456 tt_local_entry = tt_local_hash_find(bat_priv, tt_ptr);
442 457
443 if (hna_local_entry) 458 if (tt_local_entry)
444 hna_local_del(bat_priv, hna_local_entry, 459 tt_local_del(bat_priv, tt_local_entry,
445 "global hna received"); 460 "global tt received");
446 461
447 spin_unlock_bh(&bat_priv->hna_lhash_lock); 462 spin_unlock_bh(&bat_priv->tt_lhash_lock);
448 463
449 hna_buff_count++; 464 tt_buff_count++;
450 } 465 }
451 466
452 /* initialize, and overwrite if malloc succeeds */ 467 /* initialize, and overwrite if malloc succeeds */
453 orig_node->hna_buff = NULL; 468 orig_node->tt_buff = NULL;
454 orig_node->hna_buff_len = 0; 469 orig_node->tt_buff_len = 0;
455 470
456 if (hna_buff_len > 0) { 471 if (tt_buff_len > 0) {
457 orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC); 472 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
458 if (orig_node->hna_buff) { 473 if (orig_node->tt_buff) {
459 memcpy(orig_node->hna_buff, hna_buff, hna_buff_len); 474 memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
460 orig_node->hna_buff_len = hna_buff_len; 475 orig_node->tt_buff_len = tt_buff_len;
461 } 476 }
462 } 477 }
463} 478}
464 479
465int hna_global_seq_print_text(struct seq_file *seq, void *offset) 480int tt_global_seq_print_text(struct seq_file *seq, void *offset)
466{ 481{
467 struct net_device *net_dev = (struct net_device *)seq->private; 482 struct net_device *net_dev = (struct net_device *)seq->private;
468 struct bat_priv *bat_priv = netdev_priv(net_dev); 483 struct bat_priv *bat_priv = netdev_priv(net_dev);
469 struct hashtable_t *hash = bat_priv->hna_global_hash; 484 struct hashtable_t *hash = bat_priv->tt_global_hash;
470 struct hna_global_entry *hna_global_entry; 485 struct tt_global_entry *tt_global_entry;
486 struct hard_iface *primary_if;
471 struct hlist_node *node; 487 struct hlist_node *node;
472 struct hlist_head *head; 488 struct hlist_head *head;
473 size_t buf_size, pos; 489 size_t buf_size, pos;
474 char *buff; 490 char *buff;
475 int i; 491 int i, ret = 0;
476 492
477 if (!bat_priv->primary_if) { 493 primary_if = primary_if_get_selected(bat_priv);
478 return seq_printf(seq, "BATMAN mesh %s disabled - " 494 if (!primary_if) {
479 "please specify interfaces to enable it\n", 495 ret = seq_printf(seq, "BATMAN mesh %s disabled - please "
480 net_dev->name); 496 "specify interfaces to enable it\n",
497 net_dev->name);
498 goto out;
481 } 499 }
482 500
483 seq_printf(seq, "Globally announced HNAs received via the mesh %s\n", 501 if (primary_if->if_status != IF_ACTIVE) {
502 ret = seq_printf(seq, "BATMAN mesh %s disabled - "
503 "primary interface not active\n",
504 net_dev->name);
505 goto out;
506 }
507
508 seq_printf(seq,
509 "Globally announced TT entries received via the mesh %s\n",
484 net_dev->name); 510 net_dev->name);
485 511
486 spin_lock_bh(&bat_priv->hna_ghash_lock); 512 spin_lock_bh(&bat_priv->tt_ghash_lock);
487 513
488 buf_size = 1; 514 buf_size = 1;
489 /* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/ 515 /* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/
@@ -498,8 +524,9 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
498 524
499 buff = kmalloc(buf_size, GFP_ATOMIC); 525 buff = kmalloc(buf_size, GFP_ATOMIC);
500 if (!buff) { 526 if (!buff) {
501 spin_unlock_bh(&bat_priv->hna_ghash_lock); 527 spin_unlock_bh(&bat_priv->tt_ghash_lock);
502 return -ENOMEM; 528 ret = -ENOMEM;
529 goto out;
503 } 530 }
504 buff[0] = '\0'; 531 buff[0] = '\0';
505 pos = 0; 532 pos = 0;
@@ -508,101 +535,104 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset)
508 head = &hash->table[i]; 535 head = &hash->table[i];
509 536
510 rcu_read_lock(); 537 rcu_read_lock();
511 hlist_for_each_entry_rcu(hna_global_entry, node, 538 hlist_for_each_entry_rcu(tt_global_entry, node,
512 head, hash_entry) { 539 head, hash_entry) {
513 pos += snprintf(buff + pos, 44, 540 pos += snprintf(buff + pos, 44,
514 " * %pM via %pM\n", 541 " * %pM via %pM\n",
515 hna_global_entry->addr, 542 tt_global_entry->addr,
516 hna_global_entry->orig_node->orig); 543 tt_global_entry->orig_node->orig);
517 } 544 }
518 rcu_read_unlock(); 545 rcu_read_unlock();
519 } 546 }
520 547
521 spin_unlock_bh(&bat_priv->hna_ghash_lock); 548 spin_unlock_bh(&bat_priv->tt_ghash_lock);
522 549
523 seq_printf(seq, "%s", buff); 550 seq_printf(seq, "%s", buff);
524 kfree(buff); 551 kfree(buff);
525 return 0; 552out:
553 if (primary_if)
554 hardif_free_ref(primary_if);
555 return ret;
526} 556}
527 557
528static void _hna_global_del_orig(struct bat_priv *bat_priv, 558static void _tt_global_del_orig(struct bat_priv *bat_priv,
529 struct hna_global_entry *hna_global_entry, 559 struct tt_global_entry *tt_global_entry,
530 char *message) 560 char *message)
531{ 561{
532 bat_dbg(DBG_ROUTES, bat_priv, 562 bat_dbg(DBG_ROUTES, bat_priv,
533 "Deleting global hna entry %pM (via %pM): %s\n", 563 "Deleting global tt entry %pM (via %pM): %s\n",
534 hna_global_entry->addr, hna_global_entry->orig_node->orig, 564 tt_global_entry->addr, tt_global_entry->orig_node->orig,
535 message); 565 message);
536 566
537 hash_remove(bat_priv->hna_global_hash, compare_ghna, choose_orig, 567 hash_remove(bat_priv->tt_global_hash, compare_gtt, choose_orig,
538 hna_global_entry->addr); 568 tt_global_entry->addr);
539 kfree(hna_global_entry); 569 kfree(tt_global_entry);
540} 570}
541 571
542void hna_global_del_orig(struct bat_priv *bat_priv, 572void tt_global_del_orig(struct bat_priv *bat_priv,
543 struct orig_node *orig_node, char *message) 573 struct orig_node *orig_node, char *message)
544{ 574{
545 struct hna_global_entry *hna_global_entry; 575 struct tt_global_entry *tt_global_entry;
546 int hna_buff_count = 0; 576 int tt_buff_count = 0;
547 unsigned char *hna_ptr; 577 unsigned char *tt_ptr;
548 578
549 if (orig_node->hna_buff_len == 0) 579 if (orig_node->tt_buff_len == 0)
550 return; 580 return;
551 581
552 spin_lock_bh(&bat_priv->hna_ghash_lock); 582 spin_lock_bh(&bat_priv->tt_ghash_lock);
553 583
554 while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) { 584 while ((tt_buff_count + 1) * ETH_ALEN <= orig_node->tt_buff_len) {
555 hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN); 585 tt_ptr = orig_node->tt_buff + (tt_buff_count * ETH_ALEN);
556 hna_global_entry = hna_global_hash_find(bat_priv, hna_ptr); 586 tt_global_entry = tt_global_hash_find(bat_priv, tt_ptr);
557 587
558 if ((hna_global_entry) && 588 if ((tt_global_entry) &&
559 (hna_global_entry->orig_node == orig_node)) 589 (tt_global_entry->orig_node == orig_node))
560 _hna_global_del_orig(bat_priv, hna_global_entry, 590 _tt_global_del_orig(bat_priv, tt_global_entry,
561 message); 591 message);
562 592
563 hna_buff_count++; 593 tt_buff_count++;
564 } 594 }
565 595
566 spin_unlock_bh(&bat_priv->hna_ghash_lock); 596 spin_unlock_bh(&bat_priv->tt_ghash_lock);
567 597
568 orig_node->hna_buff_len = 0; 598 orig_node->tt_buff_len = 0;
569 kfree(orig_node->hna_buff); 599 kfree(orig_node->tt_buff);
570 orig_node->hna_buff = NULL; 600 orig_node->tt_buff = NULL;
571} 601}
572 602
573static void hna_global_del(struct hlist_node *node, void *arg) 603static void tt_global_del(struct hlist_node *node, void *arg)
574{ 604{
575 void *data = container_of(node, struct hna_global_entry, hash_entry); 605 void *data = container_of(node, struct tt_global_entry, hash_entry);
576 606
577 kfree(data); 607 kfree(data);
578} 608}
579 609
580void hna_global_free(struct bat_priv *bat_priv) 610void tt_global_free(struct bat_priv *bat_priv)
581{ 611{
582 if (!bat_priv->hna_global_hash) 612 if (!bat_priv->tt_global_hash)
583 return; 613 return;
584 614
585 hash_delete(bat_priv->hna_global_hash, hna_global_del, NULL); 615 hash_delete(bat_priv->tt_global_hash, tt_global_del, NULL);
586 bat_priv->hna_global_hash = NULL; 616 bat_priv->tt_global_hash = NULL;
587} 617}
588 618
589struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr) 619struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr)
590{ 620{
591 struct hna_global_entry *hna_global_entry; 621 struct tt_global_entry *tt_global_entry;
592 struct orig_node *orig_node = NULL; 622 struct orig_node *orig_node = NULL;
593 623
594 spin_lock_bh(&bat_priv->hna_ghash_lock); 624 spin_lock_bh(&bat_priv->tt_ghash_lock);
595 hna_global_entry = hna_global_hash_find(bat_priv, addr); 625 tt_global_entry = tt_global_hash_find(bat_priv, addr);
596 626
597 if (!hna_global_entry) 627 if (!tt_global_entry)
598 goto out; 628 goto out;
599 629
600 if (!atomic_inc_not_zero(&hna_global_entry->orig_node->refcount)) 630 if (!atomic_inc_not_zero(&tt_global_entry->orig_node->refcount))
601 goto out; 631 goto out;
602 632
603 orig_node = hna_global_entry->orig_node; 633 orig_node = tt_global_entry->orig_node;
604 634
605out: 635out:
606 spin_unlock_bh(&bat_priv->hna_ghash_lock); 636 spin_unlock_bh(&bat_priv->tt_ghash_lock);
607 return orig_node; 637 return orig_node;
608} 638}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index f19931ca1457..46152c38cc95 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -22,22 +22,22 @@
22#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ 22#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
23#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ 23#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
24 24
25int hna_local_init(struct bat_priv *bat_priv); 25int tt_local_init(struct bat_priv *bat_priv);
26void hna_local_add(struct net_device *soft_iface, uint8_t *addr); 26void tt_local_add(struct net_device *soft_iface, uint8_t *addr);
27void hna_local_remove(struct bat_priv *bat_priv, 27void tt_local_remove(struct bat_priv *bat_priv,
28 uint8_t *addr, char *message); 28 uint8_t *addr, char *message);
29int hna_local_fill_buffer(struct bat_priv *bat_priv, 29int tt_local_fill_buffer(struct bat_priv *bat_priv,
30 unsigned char *buff, int buff_len); 30 unsigned char *buff, int buff_len);
31int hna_local_seq_print_text(struct seq_file *seq, void *offset); 31int tt_local_seq_print_text(struct seq_file *seq, void *offset);
32void hna_local_free(struct bat_priv *bat_priv); 32void tt_local_free(struct bat_priv *bat_priv);
33int hna_global_init(struct bat_priv *bat_priv); 33int tt_global_init(struct bat_priv *bat_priv);
34void hna_global_add_orig(struct bat_priv *bat_priv, 34void tt_global_add_orig(struct bat_priv *bat_priv,
35 struct orig_node *orig_node, 35 struct orig_node *orig_node,
36 unsigned char *hna_buff, int hna_buff_len); 36 unsigned char *tt_buff, int tt_buff_len);
37int hna_global_seq_print_text(struct seq_file *seq, void *offset); 37int tt_global_seq_print_text(struct seq_file *seq, void *offset);
38void hna_global_del_orig(struct bat_priv *bat_priv, 38void tt_global_del_orig(struct bat_priv *bat_priv,
39 struct orig_node *orig_node, char *message); 39 struct orig_node *orig_node, char *message);
40void hna_global_free(struct bat_priv *bat_priv); 40void tt_global_free(struct bat_priv *bat_priv);
41struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr); 41struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr);
42 42
43#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ 43#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 83445cf0cc9f..fab70e8b16ee 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -67,7 +67,7 @@ struct hard_iface {
67struct orig_node { 67struct orig_node {
68 uint8_t orig[ETH_ALEN]; 68 uint8_t orig[ETH_ALEN];
69 uint8_t primary_addr[ETH_ALEN]; 69 uint8_t primary_addr[ETH_ALEN];
70 struct neigh_node *router; 70 struct neigh_node __rcu *router; /* rcu protected pointer */
71 unsigned long *bcast_own; 71 unsigned long *bcast_own;
72 uint8_t *bcast_own_sum; 72 uint8_t *bcast_own_sum;
73 unsigned long last_valid; 73 unsigned long last_valid;
@@ -75,25 +75,25 @@ struct orig_node {
75 unsigned long batman_seqno_reset; 75 unsigned long batman_seqno_reset;
76 uint8_t gw_flags; 76 uint8_t gw_flags;
77 uint8_t flags; 77 uint8_t flags;
78 unsigned char *hna_buff; 78 unsigned char *tt_buff;
79 int16_t hna_buff_len; 79 int16_t tt_buff_len;
80 uint32_t last_real_seqno; 80 uint32_t last_real_seqno;
81 uint8_t last_ttl; 81 uint8_t last_ttl;
82 unsigned long bcast_bits[NUM_WORDS]; 82 unsigned long bcast_bits[NUM_WORDS];
83 uint32_t last_bcast_seqno; 83 uint32_t last_bcast_seqno;
84 struct hlist_head neigh_list; 84 struct hlist_head neigh_list;
85 struct list_head frag_list; 85 struct list_head frag_list;
86 spinlock_t neigh_list_lock; /* protects neighbor list */ 86 spinlock_t neigh_list_lock; /* protects neigh_list and router */
87 atomic_t refcount; 87 atomic_t refcount;
88 struct rcu_head rcu; 88 struct rcu_head rcu;
89 struct hlist_node hash_entry; 89 struct hlist_node hash_entry;
90 struct bat_priv *bat_priv; 90 struct bat_priv *bat_priv;
91 unsigned long last_frag_packet; 91 unsigned long last_frag_packet;
92 spinlock_t ogm_cnt_lock; /* protects: bcast_own, bcast_own_sum, 92 /* ogm_cnt_lock protects: bcast_own, bcast_own_sum,
93 * neigh_node->real_bits, 93 * neigh_node->real_bits, neigh_node->real_packet_count */
94 * neigh_node->real_packet_count */ 94 spinlock_t ogm_cnt_lock;
95 spinlock_t bcast_seqno_lock; /* protects bcast_bits, 95 /* bcast_seqno_lock protects bcast_bits, last_bcast_seqno */
96 * last_bcast_seqno */ 96 spinlock_t bcast_seqno_lock;
97 atomic_t bond_candidates; 97 atomic_t bond_candidates;
98 struct list_head bond_list; 98 struct list_head bond_list;
99}; 99};
@@ -125,6 +125,7 @@ struct neigh_node {
125 struct rcu_head rcu; 125 struct rcu_head rcu;
126 struct orig_node *orig_node; 126 struct orig_node *orig_node;
127 struct hard_iface *if_incoming; 127 struct hard_iface *if_incoming;
128 spinlock_t tq_lock; /* protects: tq_recv, tq_index */
128}; 129};
129 130
130 131
@@ -145,34 +146,34 @@ struct bat_priv {
145 atomic_t bcast_queue_left; 146 atomic_t bcast_queue_left;
146 atomic_t batman_queue_left; 147 atomic_t batman_queue_left;
147 char num_ifaces; 148 char num_ifaces;
148 struct hlist_head softif_neigh_list;
149 struct softif_neigh *softif_neigh;
150 struct debug_log *debug_log; 149 struct debug_log *debug_log;
151 struct hard_iface *primary_if;
152 struct kobject *mesh_obj; 150 struct kobject *mesh_obj;
153 struct dentry *debug_dir; 151 struct dentry *debug_dir;
154 struct hlist_head forw_bat_list; 152 struct hlist_head forw_bat_list;
155 struct hlist_head forw_bcast_list; 153 struct hlist_head forw_bcast_list;
156 struct hlist_head gw_list; 154 struct hlist_head gw_list;
155 struct hlist_head softif_neigh_vids;
157 struct list_head vis_send_list; 156 struct list_head vis_send_list;
158 struct hashtable_t *orig_hash; 157 struct hashtable_t *orig_hash;
159 struct hashtable_t *hna_local_hash; 158 struct hashtable_t *tt_local_hash;
160 struct hashtable_t *hna_global_hash; 159 struct hashtable_t *tt_global_hash;
161 struct hashtable_t *vis_hash; 160 struct hashtable_t *vis_hash;
162 spinlock_t forw_bat_list_lock; /* protects forw_bat_list */ 161 spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
163 spinlock_t forw_bcast_list_lock; /* protects */ 162 spinlock_t forw_bcast_list_lock; /* protects */
164 spinlock_t hna_lhash_lock; /* protects hna_local_hash */ 163 spinlock_t tt_lhash_lock; /* protects tt_local_hash */
165 spinlock_t hna_ghash_lock; /* protects hna_global_hash */ 164 spinlock_t tt_ghash_lock; /* protects tt_global_hash */
166 spinlock_t gw_list_lock; /* protects gw_list and curr_gw */ 165 spinlock_t gw_list_lock; /* protects gw_list and curr_gw */
167 spinlock_t vis_hash_lock; /* protects vis_hash */ 166 spinlock_t vis_hash_lock; /* protects vis_hash */
168 spinlock_t vis_list_lock; /* protects vis_info::recv_list */ 167 spinlock_t vis_list_lock; /* protects vis_info::recv_list */
169 spinlock_t softif_neigh_lock; /* protects soft-interface neigh list */ 168 spinlock_t softif_neigh_lock; /* protects soft-interface neigh list */
170 int16_t num_local_hna; 169 spinlock_t softif_neigh_vid_lock; /* protects soft-interface vid list */
171 atomic_t hna_local_changed; 170 int16_t num_local_tt;
172 struct delayed_work hna_work; 171 atomic_t tt_local_changed;
172 struct delayed_work tt_work;
173 struct delayed_work orig_work; 173 struct delayed_work orig_work;
174 struct delayed_work vis_work; 174 struct delayed_work vis_work;
175 struct gw_node __rcu *curr_gw; /* rcu protected pointer */ 175 struct gw_node __rcu *curr_gw; /* rcu protected pointer */
176 struct hard_iface __rcu *primary_if; /* rcu protected pointer */
176 struct vis_info *my_vis_info; 177 struct vis_info *my_vis_info;
177}; 178};
178 179
@@ -191,14 +192,14 @@ struct socket_packet {
191 struct icmp_packet_rr icmp_packet; 192 struct icmp_packet_rr icmp_packet;
192}; 193};
193 194
194struct hna_local_entry { 195struct tt_local_entry {
195 uint8_t addr[ETH_ALEN]; 196 uint8_t addr[ETH_ALEN];
196 unsigned long last_seen; 197 unsigned long last_seen;
197 char never_purge; 198 char never_purge;
198 struct hlist_node hash_entry; 199 struct hlist_node hash_entry;
199}; 200};
200 201
201struct hna_global_entry { 202struct tt_global_entry {
202 uint8_t addr[ETH_ALEN]; 203 uint8_t addr[ETH_ALEN];
203 struct orig_node *orig_node; 204 struct orig_node *orig_node;
204 struct hlist_node hash_entry; 205 struct hlist_node hash_entry;
@@ -261,7 +262,7 @@ struct vis_info {
261struct vis_info_entry { 262struct vis_info_entry {
262 uint8_t src[ETH_ALEN]; 263 uint8_t src[ETH_ALEN];
263 uint8_t dest[ETH_ALEN]; 264 uint8_t dest[ETH_ALEN];
264 uint8_t quality; /* quality = 0 means HNA */ 265 uint8_t quality; /* quality = 0 client */
265} __packed; 266} __packed;
266 267
267struct recvlist_node { 268struct recvlist_node {
@@ -269,11 +270,20 @@ struct recvlist_node {
269 uint8_t mac[ETH_ALEN]; 270 uint8_t mac[ETH_ALEN];
270}; 271};
271 272
273struct softif_neigh_vid {
274 struct hlist_node list;
275 struct bat_priv *bat_priv;
276 short vid;
277 atomic_t refcount;
278 struct softif_neigh __rcu *softif_neigh;
279 struct rcu_head rcu;
280 struct hlist_head softif_neigh_list;
281};
282
272struct softif_neigh { 283struct softif_neigh {
273 struct hlist_node list; 284 struct hlist_node list;
274 uint8_t addr[ETH_ALEN]; 285 uint8_t addr[ETH_ALEN];
275 unsigned long last_seen; 286 unsigned long last_seen;
276 short vid;
277 atomic_t refcount; 287 atomic_t refcount;
278 struct rcu_head rcu; 288 struct rcu_head rcu;
279}; 289};
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index 19f84bd443af..19c3daf34ac6 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -221,15 +221,17 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
221 struct hard_iface *hard_iface, uint8_t dstaddr[]) 221 struct hard_iface *hard_iface, uint8_t dstaddr[])
222{ 222{
223 struct unicast_packet tmp_uc, *unicast_packet; 223 struct unicast_packet tmp_uc, *unicast_packet;
224 struct hard_iface *primary_if;
224 struct sk_buff *frag_skb; 225 struct sk_buff *frag_skb;
225 struct unicast_frag_packet *frag1, *frag2; 226 struct unicast_frag_packet *frag1, *frag2;
226 int uc_hdr_len = sizeof(struct unicast_packet); 227 int uc_hdr_len = sizeof(struct unicast_packet);
227 int ucf_hdr_len = sizeof(struct unicast_frag_packet); 228 int ucf_hdr_len = sizeof(struct unicast_frag_packet);
228 int data_len = skb->len - uc_hdr_len; 229 int data_len = skb->len - uc_hdr_len;
229 int large_tail = 0; 230 int large_tail = 0, ret = NET_RX_DROP;
230 uint16_t seqno; 231 uint16_t seqno;
231 232
232 if (!bat_priv->primary_if) 233 primary_if = primary_if_get_selected(bat_priv);
234 if (!primary_if)
233 goto dropped; 235 goto dropped;
234 236
235 frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); 237 frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
@@ -254,7 +256,7 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
254 frag1->version = COMPAT_VERSION; 256 frag1->version = COMPAT_VERSION;
255 frag1->packet_type = BAT_UNICAST_FRAG; 257 frag1->packet_type = BAT_UNICAST_FRAG;
256 258
257 memcpy(frag1->orig, bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); 259 memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
258 memcpy(frag2, frag1, sizeof(struct unicast_frag_packet)); 260 memcpy(frag2, frag1, sizeof(struct unicast_frag_packet));
259 261
260 if (data_len & 1) 262 if (data_len & 1)
@@ -269,13 +271,17 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
269 271
270 send_skb_packet(skb, hard_iface, dstaddr); 272 send_skb_packet(skb, hard_iface, dstaddr);
271 send_skb_packet(frag_skb, hard_iface, dstaddr); 273 send_skb_packet(frag_skb, hard_iface, dstaddr);
272 return NET_RX_SUCCESS; 274 ret = NET_RX_SUCCESS;
275 goto out;
273 276
274drop_frag: 277drop_frag:
275 kfree_skb(frag_skb); 278 kfree_skb(frag_skb);
276dropped: 279dropped:
277 kfree_skb(skb); 280 kfree_skb(skb);
278 return NET_RX_DROP; 281out:
282 if (primary_if)
283 hardif_free_ref(primary_if);
284 return ret;
279} 285}
280 286
281int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) 287int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
@@ -289,12 +295,12 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
289 295
290 /* get routing information */ 296 /* get routing information */
291 if (is_multicast_ether_addr(ethhdr->h_dest)) { 297 if (is_multicast_ether_addr(ethhdr->h_dest)) {
292 orig_node = (struct orig_node *)gw_get_selected(bat_priv); 298 orig_node = (struct orig_node *)gw_get_selected_orig(bat_priv);
293 if (orig_node) 299 if (orig_node)
294 goto find_router; 300 goto find_router;
295 } 301 }
296 302
297 /* check for hna host - increases orig_node refcount */ 303 /* check for tt host - increases orig_node refcount */
298 orig_node = transtable_search(bat_priv, ethhdr->h_dest); 304 orig_node = transtable_search(bat_priv, ethhdr->h_dest);
299 305
300find_router: 306find_router:
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index f90212f42082..c39f20cc1ba6 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -194,7 +194,7 @@ static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
194{ 194{
195 /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */ 195 /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
196 if (primary && entry->quality == 0) 196 if (primary && entry->quality == 0)
197 return sprintf(buff, "HNA %pM, ", entry->dest); 197 return sprintf(buff, "TT %pM, ", entry->dest);
198 else if (compare_eth(entry->src, src)) 198 else if (compare_eth(entry->src, src))
199 return sprintf(buff, "TQ %pM %d, ", entry->dest, 199 return sprintf(buff, "TQ %pM %d, ", entry->dest,
200 entry->quality); 200 entry->quality);
@@ -204,6 +204,7 @@ static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
204 204
205int vis_seq_print_text(struct seq_file *seq, void *offset) 205int vis_seq_print_text(struct seq_file *seq, void *offset)
206{ 206{
207 struct hard_iface *primary_if;
207 struct hlist_node *node; 208 struct hlist_node *node;
208 struct hlist_head *head; 209 struct hlist_head *head;
209 struct vis_info *info; 210 struct vis_info *info;
@@ -215,15 +216,18 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
215 HLIST_HEAD(vis_if_list); 216 HLIST_HEAD(vis_if_list);
216 struct if_list_entry *entry; 217 struct if_list_entry *entry;
217 struct hlist_node *pos, *n; 218 struct hlist_node *pos, *n;
218 int i, j; 219 int i, j, ret = 0;
219 int vis_server = atomic_read(&bat_priv->vis_mode); 220 int vis_server = atomic_read(&bat_priv->vis_mode);
220 size_t buff_pos, buf_size; 221 size_t buff_pos, buf_size;
221 char *buff; 222 char *buff;
222 int compare; 223 int compare;
223 224
224 if ((!bat_priv->primary_if) || 225 primary_if = primary_if_get_selected(bat_priv);
225 (vis_server == VIS_TYPE_CLIENT_UPDATE)) 226 if (!primary_if)
226 return 0; 227 goto out;
228
229 if (vis_server == VIS_TYPE_CLIENT_UPDATE)
230 goto out;
227 231
228 buf_size = 1; 232 buf_size = 1;
229 /* Estimate length */ 233 /* Estimate length */
@@ -270,7 +274,8 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
270 buff = kmalloc(buf_size, GFP_ATOMIC); 274 buff = kmalloc(buf_size, GFP_ATOMIC);
271 if (!buff) { 275 if (!buff) {
272 spin_unlock_bh(&bat_priv->vis_hash_lock); 276 spin_unlock_bh(&bat_priv->vis_hash_lock);
273 return -ENOMEM; 277 ret = -ENOMEM;
278 goto out;
274 } 279 }
275 buff[0] = '\0'; 280 buff[0] = '\0';
276 buff_pos = 0; 281 buff_pos = 0;
@@ -328,7 +333,10 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
328 seq_printf(seq, "%s", buff); 333 seq_printf(seq, "%s", buff);
329 kfree(buff); 334 kfree(buff);
330 335
331 return 0; 336out:
337 if (primary_if)
338 hardif_free_ref(primary_if);
339 return ret;
332} 340}
333 341
334/* add the info packet to the send list, if it was not 342/* add the info packet to the send list, if it was not
@@ -558,6 +566,7 @@ static int find_best_vis_server(struct bat_priv *bat_priv,
558 struct vis_info *info) 566 struct vis_info *info)
559{ 567{
560 struct hashtable_t *hash = bat_priv->orig_hash; 568 struct hashtable_t *hash = bat_priv->orig_hash;
569 struct neigh_node *router;
561 struct hlist_node *node; 570 struct hlist_node *node;
562 struct hlist_head *head; 571 struct hlist_head *head;
563 struct orig_node *orig_node; 572 struct orig_node *orig_node;
@@ -571,13 +580,17 @@ static int find_best_vis_server(struct bat_priv *bat_priv,
571 580
572 rcu_read_lock(); 581 rcu_read_lock();
573 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { 582 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
574 if ((orig_node) && (orig_node->router) && 583 router = orig_node_get_router(orig_node);
575 (orig_node->flags & VIS_SERVER) && 584 if (!router)
576 (orig_node->router->tq_avg > best_tq)) { 585 continue;
577 best_tq = orig_node->router->tq_avg; 586
587 if ((orig_node->flags & VIS_SERVER) &&
588 (router->tq_avg > best_tq)) {
589 best_tq = router->tq_avg;
578 memcpy(packet->target_orig, orig_node->orig, 590 memcpy(packet->target_orig, orig_node->orig,
579 ETH_ALEN); 591 ETH_ALEN);
580 } 592 }
593 neigh_node_free_ref(router);
581 } 594 }
582 rcu_read_unlock(); 595 rcu_read_unlock();
583 } 596 }
@@ -605,11 +618,11 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
605 struct hlist_node *node; 618 struct hlist_node *node;
606 struct hlist_head *head; 619 struct hlist_head *head;
607 struct orig_node *orig_node; 620 struct orig_node *orig_node;
608 struct neigh_node *neigh_node; 621 struct neigh_node *router;
609 struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info; 622 struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info;
610 struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data; 623 struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data;
611 struct vis_info_entry *entry; 624 struct vis_info_entry *entry;
612 struct hna_local_entry *hna_local_entry; 625 struct tt_local_entry *tt_local_entry;
613 int best_tq = -1, i; 626 int best_tq = -1, i;
614 627
615 info->first_seen = jiffies; 628 info->first_seen = jiffies;
@@ -633,59 +646,61 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
633 646
634 rcu_read_lock(); 647 rcu_read_lock();
635 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { 648 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
636 neigh_node = orig_node->router; 649 router = orig_node_get_router(orig_node);
637 650 if (!router)
638 if (!neigh_node)
639 continue; 651 continue;
640 652
641 if (!compare_eth(neigh_node->addr, orig_node->orig)) 653 if (!compare_eth(router->addr, orig_node->orig))
642 continue; 654 goto next;
643 655
644 if (neigh_node->if_incoming->if_status != IF_ACTIVE) 656 if (router->if_incoming->if_status != IF_ACTIVE)
645 continue; 657 goto next;
646 658
647 if (neigh_node->tq_avg < 1) 659 if (router->tq_avg < 1)
648 continue; 660 goto next;
649 661
650 /* fill one entry into buffer. */ 662 /* fill one entry into buffer. */
651 entry = (struct vis_info_entry *) 663 entry = (struct vis_info_entry *)
652 skb_put(info->skb_packet, sizeof(*entry)); 664 skb_put(info->skb_packet, sizeof(*entry));
653 memcpy(entry->src, 665 memcpy(entry->src,
654 neigh_node->if_incoming->net_dev->dev_addr, 666 router->if_incoming->net_dev->dev_addr,
655 ETH_ALEN); 667 ETH_ALEN);
656 memcpy(entry->dest, orig_node->orig, ETH_ALEN); 668 memcpy(entry->dest, orig_node->orig, ETH_ALEN);
657 entry->quality = neigh_node->tq_avg; 669 entry->quality = router->tq_avg;
658 packet->entries++; 670 packet->entries++;
659 671
672next:
673 neigh_node_free_ref(router);
674
660 if (vis_packet_full(info)) 675 if (vis_packet_full(info))
661 goto unlock; 676 goto unlock;
662 } 677 }
663 rcu_read_unlock(); 678 rcu_read_unlock();
664 } 679 }
665 680
666 hash = bat_priv->hna_local_hash; 681 hash = bat_priv->tt_local_hash;
667 682
668 spin_lock_bh(&bat_priv->hna_lhash_lock); 683 spin_lock_bh(&bat_priv->tt_lhash_lock);
669 for (i = 0; i < hash->size; i++) { 684 for (i = 0; i < hash->size; i++) {
670 head = &hash->table[i]; 685 head = &hash->table[i];
671 686
672 hlist_for_each_entry(hna_local_entry, node, head, hash_entry) { 687 hlist_for_each_entry(tt_local_entry, node, head, hash_entry) {
673 entry = (struct vis_info_entry *) 688 entry = (struct vis_info_entry *)
674 skb_put(info->skb_packet, 689 skb_put(info->skb_packet,
675 sizeof(*entry)); 690 sizeof(*entry));
676 memset(entry->src, 0, ETH_ALEN); 691 memset(entry->src, 0, ETH_ALEN);
677 memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN); 692 memcpy(entry->dest, tt_local_entry->addr, ETH_ALEN);
678 entry->quality = 0; /* 0 means HNA */ 693 entry->quality = 0; /* 0 means TT */
679 packet->entries++; 694 packet->entries++;
680 695
681 if (vis_packet_full(info)) { 696 if (vis_packet_full(info)) {
682 spin_unlock_bh(&bat_priv->hna_lhash_lock); 697 spin_unlock_bh(&bat_priv->tt_lhash_lock);
683 return 0; 698 return 0;
684 } 699 }
685 } 700 }
686 } 701 }
687 702
688 spin_unlock_bh(&bat_priv->hna_lhash_lock); 703 spin_unlock_bh(&bat_priv->tt_lhash_lock);
689 return 0; 704 return 0;
690 705
691unlock: 706unlock:
@@ -725,6 +740,7 @@ static void purge_vis_packets(struct bat_priv *bat_priv)
725static void broadcast_vis_packet(struct bat_priv *bat_priv, 740static void broadcast_vis_packet(struct bat_priv *bat_priv,
726 struct vis_info *info) 741 struct vis_info *info)
727{ 742{
743 struct neigh_node *router;
728 struct hashtable_t *hash = bat_priv->orig_hash; 744 struct hashtable_t *hash = bat_priv->orig_hash;
729 struct hlist_node *node; 745 struct hlist_node *node;
730 struct hlist_head *head; 746 struct hlist_head *head;
@@ -745,19 +761,26 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv,
745 rcu_read_lock(); 761 rcu_read_lock();
746 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { 762 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
747 /* if it's a vis server and reachable, send it. */ 763 /* if it's a vis server and reachable, send it. */
748 if ((!orig_node) || (!orig_node->router))
749 continue;
750 if (!(orig_node->flags & VIS_SERVER)) 764 if (!(orig_node->flags & VIS_SERVER))
751 continue; 765 continue;
766
767 router = orig_node_get_router(orig_node);
768 if (!router)
769 continue;
770
752 /* don't send it if we already received the packet from 771 /* don't send it if we already received the packet from
753 * this node. */ 772 * this node. */
754 if (recv_list_is_in(bat_priv, &info->recv_list, 773 if (recv_list_is_in(bat_priv, &info->recv_list,
755 orig_node->orig)) 774 orig_node->orig)) {
775 neigh_node_free_ref(router);
756 continue; 776 continue;
777 }
757 778
758 memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); 779 memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
759 hard_iface = orig_node->router->if_incoming; 780 hard_iface = router->if_incoming;
760 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); 781 memcpy(dstaddr, router->addr, ETH_ALEN);
782
783 neigh_node_free_ref(router);
761 784
762 skb = skb_clone(info->skb_packet, GFP_ATOMIC); 785 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
763 if (skb) 786 if (skb)
@@ -772,60 +795,48 @@ static void unicast_vis_packet(struct bat_priv *bat_priv,
772 struct vis_info *info) 795 struct vis_info *info)
773{ 796{
774 struct orig_node *orig_node; 797 struct orig_node *orig_node;
775 struct neigh_node *neigh_node = NULL; 798 struct neigh_node *router = NULL;
776 struct sk_buff *skb; 799 struct sk_buff *skb;
777 struct vis_packet *packet; 800 struct vis_packet *packet;
778 801
779 packet = (struct vis_packet *)info->skb_packet->data; 802 packet = (struct vis_packet *)info->skb_packet->data;
780 803
781 rcu_read_lock();
782 orig_node = orig_hash_find(bat_priv, packet->target_orig); 804 orig_node = orig_hash_find(bat_priv, packet->target_orig);
783
784 if (!orig_node) 805 if (!orig_node)
785 goto unlock; 806 goto out;
786
787 neigh_node = orig_node->router;
788 807
789 if (!neigh_node) 808 router = orig_node_get_router(orig_node);
790 goto unlock; 809 if (!router)
791 810 goto out;
792 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
793 neigh_node = NULL;
794 goto unlock;
795 }
796
797 rcu_read_unlock();
798 811
799 skb = skb_clone(info->skb_packet, GFP_ATOMIC); 812 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
800 if (skb) 813 if (skb)
801 send_skb_packet(skb, neigh_node->if_incoming, 814 send_skb_packet(skb, router->if_incoming, router->addr);
802 neigh_node->addr);
803 815
804 goto out;
805
806unlock:
807 rcu_read_unlock();
808out: 816out:
809 if (neigh_node) 817 if (router)
810 neigh_node_free_ref(neigh_node); 818 neigh_node_free_ref(router);
811 if (orig_node) 819 if (orig_node)
812 orig_node_free_ref(orig_node); 820 orig_node_free_ref(orig_node);
813 return;
814} 821}
815 822
816/* only send one vis packet. called from send_vis_packets() */ 823/* only send one vis packet. called from send_vis_packets() */
817static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) 824static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
818{ 825{
826 struct hard_iface *primary_if;
819 struct vis_packet *packet; 827 struct vis_packet *packet;
820 828
829 primary_if = primary_if_get_selected(bat_priv);
830 if (!primary_if)
831 goto out;
832
821 packet = (struct vis_packet *)info->skb_packet->data; 833 packet = (struct vis_packet *)info->skb_packet->data;
822 if (packet->ttl < 2) { 834 if (packet->ttl < 2) {
823 pr_debug("Error - can't send vis packet: ttl exceeded\n"); 835 pr_debug("Error - can't send vis packet: ttl exceeded\n");
824 return; 836 goto out;
825 } 837 }
826 838
827 memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr, 839 memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
828 ETH_ALEN);
829 packet->ttl--; 840 packet->ttl--;
830 841
831 if (is_broadcast_ether_addr(packet->target_orig)) 842 if (is_broadcast_ether_addr(packet->target_orig))
@@ -833,6 +844,10 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
833 else 844 else
834 unicast_vis_packet(bat_priv, info); 845 unicast_vis_packet(bat_priv, info);
835 packet->ttl++; /* restore TTL */ 846 packet->ttl++; /* restore TTL */
847
848out:
849 if (primary_if)
850 hardif_free_ref(primary_if);
836} 851}
837 852
838/* called from timer; send (and maybe generate) vis packet. */ 853/* called from timer; send (and maybe generate) vis packet. */
@@ -859,8 +874,7 @@ static void send_vis_packets(struct work_struct *work)
859 kref_get(&info->refcount); 874 kref_get(&info->refcount);
860 spin_unlock_bh(&bat_priv->vis_hash_lock); 875 spin_unlock_bh(&bat_priv->vis_hash_lock);
861 876
862 if (bat_priv->primary_if) 877 send_vis_packet(bat_priv, info);
863 send_vis_packet(bat_priv, info);
864 878
865 spin_lock_bh(&bat_priv->vis_hash_lock); 879 spin_lock_bh(&bat_priv->vis_hash_lock);
866 send_list_del(info); 880 send_list_del(info);