aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/routing.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/routing.c')
-rw-r--r--net/batman-adv/routing.c1000
1 files changed, 569 insertions, 431 deletions
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 8828eddd3f72..c172f5d0e05a 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: 2 * Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
3 * 3 *
4 * Marek Lindner, Simon Wunderlich 4 * Marek Lindner, Simon Wunderlich
5 * 5 *
@@ -28,7 +28,6 @@
28#include "icmp_socket.h" 28#include "icmp_socket.h"
29#include "translation-table.h" 29#include "translation-table.h"
30#include "originator.h" 30#include "originator.h"
31#include "types.h"
32#include "ring_buffer.h" 31#include "ring_buffer.h"
33#include "vis.h" 32#include "vis.h"
34#include "aggregation.h" 33#include "aggregation.h"
@@ -36,35 +35,33 @@
36#include "gateway_client.h" 35#include "gateway_client.h"
37#include "unicast.h" 36#include "unicast.h"
38 37
39void slide_own_bcast_window(struct batman_if *batman_if) 38void slide_own_bcast_window(struct hard_iface *hard_iface)
40{ 39{
41 struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); 40 struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
42 struct hashtable_t *hash = bat_priv->orig_hash; 41 struct hashtable_t *hash = bat_priv->orig_hash;
43 struct hlist_node *walk; 42 struct hlist_node *node;
44 struct hlist_head *head; 43 struct hlist_head *head;
45 struct element_t *bucket;
46 struct orig_node *orig_node; 44 struct orig_node *orig_node;
47 unsigned long *word; 45 unsigned long *word;
48 int i; 46 int i;
49 size_t word_index; 47 size_t word_index;
50 48
51 spin_lock_bh(&bat_priv->orig_hash_lock);
52
53 for (i = 0; i < hash->size; i++) { 49 for (i = 0; i < hash->size; i++) {
54 head = &hash->table[i]; 50 head = &hash->table[i];
55 51
56 hlist_for_each_entry(bucket, walk, head, hlist) { 52 rcu_read_lock();
57 orig_node = bucket->data; 53 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
58 word_index = batman_if->if_num * NUM_WORDS; 54 spin_lock_bh(&orig_node->ogm_cnt_lock);
55 word_index = hard_iface->if_num * NUM_WORDS;
59 word = &(orig_node->bcast_own[word_index]); 56 word = &(orig_node->bcast_own[word_index]);
60 57
61 bit_get_packet(bat_priv, word, 1, 0); 58 bit_get_packet(bat_priv, word, 1, 0);
62 orig_node->bcast_own_sum[batman_if->if_num] = 59 orig_node->bcast_own_sum[hard_iface->if_num] =
63 bit_packet_count(word); 60 bit_packet_count(word);
61 spin_unlock_bh(&orig_node->ogm_cnt_lock);
64 } 62 }
63 rcu_read_unlock();
65 } 64 }
66
67 spin_unlock_bh(&bat_priv->orig_hash_lock);
68} 65}
69 66
70static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node, 67static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node,
@@ -90,6 +87,8 @@ static void update_route(struct bat_priv *bat_priv,
90 struct neigh_node *neigh_node, 87 struct neigh_node *neigh_node,
91 unsigned char *hna_buff, int hna_buff_len) 88 unsigned char *hna_buff, int hna_buff_len)
92{ 89{
90 struct neigh_node *neigh_node_tmp;
91
93 /* route deleted */ 92 /* route deleted */
94 if ((orig_node->router) && (!neigh_node)) { 93 if ((orig_node->router) && (!neigh_node)) {
95 94
@@ -116,7 +115,12 @@ static void update_route(struct bat_priv *bat_priv,
116 orig_node->router->addr); 115 orig_node->router->addr);
117 } 116 }
118 117
118 if (neigh_node && !atomic_inc_not_zero(&neigh_node->refcount))
119 neigh_node = NULL;
120 neigh_node_tmp = orig_node->router;
119 orig_node->router = neigh_node; 121 orig_node->router = neigh_node;
122 if (neigh_node_tmp)
123 neigh_node_free_ref(neigh_node_tmp);
120} 124}
121 125
122 126
@@ -139,73 +143,93 @@ void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
139static int is_bidirectional_neigh(struct orig_node *orig_node, 143static int is_bidirectional_neigh(struct orig_node *orig_node,
140 struct orig_node *orig_neigh_node, 144 struct orig_node *orig_neigh_node,
141 struct batman_packet *batman_packet, 145 struct batman_packet *batman_packet,
142 struct batman_if *if_incoming) 146 struct hard_iface *if_incoming)
143{ 147{
144 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 148 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
145 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 149 struct neigh_node *neigh_node = NULL, *tmp_neigh_node;
150 struct hlist_node *node;
146 unsigned char total_count; 151 unsigned char total_count;
152 uint8_t orig_eq_count, neigh_rq_count, tq_own;
153 int tq_asym_penalty, ret = 0;
147 154
148 if (orig_node == orig_neigh_node) { 155 if (orig_node == orig_neigh_node) {
149 list_for_each_entry(tmp_neigh_node, 156 rcu_read_lock();
150 &orig_node->neigh_list, 157 hlist_for_each_entry_rcu(tmp_neigh_node, node,
151 list) { 158 &orig_node->neigh_list, list) {
152 159
153 if (compare_orig(tmp_neigh_node->addr, 160 if (!compare_eth(tmp_neigh_node->addr,
154 orig_neigh_node->orig) && 161 orig_neigh_node->orig))
155 (tmp_neigh_node->if_incoming == if_incoming)) 162 continue;
156 neigh_node = tmp_neigh_node; 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;
157 } 171 }
172 rcu_read_unlock();
158 173
159 if (!neigh_node) 174 if (!neigh_node)
160 neigh_node = create_neighbor(orig_node, 175 neigh_node = create_neighbor(orig_node,
161 orig_neigh_node, 176 orig_neigh_node,
162 orig_neigh_node->orig, 177 orig_neigh_node->orig,
163 if_incoming); 178 if_incoming);
164 /* create_neighbor failed, return 0 */
165 if (!neigh_node) 179 if (!neigh_node)
166 return 0; 180 goto out;
167 181
168 neigh_node->last_valid = jiffies; 182 neigh_node->last_valid = jiffies;
169 } else { 183 } else {
170 /* find packet count of corresponding one hop neighbor */ 184 /* find packet count of corresponding one hop neighbor */
171 list_for_each_entry(tmp_neigh_node, 185 rcu_read_lock();
172 &orig_neigh_node->neigh_list, list) { 186 hlist_for_each_entry_rcu(tmp_neigh_node, node,
187 &orig_neigh_node->neigh_list, list) {
173 188
174 if (compare_orig(tmp_neigh_node->addr, 189 if (!compare_eth(tmp_neigh_node->addr,
175 orig_neigh_node->orig) && 190 orig_neigh_node->orig))
176 (tmp_neigh_node->if_incoming == if_incoming)) 191 continue;
177 neigh_node = tmp_neigh_node; 192
193 if (tmp_neigh_node->if_incoming != if_incoming)
194 continue;
195
196 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
197 continue;
198
199 neigh_node = tmp_neigh_node;
178 } 200 }
201 rcu_read_unlock();
179 202
180 if (!neigh_node) 203 if (!neigh_node)
181 neigh_node = create_neighbor(orig_neigh_node, 204 neigh_node = create_neighbor(orig_neigh_node,
182 orig_neigh_node, 205 orig_neigh_node,
183 orig_neigh_node->orig, 206 orig_neigh_node->orig,
184 if_incoming); 207 if_incoming);
185 /* create_neighbor failed, return 0 */
186 if (!neigh_node) 208 if (!neigh_node)
187 return 0; 209 goto out;
188 } 210 }
189 211
190 orig_node->last_valid = jiffies; 212 orig_node->last_valid = jiffies;
191 213
214 spin_lock_bh(&orig_node->ogm_cnt_lock);
215 orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num];
216 neigh_rq_count = neigh_node->real_packet_count;
217 spin_unlock_bh(&orig_node->ogm_cnt_lock);
218
192 /* pay attention to not get a value bigger than 100 % */ 219 /* pay attention to not get a value bigger than 100 % */
193 total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > 220 total_count = (orig_eq_count > neigh_rq_count ?
194 neigh_node->real_packet_count ? 221 neigh_rq_count : orig_eq_count);
195 neigh_node->real_packet_count :
196 orig_neigh_node->bcast_own_sum[if_incoming->if_num]);
197 222
198 /* if we have too few packets (too less data) we set tq_own to zero */ 223 /* if we have too few packets (too less data) we set tq_own to zero */
199 /* if we receive too few packets it is not considered bidirectional */ 224 /* if we receive too few packets it is not considered bidirectional */
200 if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || 225 if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) ||
201 (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) 226 (neigh_rq_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
202 orig_neigh_node->tq_own = 0; 227 tq_own = 0;
203 else 228 else
204 /* neigh_node->real_packet_count is never zero as we 229 /* neigh_node->real_packet_count is never zero as we
205 * only purge old information when getting new 230 * only purge old information when getting new
206 * information */ 231 * information */
207 orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / 232 tq_own = (TQ_MAX_VALUE * total_count) / neigh_rq_count;
208 neigh_node->real_packet_count;
209 233
210 /* 234 /*
211 * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does 235 * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
@@ -213,20 +237,16 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
213 * punishes asymmetric links more. This will give a value 237 * punishes asymmetric links more. This will give a value
214 * between 0 and TQ_MAX_VALUE 238 * between 0 and TQ_MAX_VALUE
215 */ 239 */
216 orig_neigh_node->tq_asym_penalty = 240 tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE *
217 TQ_MAX_VALUE - 241 (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) *
218 (TQ_MAX_VALUE * 242 (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) *
219 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * 243 (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count)) /
220 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * 244 (TQ_LOCAL_WINDOW_SIZE *
221 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) / 245 TQ_LOCAL_WINDOW_SIZE *
222 (TQ_LOCAL_WINDOW_SIZE * 246 TQ_LOCAL_WINDOW_SIZE);
223 TQ_LOCAL_WINDOW_SIZE * 247
224 TQ_LOCAL_WINDOW_SIZE); 248 batman_packet->tq = ((batman_packet->tq * tq_own * tq_asym_penalty) /
225 249 (TQ_MAX_VALUE * TQ_MAX_VALUE));
226 batman_packet->tq = ((batman_packet->tq *
227 orig_neigh_node->tq_own *
228 orig_neigh_node->tq_asym_penalty) /
229 (TQ_MAX_VALUE * TQ_MAX_VALUE));
230 250
231 bat_dbg(DBG_BATMAN, bat_priv, 251 bat_dbg(DBG_BATMAN, bat_priv,
232 "bidirectional: " 252 "bidirectional: "
@@ -234,34 +254,141 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
234 "real recv = %2i, local tq: %3i, asym_penalty: %3i, " 254 "real recv = %2i, local tq: %3i, asym_penalty: %3i, "
235 "total tq: %3i\n", 255 "total tq: %3i\n",
236 orig_node->orig, orig_neigh_node->orig, total_count, 256 orig_node->orig, orig_neigh_node->orig, total_count,
237 neigh_node->real_packet_count, orig_neigh_node->tq_own, 257 neigh_rq_count, tq_own, tq_asym_penalty, batman_packet->tq);
238 orig_neigh_node->tq_asym_penalty, batman_packet->tq);
239 258
240 /* if link has the minimum required transmission quality 259 /* if link has the minimum required transmission quality
241 * consider it bidirectional */ 260 * consider it bidirectional */
242 if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT) 261 if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
243 return 1; 262 ret = 1;
244 263
245 return 0; 264out:
265 if (neigh_node)
266 neigh_node_free_ref(neigh_node);
267 return ret;
268}
269
270/* caller must hold the neigh_list_lock */
271void bonding_candidate_del(struct orig_node *orig_node,
272 struct neigh_node *neigh_node)
273{
274 /* this neighbor is not part of our candidate list */
275 if (list_empty(&neigh_node->bonding_list))
276 goto out;
277
278 list_del_rcu(&neigh_node->bonding_list);
279 INIT_LIST_HEAD(&neigh_node->bonding_list);
280 neigh_node_free_ref(neigh_node);
281 atomic_dec(&orig_node->bond_candidates);
282
283out:
284 return;
285}
286
287static void bonding_candidate_add(struct orig_node *orig_node,
288 struct neigh_node *neigh_node)
289{
290 struct hlist_node *node;
291 struct neigh_node *tmp_neigh_node;
292 uint8_t best_tq, interference_candidate = 0;
293
294 spin_lock_bh(&orig_node->neigh_list_lock);
295
296 /* only consider if it has the same primary address ... */
297 if (!compare_eth(orig_node->orig,
298 neigh_node->orig_node->primary_addr))
299 goto candidate_del;
300
301 if (!orig_node->router)
302 goto candidate_del;
303
304 best_tq = orig_node->router->tq_avg;
305
306 /* ... and is good enough to be considered */
307 if (neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD)
308 goto candidate_del;
309
310 /**
311 * check if we have another candidate with the same mac address or
312 * interface. If we do, we won't select this candidate because of
313 * possible interference.
314 */
315 hlist_for_each_entry_rcu(tmp_neigh_node, node,
316 &orig_node->neigh_list, list) {
317
318 if (tmp_neigh_node == neigh_node)
319 continue;
320
321 /* we only care if the other candidate is even
322 * considered as candidate. */
323 if (list_empty(&tmp_neigh_node->bonding_list))
324 continue;
325
326 if ((neigh_node->if_incoming == tmp_neigh_node->if_incoming) ||
327 (compare_eth(neigh_node->addr, tmp_neigh_node->addr))) {
328 interference_candidate = 1;
329 break;
330 }
331 }
332
333 /* don't care further if it is an interference candidate */
334 if (interference_candidate)
335 goto candidate_del;
336
337 /* this neighbor already is part of our candidate list */
338 if (!list_empty(&neigh_node->bonding_list))
339 goto out;
340
341 if (!atomic_inc_not_zero(&neigh_node->refcount))
342 goto out;
343
344 list_add_rcu(&neigh_node->bonding_list, &orig_node->bond_list);
345 atomic_inc(&orig_node->bond_candidates);
346 goto out;
347
348candidate_del:
349 bonding_candidate_del(orig_node, neigh_node);
350
351out:
352 spin_unlock_bh(&orig_node->neigh_list_lock);
353 return;
354}
355
356/* copy primary address for bonding */
357static void bonding_save_primary(struct orig_node *orig_node,
358 struct orig_node *orig_neigh_node,
359 struct batman_packet *batman_packet)
360{
361 if (!(batman_packet->flags & PRIMARIES_FIRST_HOP))
362 return;
363
364 memcpy(orig_neigh_node->primary_addr, orig_node->orig, ETH_ALEN);
246} 365}
247 366
248static void update_orig(struct bat_priv *bat_priv, 367static void update_orig(struct bat_priv *bat_priv,
249 struct orig_node *orig_node, 368 struct orig_node *orig_node,
250 struct ethhdr *ethhdr, 369 struct ethhdr *ethhdr,
251 struct batman_packet *batman_packet, 370 struct batman_packet *batman_packet,
252 struct batman_if *if_incoming, 371 struct hard_iface *if_incoming,
253 unsigned char *hna_buff, int hna_buff_len, 372 unsigned char *hna_buff, int hna_buff_len,
254 char is_duplicate) 373 char is_duplicate)
255{ 374{
256 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 375 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
376 struct orig_node *orig_node_tmp;
377 struct hlist_node *node;
257 int tmp_hna_buff_len; 378 int tmp_hna_buff_len;
379 uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
258 380
259 bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): " 381 bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
260 "Searching and updating originator entry of received packet\n"); 382 "Searching and updating originator entry of received packet\n");
261 383
262 list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { 384 rcu_read_lock();
263 if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && 385 hlist_for_each_entry_rcu(tmp_neigh_node, node,
264 (tmp_neigh_node->if_incoming == if_incoming)) { 386 &orig_node->neigh_list, list) {
387 if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) &&
388 (tmp_neigh_node->if_incoming == if_incoming) &&
389 atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
390 if (neigh_node)
391 neigh_node_free_ref(neigh_node);
265 neigh_node = tmp_neigh_node; 392 neigh_node = tmp_neigh_node;
266 continue; 393 continue;
267 } 394 }
@@ -280,16 +407,20 @@ static void update_orig(struct bat_priv *bat_priv,
280 407
281 orig_tmp = get_orig_node(bat_priv, ethhdr->h_source); 408 orig_tmp = get_orig_node(bat_priv, ethhdr->h_source);
282 if (!orig_tmp) 409 if (!orig_tmp)
283 return; 410 goto unlock;
284 411
285 neigh_node = create_neighbor(orig_node, orig_tmp, 412 neigh_node = create_neighbor(orig_node, orig_tmp,
286 ethhdr->h_source, if_incoming); 413 ethhdr->h_source, if_incoming);
414
415 orig_node_free_ref(orig_tmp);
287 if (!neigh_node) 416 if (!neigh_node)
288 return; 417 goto unlock;
289 } else 418 } else
290 bat_dbg(DBG_BATMAN, bat_priv, 419 bat_dbg(DBG_BATMAN, bat_priv,
291 "Updating existing last-hop neighbor of originator\n"); 420 "Updating existing last-hop neighbor of originator\n");
292 421
422 rcu_read_unlock();
423
293 orig_node->flags = batman_packet->flags; 424 orig_node->flags = batman_packet->flags;
294 neigh_node->last_valid = jiffies; 425 neigh_node->last_valid = jiffies;
295 426
@@ -303,6 +434,8 @@ static void update_orig(struct bat_priv *bat_priv,
303 neigh_node->last_ttl = batman_packet->ttl; 434 neigh_node->last_ttl = batman_packet->ttl;
304 } 435 }
305 436
437 bonding_candidate_add(orig_node, neigh_node);
438
306 tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ? 439 tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ?
307 batman_packet->num_hna * ETH_ALEN : hna_buff_len); 440 batman_packet->num_hna * ETH_ALEN : hna_buff_len);
308 441
@@ -319,10 +452,22 @@ static void update_orig(struct bat_priv *bat_priv,
319 /* if the TQ is the same and the link not more symetric we 452 /* if the TQ is the same and the link not more symetric we
320 * won't consider it either */ 453 * won't consider it either */
321 if ((orig_node->router) && 454 if ((orig_node->router) &&
322 ((neigh_node->tq_avg == orig_node->router->tq_avg) && 455 (neigh_node->tq_avg == orig_node->router->tq_avg)) {
323 (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] 456 orig_node_tmp = orig_node->router->orig_node;
324 >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num]))) 457 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
325 goto update_hna; 458 bcast_own_sum_orig =
459 orig_node_tmp->bcast_own_sum[if_incoming->if_num];
460 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
461
462 orig_node_tmp = neigh_node->orig_node;
463 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
464 bcast_own_sum_neigh =
465 orig_node_tmp->bcast_own_sum[if_incoming->if_num];
466 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
467
468 if (bcast_own_sum_orig >= bcast_own_sum_neigh)
469 goto update_hna;
470 }
326 471
327 update_routes(bat_priv, orig_node, neigh_node, 472 update_routes(bat_priv, orig_node, neigh_node,
328 hna_buff, tmp_hna_buff_len); 473 hna_buff, tmp_hna_buff_len);
@@ -343,6 +488,14 @@ update_gw:
343 (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) && 488 (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) &&
344 (atomic_read(&bat_priv->gw_sel_class) > 2)) 489 (atomic_read(&bat_priv->gw_sel_class) > 2))
345 gw_check_election(bat_priv, orig_node); 490 gw_check_election(bat_priv, orig_node);
491
492 goto out;
493
494unlock:
495 rcu_read_unlock();
496out:
497 if (neigh_node)
498 neigh_node_free_ref(neigh_node);
346} 499}
347 500
348/* checks whether the host restarted and is in the protection time. 501/* checks whether the host restarted and is in the protection time.
@@ -380,34 +533,38 @@ static int window_protected(struct bat_priv *bat_priv,
380 */ 533 */
381static char count_real_packets(struct ethhdr *ethhdr, 534static char count_real_packets(struct ethhdr *ethhdr,
382 struct batman_packet *batman_packet, 535 struct batman_packet *batman_packet,
383 struct batman_if *if_incoming) 536 struct hard_iface *if_incoming)
384{ 537{
385 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 538 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
386 struct orig_node *orig_node; 539 struct orig_node *orig_node;
387 struct neigh_node *tmp_neigh_node; 540 struct neigh_node *tmp_neigh_node;
541 struct hlist_node *node;
388 char is_duplicate = 0; 542 char is_duplicate = 0;
389 int32_t seq_diff; 543 int32_t seq_diff;
390 int need_update = 0; 544 int need_update = 0;
391 int set_mark; 545 int set_mark, ret = -1;
392 546
393 orig_node = get_orig_node(bat_priv, batman_packet->orig); 547 orig_node = get_orig_node(bat_priv, batman_packet->orig);
394 if (!orig_node) 548 if (!orig_node)
395 return 0; 549 return 0;
396 550
551 spin_lock_bh(&orig_node->ogm_cnt_lock);
397 seq_diff = batman_packet->seqno - orig_node->last_real_seqno; 552 seq_diff = batman_packet->seqno - orig_node->last_real_seqno;
398 553
399 /* signalize caller that the packet is to be dropped. */ 554 /* signalize caller that the packet is to be dropped. */
400 if (window_protected(bat_priv, seq_diff, 555 if (window_protected(bat_priv, seq_diff,
401 &orig_node->batman_seqno_reset)) 556 &orig_node->batman_seqno_reset))
402 return -1; 557 goto out;
403 558
404 list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { 559 rcu_read_lock();
560 hlist_for_each_entry_rcu(tmp_neigh_node, node,
561 &orig_node->neigh_list, list) {
405 562
406 is_duplicate |= get_bit_status(tmp_neigh_node->real_bits, 563 is_duplicate |= get_bit_status(tmp_neigh_node->real_bits,
407 orig_node->last_real_seqno, 564 orig_node->last_real_seqno,
408 batman_packet->seqno); 565 batman_packet->seqno);
409 566
410 if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && 567 if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) &&
411 (tmp_neigh_node->if_incoming == if_incoming)) 568 (tmp_neigh_node->if_incoming == if_incoming))
412 set_mark = 1; 569 set_mark = 1;
413 else 570 else
@@ -421,6 +578,7 @@ static char count_real_packets(struct ethhdr *ethhdr,
421 tmp_neigh_node->real_packet_count = 578 tmp_neigh_node->real_packet_count =
422 bit_packet_count(tmp_neigh_node->real_bits); 579 bit_packet_count(tmp_neigh_node->real_bits);
423 } 580 }
581 rcu_read_unlock();
424 582
425 if (need_update) { 583 if (need_update) {
426 bat_dbg(DBG_BATMAN, bat_priv, 584 bat_dbg(DBG_BATMAN, bat_priv,
@@ -429,123 +587,21 @@ static char count_real_packets(struct ethhdr *ethhdr,
429 orig_node->last_real_seqno = batman_packet->seqno; 587 orig_node->last_real_seqno = batman_packet->seqno;
430 } 588 }
431 589
432 return is_duplicate; 590 ret = is_duplicate;
433}
434
435/* copy primary address for bonding */
436static void mark_bonding_address(struct bat_priv *bat_priv,
437 struct orig_node *orig_node,
438 struct orig_node *orig_neigh_node,
439 struct batman_packet *batman_packet)
440 591
441{ 592out:
442 if (batman_packet->flags & PRIMARIES_FIRST_HOP) 593 spin_unlock_bh(&orig_node->ogm_cnt_lock);
443 memcpy(orig_neigh_node->primary_addr, 594 orig_node_free_ref(orig_node);
444 orig_node->orig, ETH_ALEN); 595 return ret;
445
446 return;
447}
448
449/* mark possible bond.candidates in the neighbor list */
450void update_bonding_candidates(struct bat_priv *bat_priv,
451 struct orig_node *orig_node)
452{
453 int candidates;
454 int interference_candidate;
455 int best_tq;
456 struct neigh_node *tmp_neigh_node, *tmp_neigh_node2;
457 struct neigh_node *first_candidate, *last_candidate;
458
459 /* update the candidates for this originator */
460 if (!orig_node->router) {
461 orig_node->bond.candidates = 0;
462 return;
463 }
464
465 best_tq = orig_node->router->tq_avg;
466
467 /* update bond.candidates */
468
469 candidates = 0;
470
471 /* mark other nodes which also received "PRIMARIES FIRST HOP" packets
472 * as "bonding partner" */
473
474 /* first, zero the list */
475 list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
476 tmp_neigh_node->next_bond_candidate = NULL;
477 }
478
479 first_candidate = NULL;
480 last_candidate = NULL;
481 list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
482
483 /* only consider if it has the same primary address ... */
484 if (memcmp(orig_node->orig,
485 tmp_neigh_node->orig_node->primary_addr,
486 ETH_ALEN) != 0)
487 continue;
488
489 /* ... and is good enough to be considered */
490 if (tmp_neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD)
491 continue;
492
493 /* check if we have another candidate with the same
494 * mac address or interface. If we do, we won't
495 * select this candidate because of possible interference. */
496
497 interference_candidate = 0;
498 list_for_each_entry(tmp_neigh_node2,
499 &orig_node->neigh_list, list) {
500
501 if (tmp_neigh_node2 == tmp_neigh_node)
502 continue;
503
504 /* we only care if the other candidate is even
505 * considered as candidate. */
506 if (!tmp_neigh_node2->next_bond_candidate)
507 continue;
508
509
510 if ((tmp_neigh_node->if_incoming ==
511 tmp_neigh_node2->if_incoming)
512 || (memcmp(tmp_neigh_node->addr,
513 tmp_neigh_node2->addr, ETH_ALEN) == 0)) {
514
515 interference_candidate = 1;
516 break;
517 }
518 }
519 /* don't care further if it is an interference candidate */
520 if (interference_candidate)
521 continue;
522
523 if (!first_candidate) {
524 first_candidate = tmp_neigh_node;
525 tmp_neigh_node->next_bond_candidate = first_candidate;
526 } else
527 tmp_neigh_node->next_bond_candidate = last_candidate;
528
529 last_candidate = tmp_neigh_node;
530
531 candidates++;
532 }
533
534 if (candidates > 0) {
535 first_candidate->next_bond_candidate = last_candidate;
536 orig_node->bond.selected = first_candidate;
537 }
538
539 orig_node->bond.candidates = candidates;
540} 596}
541 597
542void receive_bat_packet(struct ethhdr *ethhdr, 598void receive_bat_packet(struct ethhdr *ethhdr,
543 struct batman_packet *batman_packet, 599 struct batman_packet *batman_packet,
544 unsigned char *hna_buff, int hna_buff_len, 600 unsigned char *hna_buff, int hna_buff_len,
545 struct batman_if *if_incoming) 601 struct hard_iface *if_incoming)
546{ 602{
547 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 603 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
548 struct batman_if *batman_if; 604 struct hard_iface *hard_iface;
549 struct orig_node *orig_neigh_node, *orig_node; 605 struct orig_node *orig_neigh_node, *orig_node;
550 char has_directlink_flag; 606 char has_directlink_flag;
551 char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; 607 char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
@@ -573,8 +629,8 @@ void receive_bat_packet(struct ethhdr *ethhdr,
573 629
574 has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0); 630 has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0);
575 631
576 is_single_hop_neigh = (compare_orig(ethhdr->h_source, 632 is_single_hop_neigh = (compare_eth(ethhdr->h_source,
577 batman_packet->orig) ? 1 : 0); 633 batman_packet->orig) ? 1 : 0);
578 634
579 bat_dbg(DBG_BATMAN, bat_priv, 635 bat_dbg(DBG_BATMAN, bat_priv,
580 "Received BATMAN packet via NB: %pM, IF: %s [%pM] " 636 "Received BATMAN packet via NB: %pM, IF: %s [%pM] "
@@ -587,26 +643,26 @@ void receive_bat_packet(struct ethhdr *ethhdr,
587 has_directlink_flag); 643 has_directlink_flag);
588 644
589 rcu_read_lock(); 645 rcu_read_lock();
590 list_for_each_entry_rcu(batman_if, &if_list, list) { 646 list_for_each_entry_rcu(hard_iface, &hardif_list, list) {
591 if (batman_if->if_status != IF_ACTIVE) 647 if (hard_iface->if_status != IF_ACTIVE)
592 continue; 648 continue;
593 649
594 if (batman_if->soft_iface != if_incoming->soft_iface) 650 if (hard_iface->soft_iface != if_incoming->soft_iface)
595 continue; 651 continue;
596 652
597 if (compare_orig(ethhdr->h_source, 653 if (compare_eth(ethhdr->h_source,
598 batman_if->net_dev->dev_addr)) 654 hard_iface->net_dev->dev_addr))
599 is_my_addr = 1; 655 is_my_addr = 1;
600 656
601 if (compare_orig(batman_packet->orig, 657 if (compare_eth(batman_packet->orig,
602 batman_if->net_dev->dev_addr)) 658 hard_iface->net_dev->dev_addr))
603 is_my_orig = 1; 659 is_my_orig = 1;
604 660
605 if (compare_orig(batman_packet->prev_sender, 661 if (compare_eth(batman_packet->prev_sender,
606 batman_if->net_dev->dev_addr)) 662 hard_iface->net_dev->dev_addr))
607 is_my_oldorig = 1; 663 is_my_oldorig = 1;
608 664
609 if (compare_orig(ethhdr->h_source, broadcast_addr)) 665 if (compare_eth(ethhdr->h_source, broadcast_addr))
610 is_broadcast = 1; 666 is_broadcast = 1;
611 } 667 }
612 rcu_read_unlock(); 668 rcu_read_unlock();
@@ -638,7 +694,6 @@ void receive_bat_packet(struct ethhdr *ethhdr,
638 int offset; 694 int offset;
639 695
640 orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source); 696 orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source);
641
642 if (!orig_neigh_node) 697 if (!orig_neigh_node)
643 return; 698 return;
644 699
@@ -647,18 +702,22 @@ void receive_bat_packet(struct ethhdr *ethhdr,
647 /* if received seqno equals last send seqno save new 702 /* if received seqno equals last send seqno save new
648 * seqno for bidirectional check */ 703 * seqno for bidirectional check */
649 if (has_directlink_flag && 704 if (has_directlink_flag &&
650 compare_orig(if_incoming->net_dev->dev_addr, 705 compare_eth(if_incoming->net_dev->dev_addr,
651 batman_packet->orig) && 706 batman_packet->orig) &&
652 (batman_packet->seqno - if_incoming_seqno + 2 == 0)) { 707 (batman_packet->seqno - if_incoming_seqno + 2 == 0)) {
653 offset = if_incoming->if_num * NUM_WORDS; 708 offset = if_incoming->if_num * NUM_WORDS;
709
710 spin_lock_bh(&orig_neigh_node->ogm_cnt_lock);
654 word = &(orig_neigh_node->bcast_own[offset]); 711 word = &(orig_neigh_node->bcast_own[offset]);
655 bit_mark(word, 0); 712 bit_mark(word, 0);
656 orig_neigh_node->bcast_own_sum[if_incoming->if_num] = 713 orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
657 bit_packet_count(word); 714 bit_packet_count(word);
715 spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock);
658 } 716 }
659 717
660 bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " 718 bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
661 "originator packet from myself (via neighbor)\n"); 719 "originator packet from myself (via neighbor)\n");
720 orig_node_free_ref(orig_neigh_node);
662 return; 721 return;
663 } 722 }
664 723
@@ -679,27 +738,27 @@ void receive_bat_packet(struct ethhdr *ethhdr,
679 bat_dbg(DBG_BATMAN, bat_priv, 738 bat_dbg(DBG_BATMAN, bat_priv,
680 "Drop packet: packet within seqno protection time " 739 "Drop packet: packet within seqno protection time "
681 "(sender: %pM)\n", ethhdr->h_source); 740 "(sender: %pM)\n", ethhdr->h_source);
682 return; 741 goto out;
683 } 742 }
684 743
685 if (batman_packet->tq == 0) { 744 if (batman_packet->tq == 0) {
686 bat_dbg(DBG_BATMAN, bat_priv, 745 bat_dbg(DBG_BATMAN, bat_priv,
687 "Drop packet: originator packet with tq equal 0\n"); 746 "Drop packet: originator packet with tq equal 0\n");
688 return; 747 goto out;
689 } 748 }
690 749
691 /* avoid temporary routing loops */ 750 /* avoid temporary routing loops */
692 if ((orig_node->router) && 751 if ((orig_node->router) &&
693 (orig_node->router->orig_node->router) && 752 (orig_node->router->orig_node->router) &&
694 (compare_orig(orig_node->router->addr, 753 (compare_eth(orig_node->router->addr,
695 batman_packet->prev_sender)) && 754 batman_packet->prev_sender)) &&
696 !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) && 755 !(compare_eth(batman_packet->orig, batman_packet->prev_sender)) &&
697 (compare_orig(orig_node->router->addr, 756 (compare_eth(orig_node->router->addr,
698 orig_node->router->orig_node->router->addr))) { 757 orig_node->router->orig_node->router->addr))) {
699 bat_dbg(DBG_BATMAN, bat_priv, 758 bat_dbg(DBG_BATMAN, bat_priv,
700 "Drop packet: ignoring all rebroadcast packets that " 759 "Drop packet: ignoring all rebroadcast packets that "
701 "may make me loop (sender: %pM)\n", ethhdr->h_source); 760 "may make me loop (sender: %pM)\n", ethhdr->h_source);
702 return; 761 goto out;
703 } 762 }
704 763
705 /* if sender is a direct neighbor the sender mac equals 764 /* if sender is a direct neighbor the sender mac equals
@@ -708,19 +767,21 @@ void receive_bat_packet(struct ethhdr *ethhdr,
708 orig_node : 767 orig_node :
709 get_orig_node(bat_priv, ethhdr->h_source)); 768 get_orig_node(bat_priv, ethhdr->h_source));
710 if (!orig_neigh_node) 769 if (!orig_neigh_node)
711 return; 770 goto out;
712 771
713 /* drop packet if sender is not a direct neighbor and if we 772 /* drop packet if sender is not a direct neighbor and if we
714 * don't route towards it */ 773 * don't route towards it */
715 if (!is_single_hop_neigh && (!orig_neigh_node->router)) { 774 if (!is_single_hop_neigh && (!orig_neigh_node->router)) {
716 bat_dbg(DBG_BATMAN, bat_priv, 775 bat_dbg(DBG_BATMAN, bat_priv,
717 "Drop packet: OGM via unknown neighbor!\n"); 776 "Drop packet: OGM via unknown neighbor!\n");
718 return; 777 goto out_neigh;
719 } 778 }
720 779
721 is_bidirectional = is_bidirectional_neigh(orig_node, orig_neigh_node, 780 is_bidirectional = is_bidirectional_neigh(orig_node, orig_neigh_node,
722 batman_packet, if_incoming); 781 batman_packet, if_incoming);
723 782
783 bonding_save_primary(orig_node, orig_neigh_node, batman_packet);
784
724 /* update ranking if it is not a duplicate or has the same 785 /* update ranking if it is not a duplicate or has the same
725 * seqno and similar ttl as the non-duplicate */ 786 * seqno and similar ttl as the non-duplicate */
726 if (is_bidirectional && 787 if (is_bidirectional &&
@@ -730,10 +791,6 @@ void receive_bat_packet(struct ethhdr *ethhdr,
730 update_orig(bat_priv, orig_node, ethhdr, batman_packet, 791 update_orig(bat_priv, orig_node, ethhdr, batman_packet,
731 if_incoming, hna_buff, hna_buff_len, is_duplicate); 792 if_incoming, hna_buff, hna_buff_len, is_duplicate);
732 793
733 mark_bonding_address(bat_priv, orig_node,
734 orig_neigh_node, batman_packet);
735 update_bonding_candidates(bat_priv, orig_node);
736
737 /* is single hop (direct) neighbor */ 794 /* is single hop (direct) neighbor */
738 if (is_single_hop_neigh) { 795 if (is_single_hop_neigh) {
739 796
@@ -743,31 +800,36 @@ void receive_bat_packet(struct ethhdr *ethhdr,
743 800
744 bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: " 801 bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
745 "rebroadcast neighbor packet with direct link flag\n"); 802 "rebroadcast neighbor packet with direct link flag\n");
746 return; 803 goto out_neigh;
747 } 804 }
748 805
749 /* multihop originator */ 806 /* multihop originator */
750 if (!is_bidirectional) { 807 if (!is_bidirectional) {
751 bat_dbg(DBG_BATMAN, bat_priv, 808 bat_dbg(DBG_BATMAN, bat_priv,
752 "Drop packet: not received via bidirectional link\n"); 809 "Drop packet: not received via bidirectional link\n");
753 return; 810 goto out_neigh;
754 } 811 }
755 812
756 if (is_duplicate) { 813 if (is_duplicate) {
757 bat_dbg(DBG_BATMAN, bat_priv, 814 bat_dbg(DBG_BATMAN, bat_priv,
758 "Drop packet: duplicate packet received\n"); 815 "Drop packet: duplicate packet received\n");
759 return; 816 goto out_neigh;
760 } 817 }
761 818
762 bat_dbg(DBG_BATMAN, bat_priv, 819 bat_dbg(DBG_BATMAN, bat_priv,
763 "Forwarding packet: rebroadcast originator packet\n"); 820 "Forwarding packet: rebroadcast originator packet\n");
764 schedule_forward_packet(orig_node, ethhdr, batman_packet, 821 schedule_forward_packet(orig_node, ethhdr, batman_packet,
765 0, hna_buff_len, if_incoming); 822 0, hna_buff_len, if_incoming);
823
824out_neigh:
825 if ((orig_neigh_node) && (!is_single_hop_neigh))
826 orig_node_free_ref(orig_neigh_node);
827out:
828 orig_node_free_ref(orig_node);
766} 829}
767 830
768int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if) 831int recv_bat_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
769{ 832{
770 struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
771 struct ethhdr *ethhdr; 833 struct ethhdr *ethhdr;
772 834
773 /* drop packet if it has not necessary minimum size */ 835 /* drop packet if it has not necessary minimum size */
@@ -794,12 +856,10 @@ int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if)
794 856
795 ethhdr = (struct ethhdr *)skb_mac_header(skb); 857 ethhdr = (struct ethhdr *)skb_mac_header(skb);
796 858
797 spin_lock_bh(&bat_priv->orig_hash_lock);
798 receive_aggr_bat_packet(ethhdr, 859 receive_aggr_bat_packet(ethhdr,
799 skb->data, 860 skb->data,
800 skb_headlen(skb), 861 skb_headlen(skb),
801 batman_if); 862 hard_iface);
802 spin_unlock_bh(&bat_priv->orig_hash_lock);
803 863
804 kfree_skb(skb); 864 kfree_skb(skb);
805 return NET_RX_SUCCESS; 865 return NET_RX_SUCCESS;
@@ -808,135 +868,144 @@ int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if)
808static int recv_my_icmp_packet(struct bat_priv *bat_priv, 868static int recv_my_icmp_packet(struct bat_priv *bat_priv,
809 struct sk_buff *skb, size_t icmp_len) 869 struct sk_buff *skb, size_t icmp_len)
810{ 870{
811 struct orig_node *orig_node; 871 struct orig_node *orig_node = NULL;
872 struct neigh_node *neigh_node = NULL;
812 struct icmp_packet_rr *icmp_packet; 873 struct icmp_packet_rr *icmp_packet;
813 struct ethhdr *ethhdr; 874 int ret = NET_RX_DROP;
814 struct batman_if *batman_if;
815 int ret;
816 uint8_t dstaddr[ETH_ALEN];
817 875
818 icmp_packet = (struct icmp_packet_rr *)skb->data; 876 icmp_packet = (struct icmp_packet_rr *)skb->data;
819 ethhdr = (struct ethhdr *)skb_mac_header(skb);
820 877
821 /* add data to device queue */ 878 /* add data to device queue */
822 if (icmp_packet->msg_type != ECHO_REQUEST) { 879 if (icmp_packet->msg_type != ECHO_REQUEST) {
823 bat_socket_receive_packet(icmp_packet, icmp_len); 880 bat_socket_receive_packet(icmp_packet, icmp_len);
824 return NET_RX_DROP; 881 goto out;
825 } 882 }
826 883
827 if (!bat_priv->primary_if) 884 if (!bat_priv->primary_if)
828 return NET_RX_DROP; 885 goto out;
829 886
830 /* answer echo request (ping) */ 887 /* answer echo request (ping) */
831 /* get routing information */ 888 /* get routing information */
832 spin_lock_bh(&bat_priv->orig_hash_lock); 889 rcu_read_lock();
833 orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, 890 orig_node = orig_hash_find(bat_priv, icmp_packet->orig);
834 compare_orig, choose_orig,
835 icmp_packet->orig));
836 ret = NET_RX_DROP;
837
838 if ((orig_node) && (orig_node->router)) {
839
840 /* don't lock while sending the packets ... we therefore
841 * copy the required data before sending */
842 batman_if = orig_node->router->if_incoming;
843 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
844 spin_unlock_bh(&bat_priv->orig_hash_lock);
845
846 /* create a copy of the skb, if needed, to modify it. */
847 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
848 return NET_RX_DROP;
849 891
850 icmp_packet = (struct icmp_packet_rr *)skb->data; 892 if (!orig_node)
851 ethhdr = (struct ethhdr *)skb_mac_header(skb); 893 goto unlock;
852 894
853 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 895 neigh_node = orig_node->router;
854 memcpy(icmp_packet->orig,
855 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
856 icmp_packet->msg_type = ECHO_REPLY;
857 icmp_packet->ttl = TTL;
858 896
859 send_skb_packet(skb, batman_if, dstaddr); 897 if (!neigh_node)
860 ret = NET_RX_SUCCESS; 898 goto unlock;
861 899
862 } else 900 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
863 spin_unlock_bh(&bat_priv->orig_hash_lock); 901 neigh_node = NULL;
902 goto unlock;
903 }
904
905 rcu_read_unlock();
906
907 /* create a copy of the skb, if needed, to modify it. */
908 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
909 goto out;
910
911 icmp_packet = (struct icmp_packet_rr *)skb->data;
912
913 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
914 memcpy(icmp_packet->orig,
915 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
916 icmp_packet->msg_type = ECHO_REPLY;
917 icmp_packet->ttl = TTL;
864 918
919 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
920 ret = NET_RX_SUCCESS;
921 goto out;
922
923unlock:
924 rcu_read_unlock();
925out:
926 if (neigh_node)
927 neigh_node_free_ref(neigh_node);
928 if (orig_node)
929 orig_node_free_ref(orig_node);
865 return ret; 930 return ret;
866} 931}
867 932
868static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, 933static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
869 struct sk_buff *skb, size_t icmp_len) 934 struct sk_buff *skb)
870{ 935{
871 struct orig_node *orig_node; 936 struct orig_node *orig_node = NULL;
937 struct neigh_node *neigh_node = NULL;
872 struct icmp_packet *icmp_packet; 938 struct icmp_packet *icmp_packet;
873 struct ethhdr *ethhdr; 939 int ret = NET_RX_DROP;
874 struct batman_if *batman_if;
875 int ret;
876 uint8_t dstaddr[ETH_ALEN];
877 940
878 icmp_packet = (struct icmp_packet *)skb->data; 941 icmp_packet = (struct icmp_packet *)skb->data;
879 ethhdr = (struct ethhdr *)skb_mac_header(skb);
880 942
881 /* send TTL exceeded if packet is an echo request (traceroute) */ 943 /* send TTL exceeded if packet is an echo request (traceroute) */
882 if (icmp_packet->msg_type != ECHO_REQUEST) { 944 if (icmp_packet->msg_type != ECHO_REQUEST) {
883 pr_debug("Warning - can't forward icmp packet from %pM to " 945 pr_debug("Warning - can't forward icmp packet from %pM to "
884 "%pM: ttl exceeded\n", icmp_packet->orig, 946 "%pM: ttl exceeded\n", icmp_packet->orig,
885 icmp_packet->dst); 947 icmp_packet->dst);
886 return NET_RX_DROP; 948 goto out;
887 } 949 }
888 950
889 if (!bat_priv->primary_if) 951 if (!bat_priv->primary_if)
890 return NET_RX_DROP; 952 goto out;
891 953
892 /* get routing information */ 954 /* get routing information */
893 spin_lock_bh(&bat_priv->orig_hash_lock); 955 rcu_read_lock();
894 orig_node = ((struct orig_node *) 956 orig_node = orig_hash_find(bat_priv, icmp_packet->orig);
895 hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
896 icmp_packet->orig));
897 ret = NET_RX_DROP;
898
899 if ((orig_node) && (orig_node->router)) {
900
901 /* don't lock while sending the packets ... we therefore
902 * copy the required data before sending */
903 batman_if = orig_node->router->if_incoming;
904 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
905 spin_unlock_bh(&bat_priv->orig_hash_lock);
906
907 /* create a copy of the skb, if needed, to modify it. */
908 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
909 return NET_RX_DROP;
910 957
911 icmp_packet = (struct icmp_packet *) skb->data; 958 if (!orig_node)
912 ethhdr = (struct ethhdr *)skb_mac_header(skb); 959 goto unlock;
913 960
914 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 961 neigh_node = orig_node->router;
915 memcpy(icmp_packet->orig,
916 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
917 icmp_packet->msg_type = TTL_EXCEEDED;
918 icmp_packet->ttl = TTL;
919 962
920 send_skb_packet(skb, batman_if, dstaddr); 963 if (!neigh_node)
921 ret = NET_RX_SUCCESS; 964 goto unlock;
922 965
923 } else 966 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
924 spin_unlock_bh(&bat_priv->orig_hash_lock); 967 neigh_node = NULL;
968 goto unlock;
969 }
925 970
971 rcu_read_unlock();
972
973 /* create a copy of the skb, if needed, to modify it. */
974 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
975 goto out;
976
977 icmp_packet = (struct icmp_packet *)skb->data;
978
979 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
980 memcpy(icmp_packet->orig,
981 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
982 icmp_packet->msg_type = TTL_EXCEEDED;
983 icmp_packet->ttl = TTL;
984
985 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
986 ret = NET_RX_SUCCESS;
987 goto out;
988
989unlock:
990 rcu_read_unlock();
991out:
992 if (neigh_node)
993 neigh_node_free_ref(neigh_node);
994 if (orig_node)
995 orig_node_free_ref(orig_node);
926 return ret; 996 return ret;
927} 997}
928 998
929 999
930int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) 1000int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
931{ 1001{
932 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); 1002 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
933 struct icmp_packet_rr *icmp_packet; 1003 struct icmp_packet_rr *icmp_packet;
934 struct ethhdr *ethhdr; 1004 struct ethhdr *ethhdr;
935 struct orig_node *orig_node; 1005 struct orig_node *orig_node = NULL;
936 struct batman_if *batman_if; 1006 struct neigh_node *neigh_node = NULL;
937 int hdr_size = sizeof(struct icmp_packet); 1007 int hdr_size = sizeof(struct icmp_packet);
938 int ret; 1008 int ret = NET_RX_DROP;
939 uint8_t dstaddr[ETH_ALEN];
940 1009
941 /** 1010 /**
942 * we truncate all incoming icmp packets if they don't match our size 1011 * we truncate all incoming icmp packets if they don't match our size
@@ -946,21 +1015,21 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if)
946 1015
947 /* drop packet if it has not necessary minimum size */ 1016 /* drop packet if it has not necessary minimum size */
948 if (unlikely(!pskb_may_pull(skb, hdr_size))) 1017 if (unlikely(!pskb_may_pull(skb, hdr_size)))
949 return NET_RX_DROP; 1018 goto out;
950 1019
951 ethhdr = (struct ethhdr *)skb_mac_header(skb); 1020 ethhdr = (struct ethhdr *)skb_mac_header(skb);
952 1021
953 /* packet with unicast indication but broadcast recipient */ 1022 /* packet with unicast indication but broadcast recipient */
954 if (is_broadcast_ether_addr(ethhdr->h_dest)) 1023 if (is_broadcast_ether_addr(ethhdr->h_dest))
955 return NET_RX_DROP; 1024 goto out;
956 1025
957 /* packet with broadcast sender address */ 1026 /* packet with broadcast sender address */
958 if (is_broadcast_ether_addr(ethhdr->h_source)) 1027 if (is_broadcast_ether_addr(ethhdr->h_source))
959 return NET_RX_DROP; 1028 goto out;
960 1029
961 /* not for me */ 1030 /* not for me */
962 if (!is_my_mac(ethhdr->h_dest)) 1031 if (!is_my_mac(ethhdr->h_dest))
963 return NET_RX_DROP; 1032 goto out;
964 1033
965 icmp_packet = (struct icmp_packet_rr *)skb->data; 1034 icmp_packet = (struct icmp_packet_rr *)skb->data;
966 1035
@@ -978,53 +1047,61 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if)
978 1047
979 /* TTL exceeded */ 1048 /* TTL exceeded */
980 if (icmp_packet->ttl < 2) 1049 if (icmp_packet->ttl < 2)
981 return recv_icmp_ttl_exceeded(bat_priv, skb, hdr_size); 1050 return recv_icmp_ttl_exceeded(bat_priv, skb);
982
983 ret = NET_RX_DROP;
984 1051
985 /* get routing information */ 1052 /* get routing information */
986 spin_lock_bh(&bat_priv->orig_hash_lock); 1053 rcu_read_lock();
987 orig_node = ((struct orig_node *) 1054 orig_node = orig_hash_find(bat_priv, icmp_packet->dst);
988 hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
989 icmp_packet->dst));
990 1055
991 if ((orig_node) && (orig_node->router)) { 1056 if (!orig_node)
1057 goto unlock;
992 1058
993 /* don't lock while sending the packets ... we therefore 1059 neigh_node = orig_node->router;
994 * copy the required data before sending */
995 batman_if = orig_node->router->if_incoming;
996 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
997 spin_unlock_bh(&bat_priv->orig_hash_lock);
998 1060
999 /* create a copy of the skb, if needed, to modify it. */ 1061 if (!neigh_node)
1000 if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 1062 goto unlock;
1001 return NET_RX_DROP;
1002 1063
1003 icmp_packet = (struct icmp_packet_rr *)skb->data; 1064 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
1004 ethhdr = (struct ethhdr *)skb_mac_header(skb); 1065 neigh_node = NULL;
1066 goto unlock;
1067 }
1005 1068
1006 /* decrement ttl */ 1069 rcu_read_unlock();
1007 icmp_packet->ttl--;
1008 1070
1009 /* route it */ 1071 /* create a copy of the skb, if needed, to modify it. */
1010 send_skb_packet(skb, batman_if, dstaddr); 1072 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
1011 ret = NET_RX_SUCCESS; 1073 goto out;
1012 1074
1013 } else 1075 icmp_packet = (struct icmp_packet_rr *)skb->data;
1014 spin_unlock_bh(&bat_priv->orig_hash_lock); 1076
1077 /* decrement ttl */
1078 icmp_packet->ttl--;
1015 1079
1080 /* route it */
1081 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1082 ret = NET_RX_SUCCESS;
1083 goto out;
1084
1085unlock:
1086 rcu_read_unlock();
1087out:
1088 if (neigh_node)
1089 neigh_node_free_ref(neigh_node);
1090 if (orig_node)
1091 orig_node_free_ref(orig_node);
1016 return ret; 1092 return ret;
1017} 1093}
1018 1094
1019/* find a suitable router for this originator, and use 1095/* find a suitable router for this originator, and use
1020 * bonding if possible. */ 1096 * bonding if possible. increases the found neighbors
1097 * refcount.*/
1021struct neigh_node *find_router(struct bat_priv *bat_priv, 1098struct neigh_node *find_router(struct bat_priv *bat_priv,
1022 struct orig_node *orig_node, 1099 struct orig_node *orig_node,
1023 struct batman_if *recv_if) 1100 struct hard_iface *recv_if)
1024{ 1101{
1025 struct orig_node *primary_orig_node; 1102 struct orig_node *primary_orig_node;
1026 struct orig_node *router_orig; 1103 struct orig_node *router_orig;
1027 struct neigh_node *router, *first_candidate, *best_router; 1104 struct neigh_node *router, *first_candidate, *tmp_neigh_node;
1028 static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; 1105 static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
1029 int bonding_enabled; 1106 int bonding_enabled;
1030 1107
@@ -1036,78 +1113,128 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
1036 1113
1037 /* without bonding, the first node should 1114 /* without bonding, the first node should
1038 * always choose the default router. */ 1115 * always choose the default router. */
1039
1040 bonding_enabled = atomic_read(&bat_priv->bonding); 1116 bonding_enabled = atomic_read(&bat_priv->bonding);
1041 1117
1042 if ((!recv_if) && (!bonding_enabled)) 1118 rcu_read_lock();
1043 return orig_node->router; 1119 /* select default router to output */
1044 1120 router = orig_node->router;
1045 router_orig = orig_node->router->orig_node; 1121 router_orig = orig_node->router->orig_node;
1122 if (!router_orig || !atomic_inc_not_zero(&router->refcount)) {
1123 rcu_read_unlock();
1124 return NULL;
1125 }
1126
1127 if ((!recv_if) && (!bonding_enabled))
1128 goto return_router;
1046 1129
1047 /* if we have something in the primary_addr, we can search 1130 /* if we have something in the primary_addr, we can search
1048 * for a potential bonding candidate. */ 1131 * for a potential bonding candidate. */
1049 if (memcmp(router_orig->primary_addr, zero_mac, ETH_ALEN) == 0) 1132 if (compare_eth(router_orig->primary_addr, zero_mac))
1050 return orig_node->router; 1133 goto return_router;
1051 1134
1052 /* find the orig_node which has the primary interface. might 1135 /* find the orig_node which has the primary interface. might
1053 * even be the same as our router_orig in many cases */ 1136 * even be the same as our router_orig in many cases */
1054 1137
1055 if (memcmp(router_orig->primary_addr, 1138 if (compare_eth(router_orig->primary_addr, router_orig->orig)) {
1056 router_orig->orig, ETH_ALEN) == 0) {
1057 primary_orig_node = router_orig; 1139 primary_orig_node = router_orig;
1058 } else { 1140 } else {
1059 primary_orig_node = hash_find(bat_priv->orig_hash, compare_orig, 1141 primary_orig_node = orig_hash_find(bat_priv,
1060 choose_orig, 1142 router_orig->primary_addr);
1061 router_orig->primary_addr);
1062
1063 if (!primary_orig_node) 1143 if (!primary_orig_node)
1064 return orig_node->router; 1144 goto return_router;
1145
1146 orig_node_free_ref(primary_orig_node);
1065 } 1147 }
1066 1148
1067 /* with less than 2 candidates, we can't do any 1149 /* with less than 2 candidates, we can't do any
1068 * bonding and prefer the original router. */ 1150 * bonding and prefer the original router. */
1069 1151 if (atomic_read(&primary_orig_node->bond_candidates) < 2)
1070 if (primary_orig_node->bond.candidates < 2) 1152 goto return_router;
1071 return orig_node->router;
1072 1153
1073 1154
1074 /* all nodes between should choose a candidate which 1155 /* all nodes between should choose a candidate which
1075 * is is not on the interface where the packet came 1156 * is is not on the interface where the packet came
1076 * in. */ 1157 * in. */
1077 first_candidate = primary_orig_node->bond.selected; 1158
1078 router = first_candidate; 1159 neigh_node_free_ref(router);
1160 first_candidate = NULL;
1161 router = NULL;
1079 1162
1080 if (bonding_enabled) { 1163 if (bonding_enabled) {
1081 /* in the bonding case, send the packets in a round 1164 /* in the bonding case, send the packets in a round
1082 * robin fashion over the remaining interfaces. */ 1165 * robin fashion over the remaining interfaces. */
1083 do { 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;
1084 /* recv_if == NULL on the first node. */ 1171 /* recv_if == NULL on the first node. */
1085 if (router->if_incoming != recv_if) 1172 if (tmp_neigh_node->if_incoming != recv_if &&
1173 atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
1174 router = tmp_neigh_node;
1086 break; 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;
1087 1183
1088 router = router->next_bond_candidate; 1184 if (!router) {
1089 } while (router != first_candidate); 1185 rcu_read_unlock();
1186 return NULL;
1187 }
1090 1188
1091 primary_orig_node->bond.selected = router->next_bond_candidate; 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);
1092 1198
1093 } else { 1199 } else {
1094 /* if bonding is disabled, use the best of the 1200 /* if bonding is disabled, use the best of the
1095 * remaining candidates which are not using 1201 * remaining candidates which are not using
1096 * this interface. */ 1202 * this interface. */
1097 best_router = first_candidate; 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;
1098 1207
1099 do {
1100 /* recv_if == NULL on the first node. */ 1208 /* recv_if == NULL on the first node. */
1101 if ((router->if_incoming != recv_if) && 1209 if (tmp_neigh_node->if_incoming == recv_if)
1102 (router->tq_avg > best_router->tq_avg)) 1210 continue;
1103 best_router = router;
1104 1211
1105 router = router->next_bond_candidate; 1212 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
1106 } while (router != first_candidate); 1213 continue;
1107 1214
1108 router = best_router; 1215 /* if we don't have a router yet
1109 } 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 }
1110 1230
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:
1237 rcu_read_unlock();
1111 return router; 1238 return router;
1112} 1239}
1113 1240
@@ -1136,17 +1263,14 @@ static int check_unicast_packet(struct sk_buff *skb, int hdr_size)
1136 return 0; 1263 return 0;
1137} 1264}
1138 1265
1139int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, 1266int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1140 int hdr_size)
1141{ 1267{
1142 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); 1268 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1143 struct orig_node *orig_node; 1269 struct orig_node *orig_node = NULL;
1144 struct neigh_node *router; 1270 struct neigh_node *neigh_node = NULL;
1145 struct batman_if *batman_if;
1146 uint8_t dstaddr[ETH_ALEN];
1147 struct unicast_packet *unicast_packet; 1271 struct unicast_packet *unicast_packet;
1148 struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); 1272 struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
1149 int ret; 1273 int ret = NET_RX_DROP;
1150 struct sk_buff *new_skb; 1274 struct sk_buff *new_skb;
1151 1275
1152 unicast_packet = (struct unicast_packet *)skb->data; 1276 unicast_packet = (struct unicast_packet *)skb->data;
@@ -1156,53 +1280,51 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if,
1156 pr_debug("Warning - can't forward unicast packet from %pM to " 1280 pr_debug("Warning - can't forward unicast packet from %pM to "
1157 "%pM: ttl exceeded\n", ethhdr->h_source, 1281 "%pM: ttl exceeded\n", ethhdr->h_source,
1158 unicast_packet->dest); 1282 unicast_packet->dest);
1159 return NET_RX_DROP; 1283 goto out;
1160 } 1284 }
1161 1285
1162 /* get routing information */ 1286 /* get routing information */
1163 spin_lock_bh(&bat_priv->orig_hash_lock); 1287 rcu_read_lock();
1164 orig_node = ((struct orig_node *) 1288 orig_node = orig_hash_find(bat_priv, unicast_packet->dest);
1165 hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
1166 unicast_packet->dest));
1167
1168 router = find_router(bat_priv, orig_node, recv_if);
1169 1289
1170 if (!router) { 1290 if (!orig_node)
1171 spin_unlock_bh(&bat_priv->orig_hash_lock); 1291 goto unlock;
1172 return NET_RX_DROP;
1173 }
1174 1292
1175 /* don't lock while sending the packets ... we therefore 1293 rcu_read_unlock();
1176 * copy the required data before sending */
1177 1294
1178 batman_if = router->if_incoming; 1295 /* find_router() increases neigh_nodes refcount if found. */
1179 memcpy(dstaddr, router->addr, ETH_ALEN); 1296 neigh_node = find_router(bat_priv, orig_node, recv_if);
1180 1297
1181 spin_unlock_bh(&bat_priv->orig_hash_lock); 1298 if (!neigh_node)
1299 goto out;
1182 1300
1183 /* create a copy of the skb, if needed, to modify it. */ 1301 /* create a copy of the skb, if needed, to modify it. */
1184 if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 1302 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
1185 return NET_RX_DROP; 1303 goto out;
1186 1304
1187 unicast_packet = (struct unicast_packet *)skb->data; 1305 unicast_packet = (struct unicast_packet *)skb->data;
1188 1306
1189 if (unicast_packet->packet_type == BAT_UNICAST && 1307 if (unicast_packet->packet_type == BAT_UNICAST &&
1190 atomic_read(&bat_priv->fragmentation) && 1308 atomic_read(&bat_priv->fragmentation) &&
1191 skb->len > batman_if->net_dev->mtu) 1309 skb->len > neigh_node->if_incoming->net_dev->mtu) {
1192 return frag_send_skb(skb, bat_priv, batman_if, 1310 ret = frag_send_skb(skb, bat_priv,
1193 dstaddr); 1311 neigh_node->if_incoming, neigh_node->addr);
1312 goto out;
1313 }
1194 1314
1195 if (unicast_packet->packet_type == BAT_UNICAST_FRAG && 1315 if (unicast_packet->packet_type == BAT_UNICAST_FRAG &&
1196 2 * skb->len - hdr_size <= batman_if->net_dev->mtu) { 1316 frag_can_reassemble(skb, neigh_node->if_incoming->net_dev->mtu)) {
1197 1317
1198 ret = frag_reassemble_skb(skb, bat_priv, &new_skb); 1318 ret = frag_reassemble_skb(skb, bat_priv, &new_skb);
1199 1319
1200 if (ret == NET_RX_DROP) 1320 if (ret == NET_RX_DROP)
1201 return NET_RX_DROP; 1321 goto out;
1202 1322
1203 /* packet was buffered for late merge */ 1323 /* packet was buffered for late merge */
1204 if (!new_skb) 1324 if (!new_skb) {
1205 return NET_RX_SUCCESS; 1325 ret = NET_RX_SUCCESS;
1326 goto out;
1327 }
1206 1328
1207 skb = new_skb; 1329 skb = new_skb;
1208 unicast_packet = (struct unicast_packet *)skb->data; 1330 unicast_packet = (struct unicast_packet *)skb->data;
@@ -1212,12 +1334,21 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if,
1212 unicast_packet->ttl--; 1334 unicast_packet->ttl--;
1213 1335
1214 /* route it */ 1336 /* route it */
1215 send_skb_packet(skb, batman_if, dstaddr); 1337 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1338 ret = NET_RX_SUCCESS;
1339 goto out;
1216 1340
1217 return NET_RX_SUCCESS; 1341unlock:
1342 rcu_read_unlock();
1343out:
1344 if (neigh_node)
1345 neigh_node_free_ref(neigh_node);
1346 if (orig_node)
1347 orig_node_free_ref(orig_node);
1348 return ret;
1218} 1349}
1219 1350
1220int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if) 1351int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1221{ 1352{
1222 struct unicast_packet *unicast_packet; 1353 struct unicast_packet *unicast_packet;
1223 int hdr_size = sizeof(struct unicast_packet); 1354 int hdr_size = sizeof(struct unicast_packet);
@@ -1233,10 +1364,10 @@ int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
1233 return NET_RX_SUCCESS; 1364 return NET_RX_SUCCESS;
1234 } 1365 }
1235 1366
1236 return route_unicast_packet(skb, recv_if, hdr_size); 1367 return route_unicast_packet(skb, recv_if);
1237} 1368}
1238 1369
1239int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if) 1370int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1240{ 1371{
1241 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); 1372 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1242 struct unicast_frag_packet *unicast_packet; 1373 struct unicast_frag_packet *unicast_packet;
@@ -1266,89 +1397,96 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if)
1266 return NET_RX_SUCCESS; 1397 return NET_RX_SUCCESS;
1267 } 1398 }
1268 1399
1269 return route_unicast_packet(skb, recv_if, hdr_size); 1400 return route_unicast_packet(skb, recv_if);
1270} 1401}
1271 1402
1272 1403
1273int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) 1404int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1274{ 1405{
1275 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); 1406 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1276 struct orig_node *orig_node; 1407 struct orig_node *orig_node = NULL;
1277 struct bcast_packet *bcast_packet; 1408 struct bcast_packet *bcast_packet;
1278 struct ethhdr *ethhdr; 1409 struct ethhdr *ethhdr;
1279 int hdr_size = sizeof(struct bcast_packet); 1410 int hdr_size = sizeof(struct bcast_packet);
1411 int ret = NET_RX_DROP;
1280 int32_t seq_diff; 1412 int32_t seq_diff;
1281 1413
1282 /* drop packet if it has not necessary minimum size */ 1414 /* drop packet if it has not necessary minimum size */
1283 if (unlikely(!pskb_may_pull(skb, hdr_size))) 1415 if (unlikely(!pskb_may_pull(skb, hdr_size)))
1284 return NET_RX_DROP; 1416 goto out;
1285 1417
1286 ethhdr = (struct ethhdr *)skb_mac_header(skb); 1418 ethhdr = (struct ethhdr *)skb_mac_header(skb);
1287 1419
1288 /* packet with broadcast indication but unicast recipient */ 1420 /* packet with broadcast indication but unicast recipient */
1289 if (!is_broadcast_ether_addr(ethhdr->h_dest)) 1421 if (!is_broadcast_ether_addr(ethhdr->h_dest))
1290 return NET_RX_DROP; 1422 goto out;
1291 1423
1292 /* packet with broadcast sender address */ 1424 /* packet with broadcast sender address */
1293 if (is_broadcast_ether_addr(ethhdr->h_source)) 1425 if (is_broadcast_ether_addr(ethhdr->h_source))
1294 return NET_RX_DROP; 1426 goto out;
1295 1427
1296 /* ignore broadcasts sent by myself */ 1428 /* ignore broadcasts sent by myself */
1297 if (is_my_mac(ethhdr->h_source)) 1429 if (is_my_mac(ethhdr->h_source))
1298 return NET_RX_DROP; 1430 goto out;
1299 1431
1300 bcast_packet = (struct bcast_packet *)skb->data; 1432 bcast_packet = (struct bcast_packet *)skb->data;
1301 1433
1302 /* ignore broadcasts originated by myself */ 1434 /* ignore broadcasts originated by myself */
1303 if (is_my_mac(bcast_packet->orig)) 1435 if (is_my_mac(bcast_packet->orig))
1304 return NET_RX_DROP; 1436 goto out;
1305 1437
1306 if (bcast_packet->ttl < 2) 1438 if (bcast_packet->ttl < 2)
1307 return NET_RX_DROP; 1439 goto out;
1308 1440
1309 spin_lock_bh(&bat_priv->orig_hash_lock); 1441 rcu_read_lock();
1310 orig_node = ((struct orig_node *) 1442 orig_node = orig_hash_find(bat_priv, bcast_packet->orig);
1311 hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
1312 bcast_packet->orig));
1313 1443
1314 if (!orig_node) { 1444 if (!orig_node)
1315 spin_unlock_bh(&bat_priv->orig_hash_lock); 1445 goto rcu_unlock;
1316 return NET_RX_DROP; 1446
1317 } 1447 rcu_read_unlock();
1448
1449 spin_lock_bh(&orig_node->bcast_seqno_lock);
1318 1450
1319 /* check whether the packet is a duplicate */ 1451 /* check whether the packet is a duplicate */
1320 if (get_bit_status(orig_node->bcast_bits, 1452 if (get_bit_status(orig_node->bcast_bits, orig_node->last_bcast_seqno,
1321 orig_node->last_bcast_seqno, 1453 ntohl(bcast_packet->seqno)))
1322 ntohl(bcast_packet->seqno))) { 1454 goto spin_unlock;
1323 spin_unlock_bh(&bat_priv->orig_hash_lock);
1324 return NET_RX_DROP;
1325 }
1326 1455
1327 seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno; 1456 seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno;
1328 1457
1329 /* check whether the packet is old and the host just restarted. */ 1458 /* check whether the packet is old and the host just restarted. */
1330 if (window_protected(bat_priv, seq_diff, 1459 if (window_protected(bat_priv, seq_diff,
1331 &orig_node->bcast_seqno_reset)) { 1460 &orig_node->bcast_seqno_reset))
1332 spin_unlock_bh(&bat_priv->orig_hash_lock); 1461 goto spin_unlock;
1333 return NET_RX_DROP;
1334 }
1335 1462
1336 /* mark broadcast in flood history, update window position 1463 /* mark broadcast in flood history, update window position
1337 * if required. */ 1464 * if required. */
1338 if (bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1)) 1465 if (bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1))
1339 orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno); 1466 orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno);
1340 1467
1341 spin_unlock_bh(&bat_priv->orig_hash_lock); 1468 spin_unlock_bh(&orig_node->bcast_seqno_lock);
1469
1342 /* rebroadcast packet */ 1470 /* rebroadcast packet */
1343 add_bcast_packet_to_list(bat_priv, skb); 1471 add_bcast_packet_to_list(bat_priv, skb);
1344 1472
1345 /* broadcast for me */ 1473 /* broadcast for me */
1346 interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); 1474 interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size);
1475 ret = NET_RX_SUCCESS;
1476 goto out;
1347 1477
1348 return NET_RX_SUCCESS; 1478rcu_unlock:
1479 rcu_read_unlock();
1480 goto out;
1481spin_unlock:
1482 spin_unlock_bh(&orig_node->bcast_seqno_lock);
1483out:
1484 if (orig_node)
1485 orig_node_free_ref(orig_node);
1486 return ret;
1349} 1487}
1350 1488
1351int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if) 1489int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1352{ 1490{
1353 struct vis_packet *vis_packet; 1491 struct vis_packet *vis_packet;
1354 struct ethhdr *ethhdr; 1492 struct ethhdr *ethhdr;