Merge branch 'master' into next
[pandora-kernel.git] / drivers / staging / batman-adv / routing.c
1 /*
2  * Copyright (C) 2007-2009 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
553         /* drop packet if it has not necessary minimum size */
554         if (skb_headlen(skb) < sizeof(struct batman_packet))
555                 return NET_RX_DROP;
556
557         ethhdr = (struct ethhdr *)skb_mac_header(skb);
558
559         /* packet with broadcast indication but unicast recipient */
560         if (!is_bcast(ethhdr->h_dest))
561                 return NET_RX_DROP;
562
563         /* packet with broadcast sender address */
564         if (is_bcast(ethhdr->h_source))
565                 return NET_RX_DROP;
566
567         spin_lock_irqsave(&orig_hash_lock, flags);
568         /* TODO: we use headlen instead of "length", because
569          * only this data is paged in. */
570         /* TODO: is another skb_copy needed here? there will be
571          * written on the data, but nobody (?) should further use
572          * this data */
573         receive_aggr_bat_packet(ethhdr,
574                                 skb->data,
575                                 skb_headlen(skb),
576                                 batman_if);
577         spin_unlock_irqrestore(&orig_hash_lock, flags);
578
579         kfree_skb(skb);
580         return NET_RX_SUCCESS;
581 }
582
583 static int recv_my_icmp_packet(struct sk_buff *skb)
584 {
585         struct orig_node *orig_node;
586         struct icmp_packet *icmp_packet;
587         struct ethhdr *ethhdr;
588         struct sk_buff *skb_old;
589         struct batman_if *batman_if;
590         int ret;
591         unsigned long flags;
592         uint8_t dstaddr[ETH_ALEN];
593
594         icmp_packet = (struct icmp_packet *) skb->data;
595         ethhdr = (struct ethhdr *) skb_mac_header(skb);
596
597         /* add data to device queue */
598         if (icmp_packet->msg_type != ECHO_REQUEST) {
599                 bat_device_receive_packet(icmp_packet);
600                 return NET_RX_DROP;
601         }
602
603         /* answer echo request (ping) */
604         /* get routing information */
605         spin_lock_irqsave(&orig_hash_lock, flags);
606         orig_node = ((struct orig_node *)hash_find(orig_hash,
607                                                    icmp_packet->orig));
608         ret = NET_RX_DROP;
609
610         if ((orig_node != NULL) &&
611             (orig_node->batman_if != NULL) &&
612             (orig_node->router != NULL)) {
613
614                 /* don't lock while sending the packets ... we therefore
615                  * copy the required data before sending */
616                 batman_if = orig_node->batman_if;
617                 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
618                 spin_unlock_irqrestore(&orig_hash_lock, flags);
619
620                 /* create a copy of the skb, if needed, to modify it. */
621                 skb_old = NULL;
622                 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
623                         skb_old = skb;
624                         skb = skb_copy(skb, GFP_ATOMIC);
625                         if (!skb)
626                                 return NET_RX_DROP;
627                         icmp_packet = (struct icmp_packet *) skb->data;
628                         kfree_skb(skb_old);
629                 }
630
631                 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
632                 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
633                 icmp_packet->msg_type = ECHO_REPLY;
634                 icmp_packet->ttl = TTL;
635
636                 send_skb_packet(skb, batman_if, dstaddr);
637                 ret = NET_RX_SUCCESS;
638
639         } else
640                 spin_unlock_irqrestore(&orig_hash_lock, flags);
641
642         return ret;
643 }
644
645 static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
646 {
647         struct orig_node *orig_node;
648         struct icmp_packet *icmp_packet;
649         struct ethhdr *ethhdr;
650         struct sk_buff *skb_old;
651         struct batman_if *batman_if;
652         int ret;
653         unsigned long flags;
654         uint8_t dstaddr[ETH_ALEN];
655
656         icmp_packet = (struct icmp_packet *)skb->data;
657         ethhdr = (struct ethhdr *)skb_mac_header(skb);
658
659         /* send TTL exceeded if packet is an echo request (traceroute) */
660         if (icmp_packet->msg_type != ECHO_REQUEST) {
661                 printk(KERN_WARNING "batman-adv:Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n",
662                         icmp_packet->orig, icmp_packet->dst);
663                 return NET_RX_DROP;
664         }
665
666         /* get routing information */
667         spin_lock_irqsave(&orig_hash_lock, flags);
668         orig_node = ((struct orig_node *)
669                      hash_find(orig_hash, icmp_packet->orig));
670         ret = NET_RX_DROP;
671
672         if ((orig_node != NULL) &&
673             (orig_node->batman_if != NULL) &&
674             (orig_node->router != NULL)) {
675
676                 /* don't lock while sending the packets ... we therefore
677                  * copy the required data before sending */
678                 batman_if = orig_node->batman_if;
679                 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
680                 spin_unlock_irqrestore(&orig_hash_lock, flags);
681
682                 /* create a copy of the skb, if needed, to modify it. */
683                 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
684                         skb_old = skb;
685                         skb = skb_copy(skb, GFP_ATOMIC);
686                         if (!skb)
687                                 return NET_RX_DROP;
688                         icmp_packet = (struct icmp_packet *) skb->data;
689                         kfree_skb(skb_old);
690                 }
691
692                 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
693                 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
694                 icmp_packet->msg_type = TTL_EXCEEDED;
695                 icmp_packet->ttl = TTL;
696
697                 send_skb_packet(skb, batman_if, dstaddr);
698                 ret = NET_RX_SUCCESS;
699
700         } else
701                 spin_unlock_irqrestore(&orig_hash_lock, flags);
702
703         return ret;
704 }
705
706
707 int recv_icmp_packet(struct sk_buff *skb)
708 {
709         struct icmp_packet *icmp_packet;
710         struct ethhdr *ethhdr;
711         struct orig_node *orig_node;
712         struct sk_buff *skb_old;
713         struct batman_if *batman_if;
714         int hdr_size = sizeof(struct icmp_packet);
715         int ret;
716         unsigned long flags;
717         uint8_t dstaddr[ETH_ALEN];
718
719         /* drop packet if it has not necessary minimum size */
720         if (skb_headlen(skb) < hdr_size)
721                 return NET_RX_DROP;
722
723         ethhdr = (struct ethhdr *)skb_mac_header(skb);
724
725         /* packet with unicast indication but broadcast recipient */
726         if (is_bcast(ethhdr->h_dest))
727                 return NET_RX_DROP;
728
729         /* packet with broadcast sender address */
730         if (is_bcast(ethhdr->h_source))
731                 return NET_RX_DROP;
732
733         /* not for me */
734         if (!is_my_mac(ethhdr->h_dest))
735                 return NET_RX_DROP;
736
737         icmp_packet = (struct icmp_packet *) skb->data;
738
739         /* packet for me */
740         if (is_my_mac(icmp_packet->dst))
741                 return recv_my_icmp_packet(skb);
742
743         /* TTL exceeded */
744         if (icmp_packet->ttl < 2)
745                 return recv_icmp_ttl_exceeded(skb);
746
747         ret = NET_RX_DROP;
748
749         /* get routing information */
750         spin_lock_irqsave(&orig_hash_lock, flags);
751         orig_node = ((struct orig_node *)
752                      hash_find(orig_hash, icmp_packet->dst));
753
754         if ((orig_node != NULL) &&
755             (orig_node->batman_if != NULL) &&
756             (orig_node->router != NULL)) {
757
758                 /* don't lock while sending the packets ... we therefore
759                  * copy the required data before sending */
760                 batman_if = orig_node->batman_if;
761                 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
762                 spin_unlock_irqrestore(&orig_hash_lock, flags);
763
764                 /* create a copy of the skb, if needed, to modify it. */
765                 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
766                         skb_old = skb;
767                         skb = skb_copy(skb, GFP_ATOMIC);
768                         if (!skb)
769                                 return NET_RX_DROP;
770                         icmp_packet = (struct icmp_packet *) skb->data;
771                         kfree_skb(skb_old);
772                 }
773
774                 /* decrement ttl */
775                 icmp_packet->ttl--;
776
777                 /* route it */
778                 send_skb_packet(skb, batman_if, dstaddr);
779                 ret = NET_RX_SUCCESS;
780
781         } else
782                 spin_unlock_irqrestore(&orig_hash_lock, flags);
783
784         return ret;
785 }
786
787 int recv_unicast_packet(struct sk_buff *skb)
788 {
789         struct unicast_packet *unicast_packet;
790         struct orig_node *orig_node;
791         struct ethhdr *ethhdr;
792         struct batman_if *batman_if;
793         struct sk_buff *skb_old;
794         uint8_t dstaddr[ETH_ALEN];
795         int hdr_size = sizeof(struct unicast_packet);
796         int ret;
797         unsigned long flags;
798
799         /* drop packet if it has not necessary minimum size */
800         if (skb_headlen(skb) < hdr_size)
801                 return NET_RX_DROP;
802
803         ethhdr = (struct ethhdr *) skb_mac_header(skb);
804
805         /* packet with unicast indication but broadcast recipient */
806         if (is_bcast(ethhdr->h_dest))
807                 return NET_RX_DROP;
808
809         /* packet with broadcast sender address */
810         if (is_bcast(ethhdr->h_source))
811                 return NET_RX_DROP;
812
813         /* not for me */
814         if (!is_my_mac(ethhdr->h_dest))
815                 return NET_RX_DROP;
816
817         unicast_packet = (struct unicast_packet *) skb->data;
818
819         /* packet for me */
820         if (is_my_mac(unicast_packet->dest)) {
821                 interface_rx(skb, hdr_size);
822                 return NET_RX_SUCCESS;
823         }
824
825         /* TTL exceeded */
826         if (unicast_packet->ttl < 2) {
827                 printk(KERN_WARNING "batman-adv:Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n",
828                        ethhdr->h_source, unicast_packet->dest);
829                 return NET_RX_DROP;
830         }
831
832         ret = NET_RX_DROP;
833         /* get routing information */
834         spin_lock_irqsave(&orig_hash_lock, flags);
835         orig_node = ((struct orig_node *)
836                      hash_find(orig_hash, unicast_packet->dest));
837
838         if ((orig_node != NULL) &&
839             (orig_node->batman_if != NULL) &&
840             (orig_node->router != NULL)) {
841
842                 /* don't lock while sending the packets ... we therefore
843                  * copy the required data before sending */
844                 batman_if = orig_node->batman_if;
845                 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
846                 spin_unlock_irqrestore(&orig_hash_lock, flags);
847
848                 /* create a copy of the skb, if needed, to modify it. */
849                 if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) {
850                         skb_old = skb;
851                         skb = skb_copy(skb, GFP_ATOMIC);
852                         if (!skb)
853                                 return NET_RX_DROP;
854                         unicast_packet = (struct unicast_packet *) skb->data;
855                         kfree_skb(skb_old);
856                 }
857                 /* decrement ttl */
858                 unicast_packet->ttl--;
859
860                 /* route it */
861                 send_skb_packet(skb, batman_if, dstaddr);
862                 ret = NET_RX_SUCCESS;
863
864         } else
865                 spin_unlock_irqrestore(&orig_hash_lock, flags);
866
867         return ret;
868 }
869
870
871 int recv_bcast_packet(struct sk_buff *skb)
872 {
873         struct orig_node *orig_node;
874         struct bcast_packet *bcast_packet;
875         struct ethhdr *ethhdr;
876         int hdr_size = sizeof(struct bcast_packet);
877         unsigned long flags;
878
879         /* drop packet if it has not necessary minimum size */
880         if (skb_headlen(skb) < hdr_size)
881                 return NET_RX_DROP;
882
883         ethhdr = (struct ethhdr *)skb_mac_header(skb);
884
885         /* packet with broadcast indication but unicast recipient */
886         if (!is_bcast(ethhdr->h_dest))
887                 return NET_RX_DROP;
888
889         /* packet with broadcast sender address */
890         if (is_bcast(ethhdr->h_source))
891                 return NET_RX_DROP;
892
893         /* ignore broadcasts sent by myself */
894         if (is_my_mac(ethhdr->h_source))
895                 return NET_RX_DROP;
896
897         bcast_packet = (struct bcast_packet *) skb->data;
898
899         /* ignore broadcasts originated by myself */
900         if (is_my_mac(bcast_packet->orig))
901                 return NET_RX_DROP;
902
903         spin_lock_irqsave(&orig_hash_lock, flags);
904         orig_node = ((struct orig_node *)
905                      hash_find(orig_hash, bcast_packet->orig));
906
907         if (orig_node == NULL) {
908                 spin_unlock_irqrestore(&orig_hash_lock, flags);
909                 return NET_RX_DROP;
910         }
911
912         /* check flood history */
913         if (get_bit_status(orig_node->bcast_bits,
914                            orig_node->last_bcast_seqno,
915                            ntohs(bcast_packet->seqno))) {
916                 spin_unlock_irqrestore(&orig_hash_lock, flags);
917                 return NET_RX_DROP;
918         }
919
920         /* mark broadcast in flood history */
921         if (bit_get_packet(orig_node->bcast_bits,
922                            ntohs(bcast_packet->seqno) -
923                            orig_node->last_bcast_seqno, 1))
924                 orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
925
926         spin_unlock_irqrestore(&orig_hash_lock, flags);
927
928         /* rebroadcast packet */
929         add_bcast_packet_to_list(skb);
930
931         /* broadcast for me */
932         interface_rx(skb, hdr_size);
933
934         return NET_RX_SUCCESS;
935 }
936
937 int recv_vis_packet(struct sk_buff *skb)
938 {
939         struct vis_packet *vis_packet;
940         struct ethhdr *ethhdr;
941         int hdr_size = sizeof(struct vis_packet);
942
943         if (skb_headlen(skb) < hdr_size)
944                 return NET_RX_DROP;
945
946         vis_packet = (struct vis_packet *) skb->data;
947         ethhdr = (struct ethhdr *)skb_mac_header(skb);
948
949         /* not for me */
950         if (!is_my_mac(ethhdr->h_dest))
951                 return NET_RX_DROP;
952
953         /* ignore own packets */
954         if (is_my_mac(vis_packet->vis_orig))
955                 return NET_RX_DROP;
956
957         if (is_my_mac(vis_packet->sender_orig))
958                 return NET_RX_DROP;
959
960         switch (vis_packet->vis_type) {
961         case VIS_TYPE_SERVER_SYNC:
962                 /* TODO: handle fragmented skbs properly */
963                 receive_server_sync_packet(vis_packet, skb_headlen(skb));
964                 break;
965
966         case VIS_TYPE_CLIENT_UPDATE:
967                 /* TODO: handle fragmented skbs properly */
968                 receive_client_update_packet(vis_packet, skb_headlen(skb));
969                 break;
970
971         default:        /* ignore unknown packet */
972                 break;
973         }
974
975         /* We take a copy of the data in the packet, so we should
976            always free the skbuf. */
977         return NET_RX_DROP;
978 }