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