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