]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/batman-adv/routing.c
Merge firewire branches to be released post v2.6.35
[mv-sheeva.git] / drivers / staging / batman-adv / routing.c
1 /*
2  * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
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 "device.h"
29 #include "translation-table.h"
30 #include "originator.h"
31 #include "types.h"
32 #include "ring_buffer.h"
33 #include "vis.h"
34 #include "aggregation.h"
35
36 DECLARE_WAIT_QUEUE_HEAD(thread_wait);
37
38 void slide_own_bcast_window(struct batman_if *batman_if)
39 {
40         HASHIT(hashit);
41         struct orig_node *orig_node;
42         TYPE_OF_WORD *word;
43         unsigned long flags;
44
45         spin_lock_irqsave(&orig_hash_lock, flags);
46
47         while (hash_iterate(orig_hash, &hashit)) {
48                 orig_node = hashit.bucket->data;
49                 word = &(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]);
50
51                 bit_get_packet(word, 1, 0);
52                 orig_node->bcast_own_sum[batman_if->if_num] =
53                         bit_packet_count(word);
54         }
55
56         spin_unlock_irqrestore(&orig_hash_lock, flags);
57 }
58
59 static void update_HNA(struct orig_node *orig_node,
60                        unsigned char *hna_buff, int hna_buff_len)
61 {
62         if ((hna_buff_len != orig_node->hna_buff_len) ||
63             ((hna_buff_len > 0) &&
64              (orig_node->hna_buff_len > 0) &&
65              (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) {
66
67                 if (orig_node->hna_buff_len > 0)
68                         hna_global_del_orig(orig_node,
69                                             "originator changed hna");
70
71                 if ((hna_buff_len > 0) && (hna_buff != NULL))
72                         hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
73         }
74 }
75
76 static void update_route(struct orig_node *orig_node,
77                          struct neigh_node *neigh_node,
78                          unsigned char *hna_buff, int hna_buff_len)
79 {
80         /* route deleted */
81         if ((orig_node->router != NULL) && (neigh_node == NULL)) {
82
83                 bat_dbg(DBG_ROUTES, "Deleting route towards: %pM\n",
84                         orig_node->orig);
85                 hna_global_del_orig(orig_node, "originator timed out");
86
87                 /* route added */
88         } else if ((orig_node->router == NULL) && (neigh_node != NULL)) {
89
90                 bat_dbg(DBG_ROUTES,
91                         "Adding route towards: %pM (via %pM)\n",
92                         orig_node->orig, neigh_node->addr);
93                 hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
94
95                 /* route changed */
96         } else {
97                 bat_dbg(DBG_ROUTES,
98                         "Changing route towards: %pM "
99                         "(now via %pM - was via %pM)\n",
100                         orig_node->orig, neigh_node->addr,
101                         orig_node->router->addr);
102         }
103
104         orig_node->router = neigh_node;
105 }
106
107
108 void update_routes(struct orig_node *orig_node,
109                           struct neigh_node *neigh_node,
110                           unsigned char *hna_buff, int hna_buff_len)
111 {
112
113         if (orig_node == NULL)
114                 return;
115
116         if (orig_node->router != neigh_node)
117                 update_route(orig_node, neigh_node, hna_buff, hna_buff_len);
118         /* may be just HNA changed */
119         else
120                 update_HNA(orig_node, hna_buff, hna_buff_len);
121 }
122
123 static int isBidirectionalNeigh(struct orig_node *orig_node,
124                                 struct orig_node *orig_neigh_node,
125                                 struct batman_packet *batman_packet,
126                                 struct batman_if *if_incoming)
127 {
128         struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
129         unsigned char total_count;
130
131         if (orig_node == orig_neigh_node) {
132                 list_for_each_entry(tmp_neigh_node,
133                                     &orig_node->neigh_list,
134                                     list) {
135
136                         if (compare_orig(tmp_neigh_node->addr,
137                                          orig_neigh_node->orig) &&
138                             (tmp_neigh_node->if_incoming == if_incoming))
139                                 neigh_node = tmp_neigh_node;
140                 }
141
142                 if (!neigh_node)
143                         neigh_node = create_neighbor(orig_node,
144                                                      orig_neigh_node,
145                                                      orig_neigh_node->orig,
146                                                      if_incoming);
147                 /* create_neighbor failed, return 0 */
148                 if (!neigh_node)
149                         return 0;
150
151                 neigh_node->last_valid = jiffies;
152         } else {
153                 /* find packet count of corresponding one hop neighbor */
154                 list_for_each_entry(tmp_neigh_node,
155                                     &orig_neigh_node->neigh_list, list) {
156
157                         if (compare_orig(tmp_neigh_node->addr,
158                                          orig_neigh_node->orig) &&
159                             (tmp_neigh_node->if_incoming == if_incoming))
160                                 neigh_node = tmp_neigh_node;
161                 }
162
163                 if (!neigh_node)
164                         neigh_node = create_neighbor(orig_neigh_node,
165                                                      orig_neigh_node,
166                                                      orig_neigh_node->orig,
167                                                      if_incoming);
168                 /* create_neighbor failed, return 0 */
169                 if (!neigh_node)
170                         return 0;
171         }
172
173         orig_node->last_valid = jiffies;
174
175         /* pay attention to not get a value bigger than 100 % */
176         total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] >
177                        neigh_node->real_packet_count ?
178                        neigh_node->real_packet_count :
179                        orig_neigh_node->bcast_own_sum[if_incoming->if_num]);
180
181         /* if we have too few packets (too less data) we set tq_own to zero */
182         /* if we receive too few packets it is not considered bidirectional */
183         if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) ||
184             (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
185                 orig_neigh_node->tq_own = 0;
186         else
187                 /* neigh_node->real_packet_count is never zero as we
188                  * only purge old information when getting new
189                  * information */
190                 orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) /
191                         neigh_node->real_packet_count;
192
193         /*
194          * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
195          * affect the nearly-symmetric links only a little, but
196          * punishes asymmetric links more.  This will give a value
197          * between 0 and TQ_MAX_VALUE
198          */
199         orig_neigh_node->tq_asym_penalty =
200                 TQ_MAX_VALUE -
201                 (TQ_MAX_VALUE *
202                  (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
203                  (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
204                  (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) /
205                 (TQ_LOCAL_WINDOW_SIZE *
206                  TQ_LOCAL_WINDOW_SIZE *
207                  TQ_LOCAL_WINDOW_SIZE);
208
209         batman_packet->tq = ((batman_packet->tq *
210                               orig_neigh_node->tq_own *
211                               orig_neigh_node->tq_asym_penalty) /
212                              (TQ_MAX_VALUE * TQ_MAX_VALUE));
213
214         bat_dbg(DBG_BATMAN,
215                 "bidirectional: "
216                 "orig = %-15pM neigh = %-15pM => own_bcast = %2i, "
217                 "real recv = %2i, local tq: %3i, asym_penalty: %3i, "
218                 "total tq: %3i\n",
219                 orig_node->orig, orig_neigh_node->orig, total_count,
220                 neigh_node->real_packet_count, orig_neigh_node->tq_own,
221                 orig_neigh_node->tq_asym_penalty, batman_packet->tq);
222
223         /* if link has the minimum required transmission quality
224          * consider it bidirectional */
225         if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
226                 return 1;
227
228         return 0;
229 }
230
231 static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
232                         struct batman_packet *batman_packet,
233                         struct batman_if *if_incoming,
234                         unsigned char *hna_buff, int hna_buff_len,
235                         char is_duplicate)
236 {
237         struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
238         int tmp_hna_buff_len;
239
240         bat_dbg(DBG_BATMAN, "update_originator(): "
241                 "Searching and updating originator entry of received packet\n");
242
243         list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
244                 if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) &&
245                     (tmp_neigh_node->if_incoming == if_incoming)) {
246                         neigh_node = tmp_neigh_node;
247                         continue;
248                 }
249
250                 if (is_duplicate)
251                         continue;
252
253                 ring_buffer_set(tmp_neigh_node->tq_recv,
254                                 &tmp_neigh_node->tq_index, 0);
255                 tmp_neigh_node->tq_avg =
256                         ring_buffer_avg(tmp_neigh_node->tq_recv);
257         }
258
259         if (!neigh_node) {
260                 struct orig_node *orig_tmp;
261
262                 orig_tmp = get_orig_node(ethhdr->h_source);
263                 if (!orig_tmp)
264                         return;
265
266                 neigh_node = create_neighbor(orig_node,
267                                              orig_tmp,
268                                              ethhdr->h_source, if_incoming);
269                 if (!neigh_node)
270                         return;
271         } else
272                 bat_dbg(DBG_BATMAN,
273                         "Updating existing last-hop neighbor of originator\n");
274
275         orig_node->flags = batman_packet->flags;
276         neigh_node->last_valid = jiffies;
277
278         ring_buffer_set(neigh_node->tq_recv,
279                         &neigh_node->tq_index,
280                         batman_packet->tq);
281         neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
282
283         if (!is_duplicate) {
284                 orig_node->last_ttl = batman_packet->ttl;
285                 neigh_node->last_ttl = batman_packet->ttl;
286         }
287
288         tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ?
289                             batman_packet->num_hna * ETH_ALEN : hna_buff_len);
290
291         /* if this neighbor already is our next hop there is nothing
292          * to change */
293         if (orig_node->router == neigh_node)
294                 goto update_hna;
295
296         /* if this neighbor does not offer a better TQ we won't consider it */
297         if ((orig_node->router) &&
298             (orig_node->router->tq_avg > neigh_node->tq_avg))
299                 goto update_hna;
300
301         /* if the TQ is the same and the link not more symetric we
302          * won't consider it either */
303         if ((orig_node->router) &&
304              ((neigh_node->tq_avg == orig_node->router->tq_avg) &&
305              (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num]
306               >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num])))
307                 goto update_hna;
308
309         update_routes(orig_node, neigh_node, hna_buff, tmp_hna_buff_len);
310         return;
311
312 update_hna:
313         update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len);
314 }
315
316 /* checks whether the host restarted and is in the protection time.
317  * returns:
318  *  0 if the packet is to be accepted
319  *  1 if the packet is to be ignored.
320  */
321 static int window_protected(int16_t seq_num_diff,
322                                 unsigned long *last_reset)
323 {
324         if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
325                 || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
326                 if (time_after(jiffies, *last_reset +
327                         msecs_to_jiffies(RESET_PROTECTION_MS))) {
328
329                         *last_reset = jiffies;
330                         bat_dbg(DBG_BATMAN,
331                                 "old packet received, start protection\n");
332
333                         return 0;
334                 } else
335                         return 1;
336         }
337         return 0;
338 }
339
340 /* processes a batman packet for all interfaces, adjusts the sequence number and
341  * finds out whether it is a duplicate.
342  * returns:
343  *   1 the packet is a duplicate
344  *   0 the packet has not yet been received
345  *  -1 the packet is old and has been received while the seqno window
346  *     was protected. Caller should drop it.
347  */
348 static char count_real_packets(struct ethhdr *ethhdr,
349                                struct batman_packet *batman_packet,
350                                struct batman_if *if_incoming)
351 {
352         struct orig_node *orig_node;
353         struct neigh_node *tmp_neigh_node;
354         char is_duplicate = 0;
355         int16_t seq_diff;
356         int need_update = 0;
357         int set_mark;
358
359         orig_node = get_orig_node(batman_packet->orig);
360         if (orig_node == NULL)
361                 return 0;
362
363         seq_diff = batman_packet->seqno - orig_node->last_real_seqno;
364
365         /* signalize caller that the packet is to be dropped. */
366         if (window_protected(seq_diff, &orig_node->batman_seqno_reset))
367                 return -1;
368
369         list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
370
371                 is_duplicate |= get_bit_status(tmp_neigh_node->real_bits,
372                                                orig_node->last_real_seqno,
373                                                batman_packet->seqno);
374
375                 if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) &&
376                     (tmp_neigh_node->if_incoming == if_incoming))
377                         set_mark = 1;
378                 else
379                         set_mark = 0;
380
381                 /* if the window moved, set the update flag. */
382                 need_update |= bit_get_packet(tmp_neigh_node->real_bits,
383                                                 seq_diff, set_mark);
384
385                 tmp_neigh_node->real_packet_count =
386                         bit_packet_count(tmp_neigh_node->real_bits);
387         }
388
389         if (need_update) {
390                 bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d\n",
391                         orig_node->last_real_seqno, batman_packet->seqno);
392                 orig_node->last_real_seqno = batman_packet->seqno;
393         }
394
395         return is_duplicate;
396 }
397
398 void receive_bat_packet(struct ethhdr *ethhdr,
399                                 struct batman_packet *batman_packet,
400                                 unsigned char *hna_buff, int hna_buff_len,
401                                 struct batman_if *if_incoming)
402 {
403         struct batman_if *batman_if;
404         struct orig_node *orig_neigh_node, *orig_node;
405         char has_directlink_flag;
406         char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
407         char is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
408         char is_duplicate;
409         unsigned short if_incoming_seqno;
410
411         /* Silently drop when the batman packet is actually not a
412          * correct packet.
413          *
414          * This might happen if a packet is padded (e.g. Ethernet has a
415          * minimum frame length of 64 byte) and the aggregation interprets
416          * it as an additional length.
417          *
418          * TODO: A more sane solution would be to have a bit in the
419          * batman_packet to detect whether the packet is the last
420          * packet in an aggregation.  Here we expect that the padding
421          * is always zero (or not 0x01)
422          */
423         if (batman_packet->packet_type != BAT_PACKET)
424                 return;
425
426         /* could be changed by schedule_own_packet() */
427         if_incoming_seqno = atomic_read(&if_incoming->seqno);
428
429         has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0);
430
431         is_single_hop_neigh = (compare_orig(ethhdr->h_source,
432                                             batman_packet->orig) ? 1 : 0);
433
434         bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] "
435                 "(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, "
436                 "TTL %d, V %d, IDF %d)\n",
437                 ethhdr->h_source, if_incoming->dev, if_incoming->addr_str,
438                 batman_packet->orig, batman_packet->prev_sender,
439                 batman_packet->seqno, batman_packet->tq, batman_packet->ttl,
440                 batman_packet->version, has_directlink_flag);
441
442         list_for_each_entry_rcu(batman_if, &if_list, list) {
443                 if (batman_if->if_status != IF_ACTIVE)
444                         continue;
445
446                 if (compare_orig(ethhdr->h_source,
447                                  batman_if->net_dev->dev_addr))
448                         is_my_addr = 1;
449
450                 if (compare_orig(batman_packet->orig,
451                                  batman_if->net_dev->dev_addr))
452                         is_my_orig = 1;
453
454                 if (compare_orig(batman_packet->prev_sender,
455                                  batman_if->net_dev->dev_addr))
456                         is_my_oldorig = 1;
457
458                 if (compare_orig(ethhdr->h_source, broadcastAddr))
459                         is_broadcast = 1;
460         }
461
462         if (batman_packet->version != COMPAT_VERSION) {
463                 bat_dbg(DBG_BATMAN,
464                         "Drop packet: incompatible batman version (%i)\n",
465                         batman_packet->version);
466                 return;
467         }
468
469         if (is_my_addr) {
470                 bat_dbg(DBG_BATMAN,
471                         "Drop packet: received my own broadcast (sender: %pM"
472                         ")\n",
473                         ethhdr->h_source);
474                 return;
475         }
476
477         if (is_broadcast) {
478                 bat_dbg(DBG_BATMAN, "Drop packet: "
479                 "ignoring all packets with broadcast source addr (sender: %pM"
480                 ")\n", ethhdr->h_source);
481                 return;
482         }
483
484         if (is_my_orig) {
485                 TYPE_OF_WORD *word;
486                 int offset;
487
488                 orig_neigh_node = get_orig_node(ethhdr->h_source);
489
490                 if (!orig_neigh_node)
491                         return;
492
493                 /* neighbor has to indicate direct link and it has to
494                  * come via the corresponding interface */
495                 /* if received seqno equals last send seqno save new
496                  * seqno for bidirectional check */
497                 if (has_directlink_flag &&
498                     compare_orig(if_incoming->net_dev->dev_addr,
499                                  batman_packet->orig) &&
500                     (batman_packet->seqno - if_incoming_seqno + 2 == 0)) {
501                         offset = if_incoming->if_num * NUM_WORDS;
502                         word = &(orig_neigh_node->bcast_own[offset]);
503                         bit_mark(word, 0);
504                         orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
505                                 bit_packet_count(word);
506                 }
507
508                 bat_dbg(DBG_BATMAN, "Drop packet: "
509                         "originator packet from myself (via neighbor)\n");
510                 return;
511         }
512
513         if (is_my_oldorig) {
514                 bat_dbg(DBG_BATMAN,
515                         "Drop packet: ignoring all rebroadcast echos (sender: "
516                         "%pM)\n", ethhdr->h_source);
517                 return;
518         }
519
520         orig_node = get_orig_node(batman_packet->orig);
521         if (orig_node == NULL)
522                 return;
523
524         is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming);
525
526         if (is_duplicate == -1) {
527                 bat_dbg(DBG_BATMAN,
528                         "Drop packet: packet within seqno protection time "
529                         "(sender: %pM)\n", ethhdr->h_source);
530                 return;
531         }
532
533         if (batman_packet->tq == 0) {
534                 bat_dbg(DBG_BATMAN,
535                         "Drop packet: originator packet with tq equal 0\n");
536                 return;
537         }
538
539         /* avoid temporary routing loops */
540         if ((orig_node->router) &&
541             (orig_node->router->orig_node->router) &&
542             (compare_orig(orig_node->router->addr,
543                           batman_packet->prev_sender)) &&
544             !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) &&
545             (compare_orig(orig_node->router->addr,
546                           orig_node->router->orig_node->router->addr))) {
547                 bat_dbg(DBG_BATMAN,
548                         "Drop packet: ignoring all rebroadcast packets that "
549                         "may make me loop (sender: %pM)\n", ethhdr->h_source);
550                 return;
551         }
552
553         /* if sender is a direct neighbor the sender mac equals
554          * originator mac */
555         orig_neigh_node = (is_single_hop_neigh ?
556                            orig_node : get_orig_node(ethhdr->h_source));
557         if (orig_neigh_node == NULL)
558                 return;
559
560         /* drop packet if sender is not a direct neighbor and if we
561          * don't route towards it */
562         if (!is_single_hop_neigh &&
563             (orig_neigh_node->router == NULL)) {
564                 bat_dbg(DBG_BATMAN, "Drop packet: OGM via unknown neighbor!\n");
565                 return;
566         }
567
568         is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node,
569                                                 batman_packet, if_incoming);
570
571         /* update ranking if it is not a duplicate or has the same
572          * seqno and similar ttl as the non-duplicate */
573         if (is_bidirectional &&
574             (!is_duplicate ||
575              ((orig_node->last_real_seqno == batman_packet->seqno) &&
576               (orig_node->last_ttl - 3 <= batman_packet->ttl))))
577                 update_orig(orig_node, ethhdr, batman_packet,
578                             if_incoming, hna_buff, hna_buff_len, is_duplicate);
579
580         /* is single hop (direct) neighbor */
581         if (is_single_hop_neigh) {
582
583                 /* mark direct link on incoming interface */
584                 schedule_forward_packet(orig_node, ethhdr, batman_packet,
585                                         1, hna_buff_len, if_incoming);
586
587                 bat_dbg(DBG_BATMAN, "Forwarding packet: "
588                         "rebroadcast neighbor packet with direct link flag\n");
589                 return;
590         }
591
592         /* multihop originator */
593         if (!is_bidirectional) {
594                 bat_dbg(DBG_BATMAN,
595                         "Drop packet: not received via bidirectional link\n");
596                 return;
597         }
598
599         if (is_duplicate) {
600                 bat_dbg(DBG_BATMAN, "Drop packet: duplicate packet received\n");
601                 return;
602         }
603
604         bat_dbg(DBG_BATMAN,
605                 "Forwarding packet: rebroadcast originator packet\n");
606         schedule_forward_packet(orig_node, ethhdr, batman_packet,
607                                 0, hna_buff_len, if_incoming);
608 }
609
610 int recv_bat_packet(struct sk_buff *skb,
611                                 struct batman_if *batman_if)
612 {
613         struct ethhdr *ethhdr;
614         unsigned long flags;
615         struct sk_buff *skb_old;
616
617         /* drop packet if it has not necessary minimum size */
618         if (skb_headlen(skb) < sizeof(struct batman_packet))
619                 return NET_RX_DROP;
620
621         ethhdr = (struct ethhdr *)skb_mac_header(skb);
622
623         /* packet with broadcast indication but unicast recipient */
624         if (!is_bcast(ethhdr->h_dest))
625                 return NET_RX_DROP;
626
627         /* packet with broadcast sender address */
628         if (is_bcast(ethhdr->h_source))
629                 return NET_RX_DROP;
630
631         /* TODO: we use headlen instead of "length", because
632          * only this data is paged in. */
633
634         /* create a copy of the skb, if needed, to modify it. */
635         if (!skb_clone_writable(skb, skb_headlen(skb))) {
636                 skb_old = skb;
637                 skb = skb_copy(skb, GFP_ATOMIC);
638                 if (!skb)
639                         return NET_RX_DROP;
640                 ethhdr = (struct ethhdr *)skb_mac_header(skb);
641                 kfree_skb(skb_old);
642         }
643
644         spin_lock_irqsave(&orig_hash_lock, flags);
645         receive_aggr_bat_packet(ethhdr,
646                                 skb->data,
647                                 skb_headlen(skb),
648                                 batman_if);
649         spin_unlock_irqrestore(&orig_hash_lock, flags);
650
651         kfree_skb(skb);
652         return NET_RX_SUCCESS;
653 }
654
655 static int recv_my_icmp_packet(struct sk_buff *skb)
656 {
657         struct orig_node *orig_node;
658         struct icmp_packet *icmp_packet;
659         struct ethhdr *ethhdr;
660         struct sk_buff *skb_old;
661         struct batman_if *batman_if;
662         int ret;
663         unsigned long flags;
664         uint8_t dstaddr[ETH_ALEN];
665
666         icmp_packet = (struct icmp_packet *)skb->data;
667         ethhdr = (struct ethhdr *)skb_mac_header(skb);
668
669         /* add data to device queue */
670         if (icmp_packet->msg_type != ECHO_REQUEST) {
671                 bat_device_receive_packet(icmp_packet);
672                 return NET_RX_DROP;
673         }
674
675         /* answer echo request (ping) */
676         /* get routing information */
677         spin_lock_irqsave(&orig_hash_lock, flags);
678         orig_node = ((struct orig_node *)hash_find(orig_hash,
679                                                    icmp_packet->orig));
680         ret = NET_RX_DROP;
681
682         if ((orig_node != NULL) &&
683             (orig_node->router != NULL)) {
684
685                 /* don't lock while sending the packets ... we therefore
686                  * copy the required data before sending */
687                 batman_if = orig_node->router->if_incoming;
688                 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
689                 spin_unlock_irqrestore(&orig_hash_lock, flags);
690
691                 /* create a copy of the skb, if needed, to modify it. */
692                 skb_old = NULL;
693                 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
694                         skb_old = skb;
695                         skb = skb_copy(skb, GFP_ATOMIC);
696                         if (!skb)
697                                 return NET_RX_DROP;
698
699                         icmp_packet = (struct icmp_packet *)skb->data;
700                         ethhdr = (struct ethhdr *)skb_mac_header(skb);
701                         kfree_skb(skb_old);
702                 }
703
704                 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
705                 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
706                 icmp_packet->msg_type = ECHO_REPLY;
707                 icmp_packet->ttl = TTL;
708
709                 send_skb_packet(skb, batman_if, dstaddr);
710                 ret = NET_RX_SUCCESS;
711
712         } else
713                 spin_unlock_irqrestore(&orig_hash_lock, flags);
714
715         return ret;
716 }
717
718 static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
719 {
720         struct orig_node *orig_node;
721         struct icmp_packet *icmp_packet;
722         struct ethhdr *ethhdr;
723         struct sk_buff *skb_old;
724         struct batman_if *batman_if;
725         int ret;
726         unsigned long flags;
727         uint8_t dstaddr[ETH_ALEN];
728
729         icmp_packet = (struct icmp_packet *)skb->data;
730         ethhdr = (struct ethhdr *)skb_mac_header(skb);
731
732         /* send TTL exceeded if packet is an echo request (traceroute) */
733         if (icmp_packet->msg_type != ECHO_REQUEST) {
734                 printk(KERN_WARNING "batman-adv:"
735                        "Warning - can't forward icmp packet from %pM to %pM: "
736                        "ttl exceeded\n",
737                        icmp_packet->orig, icmp_packet->dst);
738                 return NET_RX_DROP;
739         }
740
741         /* get routing information */
742         spin_lock_irqsave(&orig_hash_lock, flags);
743         orig_node = ((struct orig_node *)
744                      hash_find(orig_hash, icmp_packet->orig));
745         ret = NET_RX_DROP;
746
747         if ((orig_node != NULL) &&
748             (orig_node->router != NULL)) {
749
750                 /* don't lock while sending the packets ... we therefore
751                  * copy the required data before sending */
752                 batman_if = orig_node->router->if_incoming;
753                 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
754                 spin_unlock_irqrestore(&orig_hash_lock, flags);
755
756                 /* create a copy of the skb, if needed, to modify it. */
757                 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
758                         skb_old = skb;
759                         skb = skb_copy(skb, GFP_ATOMIC);
760                         if (!skb)
761                                 return NET_RX_DROP;
762                         icmp_packet = (struct icmp_packet *) skb->data;
763                         ethhdr = (struct ethhdr *)skb_mac_header(skb);
764                         kfree_skb(skb_old);
765                 }
766
767                 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
768                 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
769                 icmp_packet->msg_type = TTL_EXCEEDED;
770                 icmp_packet->ttl = TTL;
771
772                 send_skb_packet(skb, batman_if, dstaddr);
773                 ret = NET_RX_SUCCESS;
774
775         } else
776                 spin_unlock_irqrestore(&orig_hash_lock, flags);
777
778         return ret;
779 }
780
781
782 int recv_icmp_packet(struct sk_buff *skb)
783 {
784         struct icmp_packet *icmp_packet;
785         struct ethhdr *ethhdr;
786         struct orig_node *orig_node;
787         struct sk_buff *skb_old;
788         struct batman_if *batman_if;
789         int hdr_size = sizeof(struct icmp_packet);
790         int ret;
791         unsigned long flags;
792         uint8_t dstaddr[ETH_ALEN];
793
794         /* drop packet if it has not necessary minimum size */
795         if (skb_headlen(skb) < hdr_size)
796                 return NET_RX_DROP;
797
798         ethhdr = (struct ethhdr *)skb_mac_header(skb);
799
800         /* packet with unicast indication but broadcast recipient */
801         if (is_bcast(ethhdr->h_dest))
802                 return NET_RX_DROP;
803
804         /* packet with broadcast sender address */
805         if (is_bcast(ethhdr->h_source))
806                 return NET_RX_DROP;
807
808         /* not for me */
809         if (!is_my_mac(ethhdr->h_dest))
810                 return NET_RX_DROP;
811
812         icmp_packet = (struct icmp_packet *)skb->data;
813
814         /* packet for me */
815         if (is_my_mac(icmp_packet->dst))
816                 return recv_my_icmp_packet(skb);
817
818         /* TTL exceeded */
819         if (icmp_packet->ttl < 2)
820                 return recv_icmp_ttl_exceeded(skb);
821
822         ret = NET_RX_DROP;
823
824         /* get routing information */
825         spin_lock_irqsave(&orig_hash_lock, flags);
826         orig_node = ((struct orig_node *)
827                      hash_find(orig_hash, icmp_packet->dst));
828
829         if ((orig_node != NULL) &&
830             (orig_node->router != NULL)) {
831
832                 /* don't lock while sending the packets ... we therefore
833                  * copy the required data before sending */
834                 batman_if = orig_node->router->if_incoming;
835                 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
836                 spin_unlock_irqrestore(&orig_hash_lock, flags);
837
838                 /* create a copy of the skb, if needed, to modify it. */
839                 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
840                         skb_old = skb;
841                         skb = skb_copy(skb, GFP_ATOMIC);
842                         if (!skb)
843                                 return NET_RX_DROP;
844                         icmp_packet = (struct icmp_packet *)skb->data;
845                         ethhdr = (struct ethhdr *)skb_mac_header(skb);
846                         kfree_skb(skb_old);
847                 }
848
849                 /* decrement ttl */
850                 icmp_packet->ttl--;
851
852                 /* route it */
853                 send_skb_packet(skb, batman_if, dstaddr);
854                 ret = NET_RX_SUCCESS;
855
856         } else
857                 spin_unlock_irqrestore(&orig_hash_lock, flags);
858
859         return ret;
860 }
861
862 int recv_unicast_packet(struct sk_buff *skb)
863 {
864         struct unicast_packet *unicast_packet;
865         struct orig_node *orig_node;
866         struct ethhdr *ethhdr;
867         struct batman_if *batman_if;
868         struct sk_buff *skb_old;
869         uint8_t dstaddr[ETH_ALEN];
870         int hdr_size = sizeof(struct unicast_packet);
871         int ret;
872         unsigned long flags;
873
874         /* drop packet if it has not necessary minimum size */
875         if (skb_headlen(skb) < hdr_size)
876                 return NET_RX_DROP;
877
878         ethhdr = (struct ethhdr *) skb_mac_header(skb);
879
880         /* packet with unicast indication but broadcast recipient */
881         if (is_bcast(ethhdr->h_dest))
882                 return NET_RX_DROP;
883
884         /* packet with broadcast sender address */
885         if (is_bcast(ethhdr->h_source))
886                 return NET_RX_DROP;
887
888         /* not for me */
889         if (!is_my_mac(ethhdr->h_dest))
890                 return NET_RX_DROP;
891
892         unicast_packet = (struct unicast_packet *) skb->data;
893
894         /* packet for me */
895         if (is_my_mac(unicast_packet->dest)) {
896                 interface_rx(skb, hdr_size);
897                 return NET_RX_SUCCESS;
898         }
899
900         /* TTL exceeded */
901         if (unicast_packet->ttl < 2) {
902                 printk(KERN_WARNING "batman-adv:Warning - "
903                        "can't forward unicast packet from %pM to %pM: "
904                        "ttl exceeded\n",
905                        ethhdr->h_source, unicast_packet->dest);
906                 return NET_RX_DROP;
907         }
908
909         ret = NET_RX_DROP;
910         /* get routing information */
911         spin_lock_irqsave(&orig_hash_lock, flags);
912         orig_node = ((struct orig_node *)
913                      hash_find(orig_hash, unicast_packet->dest));
914
915         if ((orig_node != NULL) &&
916             (orig_node->router != NULL)) {
917
918                 /* don't lock while sending the packets ... we therefore
919                  * copy the required data before sending */
920                 batman_if = orig_node->router->if_incoming;
921                 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
922                 spin_unlock_irqrestore(&orig_hash_lock, flags);
923
924                 /* create a copy of the skb, if needed, to modify it. */
925                 if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) {
926                         skb_old = skb;
927                         skb = skb_copy(skb, GFP_ATOMIC);
928                         if (!skb)
929                                 return NET_RX_DROP;
930                         unicast_packet = (struct unicast_packet *)skb->data;
931                         ethhdr = (struct ethhdr *)skb_mac_header(skb);
932                         kfree_skb(skb_old);
933                 }
934                 /* decrement ttl */
935                 unicast_packet->ttl--;
936
937                 /* route it */
938                 send_skb_packet(skb, batman_if, dstaddr);
939                 ret = NET_RX_SUCCESS;
940
941         } else
942                 spin_unlock_irqrestore(&orig_hash_lock, flags);
943
944         return ret;
945 }
946
947 int recv_bcast_packet(struct sk_buff *skb)
948 {
949         struct orig_node *orig_node;
950         struct bcast_packet *bcast_packet;
951         struct ethhdr *ethhdr;
952         int hdr_size = sizeof(struct bcast_packet);
953         int16_t seq_diff;
954         unsigned long flags;
955
956         /* drop packet if it has not necessary minimum size */
957         if (skb_headlen(skb) < hdr_size)
958                 return NET_RX_DROP;
959
960         ethhdr = (struct ethhdr *)skb_mac_header(skb);
961
962         /* packet with broadcast indication but unicast recipient */
963         if (!is_bcast(ethhdr->h_dest))
964                 return NET_RX_DROP;
965
966         /* packet with broadcast sender address */
967         if (is_bcast(ethhdr->h_source))
968                 return NET_RX_DROP;
969
970         /* ignore broadcasts sent by myself */
971         if (is_my_mac(ethhdr->h_source))
972                 return NET_RX_DROP;
973
974         bcast_packet = (struct bcast_packet *)skb->data;
975
976         /* ignore broadcasts originated by myself */
977         if (is_my_mac(bcast_packet->orig))
978                 return NET_RX_DROP;
979
980         spin_lock_irqsave(&orig_hash_lock, flags);
981         orig_node = ((struct orig_node *)
982                      hash_find(orig_hash, bcast_packet->orig));
983
984         if (orig_node == NULL) {
985                 spin_unlock_irqrestore(&orig_hash_lock, flags);
986                 return NET_RX_DROP;
987         }
988
989         /* check whether the packet is a duplicate */
990         if (get_bit_status(orig_node->bcast_bits,
991                            orig_node->last_bcast_seqno,
992                            ntohs(bcast_packet->seqno))) {
993                 spin_unlock_irqrestore(&orig_hash_lock, flags);
994                 return NET_RX_DROP;
995         }
996
997         seq_diff = ntohs(bcast_packet->seqno) - orig_node->last_bcast_seqno;
998
999         /* check whether the packet is old and the host just restarted. */
1000         if (window_protected(seq_diff, &orig_node->bcast_seqno_reset)) {
1001                 spin_unlock_irqrestore(&orig_hash_lock, flags);
1002                 return NET_RX_DROP;
1003         }
1004
1005         /* mark broadcast in flood history, update window position
1006          * if required. */
1007         if (bit_get_packet(orig_node->bcast_bits, seq_diff, 1))
1008                 orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
1009
1010         spin_unlock_irqrestore(&orig_hash_lock, flags);
1011         /* rebroadcast packet */
1012         add_bcast_packet_to_list(skb);
1013
1014         /* broadcast for me */
1015         interface_rx(skb, hdr_size);
1016
1017         return NET_RX_SUCCESS;
1018 }
1019
1020 int recv_vis_packet(struct sk_buff *skb)
1021 {
1022         struct vis_packet *vis_packet;
1023         struct ethhdr *ethhdr;
1024         struct bat_priv *bat_priv;
1025         int hdr_size = sizeof(struct vis_packet);
1026
1027         if (skb_headlen(skb) < hdr_size)
1028                 return NET_RX_DROP;
1029
1030         vis_packet = (struct vis_packet *) skb->data;
1031         ethhdr = (struct ethhdr *)skb_mac_header(skb);
1032
1033         /* not for me */
1034         if (!is_my_mac(ethhdr->h_dest))
1035                 return NET_RX_DROP;
1036
1037         /* ignore own packets */
1038         if (is_my_mac(vis_packet->vis_orig))
1039                 return NET_RX_DROP;
1040
1041         if (is_my_mac(vis_packet->sender_orig))
1042                 return NET_RX_DROP;
1043
1044         /* FIXME: each batman_if will be attached to a softif */
1045         bat_priv = netdev_priv(soft_device);
1046
1047         switch (vis_packet->vis_type) {
1048         case VIS_TYPE_SERVER_SYNC:
1049                 /* TODO: handle fragmented skbs properly */
1050                 receive_server_sync_packet(bat_priv, vis_packet,
1051                                            skb_headlen(skb));
1052                 break;
1053
1054         case VIS_TYPE_CLIENT_UPDATE:
1055                 /* TODO: handle fragmented skbs properly */
1056                 receive_client_update_packet(bat_priv, vis_packet,
1057                                              skb_headlen(skb));
1058                 break;
1059
1060         default:        /* ignore unknown packet */
1061                 break;
1062         }
1063
1064         /* We take a copy of the data in the packet, so we should
1065            always free the skbuf. */
1066         return NET_RX_DROP;
1067 }