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