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