2 * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
4 * Marek Lindner, Simon Wunderlich
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.
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.
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
26 #include "soft-interface.h"
27 #include "hard-interface.h"
29 #include "translation-table.h"
30 #include "originator.h"
32 #include "ring_buffer.h"
34 #include "aggregation.h"
36 DECLARE_WAIT_QUEUE_HEAD(thread_wait);
40 void slide_own_bcast_window(struct batman_if *batman_if)
43 struct orig_node *orig_node;
47 spin_lock_irqsave(&orig_hash_lock, flags);
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]);
53 bit_get_packet(word, 1, 0);
54 orig_node->bcast_own_sum[batman_if->if_num] =
55 bit_packet_count(word);
58 spin_unlock_irqrestore(&orig_hash_lock, flags);
61 static void update_HNA(struct orig_node *orig_node,
62 unsigned char *hna_buff, int hna_buff_len)
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))) {
69 if (orig_node->hna_buff_len > 0)
70 hna_global_del_orig(orig_node,
71 "originator changed hna");
73 if ((hna_buff_len > 0) && (hna_buff != NULL))
74 hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
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)
83 if ((orig_node->router != NULL) && (neigh_node == NULL)) {
85 bat_dbg(DBG_ROUTES, "Deleting route towards: %pM\n",
87 hna_global_del_orig(orig_node, "originator timed out");
90 } else if ((orig_node->router == NULL) && (neigh_node != NULL)) {
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);
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);
102 if (neigh_node != NULL)
103 orig_node->batman_if = neigh_node->if_incoming;
105 orig_node->batman_if = NULL;
107 orig_node->router = neigh_node;
111 void update_routes(struct orig_node *orig_node,
112 struct neigh_node *neigh_node,
113 unsigned char *hna_buff, int hna_buff_len)
116 if (orig_node == NULL)
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 */
123 update_HNA(orig_node, hna_buff, hna_buff_len);
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)
131 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
132 unsigned char total_count;
134 if (orig_node == orig_neigh_node) {
135 list_for_each_entry(tmp_neigh_node,
136 &orig_node->neigh_list,
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;
146 neigh_node = create_neighbor(orig_node,
148 orig_neigh_node->orig,
150 /* create_neighbor failed, return 0 */
154 neigh_node->last_valid = jiffies;
156 /* find packet count of corresponding one hop neighbor */
157 list_for_each_entry(tmp_neigh_node,
158 &orig_neigh_node->neigh_list, list) {
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;
167 neigh_node = create_neighbor(orig_neigh_node,
169 orig_neigh_node->orig,
171 /* create_neighbor failed, return 0 */
176 orig_node->last_valid = jiffies;
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]);
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;
190 /* neigh_node->real_packet_count is never zero as we
191 * only purge old information when getting new
193 orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) /
194 neigh_node->real_packet_count;
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
202 orig_neigh_node->tq_asym_penalty =
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);
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));
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);
222 /* if link has the minimum required transmission quality
223 * consider it bidirectional */
224 if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
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,
236 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
237 int tmp_hna_buff_len;
239 bat_dbg(DBG_BATMAN, "update_originator(): Searching and updating originator entry of received packet \n");
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;
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);
258 struct orig_node *orig_tmp;
260 orig_tmp = get_orig_node(ethhdr->h_source);
264 neigh_node = create_neighbor(orig_node,
266 ethhdr->h_source, if_incoming);
271 "Updating existing last-hop neighbor of originator\n");
273 orig_node->flags = batman_packet->flags;
274 neigh_node->last_valid = jiffies;
276 ring_buffer_set(neigh_node->tq_recv,
277 &neigh_node->tq_index,
279 neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
282 orig_node->last_ttl = batman_packet->ttl;
283 neigh_node->last_ttl = batman_packet->ttl;
286 tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ?
287 batman_packet->num_hna * ETH_ALEN : hna_buff_len);
289 /* if this neighbor already is our next hop there is nothing
291 if (orig_node->router == neigh_node)
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))
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])))
307 update_routes(orig_node, neigh_node, hna_buff, tmp_hna_buff_len);
311 update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len);
314 static char count_real_packets(struct ethhdr *ethhdr,
315 struct batman_packet *batman_packet,
316 struct batman_if *if_incoming)
318 struct orig_node *orig_node;
319 struct neigh_node *tmp_neigh_node;
320 char is_duplicate = 0;
323 orig_node = get_orig_node(batman_packet->orig);
324 if (orig_node == NULL)
327 list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
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);
339 bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 0);
341 tmp_neigh_node->real_packet_count =
342 bit_packet_count(tmp_neigh_node->real_bits);
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;
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)
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;
365 unsigned short if_incoming_seqno;
367 /* Silently drop when the batman packet is actually not a
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.
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)
379 if (batman_packet->packet_type != BAT_PACKET)
382 /* could be changed by schedule_own_packet() */
383 if_incoming_seqno = atomic_read(&if_incoming->seqno);
385 has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0);
387 is_single_hop_neigh = (compare_orig(ethhdr->h_source,
388 batman_packet->orig) ? 1 : 0);
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);
396 list_for_each_entry_rcu(batman_if, &if_list, list) {
397 if (batman_if->if_active != IF_ACTIVE)
400 if (compare_orig(ethhdr->h_source,
401 batman_if->net_dev->dev_addr))
404 if (compare_orig(batman_packet->orig,
405 batman_if->net_dev->dev_addr))
408 if (compare_orig(batman_packet->prev_sender,
409 batman_if->net_dev->dev_addr))
412 if (compare_orig(ethhdr->h_source, broadcastAddr))
416 if (batman_packet->version != COMPAT_VERSION) {
418 "Drop packet: incompatible batman version (%i)\n",
419 batman_packet->version);
425 "Drop packet: received my own broadcast (sender: %pM)\n",
431 bat_dbg(DBG_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %pM) \n", ethhdr->h_source);
439 orig_neigh_node = get_orig_node(ethhdr->h_source);
441 if (!orig_neigh_node)
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]);
455 orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
456 bit_packet_count(word);
459 bat_dbg(DBG_BATMAN, "Drop packet: originator packet from myself (via neighbor) \n");
463 if (batman_packet->tq == 0) {
464 count_real_packets(ethhdr, batman_packet, if_incoming);
466 bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0 \n");
471 bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM) \n", ethhdr->h_source);
475 is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming);
477 orig_node = get_orig_node(batman_packet->orig);
478 if (orig_node == NULL)
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);
493 /* if sender is a direct neighbor the sender mac equals
495 orig_neigh_node = (is_single_hop_neigh ?
496 orig_node : get_orig_node(ethhdr->h_source));
497 if (orig_neigh_node == NULL)
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");
508 is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node,
509 batman_packet, if_incoming);
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 &&
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);
520 /* is single hop (direct) neighbor */
521 if (is_single_hop_neigh) {
523 /* mark direct link on incoming interface */
524 schedule_forward_packet(orig_node, ethhdr, batman_packet,
525 1, hna_buff_len, if_incoming);
527 bat_dbg(DBG_BATMAN, "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
531 /* multihop originator */
532 if (!is_bidirectional) {
534 "Drop packet: not received via bidirectional link\n");
539 bat_dbg(DBG_BATMAN, "Drop packet: duplicate packet received\n");
544 "Forwarding packet: rebroadcast originator packet\n");
545 schedule_forward_packet(orig_node, ethhdr, batman_packet,
546 0, hna_buff_len, if_incoming);
549 int recv_bat_packet(struct sk_buff *skb,
550 struct batman_if *batman_if)
552 struct ethhdr *ethhdr;
555 /* drop packet if it has not necessary minimum size */
556 if (skb_headlen(skb) < sizeof(struct batman_packet))
559 ethhdr = (struct ethhdr *)skb_mac_header(skb);
561 /* packet with broadcast indication but unicast recipient */
562 if (!is_bcast(ethhdr->h_dest))
565 /* packet with broadcast sender address */
566 if (is_bcast(ethhdr->h_source))
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
575 receive_aggr_bat_packet(ethhdr,
579 spin_unlock_irqrestore(&orig_hash_lock, flags);
582 return NET_RX_SUCCESS;
585 static int recv_my_icmp_packet(struct sk_buff *skb)
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;
594 uint8_t dstaddr[ETH_ALEN];
596 icmp_packet = (struct icmp_packet *) skb->data;
597 ethhdr = (struct ethhdr *) skb_mac_header(skb);
599 /* add data to device queue */
600 if (icmp_packet->msg_type != ECHO_REQUEST) {
601 bat_device_receive_packet(icmp_packet);
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,
612 if ((orig_node != NULL) &&
613 (orig_node->batman_if != NULL) &&
614 (orig_node->router != NULL)) {
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);
622 /* create a copy of the skb, if needed, to modify it. */
624 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
626 skb = skb_copy(skb, GFP_ATOMIC);
629 icmp_packet = (struct icmp_packet *) skb->data;
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;
638 send_skb_packet(skb, batman_if, dstaddr);
639 ret = NET_RX_SUCCESS;
642 spin_unlock_irqrestore(&orig_hash_lock, flags);
647 static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
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;
656 uint8_t dstaddr[ETH_ALEN];
658 icmp_packet = (struct icmp_packet *)skb->data;
659 ethhdr = (struct ethhdr *)skb_mac_header(skb);
661 /* send TTL exceeded if packet is an echo request (traceroute) */
662 if (icmp_packet->msg_type != ECHO_REQUEST) {
663 printk(KERN_WARNING "batman-adv:Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n",
664 icmp_packet->orig, icmp_packet->dst);
668 /* get routing information */
669 spin_lock_irqsave(&orig_hash_lock, flags);
670 orig_node = ((struct orig_node *)
671 hash_find(orig_hash, icmp_packet->orig));
674 if ((orig_node != NULL) &&
675 (orig_node->batman_if != NULL) &&
676 (orig_node->router != NULL)) {
678 /* don't lock while sending the packets ... we therefore
679 * copy the required data before sending */
680 batman_if = orig_node->batman_if;
681 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
682 spin_unlock_irqrestore(&orig_hash_lock, flags);
684 /* create a copy of the skb, if needed, to modify it. */
685 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
687 skb = skb_copy(skb, GFP_ATOMIC);
690 icmp_packet = (struct icmp_packet *) skb->data;
694 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
695 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
696 icmp_packet->msg_type = TTL_EXCEEDED;
697 icmp_packet->ttl = TTL;
699 send_skb_packet(skb, batman_if, dstaddr);
700 ret = NET_RX_SUCCESS;
703 spin_unlock_irqrestore(&orig_hash_lock, flags);
709 int recv_icmp_packet(struct sk_buff *skb)
711 struct icmp_packet *icmp_packet;
712 struct ethhdr *ethhdr;
713 struct orig_node *orig_node;
714 struct sk_buff *skb_old;
715 struct batman_if *batman_if;
716 int hdr_size = sizeof(struct icmp_packet);
719 uint8_t dstaddr[ETH_ALEN];
721 /* drop packet if it has not necessary minimum size */
722 if (skb_headlen(skb) < hdr_size)
725 ethhdr = (struct ethhdr *)skb_mac_header(skb);
727 /* packet with unicast indication but broadcast recipient */
728 if (is_bcast(ethhdr->h_dest))
731 /* packet with broadcast sender address */
732 if (is_bcast(ethhdr->h_source))
736 if (!is_my_mac(ethhdr->h_dest))
739 icmp_packet = (struct icmp_packet *) skb->data;
742 if (is_my_mac(icmp_packet->dst))
743 return recv_my_icmp_packet(skb);
746 if (icmp_packet->ttl < 2)
747 return recv_icmp_ttl_exceeded(skb);
751 /* get routing information */
752 spin_lock_irqsave(&orig_hash_lock, flags);
753 orig_node = ((struct orig_node *)
754 hash_find(orig_hash, icmp_packet->dst));
756 if ((orig_node != NULL) &&
757 (orig_node->batman_if != NULL) &&
758 (orig_node->router != NULL)) {
760 /* don't lock while sending the packets ... we therefore
761 * copy the required data before sending */
762 batman_if = orig_node->batman_if;
763 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
764 spin_unlock_irqrestore(&orig_hash_lock, flags);
766 /* create a copy of the skb, if needed, to modify it. */
767 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
769 skb = skb_copy(skb, GFP_ATOMIC);
772 icmp_packet = (struct icmp_packet *) skb->data;
780 send_skb_packet(skb, batman_if, dstaddr);
781 ret = NET_RX_SUCCESS;
784 spin_unlock_irqrestore(&orig_hash_lock, flags);
789 int recv_unicast_packet(struct sk_buff *skb)
791 struct unicast_packet *unicast_packet;
792 struct orig_node *orig_node;
793 struct ethhdr *ethhdr;
794 struct batman_if *batman_if;
795 struct sk_buff *skb_old;
796 uint8_t dstaddr[ETH_ALEN];
797 int hdr_size = sizeof(struct unicast_packet);
801 /* drop packet if it has not necessary minimum size */
802 if (skb_headlen(skb) < hdr_size)
805 ethhdr = (struct ethhdr *) skb_mac_header(skb);
807 /* packet with unicast indication but broadcast recipient */
808 if (is_bcast(ethhdr->h_dest))
811 /* packet with broadcast sender address */
812 if (is_bcast(ethhdr->h_source))
816 if (!is_my_mac(ethhdr->h_dest))
819 unicast_packet = (struct unicast_packet *) skb->data;
822 if (is_my_mac(unicast_packet->dest)) {
823 interface_rx(skb, hdr_size);
824 return NET_RX_SUCCESS;
828 if (unicast_packet->ttl < 2) {
829 printk(KERN_WARNING "batman-adv:Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n",
830 ethhdr->h_source, unicast_packet->dest);
835 /* get routing information */
836 spin_lock_irqsave(&orig_hash_lock, flags);
837 orig_node = ((struct orig_node *)
838 hash_find(orig_hash, unicast_packet->dest));
840 if ((orig_node != NULL) &&
841 (orig_node->batman_if != NULL) &&
842 (orig_node->router != NULL)) {
844 /* don't lock while sending the packets ... we therefore
845 * copy the required data before sending */
846 batman_if = orig_node->batman_if;
847 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
848 spin_unlock_irqrestore(&orig_hash_lock, flags);
850 /* create a copy of the skb, if needed, to modify it. */
851 if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) {
853 skb = skb_copy(skb, GFP_ATOMIC);
856 unicast_packet = (struct unicast_packet *) skb->data;
860 unicast_packet->ttl--;
863 send_skb_packet(skb, batman_if, dstaddr);
864 ret = NET_RX_SUCCESS;
867 spin_unlock_irqrestore(&orig_hash_lock, flags);
873 int recv_bcast_packet(struct sk_buff *skb)
875 struct orig_node *orig_node;
876 struct bcast_packet *bcast_packet;
877 struct ethhdr *ethhdr;
878 int hdr_size = sizeof(struct bcast_packet);
881 /* drop packet if it has not necessary minimum size */
882 if (skb_headlen(skb) < hdr_size)
885 ethhdr = (struct ethhdr *)skb_mac_header(skb);
887 /* packet with broadcast indication but unicast recipient */
888 if (!is_bcast(ethhdr->h_dest))
891 /* packet with broadcast sender address */
892 if (is_bcast(ethhdr->h_source))
895 /* ignore broadcasts sent by myself */
896 if (is_my_mac(ethhdr->h_source))
899 bcast_packet = (struct bcast_packet *) skb->data;
901 /* ignore broadcasts originated by myself */
902 if (is_my_mac(bcast_packet->orig))
905 spin_lock_irqsave(&orig_hash_lock, flags);
906 orig_node = ((struct orig_node *)
907 hash_find(orig_hash, bcast_packet->orig));
909 if (orig_node == NULL) {
910 spin_unlock_irqrestore(&orig_hash_lock, flags);
914 /* check flood history */
915 if (get_bit_status(orig_node->bcast_bits,
916 orig_node->last_bcast_seqno,
917 ntohs(bcast_packet->seqno))) {
918 spin_unlock_irqrestore(&orig_hash_lock, flags);
922 /* mark broadcast in flood history */
923 if (bit_get_packet(orig_node->bcast_bits,
924 ntohs(bcast_packet->seqno) -
925 orig_node->last_bcast_seqno, 1))
926 orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
928 spin_unlock_irqrestore(&orig_hash_lock, flags);
930 /* rebroadcast packet */
931 add_bcast_packet_to_list(skb);
933 /* broadcast for me */
934 interface_rx(skb, hdr_size);
936 return NET_RX_SUCCESS;
939 int recv_vis_packet(struct sk_buff *skb)
941 struct vis_packet *vis_packet;
942 struct ethhdr *ethhdr;
943 int hdr_size = sizeof(struct vis_packet);
946 if (skb_headlen(skb) < hdr_size)
949 vis_packet = (struct vis_packet *) skb->data;
950 ethhdr = (struct ethhdr *)skb_mac_header(skb);
953 if (!is_my_mac(ethhdr->h_dest))
956 /* ignore own packets */
957 if (is_my_mac(vis_packet->vis_orig))
960 if (is_my_mac(vis_packet->sender_orig))
963 switch (vis_packet->vis_type) {
964 case VIS_TYPE_SERVER_SYNC:
965 /* TODO: handle fragmented skbs properly */
966 receive_server_sync_packet(vis_packet, skb_headlen(skb));
967 ret = NET_RX_SUCCESS;
970 case VIS_TYPE_CLIENT_UPDATE:
971 /* TODO: handle fragmented skbs properly */
972 receive_client_update_packet(vis_packet, skb_headlen(skb));
973 ret = NET_RX_SUCCESS;
976 default: /* ignore unknown packet */