batman-adv: convert neighbor list to hlist
[deliverable/linux.git] / net / batman-adv / routing.c
CommitLineData
c6c8fea2 1/*
64afe353 2 * Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
c6c8fea2
SE
3 *
4 * Marek Lindner, Simon Wunderlich
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA
19 *
20 */
21
22#include "main.h"
23#include "routing.h"
24#include "send.h"
25#include "hash.h"
26#include "soft-interface.h"
27#include "hard-interface.h"
28#include "icmp_socket.h"
29#include "translation-table.h"
30#include "originator.h"
c6c8fea2
SE
31#include "ring_buffer.h"
32#include "vis.h"
33#include "aggregation.h"
34#include "gateway_common.h"
35#include "gateway_client.h"
36#include "unicast.h"
37
38void slide_own_bcast_window(struct batman_if *batman_if)
39{
40 struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
41 struct hashtable_t *hash = bat_priv->orig_hash;
42 struct hlist_node *walk;
43 struct hlist_head *head;
44 struct element_t *bucket;
45 struct orig_node *orig_node;
46 unsigned long *word;
47 int i;
48 size_t word_index;
49
50 spin_lock_bh(&bat_priv->orig_hash_lock);
51
52 for (i = 0; i < hash->size; i++) {
53 head = &hash->table[i];
54
55 hlist_for_each_entry(bucket, walk, head, hlist) {
56 orig_node = bucket->data;
57 word_index = batman_if->if_num * NUM_WORDS;
58 word = &(orig_node->bcast_own[word_index]);
59
60 bit_get_packet(bat_priv, word, 1, 0);
61 orig_node->bcast_own_sum[batman_if->if_num] =
62 bit_packet_count(word);
63 }
64 }
65
66 spin_unlock_bh(&bat_priv->orig_hash_lock);
67}
68
69static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node,
70 unsigned char *hna_buff, int hna_buff_len)
71{
72 if ((hna_buff_len != orig_node->hna_buff_len) ||
73 ((hna_buff_len > 0) &&
74 (orig_node->hna_buff_len > 0) &&
75 (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) {
76
77 if (orig_node->hna_buff_len > 0)
78 hna_global_del_orig(bat_priv, orig_node,
79 "originator changed hna");
80
81 if ((hna_buff_len > 0) && (hna_buff))
82 hna_global_add_orig(bat_priv, orig_node,
83 hna_buff, hna_buff_len);
84 }
85}
86
87static void update_route(struct bat_priv *bat_priv,
88 struct orig_node *orig_node,
89 struct neigh_node *neigh_node,
90 unsigned char *hna_buff, int hna_buff_len)
91{
a8e7f4bc
ML
92 struct neigh_node *neigh_node_tmp;
93
c6c8fea2
SE
94 /* route deleted */
95 if ((orig_node->router) && (!neigh_node)) {
96
97 bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n",
98 orig_node->orig);
99 hna_global_del_orig(bat_priv, orig_node,
100 "originator timed out");
101
102 /* route added */
103 } else if ((!orig_node->router) && (neigh_node)) {
104
105 bat_dbg(DBG_ROUTES, bat_priv,
106 "Adding route towards: %pM (via %pM)\n",
107 orig_node->orig, neigh_node->addr);
108 hna_global_add_orig(bat_priv, orig_node,
109 hna_buff, hna_buff_len);
110
111 /* route changed */
112 } else {
113 bat_dbg(DBG_ROUTES, bat_priv,
114 "Changing route towards: %pM "
115 "(now via %pM - was via %pM)\n",
116 orig_node->orig, neigh_node->addr,
117 orig_node->router->addr);
118 }
119
a8e7f4bc
ML
120 if (neigh_node)
121 kref_get(&neigh_node->refcount);
122 neigh_node_tmp = orig_node->router;
c6c8fea2 123 orig_node->router = neigh_node;
a8e7f4bc
ML
124 if (neigh_node_tmp)
125 kref_put(&neigh_node_tmp->refcount, neigh_node_free_ref);
c6c8fea2
SE
126}
127
128
129void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
130 struct neigh_node *neigh_node, unsigned char *hna_buff,
131 int hna_buff_len)
132{
133
134 if (!orig_node)
135 return;
136
137 if (orig_node->router != neigh_node)
138 update_route(bat_priv, orig_node, neigh_node,
139 hna_buff, hna_buff_len);
140 /* may be just HNA changed */
141 else
142 update_HNA(bat_priv, orig_node, hna_buff, hna_buff_len);
143}
144
145static int is_bidirectional_neigh(struct orig_node *orig_node,
146 struct orig_node *orig_neigh_node,
147 struct batman_packet *batman_packet,
148 struct batman_if *if_incoming)
149{
150 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
151 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
9591a79f 152 struct hlist_node *node;
c6c8fea2
SE
153 unsigned char total_count;
154
155 if (orig_node == orig_neigh_node) {
9591a79f
ML
156 hlist_for_each_entry(tmp_neigh_node, node,
157 &orig_node->neigh_list, list) {
c6c8fea2
SE
158
159 if (compare_orig(tmp_neigh_node->addr,
160 orig_neigh_node->orig) &&
161 (tmp_neigh_node->if_incoming == if_incoming))
162 neigh_node = tmp_neigh_node;
163 }
164
165 if (!neigh_node)
166 neigh_node = create_neighbor(orig_node,
167 orig_neigh_node,
168 orig_neigh_node->orig,
169 if_incoming);
170 /* create_neighbor failed, return 0 */
171 if (!neigh_node)
172 return 0;
173
174 neigh_node->last_valid = jiffies;
175 } else {
176 /* find packet count of corresponding one hop neighbor */
9591a79f
ML
177 hlist_for_each_entry(tmp_neigh_node, node,
178 &orig_neigh_node->neigh_list, list) {
c6c8fea2
SE
179
180 if (compare_orig(tmp_neigh_node->addr,
181 orig_neigh_node->orig) &&
182 (tmp_neigh_node->if_incoming == if_incoming))
183 neigh_node = tmp_neigh_node;
184 }
185
186 if (!neigh_node)
187 neigh_node = create_neighbor(orig_neigh_node,
188 orig_neigh_node,
189 orig_neigh_node->orig,
190 if_incoming);
191 /* create_neighbor failed, return 0 */
192 if (!neigh_node)
193 return 0;
194 }
195
196 orig_node->last_valid = jiffies;
197
198 /* pay attention to not get a value bigger than 100 % */
199 total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] >
200 neigh_node->real_packet_count ?
201 neigh_node->real_packet_count :
202 orig_neigh_node->bcast_own_sum[if_incoming->if_num]);
203
204 /* if we have too few packets (too less data) we set tq_own to zero */
205 /* if we receive too few packets it is not considered bidirectional */
206 if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) ||
207 (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
208 orig_neigh_node->tq_own = 0;
209 else
210 /* neigh_node->real_packet_count is never zero as we
211 * only purge old information when getting new
212 * information */
213 orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) /
214 neigh_node->real_packet_count;
215
216 /*
217 * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
218 * affect the nearly-symmetric links only a little, but
219 * punishes asymmetric links more. This will give a value
220 * between 0 and TQ_MAX_VALUE
221 */
222 orig_neigh_node->tq_asym_penalty =
223 TQ_MAX_VALUE -
224 (TQ_MAX_VALUE *
225 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
226 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
227 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) /
228 (TQ_LOCAL_WINDOW_SIZE *
229 TQ_LOCAL_WINDOW_SIZE *
230 TQ_LOCAL_WINDOW_SIZE);
231
232 batman_packet->tq = ((batman_packet->tq *
233 orig_neigh_node->tq_own *
234 orig_neigh_node->tq_asym_penalty) /
235 (TQ_MAX_VALUE * TQ_MAX_VALUE));
236
237 bat_dbg(DBG_BATMAN, bat_priv,
238 "bidirectional: "
239 "orig = %-15pM neigh = %-15pM => own_bcast = %2i, "
240 "real recv = %2i, local tq: %3i, asym_penalty: %3i, "
241 "total tq: %3i\n",
242 orig_node->orig, orig_neigh_node->orig, total_count,
243 neigh_node->real_packet_count, orig_neigh_node->tq_own,
244 orig_neigh_node->tq_asym_penalty, batman_packet->tq);
245
246 /* if link has the minimum required transmission quality
247 * consider it bidirectional */
248 if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
249 return 1;
250
251 return 0;
252}
253
254static void update_orig(struct bat_priv *bat_priv,
255 struct orig_node *orig_node,
256 struct ethhdr *ethhdr,
257 struct batman_packet *batman_packet,
258 struct batman_if *if_incoming,
259 unsigned char *hna_buff, int hna_buff_len,
260 char is_duplicate)
261{
262 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
9591a79f 263 struct hlist_node *node;
c6c8fea2
SE
264 int tmp_hna_buff_len;
265
266 bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
267 "Searching and updating originator entry of received packet\n");
268
9591a79f
ML
269 hlist_for_each_entry(tmp_neigh_node, node,
270 &orig_node->neigh_list, list) {
c6c8fea2
SE
271 if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) &&
272 (tmp_neigh_node->if_incoming == if_incoming)) {
273 neigh_node = tmp_neigh_node;
274 continue;
275 }
276
277 if (is_duplicate)
278 continue;
279
280 ring_buffer_set(tmp_neigh_node->tq_recv,
281 &tmp_neigh_node->tq_index, 0);
282 tmp_neigh_node->tq_avg =
283 ring_buffer_avg(tmp_neigh_node->tq_recv);
284 }
285
286 if (!neigh_node) {
287 struct orig_node *orig_tmp;
288
289 orig_tmp = get_orig_node(bat_priv, ethhdr->h_source);
290 if (!orig_tmp)
291 return;
292
293 neigh_node = create_neighbor(orig_node, orig_tmp,
294 ethhdr->h_source, if_incoming);
295 if (!neigh_node)
296 return;
297 } else
298 bat_dbg(DBG_BATMAN, bat_priv,
299 "Updating existing last-hop neighbor of originator\n");
300
301 orig_node->flags = batman_packet->flags;
302 neigh_node->last_valid = jiffies;
303
304 ring_buffer_set(neigh_node->tq_recv,
305 &neigh_node->tq_index,
306 batman_packet->tq);
307 neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
308
309 if (!is_duplicate) {
310 orig_node->last_ttl = batman_packet->ttl;
311 neigh_node->last_ttl = batman_packet->ttl;
312 }
313
314 tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ?
315 batman_packet->num_hna * ETH_ALEN : hna_buff_len);
316
317 /* if this neighbor already is our next hop there is nothing
318 * to change */
319 if (orig_node->router == neigh_node)
320 goto update_hna;
321
322 /* if this neighbor does not offer a better TQ we won't consider it */
323 if ((orig_node->router) &&
324 (orig_node->router->tq_avg > neigh_node->tq_avg))
325 goto update_hna;
326
327 /* if the TQ is the same and the link not more symetric we
328 * won't consider it either */
329 if ((orig_node->router) &&
330 ((neigh_node->tq_avg == orig_node->router->tq_avg) &&
331 (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num]
332 >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num])))
333 goto update_hna;
334
335 update_routes(bat_priv, orig_node, neigh_node,
336 hna_buff, tmp_hna_buff_len);
337 goto update_gw;
338
339update_hna:
340 update_routes(bat_priv, orig_node, orig_node->router,
341 hna_buff, tmp_hna_buff_len);
342
343update_gw:
344 if (orig_node->gw_flags != batman_packet->gw_flags)
345 gw_node_update(bat_priv, orig_node, batman_packet->gw_flags);
346
347 orig_node->gw_flags = batman_packet->gw_flags;
348
349 /* restart gateway selection if fast or late switching was enabled */
350 if ((orig_node->gw_flags) &&
351 (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) &&
352 (atomic_read(&bat_priv->gw_sel_class) > 2))
353 gw_check_election(bat_priv, orig_node);
354}
355
356/* checks whether the host restarted and is in the protection time.
357 * returns:
358 * 0 if the packet is to be accepted
359 * 1 if the packet is to be ignored.
360 */
361static int window_protected(struct bat_priv *bat_priv,
362 int32_t seq_num_diff,
363 unsigned long *last_reset)
364{
365 if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
366 || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
367 if (time_after(jiffies, *last_reset +
368 msecs_to_jiffies(RESET_PROTECTION_MS))) {
369
370 *last_reset = jiffies;
371 bat_dbg(DBG_BATMAN, bat_priv,
372 "old packet received, start protection\n");
373
374 return 0;
375 } else
376 return 1;
377 }
378 return 0;
379}
380
381/* processes a batman packet for all interfaces, adjusts the sequence number and
382 * finds out whether it is a duplicate.
383 * returns:
384 * 1 the packet is a duplicate
385 * 0 the packet has not yet been received
386 * -1 the packet is old and has been received while the seqno window
387 * was protected. Caller should drop it.
388 */
389static char count_real_packets(struct ethhdr *ethhdr,
390 struct batman_packet *batman_packet,
391 struct batman_if *if_incoming)
392{
393 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
394 struct orig_node *orig_node;
395 struct neigh_node *tmp_neigh_node;
9591a79f 396 struct hlist_node *node;
c6c8fea2
SE
397 char is_duplicate = 0;
398 int32_t seq_diff;
399 int need_update = 0;
400 int set_mark;
401
402 orig_node = get_orig_node(bat_priv, batman_packet->orig);
403 if (!orig_node)
404 return 0;
405
406 seq_diff = batman_packet->seqno - orig_node->last_real_seqno;
407
408 /* signalize caller that the packet is to be dropped. */
409 if (window_protected(bat_priv, seq_diff,
410 &orig_node->batman_seqno_reset))
411 return -1;
412
9591a79f
ML
413 hlist_for_each_entry(tmp_neigh_node, node,
414 &orig_node->neigh_list, list) {
c6c8fea2
SE
415
416 is_duplicate |= get_bit_status(tmp_neigh_node->real_bits,
417 orig_node->last_real_seqno,
418 batman_packet->seqno);
419
420 if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) &&
421 (tmp_neigh_node->if_incoming == if_incoming))
422 set_mark = 1;
423 else
424 set_mark = 0;
425
426 /* if the window moved, set the update flag. */
427 need_update |= bit_get_packet(bat_priv,
428 tmp_neigh_node->real_bits,
429 seq_diff, set_mark);
430
431 tmp_neigh_node->real_packet_count =
432 bit_packet_count(tmp_neigh_node->real_bits);
433 }
434
435 if (need_update) {
436 bat_dbg(DBG_BATMAN, bat_priv,
437 "updating last_seqno: old %d, new %d\n",
438 orig_node->last_real_seqno, batman_packet->seqno);
439 orig_node->last_real_seqno = batman_packet->seqno;
440 }
441
442 return is_duplicate;
443}
444
445/* copy primary address for bonding */
74ef1153 446static void mark_bonding_address(struct orig_node *orig_node,
c6c8fea2
SE
447 struct orig_node *orig_neigh_node,
448 struct batman_packet *batman_packet)
449
450{
451 if (batman_packet->flags & PRIMARIES_FIRST_HOP)
452 memcpy(orig_neigh_node->primary_addr,
453 orig_node->orig, ETH_ALEN);
454
455 return;
456}
457
458/* mark possible bond.candidates in the neighbor list */
74ef1153 459void update_bonding_candidates(struct orig_node *orig_node)
c6c8fea2
SE
460{
461 int candidates;
462 int interference_candidate;
463 int best_tq;
9591a79f 464 struct hlist_node *node, *node2;
c6c8fea2
SE
465 struct neigh_node *tmp_neigh_node, *tmp_neigh_node2;
466 struct neigh_node *first_candidate, *last_candidate;
467
468 /* update the candidates for this originator */
469 if (!orig_node->router) {
470 orig_node->bond.candidates = 0;
471 return;
472 }
473
474 best_tq = orig_node->router->tq_avg;
475
476 /* update bond.candidates */
477
478 candidates = 0;
479
480 /* mark other nodes which also received "PRIMARIES FIRST HOP" packets
481 * as "bonding partner" */
482
483 /* first, zero the list */
9591a79f
ML
484 hlist_for_each_entry(tmp_neigh_node, node,
485 &orig_node->neigh_list, list) {
c6c8fea2
SE
486 tmp_neigh_node->next_bond_candidate = NULL;
487 }
488
489 first_candidate = NULL;
490 last_candidate = NULL;
9591a79f
ML
491 hlist_for_each_entry(tmp_neigh_node, node,
492 &orig_node->neigh_list, list) {
c6c8fea2
SE
493
494 /* only consider if it has the same primary address ... */
495 if (memcmp(orig_node->orig,
496 tmp_neigh_node->orig_node->primary_addr,
497 ETH_ALEN) != 0)
498 continue;
499
500 /* ... and is good enough to be considered */
501 if (tmp_neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD)
502 continue;
503
504 /* check if we have another candidate with the same
505 * mac address or interface. If we do, we won't
506 * select this candidate because of possible interference. */
507
508 interference_candidate = 0;
9591a79f
ML
509 hlist_for_each_entry(tmp_neigh_node2, node2,
510 &orig_node->neigh_list, list) {
c6c8fea2
SE
511
512 if (tmp_neigh_node2 == tmp_neigh_node)
513 continue;
514
515 /* we only care if the other candidate is even
516 * considered as candidate. */
517 if (!tmp_neigh_node2->next_bond_candidate)
518 continue;
519
520
521 if ((tmp_neigh_node->if_incoming ==
522 tmp_neigh_node2->if_incoming)
523 || (memcmp(tmp_neigh_node->addr,
524 tmp_neigh_node2->addr, ETH_ALEN) == 0)) {
525
526 interference_candidate = 1;
527 break;
528 }
529 }
530 /* don't care further if it is an interference candidate */
531 if (interference_candidate)
532 continue;
533
534 if (!first_candidate) {
535 first_candidate = tmp_neigh_node;
536 tmp_neigh_node->next_bond_candidate = first_candidate;
537 } else
538 tmp_neigh_node->next_bond_candidate = last_candidate;
539
540 last_candidate = tmp_neigh_node;
541
542 candidates++;
543 }
544
545 if (candidates > 0) {
546 first_candidate->next_bond_candidate = last_candidate;
547 orig_node->bond.selected = first_candidate;
548 }
549
550 orig_node->bond.candidates = candidates;
551}
552
553void receive_bat_packet(struct ethhdr *ethhdr,
554 struct batman_packet *batman_packet,
555 unsigned char *hna_buff, int hna_buff_len,
556 struct batman_if *if_incoming)
557{
558 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
559 struct batman_if *batman_if;
560 struct orig_node *orig_neigh_node, *orig_node;
561 char has_directlink_flag;
562 char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
563 char is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
564 char is_duplicate;
565 uint32_t if_incoming_seqno;
566
567 /* Silently drop when the batman packet is actually not a
568 * correct packet.
569 *
570 * This might happen if a packet is padded (e.g. Ethernet has a
571 * minimum frame length of 64 byte) and the aggregation interprets
572 * it as an additional length.
573 *
574 * TODO: A more sane solution would be to have a bit in the
575 * batman_packet to detect whether the packet is the last
576 * packet in an aggregation. Here we expect that the padding
577 * is always zero (or not 0x01)
578 */
579 if (batman_packet->packet_type != BAT_PACKET)
580 return;
581
582 /* could be changed by schedule_own_packet() */
583 if_incoming_seqno = atomic_read(&if_incoming->seqno);
584
585 has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0);
586
587 is_single_hop_neigh = (compare_orig(ethhdr->h_source,
588 batman_packet->orig) ? 1 : 0);
589
590 bat_dbg(DBG_BATMAN, bat_priv,
591 "Received BATMAN packet via NB: %pM, IF: %s [%pM] "
592 "(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, "
593 "TTL %d, V %d, IDF %d)\n",
594 ethhdr->h_source, if_incoming->net_dev->name,
595 if_incoming->net_dev->dev_addr, batman_packet->orig,
596 batman_packet->prev_sender, batman_packet->seqno,
597 batman_packet->tq, batman_packet->ttl, batman_packet->version,
598 has_directlink_flag);
599
600 rcu_read_lock();
601 list_for_each_entry_rcu(batman_if, &if_list, list) {
602 if (batman_if->if_status != IF_ACTIVE)
603 continue;
604
605 if (batman_if->soft_iface != if_incoming->soft_iface)
606 continue;
607
608 if (compare_orig(ethhdr->h_source,
609 batman_if->net_dev->dev_addr))
610 is_my_addr = 1;
611
612 if (compare_orig(batman_packet->orig,
613 batman_if->net_dev->dev_addr))
614 is_my_orig = 1;
615
616 if (compare_orig(batman_packet->prev_sender,
617 batman_if->net_dev->dev_addr))
618 is_my_oldorig = 1;
619
620 if (compare_orig(ethhdr->h_source, broadcast_addr))
621 is_broadcast = 1;
622 }
623 rcu_read_unlock();
624
625 if (batman_packet->version != COMPAT_VERSION) {
626 bat_dbg(DBG_BATMAN, bat_priv,
627 "Drop packet: incompatible batman version (%i)\n",
628 batman_packet->version);
629 return;
630 }
631
632 if (is_my_addr) {
633 bat_dbg(DBG_BATMAN, bat_priv,
634 "Drop packet: received my own broadcast (sender: %pM"
635 ")\n",
636 ethhdr->h_source);
637 return;
638 }
639
640 if (is_broadcast) {
641 bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
642 "ignoring all packets with broadcast source addr (sender: %pM"
643 ")\n", ethhdr->h_source);
644 return;
645 }
646
647 if (is_my_orig) {
648 unsigned long *word;
649 int offset;
650
651 orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source);
652
653 if (!orig_neigh_node)
654 return;
655
656 /* neighbor has to indicate direct link and it has to
657 * come via the corresponding interface */
658 /* if received seqno equals last send seqno save new
659 * seqno for bidirectional check */
660 if (has_directlink_flag &&
661 compare_orig(if_incoming->net_dev->dev_addr,
662 batman_packet->orig) &&
663 (batman_packet->seqno - if_incoming_seqno + 2 == 0)) {
664 offset = if_incoming->if_num * NUM_WORDS;
665 word = &(orig_neigh_node->bcast_own[offset]);
666 bit_mark(word, 0);
667 orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
668 bit_packet_count(word);
669 }
670
671 bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
672 "originator packet from myself (via neighbor)\n");
673 return;
674 }
675
676 if (is_my_oldorig) {
677 bat_dbg(DBG_BATMAN, bat_priv,
678 "Drop packet: ignoring all rebroadcast echos (sender: "
679 "%pM)\n", ethhdr->h_source);
680 return;
681 }
682
683 orig_node = get_orig_node(bat_priv, batman_packet->orig);
684 if (!orig_node)
685 return;
686
687 is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming);
688
689 if (is_duplicate == -1) {
690 bat_dbg(DBG_BATMAN, bat_priv,
691 "Drop packet: packet within seqno protection time "
692 "(sender: %pM)\n", ethhdr->h_source);
693 return;
694 }
695
696 if (batman_packet->tq == 0) {
697 bat_dbg(DBG_BATMAN, bat_priv,
698 "Drop packet: originator packet with tq equal 0\n");
699 return;
700 }
701
702 /* avoid temporary routing loops */
703 if ((orig_node->router) &&
704 (orig_node->router->orig_node->router) &&
705 (compare_orig(orig_node->router->addr,
706 batman_packet->prev_sender)) &&
707 !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) &&
708 (compare_orig(orig_node->router->addr,
709 orig_node->router->orig_node->router->addr))) {
710 bat_dbg(DBG_BATMAN, bat_priv,
711 "Drop packet: ignoring all rebroadcast packets that "
712 "may make me loop (sender: %pM)\n", ethhdr->h_source);
713 return;
714 }
715
716 /* if sender is a direct neighbor the sender mac equals
717 * originator mac */
718 orig_neigh_node = (is_single_hop_neigh ?
719 orig_node :
720 get_orig_node(bat_priv, ethhdr->h_source));
721 if (!orig_neigh_node)
722 return;
723
724 /* drop packet if sender is not a direct neighbor and if we
725 * don't route towards it */
726 if (!is_single_hop_neigh && (!orig_neigh_node->router)) {
727 bat_dbg(DBG_BATMAN, bat_priv,
728 "Drop packet: OGM via unknown neighbor!\n");
729 return;
730 }
731
732 is_bidirectional = is_bidirectional_neigh(orig_node, orig_neigh_node,
733 batman_packet, if_incoming);
734
735 /* update ranking if it is not a duplicate or has the same
736 * seqno and similar ttl as the non-duplicate */
737 if (is_bidirectional &&
738 (!is_duplicate ||
739 ((orig_node->last_real_seqno == batman_packet->seqno) &&
740 (orig_node->last_ttl - 3 <= batman_packet->ttl))))
741 update_orig(bat_priv, orig_node, ethhdr, batman_packet,
742 if_incoming, hna_buff, hna_buff_len, is_duplicate);
743
74ef1153
SW
744 mark_bonding_address(orig_node, orig_neigh_node, batman_packet);
745 update_bonding_candidates(orig_node);
c6c8fea2
SE
746
747 /* is single hop (direct) neighbor */
748 if (is_single_hop_neigh) {
749
750 /* mark direct link on incoming interface */
751 schedule_forward_packet(orig_node, ethhdr, batman_packet,
752 1, hna_buff_len, if_incoming);
753
754 bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
755 "rebroadcast neighbor packet with direct link flag\n");
756 return;
757 }
758
759 /* multihop originator */
760 if (!is_bidirectional) {
761 bat_dbg(DBG_BATMAN, bat_priv,
762 "Drop packet: not received via bidirectional link\n");
763 return;
764 }
765
766 if (is_duplicate) {
767 bat_dbg(DBG_BATMAN, bat_priv,
768 "Drop packet: duplicate packet received\n");
769 return;
770 }
771
772 bat_dbg(DBG_BATMAN, bat_priv,
773 "Forwarding packet: rebroadcast originator packet\n");
774 schedule_forward_packet(orig_node, ethhdr, batman_packet,
775 0, hna_buff_len, if_incoming);
776}
777
778int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if)
779{
780 struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
781 struct ethhdr *ethhdr;
782
783 /* drop packet if it has not necessary minimum size */
784 if (unlikely(!pskb_may_pull(skb, sizeof(struct batman_packet))))
785 return NET_RX_DROP;
786
787 ethhdr = (struct ethhdr *)skb_mac_header(skb);
788
789 /* packet with broadcast indication but unicast recipient */
790 if (!is_broadcast_ether_addr(ethhdr->h_dest))
791 return NET_RX_DROP;
792
793 /* packet with broadcast sender address */
794 if (is_broadcast_ether_addr(ethhdr->h_source))
795 return NET_RX_DROP;
796
797 /* create a copy of the skb, if needed, to modify it. */
798 if (skb_cow(skb, 0) < 0)
799 return NET_RX_DROP;
800
801 /* keep skb linear */
802 if (skb_linearize(skb) < 0)
803 return NET_RX_DROP;
804
805 ethhdr = (struct ethhdr *)skb_mac_header(skb);
806
807 spin_lock_bh(&bat_priv->orig_hash_lock);
808 receive_aggr_bat_packet(ethhdr,
809 skb->data,
810 skb_headlen(skb),
811 batman_if);
812 spin_unlock_bh(&bat_priv->orig_hash_lock);
813
814 kfree_skb(skb);
815 return NET_RX_SUCCESS;
816}
817
818static int recv_my_icmp_packet(struct bat_priv *bat_priv,
819 struct sk_buff *skb, size_t icmp_len)
820{
821 struct orig_node *orig_node;
822 struct icmp_packet_rr *icmp_packet;
c6c8fea2
SE
823 struct batman_if *batman_if;
824 int ret;
825 uint8_t dstaddr[ETH_ALEN];
826
827 icmp_packet = (struct icmp_packet_rr *)skb->data;
c6c8fea2
SE
828
829 /* add data to device queue */
830 if (icmp_packet->msg_type != ECHO_REQUEST) {
831 bat_socket_receive_packet(icmp_packet, icmp_len);
832 return NET_RX_DROP;
833 }
834
835 if (!bat_priv->primary_if)
836 return NET_RX_DROP;
837
838 /* answer echo request (ping) */
839 /* get routing information */
840 spin_lock_bh(&bat_priv->orig_hash_lock);
841 orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
842 compare_orig, choose_orig,
843 icmp_packet->orig));
844 ret = NET_RX_DROP;
845
846 if ((orig_node) && (orig_node->router)) {
847
848 /* don't lock while sending the packets ... we therefore
849 * copy the required data before sending */
850 batman_if = orig_node->router->if_incoming;
851 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
852 spin_unlock_bh(&bat_priv->orig_hash_lock);
853
854 /* create a copy of the skb, if needed, to modify it. */
855 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
856 return NET_RX_DROP;
857
858 icmp_packet = (struct icmp_packet_rr *)skb->data;
c6c8fea2
SE
859
860 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
861 memcpy(icmp_packet->orig,
862 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
863 icmp_packet->msg_type = ECHO_REPLY;
864 icmp_packet->ttl = TTL;
865
866 send_skb_packet(skb, batman_if, dstaddr);
867 ret = NET_RX_SUCCESS;
868
869 } else
870 spin_unlock_bh(&bat_priv->orig_hash_lock);
871
872 return ret;
873}
874
875static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
74ef1153 876 struct sk_buff *skb)
c6c8fea2
SE
877{
878 struct orig_node *orig_node;
879 struct icmp_packet *icmp_packet;
c6c8fea2
SE
880 struct batman_if *batman_if;
881 int ret;
882 uint8_t dstaddr[ETH_ALEN];
883
884 icmp_packet = (struct icmp_packet *)skb->data;
c6c8fea2
SE
885
886 /* send TTL exceeded if packet is an echo request (traceroute) */
887 if (icmp_packet->msg_type != ECHO_REQUEST) {
888 pr_debug("Warning - can't forward icmp packet from %pM to "
889 "%pM: ttl exceeded\n", icmp_packet->orig,
890 icmp_packet->dst);
891 return NET_RX_DROP;
892 }
893
894 if (!bat_priv->primary_if)
895 return NET_RX_DROP;
896
897 /* get routing information */
898 spin_lock_bh(&bat_priv->orig_hash_lock);
899 orig_node = ((struct orig_node *)
900 hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
901 icmp_packet->orig));
902 ret = NET_RX_DROP;
903
904 if ((orig_node) && (orig_node->router)) {
905
906 /* don't lock while sending the packets ... we therefore
907 * copy the required data before sending */
908 batman_if = orig_node->router->if_incoming;
909 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
910 spin_unlock_bh(&bat_priv->orig_hash_lock);
911
912 /* create a copy of the skb, if needed, to modify it. */
913 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
914 return NET_RX_DROP;
915
916 icmp_packet = (struct icmp_packet *) skb->data;
c6c8fea2
SE
917
918 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
919 memcpy(icmp_packet->orig,
920 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
921 icmp_packet->msg_type = TTL_EXCEEDED;
922 icmp_packet->ttl = TTL;
923
924 send_skb_packet(skb, batman_if, dstaddr);
925 ret = NET_RX_SUCCESS;
926
927 } else
928 spin_unlock_bh(&bat_priv->orig_hash_lock);
929
930 return ret;
931}
932
933
934int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if)
935{
936 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
937 struct icmp_packet_rr *icmp_packet;
938 struct ethhdr *ethhdr;
939 struct orig_node *orig_node;
940 struct batman_if *batman_if;
941 int hdr_size = sizeof(struct icmp_packet);
942 int ret;
943 uint8_t dstaddr[ETH_ALEN];
944
945 /**
946 * we truncate all incoming icmp packets if they don't match our size
947 */
948 if (skb->len >= sizeof(struct icmp_packet_rr))
949 hdr_size = sizeof(struct icmp_packet_rr);
950
951 /* drop packet if it has not necessary minimum size */
952 if (unlikely(!pskb_may_pull(skb, hdr_size)))
953 return NET_RX_DROP;
954
955 ethhdr = (struct ethhdr *)skb_mac_header(skb);
956
957 /* packet with unicast indication but broadcast recipient */
958 if (is_broadcast_ether_addr(ethhdr->h_dest))
959 return NET_RX_DROP;
960
961 /* packet with broadcast sender address */
962 if (is_broadcast_ether_addr(ethhdr->h_source))
963 return NET_RX_DROP;
964
965 /* not for me */
966 if (!is_my_mac(ethhdr->h_dest))
967 return NET_RX_DROP;
968
969 icmp_packet = (struct icmp_packet_rr *)skb->data;
970
971 /* add record route information if not full */
972 if ((hdr_size == sizeof(struct icmp_packet_rr)) &&
973 (icmp_packet->rr_cur < BAT_RR_LEN)) {
974 memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]),
975 ethhdr->h_dest, ETH_ALEN);
976 icmp_packet->rr_cur++;
977 }
978
979 /* packet for me */
980 if (is_my_mac(icmp_packet->dst))
981 return recv_my_icmp_packet(bat_priv, skb, hdr_size);
982
983 /* TTL exceeded */
984 if (icmp_packet->ttl < 2)
74ef1153 985 return recv_icmp_ttl_exceeded(bat_priv, skb);
c6c8fea2
SE
986
987 ret = NET_RX_DROP;
988
989 /* get routing information */
990 spin_lock_bh(&bat_priv->orig_hash_lock);
991 orig_node = ((struct orig_node *)
992 hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
993 icmp_packet->dst));
994
995 if ((orig_node) && (orig_node->router)) {
996
997 /* don't lock while sending the packets ... we therefore
998 * copy the required data before sending */
999 batman_if = orig_node->router->if_incoming;
1000 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
1001 spin_unlock_bh(&bat_priv->orig_hash_lock);
1002
1003 /* create a copy of the skb, if needed, to modify it. */
1004 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
1005 return NET_RX_DROP;
1006
1007 icmp_packet = (struct icmp_packet_rr *)skb->data;
c6c8fea2
SE
1008
1009 /* decrement ttl */
1010 icmp_packet->ttl--;
1011
1012 /* route it */
1013 send_skb_packet(skb, batman_if, dstaddr);
1014 ret = NET_RX_SUCCESS;
1015
1016 } else
1017 spin_unlock_bh(&bat_priv->orig_hash_lock);
1018
1019 return ret;
1020}
1021
1022/* find a suitable router for this originator, and use
1023 * bonding if possible. */
1024struct neigh_node *find_router(struct bat_priv *bat_priv,
1025 struct orig_node *orig_node,
1026 struct batman_if *recv_if)
1027{
1028 struct orig_node *primary_orig_node;
1029 struct orig_node *router_orig;
1030 struct neigh_node *router, *first_candidate, *best_router;
1031 static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
1032 int bonding_enabled;
1033
1034 if (!orig_node)
1035 return NULL;
1036
1037 if (!orig_node->router)
1038 return NULL;
1039
1040 /* without bonding, the first node should
1041 * always choose the default router. */
1042
1043 bonding_enabled = atomic_read(&bat_priv->bonding);
1044
1045 if ((!recv_if) && (!bonding_enabled))
1046 return orig_node->router;
1047
1048 router_orig = orig_node->router->orig_node;
1049
1050 /* if we have something in the primary_addr, we can search
1051 * for a potential bonding candidate. */
1052 if (memcmp(router_orig->primary_addr, zero_mac, ETH_ALEN) == 0)
1053 return orig_node->router;
1054
1055 /* find the orig_node which has the primary interface. might
1056 * even be the same as our router_orig in many cases */
1057
1058 if (memcmp(router_orig->primary_addr,
1059 router_orig->orig, ETH_ALEN) == 0) {
1060 primary_orig_node = router_orig;
1061 } else {
1062 primary_orig_node = hash_find(bat_priv->orig_hash, compare_orig,
1063 choose_orig,
1064 router_orig->primary_addr);
1065
1066 if (!primary_orig_node)
1067 return orig_node->router;
1068 }
1069
1070 /* with less than 2 candidates, we can't do any
1071 * bonding and prefer the original router. */
1072
1073 if (primary_orig_node->bond.candidates < 2)
1074 return orig_node->router;
1075
1076
1077 /* all nodes between should choose a candidate which
1078 * is is not on the interface where the packet came
1079 * in. */
1080 first_candidate = primary_orig_node->bond.selected;
1081 router = first_candidate;
1082
1083 if (bonding_enabled) {
1084 /* in the bonding case, send the packets in a round
1085 * robin fashion over the remaining interfaces. */
1086 do {
1087 /* recv_if == NULL on the first node. */
1088 if (router->if_incoming != recv_if)
1089 break;
1090
1091 router = router->next_bond_candidate;
1092 } while (router != first_candidate);
1093
1094 primary_orig_node->bond.selected = router->next_bond_candidate;
1095
1096 } else {
1097 /* if bonding is disabled, use the best of the
1098 * remaining candidates which are not using
1099 * this interface. */
1100 best_router = first_candidate;
1101
1102 do {
1103 /* recv_if == NULL on the first node. */
1104 if ((router->if_incoming != recv_if) &&
1105 (router->tq_avg > best_router->tq_avg))
1106 best_router = router;
1107
1108 router = router->next_bond_candidate;
1109 } while (router != first_candidate);
1110
1111 router = best_router;
1112 }
1113
1114 return router;
1115}
1116
1117static int check_unicast_packet(struct sk_buff *skb, int hdr_size)
1118{
1119 struct ethhdr *ethhdr;
1120
1121 /* drop packet if it has not necessary minimum size */
1122 if (unlikely(!pskb_may_pull(skb, hdr_size)))
1123 return -1;
1124
1125 ethhdr = (struct ethhdr *)skb_mac_header(skb);
1126
1127 /* packet with unicast indication but broadcast recipient */
1128 if (is_broadcast_ether_addr(ethhdr->h_dest))
1129 return -1;
1130
1131 /* packet with broadcast sender address */
1132 if (is_broadcast_ether_addr(ethhdr->h_source))
1133 return -1;
1134
1135 /* not for me */
1136 if (!is_my_mac(ethhdr->h_dest))
1137 return -1;
1138
1139 return 0;
1140}
1141
1142int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if,
1143 int hdr_size)
1144{
1145 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1146 struct orig_node *orig_node;
1147 struct neigh_node *router;
1148 struct batman_if *batman_if;
1149 uint8_t dstaddr[ETH_ALEN];
1150 struct unicast_packet *unicast_packet;
1151 struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
1152 int ret;
1153 struct sk_buff *new_skb;
1154
1155 unicast_packet = (struct unicast_packet *)skb->data;
1156
1157 /* TTL exceeded */
1158 if (unicast_packet->ttl < 2) {
1159 pr_debug("Warning - can't forward unicast packet from %pM to "
1160 "%pM: ttl exceeded\n", ethhdr->h_source,
1161 unicast_packet->dest);
1162 return NET_RX_DROP;
1163 }
1164
1165 /* get routing information */
1166 spin_lock_bh(&bat_priv->orig_hash_lock);
1167 orig_node = ((struct orig_node *)
1168 hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
1169 unicast_packet->dest));
1170
1171 router = find_router(bat_priv, orig_node, recv_if);
1172
1173 if (!router) {
1174 spin_unlock_bh(&bat_priv->orig_hash_lock);
1175 return NET_RX_DROP;
1176 }
1177
1178 /* don't lock while sending the packets ... we therefore
1179 * copy the required data before sending */
1180
1181 batman_if = router->if_incoming;
1182 memcpy(dstaddr, router->addr, ETH_ALEN);
1183
1184 spin_unlock_bh(&bat_priv->orig_hash_lock);
1185
1186 /* create a copy of the skb, if needed, to modify it. */
1187 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
1188 return NET_RX_DROP;
1189
1190 unicast_packet = (struct unicast_packet *)skb->data;
1191
1192 if (unicast_packet->packet_type == BAT_UNICAST &&
1193 atomic_read(&bat_priv->fragmentation) &&
1194 skb->len > batman_if->net_dev->mtu)
1195 return frag_send_skb(skb, bat_priv, batman_if,
1196 dstaddr);
1197
1198 if (unicast_packet->packet_type == BAT_UNICAST_FRAG &&
ae361ce1 1199 frag_can_reassemble(skb, batman_if->net_dev->mtu)) {
c6c8fea2
SE
1200
1201 ret = frag_reassemble_skb(skb, bat_priv, &new_skb);
1202
1203 if (ret == NET_RX_DROP)
1204 return NET_RX_DROP;
1205
1206 /* packet was buffered for late merge */
1207 if (!new_skb)
1208 return NET_RX_SUCCESS;
1209
1210 skb = new_skb;
1211 unicast_packet = (struct unicast_packet *)skb->data;
1212 }
1213
1214 /* decrement ttl */
1215 unicast_packet->ttl--;
1216
1217 /* route it */
1218 send_skb_packet(skb, batman_if, dstaddr);
1219
1220 return NET_RX_SUCCESS;
1221}
1222
1223int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
1224{
1225 struct unicast_packet *unicast_packet;
1226 int hdr_size = sizeof(struct unicast_packet);
1227
1228 if (check_unicast_packet(skb, hdr_size) < 0)
1229 return NET_RX_DROP;
1230
1231 unicast_packet = (struct unicast_packet *)skb->data;
1232
1233 /* packet for me */
1234 if (is_my_mac(unicast_packet->dest)) {
1235 interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size);
1236 return NET_RX_SUCCESS;
1237 }
1238
1239 return route_unicast_packet(skb, recv_if, hdr_size);
1240}
1241
1242int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if)
1243{
1244 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1245 struct unicast_frag_packet *unicast_packet;
1246 int hdr_size = sizeof(struct unicast_frag_packet);
1247 struct sk_buff *new_skb = NULL;
1248 int ret;
1249
1250 if (check_unicast_packet(skb, hdr_size) < 0)
1251 return NET_RX_DROP;
1252
1253 unicast_packet = (struct unicast_frag_packet *)skb->data;
1254
1255 /* packet for me */
1256 if (is_my_mac(unicast_packet->dest)) {
1257
1258 ret = frag_reassemble_skb(skb, bat_priv, &new_skb);
1259
1260 if (ret == NET_RX_DROP)
1261 return NET_RX_DROP;
1262
1263 /* packet was buffered for late merge */
1264 if (!new_skb)
1265 return NET_RX_SUCCESS;
1266
1267 interface_rx(recv_if->soft_iface, new_skb, recv_if,
1268 sizeof(struct unicast_packet));
1269 return NET_RX_SUCCESS;
1270 }
1271
1272 return route_unicast_packet(skb, recv_if, hdr_size);
1273}
1274
1275
1276int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if)
1277{
1278 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1279 struct orig_node *orig_node;
1280 struct bcast_packet *bcast_packet;
1281 struct ethhdr *ethhdr;
1282 int hdr_size = sizeof(struct bcast_packet);
1283 int32_t seq_diff;
1284
1285 /* drop packet if it has not necessary minimum size */
1286 if (unlikely(!pskb_may_pull(skb, hdr_size)))
1287 return NET_RX_DROP;
1288
1289 ethhdr = (struct ethhdr *)skb_mac_header(skb);
1290
1291 /* packet with broadcast indication but unicast recipient */
1292 if (!is_broadcast_ether_addr(ethhdr->h_dest))
1293 return NET_RX_DROP;
1294
1295 /* packet with broadcast sender address */
1296 if (is_broadcast_ether_addr(ethhdr->h_source))
1297 return NET_RX_DROP;
1298
1299 /* ignore broadcasts sent by myself */
1300 if (is_my_mac(ethhdr->h_source))
1301 return NET_RX_DROP;
1302
1303 bcast_packet = (struct bcast_packet *)skb->data;
1304
1305 /* ignore broadcasts originated by myself */
1306 if (is_my_mac(bcast_packet->orig))
1307 return NET_RX_DROP;
1308
1309 if (bcast_packet->ttl < 2)
1310 return NET_RX_DROP;
1311
1312 spin_lock_bh(&bat_priv->orig_hash_lock);
1313 orig_node = ((struct orig_node *)
1314 hash_find(bat_priv->orig_hash, compare_orig, choose_orig,
1315 bcast_packet->orig));
1316
1317 if (!orig_node) {
1318 spin_unlock_bh(&bat_priv->orig_hash_lock);
1319 return NET_RX_DROP;
1320 }
1321
1322 /* check whether the packet is a duplicate */
1323 if (get_bit_status(orig_node->bcast_bits,
1324 orig_node->last_bcast_seqno,
1325 ntohl(bcast_packet->seqno))) {
1326 spin_unlock_bh(&bat_priv->orig_hash_lock);
1327 return NET_RX_DROP;
1328 }
1329
1330 seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno;
1331
1332 /* check whether the packet is old and the host just restarted. */
1333 if (window_protected(bat_priv, seq_diff,
1334 &orig_node->bcast_seqno_reset)) {
1335 spin_unlock_bh(&bat_priv->orig_hash_lock);
1336 return NET_RX_DROP;
1337 }
1338
1339 /* mark broadcast in flood history, update window position
1340 * if required. */
1341 if (bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1))
1342 orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno);
1343
1344 spin_unlock_bh(&bat_priv->orig_hash_lock);
1345 /* rebroadcast packet */
1346 add_bcast_packet_to_list(bat_priv, skb);
1347
1348 /* broadcast for me */
1349 interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size);
1350
1351 return NET_RX_SUCCESS;
1352}
1353
1354int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if)
1355{
1356 struct vis_packet *vis_packet;
1357 struct ethhdr *ethhdr;
1358 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1359 int hdr_size = sizeof(struct vis_packet);
1360
1361 /* keep skb linear */
1362 if (skb_linearize(skb) < 0)
1363 return NET_RX_DROP;
1364
1365 if (unlikely(!pskb_may_pull(skb, hdr_size)))
1366 return NET_RX_DROP;
1367
1368 vis_packet = (struct vis_packet *)skb->data;
1369 ethhdr = (struct ethhdr *)skb_mac_header(skb);
1370
1371 /* not for me */
1372 if (!is_my_mac(ethhdr->h_dest))
1373 return NET_RX_DROP;
1374
1375 /* ignore own packets */
1376 if (is_my_mac(vis_packet->vis_orig))
1377 return NET_RX_DROP;
1378
1379 if (is_my_mac(vis_packet->sender_orig))
1380 return NET_RX_DROP;
1381
1382 switch (vis_packet->vis_type) {
1383 case VIS_TYPE_SERVER_SYNC:
1384 receive_server_sync_packet(bat_priv, vis_packet,
1385 skb_headlen(skb));
1386 break;
1387
1388 case VIS_TYPE_CLIENT_UPDATE:
1389 receive_client_update_packet(bat_priv, vis_packet,
1390 skb_headlen(skb));
1391 break;
1392
1393 default: /* ignore unknown packet */
1394 break;
1395 }
1396
1397 /* We take a copy of the data in the packet, so we should
1398 always free the skbuf. */
1399 return NET_RX_DROP;
1400}
This page took 0.108295 seconds and 5 git commands to generate.