aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/batman-adv/routing.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/batman-adv/routing.c')
-rw-r--r--drivers/staging/batman-adv/routing.c563
1 files changed, 244 insertions, 319 deletions
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c
index f8464cad30b..e0d093f5d52 100644
--- a/drivers/staging/batman-adv/routing.c
+++ b/drivers/staging/batman-adv/routing.c
@@ -36,15 +36,16 @@
36 36
37DECLARE_WAIT_QUEUE_HEAD(thread_wait); 37DECLARE_WAIT_QUEUE_HEAD(thread_wait);
38 38
39static atomic_t data_ready_cond;
40atomic_t exit_cond; 39atomic_t exit_cond;
40
41void slide_own_bcast_window(struct batman_if *batman_if) 41void slide_own_bcast_window(struct batman_if *batman_if)
42{ 42{
43 HASHIT(hashit); 43 HASHIT(hashit);
44 struct orig_node *orig_node; 44 struct orig_node *orig_node;
45 TYPE_OF_WORD *word; 45 TYPE_OF_WORD *word;
46 unsigned long flags;
46 47
47 spin_lock(&orig_hash_lock); 48 spin_lock_irqsave(&orig_hash_lock, flags);
48 49
49 while (hash_iterate(orig_hash, &hashit)) { 50 while (hash_iterate(orig_hash, &hashit)) {
50 orig_node = hashit.bucket->data; 51 orig_node = hashit.bucket->data;
@@ -55,7 +56,7 @@ void slide_own_bcast_window(struct batman_if *batman_if)
55 bit_packet_count(word); 56 bit_packet_count(word);
56 } 57 }
57 58
58 spin_unlock(&orig_hash_lock); 59 spin_unlock_irqrestore(&orig_hash_lock, flags);
59} 60}
60 61
61static void update_HNA(struct orig_node *orig_node, 62static void update_HNA(struct orig_node *orig_node,
@@ -365,10 +366,9 @@ static char count_real_packets(struct ethhdr *ethhdr,
365} 366}
366 367
367void receive_bat_packet(struct ethhdr *ethhdr, 368void receive_bat_packet(struct ethhdr *ethhdr,
368 struct batman_packet *batman_packet, 369 struct batman_packet *batman_packet,
369 unsigned char *hna_buff, 370 unsigned char *hna_buff, int hna_buff_len,
370 int hna_buff_len, 371 struct batman_if *if_incoming)
371 struct batman_if *if_incoming)
372{ 372{
373 struct batman_if *batman_if; 373 struct batman_if *batman_if;
374 struct orig_node *orig_neigh_node, *orig_node; 374 struct orig_node *orig_neigh_node, *orig_node;
@@ -566,95 +566,118 @@ void receive_bat_packet(struct ethhdr *ethhdr,
566 0, hna_buff_len, if_incoming); 566 0, hna_buff_len, if_incoming);
567} 567}
568 568
569 569int recv_bat_packet(struct sk_buff *skb,
570static int receive_raw_packet(struct socket *raw_sock, 570 struct batman_if *batman_if)
571 unsigned char *packet_buff, int packet_buff_len)
572{ 571{
573 struct kvec iov; 572 struct ethhdr *ethhdr;
574 struct msghdr msg; 573 unsigned long flags;
575 574
576 iov.iov_base = packet_buff; 575 /* drop packet if it has not necessary minimum size */
577 iov.iov_len = packet_buff_len; 576 if (skb_headlen(skb) < sizeof(struct batman_packet))
577 return NET_RX_DROP;
578 578
579 msg.msg_flags = MSG_DONTWAIT; /* non-blocking */ 579 ethhdr = (struct ethhdr *)skb_mac_header(skb);
580 msg.msg_name = NULL;
581 msg.msg_namelen = 0;
582 msg.msg_control = NULL;
583 580
584 return kernel_recvmsg(raw_sock, &msg, &iov, 1, packet_buff_len,
585 MSG_DONTWAIT);
586}
587
588static void recv_bat_packet(struct ethhdr *ethhdr,
589 unsigned char *packet_buff,
590 int result,
591 struct batman_if *batman_if)
592{
593 /* packet with broadcast indication but unicast recipient */ 581 /* packet with broadcast indication but unicast recipient */
594 if (!is_bcast(ethhdr->h_dest)) 582 if (!is_bcast(ethhdr->h_dest))
595 return; 583 return NET_RX_DROP;
596 584
597 /* packet with broadcast sender address */ 585 /* packet with broadcast sender address */
598 if (is_bcast(ethhdr->h_source)) 586 if (is_bcast(ethhdr->h_source))
599 return; 587 return NET_RX_DROP;
600 588
601 /* drop packet if it has not at least one batman packet as payload */ 589 spin_lock_irqsave(&orig_hash_lock, flags);
602 if (result < sizeof(struct ethhdr) + sizeof(struct batman_packet)) 590 /* TODO: we use headlen instead of "length", because
603 return; 591 * only this data is paged in. */
604 592 /* TODO: is another skb_copy needed here? there will be
605 spin_lock(&orig_hash_lock); 593 * written on the data, but nobody (?) should further use
594 * this data */
606 receive_aggr_bat_packet(ethhdr, 595 receive_aggr_bat_packet(ethhdr,
607 packet_buff + sizeof(struct ethhdr), 596 skb->data,
608 result - sizeof(struct ethhdr), 597 skb_headlen(skb),
609 batman_if); 598 batman_if);
610 spin_unlock(&orig_hash_lock); 599 spin_unlock_irqrestore(&orig_hash_lock, flags);
600
601 kfree_skb(skb);
602 return NET_RX_SUCCESS;
611} 603}
612 604
613static void recv_my_icmp_packet(struct ethhdr *ethhdr, 605static int recv_my_icmp_packet(struct sk_buff *skb)
614 struct icmp_packet *icmp_packet,
615 unsigned char *packet_buff,
616 int result)
617{ 606{
618 struct orig_node *orig_node; 607 struct orig_node *orig_node;
608 struct icmp_packet *icmp_packet;
609 struct ethhdr *ethhdr;
610 struct sk_buff *skb_old;
611 struct batman_if *batman_if;
612 int ret;
613 unsigned long flags;
614 uint8_t dstaddr[ETH_ALEN];
615
616 icmp_packet = (struct icmp_packet *) skb->data;
617 ethhdr = (struct ethhdr *) skb_mac_header(skb);
619 618
620 /* add data to device queue */ 619 /* add data to device queue */
621 if (icmp_packet->msg_type != ECHO_REQUEST) { 620 if (icmp_packet->msg_type != ECHO_REQUEST) {
622 bat_device_receive_packet(icmp_packet); 621 bat_device_receive_packet(icmp_packet);
623 return; 622 return NET_RX_DROP;
624 } 623 }
625 624
626 /* answer echo request (ping) */ 625 /* answer echo request (ping) */
627 /* get routing information */ 626 /* get routing information */
628 spin_lock(&orig_hash_lock); 627 spin_lock_irqsave(&orig_hash_lock, flags);
629 orig_node = ((struct orig_node *)hash_find(orig_hash, 628 orig_node = ((struct orig_node *)hash_find(orig_hash,
630 icmp_packet->orig)); 629 icmp_packet->orig));
630 ret = NET_RX_DROP;
631 631
632 if ((orig_node != NULL) && 632 if ((orig_node != NULL) &&
633 (orig_node->batman_if != NULL) && 633 (orig_node->batman_if != NULL) &&
634 (orig_node->router != NULL)) { 634 (orig_node->router != NULL)) {
635
636 /* don't lock while sending the packets ... we therefore
637 * copy the required data before sending */
638 batman_if = orig_node->batman_if;
639 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
640 spin_unlock_irqrestore(&orig_hash_lock, flags);
641
642 /* create a copy of the skb, if needed, to modify it. */
643 skb_old = NULL;
644 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
645 skb_old = skb;
646 skb = skb_copy(skb, GFP_ATOMIC);
647 if (!skb)
648 return NET_RX_DROP;
649 icmp_packet = (struct icmp_packet *) skb->data;
650 kfree_skb(skb_old);
651 }
652
635 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 653 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
636 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); 654 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
637 icmp_packet->msg_type = ECHO_REPLY; 655 icmp_packet->msg_type = ECHO_REPLY;
638 icmp_packet->ttl = TTL; 656 icmp_packet->ttl = TTL;
639 657
640 send_raw_packet(packet_buff + sizeof(struct ethhdr), 658 send_skb_packet(skb, batman_if, dstaddr);
641 result - sizeof(struct ethhdr), 659 ret = NET_RX_SUCCESS;
642 orig_node->batman_if,
643 orig_node->router->addr);
644 }
645 660
646 spin_unlock(&orig_hash_lock); 661 } else
647 return; 662 spin_unlock_irqrestore(&orig_hash_lock, flags);
663
664 return ret;
648} 665}
649 666
650static void recv_icmp_ttl_exceeded(struct icmp_packet *icmp_packet, 667static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
651 struct ethhdr *ethhdr,
652 unsigned char *packet_buff,
653 int result,
654 struct batman_if *batman_if)
655{ 668{
656 unsigned char src_str[ETH_STR_LEN], dst_str[ETH_STR_LEN]; 669 unsigned char src_str[ETH_STR_LEN], dst_str[ETH_STR_LEN];
657 struct orig_node *orig_node; 670 struct orig_node *orig_node;
671 struct icmp_packet *icmp_packet;
672 struct ethhdr *ethhdr;
673 struct sk_buff *skb_old;
674 struct batman_if *batman_if;
675 int ret;
676 unsigned long flags;
677 uint8_t dstaddr[ETH_ALEN];
678
679 icmp_packet = (struct icmp_packet *) skb->data;
680 ethhdr = (struct ethhdr *) skb_mac_header(skb);
658 681
659 addr_to_string(src_str, icmp_packet->orig); 682 addr_to_string(src_str, icmp_packet->orig);
660 addr_to_string(dst_str, icmp_packet->dst); 683 addr_to_string(dst_str, icmp_packet->dst);
@@ -663,74 +686,93 @@ static void recv_icmp_ttl_exceeded(struct icmp_packet *icmp_packet,
663 686
664 /* send TTL exceeded if packet is an echo request (traceroute) */ 687 /* send TTL exceeded if packet is an echo request (traceroute) */
665 if (icmp_packet->msg_type != ECHO_REQUEST) 688 if (icmp_packet->msg_type != ECHO_REQUEST)
666 return; 689 return NET_RX_DROP;
667 690
668 /* get routing information */ 691 /* get routing information */
669 spin_lock(&orig_hash_lock); 692 spin_lock_irqsave(&orig_hash_lock, flags);
670 orig_node = ((struct orig_node *) 693 orig_node = ((struct orig_node *)
671 hash_find(orig_hash, icmp_packet->orig)); 694 hash_find(orig_hash, icmp_packet->orig));
695 ret = NET_RX_DROP;
672 696
673 if ((orig_node != NULL) && 697 if ((orig_node != NULL) &&
674 (orig_node->batman_if != NULL) && 698 (orig_node->batman_if != NULL) &&
675 (orig_node->router != NULL)) { 699 (orig_node->router != NULL)) {
700
701 /* don't lock while sending the packets ... we therefore
702 * copy the required data before sending */
703 batman_if = orig_node->batman_if;
704 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
705 spin_unlock_irqrestore(&orig_hash_lock, flags);
706
707 /* create a copy of the skb, if needed, to modify it. */
708 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
709 skb_old = skb;
710 skb = skb_copy(skb, GFP_ATOMIC);
711 if (!skb)
712 return NET_RX_DROP;
713 icmp_packet = (struct icmp_packet *) skb->data;
714 kfree_skb(skb_old);
715 }
716
676 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 717 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
677 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); 718 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
678 icmp_packet->msg_type = TTL_EXCEEDED; 719 icmp_packet->msg_type = TTL_EXCEEDED;
679 icmp_packet->ttl = TTL; 720 icmp_packet->ttl = TTL;
680 721
681 send_raw_packet(packet_buff + sizeof(struct ethhdr), 722 send_skb_packet(skb, batman_if, dstaddr);
682 result - sizeof(struct ethhdr), 723 ret = NET_RX_SUCCESS;
683 orig_node->batman_if,
684 orig_node->router->addr);
685 724
686 } 725 } else
726 spin_unlock_irqrestore(&orig_hash_lock, flags);
687 727
688 spin_unlock(&orig_hash_lock); 728 return ret;
689} 729}
690 730
691 731
692 732int recv_icmp_packet(struct sk_buff *skb)
693static void recv_icmp_packet(struct ethhdr *ethhdr,
694 unsigned char *packet_buff,
695 int result,
696 struct batman_if *batman_if)
697{ 733{
698 struct icmp_packet *icmp_packet; 734 struct icmp_packet *icmp_packet;
735 struct ethhdr *ethhdr;
699 struct orig_node *orig_node; 736 struct orig_node *orig_node;
737 struct sk_buff *skb_old;
738 struct batman_if *batman_if;
739 int hdr_size = sizeof(struct icmp_packet);
740 int ret;
741 unsigned long flags;
742 uint8_t dstaddr[ETH_ALEN];
743
744 /* drop packet if it has not necessary minimum size */
745 if (skb_headlen(skb) < hdr_size)
746 return NET_RX_DROP;
747
748 ethhdr = (struct ethhdr *)skb_mac_header(skb);
700 749
701 /* packet with unicast indication but broadcast recipient */ 750 /* packet with unicast indication but broadcast recipient */
702 if (is_bcast(ethhdr->h_dest)) 751 if (is_bcast(ethhdr->h_dest))
703 return; 752 return NET_RX_DROP;
704 753
705 /* packet with broadcast sender address */ 754 /* packet with broadcast sender address */
706 if (is_bcast(ethhdr->h_source)) 755 if (is_bcast(ethhdr->h_source))
707 return; 756 return NET_RX_DROP;
708 757
709 /* not for me */ 758 /* not for me */
710 if (!is_my_mac(ethhdr->h_dest)) 759 if (!is_my_mac(ethhdr->h_dest))
711 return; 760 return NET_RX_DROP;
712 761
713 /* drop packet if it has not necessary minimum size */ 762 icmp_packet = (struct icmp_packet *) skb->data;
714 if (result < sizeof(struct ethhdr) + sizeof(struct icmp_packet))
715 return;
716
717 icmp_packet = (struct icmp_packet *)
718 (packet_buff + sizeof(struct ethhdr));
719 763
720 /* packet for me */ 764 /* packet for me */
721 if (is_my_mac(icmp_packet->dst)) 765 if (is_my_mac(icmp_packet->dst))
722 recv_my_icmp_packet(ethhdr, icmp_packet, packet_buff, result); 766 return recv_my_icmp_packet(skb);
723 767
724 /* TTL exceeded */ 768 /* TTL exceeded */
725 if (icmp_packet->ttl < 2) { 769 if (icmp_packet->ttl < 2)
726 recv_icmp_ttl_exceeded(icmp_packet, ethhdr, packet_buff, result, 770 return recv_icmp_ttl_exceeded(skb);
727 batman_if);
728 return;
729 771
730 } 772 ret = NET_RX_DROP;
731 773
732 /* get routing information */ 774 /* get routing information */
733 spin_lock(&orig_hash_lock); 775 spin_lock_irqsave(&orig_hash_lock, flags);
734 orig_node = ((struct orig_node *) 776 orig_node = ((struct orig_node *)
735 hash_find(orig_hash, icmp_packet->dst)); 777 hash_find(orig_hash, icmp_packet->dst));
736 778
@@ -738,133 +780,169 @@ static void recv_icmp_packet(struct ethhdr *ethhdr,
738 (orig_node->batman_if != NULL) && 780 (orig_node->batman_if != NULL) &&
739 (orig_node->router != NULL)) { 781 (orig_node->router != NULL)) {
740 782
783 /* don't lock while sending the packets ... we therefore
784 * copy the required data before sending */
785 batman_if = orig_node->batman_if;
786 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
787 spin_unlock_irqrestore(&orig_hash_lock, flags);
788
789 /* create a copy of the skb, if needed, to modify it. */
790 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
791 skb_old = skb;
792 skb = skb_copy(skb, GFP_ATOMIC);
793 if (!skb)
794 return NET_RX_DROP;
795 icmp_packet = (struct icmp_packet *) skb->data;
796 kfree_skb(skb_old);
797 }
798
741 /* decrement ttl */ 799 /* decrement ttl */
742 icmp_packet->ttl--; 800 icmp_packet->ttl--;
743 801
744 /* route it */ 802 /* route it */
745 send_raw_packet(packet_buff + sizeof(struct ethhdr), 803 send_skb_packet(skb, batman_if, dstaddr);
746 result - sizeof(struct ethhdr), 804 ret = NET_RX_SUCCESS;
747 orig_node->batman_if, 805
748 orig_node->router->addr); 806 } else
749 } 807 spin_unlock_irqrestore(&orig_hash_lock, flags);
750 spin_unlock(&orig_hash_lock); 808
809 return ret;
751} 810}
752 811
753static void recv_unicast_packet(struct ethhdr *ethhdr, 812int recv_unicast_packet(struct sk_buff *skb)
754 unsigned char *packet_buff,
755 int result,
756 struct batman_if *batman_if)
757{ 813{
758 struct unicast_packet *unicast_packet; 814 struct unicast_packet *unicast_packet;
759 unsigned char src_str[ETH_STR_LEN], dst_str[ETH_STR_LEN]; 815 unsigned char src_str[ETH_STR_LEN], dst_str[ETH_STR_LEN];
760 struct orig_node *orig_node; 816 struct orig_node *orig_node;
761 int hdr_size = sizeof(struct ethhdr) + sizeof(struct unicast_packet); 817 struct ethhdr *ethhdr;
818 struct batman_if *batman_if;
819 struct sk_buff *skb_old;
820 uint8_t dstaddr[ETH_ALEN];
821 int hdr_size = sizeof(struct unicast_packet);
822 int ret;
823 unsigned long flags;
824
825 /* drop packet if it has not necessary minimum size */
826 if (skb_headlen(skb) < hdr_size)
827 return NET_RX_DROP;
828
829 ethhdr = (struct ethhdr *) skb_mac_header(skb);
762 830
763 /* packet with unicast indication but broadcast recipient */ 831 /* packet with unicast indication but broadcast recipient */
764 if (is_bcast(ethhdr->h_dest)) 832 if (is_bcast(ethhdr->h_dest))
765 return; 833 return NET_RX_DROP;
766 834
767 /* packet with broadcast sender address */ 835 /* packet with broadcast sender address */
768 if (is_bcast(ethhdr->h_source)) 836 if (is_bcast(ethhdr->h_source))
769 return; 837 return NET_RX_DROP;
770 838
771 /* not for me */ 839 /* not for me */
772 if (!is_my_mac(ethhdr->h_dest)) 840 if (!is_my_mac(ethhdr->h_dest))
773 return; 841 return NET_RX_DROP;
774
775 /* drop packet if it has not necessary minimum size */
776 if (result < hdr_size)
777 return;
778 842
779 unicast_packet = (struct unicast_packet *) 843 unicast_packet = (struct unicast_packet *) skb->data;
780 (packet_buff + sizeof(struct ethhdr));
781 844
782 /* packet for me */ 845 /* packet for me */
783 if (is_my_mac(unicast_packet->dest)) { 846 if (is_my_mac(unicast_packet->dest)) {
784 interface_rx(soft_device, packet_buff + hdr_size, 847 interface_rx(skb, hdr_size);
785 result - hdr_size); 848 return NET_RX_SUCCESS;
786 return;
787
788 } 849 }
789 850
790 /* TTL exceeded */ 851 /* TTL exceeded */
791 if (unicast_packet->ttl < 2) { 852 if (unicast_packet->ttl < 2) {
792 addr_to_string(src_str, ((struct ethhdr *) 853 addr_to_string(src_str, ethhdr->h_source);
793 (unicast_packet + 1))->h_source); 854 addr_to_string(dst_str, ethhdr->h_dest);
794 addr_to_string(dst_str, unicast_packet->dest);
795 855
796 printk(KERN_WARNING "batman-adv:Warning - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str); 856 printk(KERN_WARNING "batman-adv:Warning - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str);
797 return; 857 return NET_RX_DROP;
798 } 858 }
799 859
860 ret = NET_RX_DROP;
800 /* get routing information */ 861 /* get routing information */
801 spin_lock(&orig_hash_lock); 862 spin_lock_irqsave(&orig_hash_lock, flags);
802 orig_node = ((struct orig_node *) 863 orig_node = ((struct orig_node *)
803 hash_find(orig_hash, unicast_packet->dest)); 864 hash_find(orig_hash, unicast_packet->dest));
804 865
805 if ((orig_node != NULL) && 866 if ((orig_node != NULL) &&
806 (orig_node->batman_if != NULL) && 867 (orig_node->batman_if != NULL) &&
807 (orig_node->router != NULL)) { 868 (orig_node->router != NULL)) {
869
870 /* don't lock while sending the packets ... we therefore
871 * copy the required data before sending */
872 batman_if = orig_node->batman_if;
873 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
874 spin_unlock_irqrestore(&orig_hash_lock, flags);
875
876 /* create a copy of the skb, if needed, to modify it. */
877 if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) {
878 skb_old = skb;
879 skb = skb_copy(skb, GFP_ATOMIC);
880 if (!skb)
881 return NET_RX_DROP;
882 unicast_packet = (struct unicast_packet *) skb->data;
883 kfree_skb(skb_old);
884 }
808 /* decrement ttl */ 885 /* decrement ttl */
809 unicast_packet->ttl--; 886 unicast_packet->ttl--;
810 887
811 /* route it */ 888 /* route it */
812 send_raw_packet(packet_buff + sizeof(struct ethhdr), 889 send_skb_packet(skb, batman_if, dstaddr);
813 result - sizeof(struct ethhdr), 890 ret = NET_RX_SUCCESS;
814 orig_node->batman_if, 891
815 orig_node->router->addr); 892 } else
816 } 893 spin_unlock_irqrestore(&orig_hash_lock, flags);
817 spin_unlock(&orig_hash_lock); 894
895 return ret;
818} 896}
819 897
820 898
821static void recv_bcast_packet(struct ethhdr *ethhdr, 899int recv_bcast_packet(struct sk_buff *skb)
822 unsigned char *packet_buff,
823 int result,
824 struct batman_if *batman_if)
825{ 900{
826 struct orig_node *orig_node; 901 struct orig_node *orig_node;
827 struct bcast_packet *bcast_packet; 902 struct bcast_packet *bcast_packet;
828 int hdr_size = sizeof(struct ethhdr) + sizeof(struct bcast_packet); 903 struct ethhdr *ethhdr;
904 int hdr_size = sizeof(struct bcast_packet);
905 unsigned long flags;
906
907 /* drop packet if it has not necessary minimum size */
908 if (skb_headlen(skb) < hdr_size)
909 return NET_RX_DROP;
910
911 ethhdr = (struct ethhdr *)skb_mac_header(skb);
829 912
830 /* packet with broadcast indication but unicast recipient */ 913 /* packet with broadcast indication but unicast recipient */
831 if (!is_bcast(ethhdr->h_dest)) 914 if (!is_bcast(ethhdr->h_dest))
832 return; 915 return NET_RX_DROP;
833 916
834 /* packet with broadcast sender address */ 917 /* packet with broadcast sender address */
835 if (is_bcast(ethhdr->h_source)) 918 if (is_bcast(ethhdr->h_source))
836 return; 919 return NET_RX_DROP;
837
838 /* drop packet if it has not necessary minimum size */
839 if (result < hdr_size)
840 return;
841 920
842 /* ignore broadcasts sent by myself */ 921 /* ignore broadcasts sent by myself */
843 if (is_my_mac(ethhdr->h_source)) 922 if (is_my_mac(ethhdr->h_source))
844 return; 923 return NET_RX_DROP;
845 924
846 bcast_packet = (struct bcast_packet *) 925 bcast_packet = (struct bcast_packet *) skb->data;
847 (packet_buff + sizeof(struct ethhdr));
848 926
849 /* ignore broadcasts originated by myself */ 927 /* ignore broadcasts originated by myself */
850 if (is_my_mac(bcast_packet->orig)) 928 if (is_my_mac(bcast_packet->orig))
851 return; 929 return NET_RX_DROP;
852 930
853 spin_lock(&orig_hash_lock); 931 spin_lock_irqsave(&orig_hash_lock, flags);
854 orig_node = ((struct orig_node *) 932 orig_node = ((struct orig_node *)
855 hash_find(orig_hash, bcast_packet->orig)); 933 hash_find(orig_hash, bcast_packet->orig));
856 934
857 if (orig_node == NULL) { 935 if (orig_node == NULL) {
858 spin_unlock(&orig_hash_lock); 936 spin_unlock_irqrestore(&orig_hash_lock, flags);
859 return; 937 return NET_RX_DROP;
860 } 938 }
861 939
862 /* check flood history */ 940 /* check flood history */
863 if (get_bit_status(orig_node->bcast_bits, 941 if (get_bit_status(orig_node->bcast_bits,
864 orig_node->last_bcast_seqno, 942 orig_node->last_bcast_seqno,
865 ntohs(bcast_packet->seqno))) { 943 ntohs(bcast_packet->seqno))) {
866 spin_unlock(&orig_hash_lock); 944 spin_unlock_irqrestore(&orig_hash_lock, flags);
867 return; 945 return NET_RX_DROP;
868 } 946 }
869 947
870 /* mark broadcast in flood history */ 948 /* mark broadcast in flood history */
@@ -873,211 +951,58 @@ static void recv_bcast_packet(struct ethhdr *ethhdr,
873 orig_node->last_bcast_seqno, 1)) 951 orig_node->last_bcast_seqno, 1))
874 orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno); 952 orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
875 953
876 spin_unlock(&orig_hash_lock); 954 spin_unlock_irqrestore(&orig_hash_lock, flags);
955
956 /* rebroadcast packet */
957 add_bcast_packet_to_list(skb);
877 958
878 /* broadcast for me */ 959 /* broadcast for me */
879 interface_rx(soft_device, packet_buff + hdr_size, result - hdr_size); 960 interface_rx(skb, hdr_size);
880 961
881 /* rebroadcast packet */ 962 return NET_RX_SUCCESS;
882 add_bcast_packet_to_list(packet_buff + sizeof(struct ethhdr),
883 result - sizeof(struct ethhdr));
884} 963}
885 964
886static void recv_vis_packet(struct ethhdr *ethhdr, 965int recv_vis_packet(struct sk_buff *skb)
887 unsigned char *packet_buff,
888 int result)
889{ 966{
890 struct vis_packet *vis_packet; 967 struct vis_packet *vis_packet;
891 int hdr_size = sizeof(struct ethhdr) + sizeof(struct vis_packet); 968 struct ethhdr *ethhdr;
892 int vis_info_len; 969 int hdr_size = sizeof(struct vis_packet);
970 int ret;
893 971
894 /* drop if too short. */ 972 if (skb_headlen(skb) < hdr_size)
895 if (result < hdr_size) 973 return NET_RX_DROP;
896 return; 974
975 vis_packet = (struct vis_packet *) skb->data;
976 ethhdr = (struct ethhdr *)skb_mac_header(skb);
897 977
898 /* not for me */ 978 /* not for me */
899 if (!is_my_mac(ethhdr->h_dest)) 979 if (!is_my_mac(ethhdr->h_dest))
900 return; 980 return NET_RX_DROP;
901
902 vis_packet = (struct vis_packet *)(packet_buff + sizeof(struct ethhdr));
903 vis_info_len = result - hdr_size;
904 981
905 /* ignore own packets */ 982 /* ignore own packets */
906 if (is_my_mac(vis_packet->vis_orig)) 983 if (is_my_mac(vis_packet->vis_orig))
907 return; 984 return NET_RX_DROP;
908 985
909 if (is_my_mac(vis_packet->sender_orig)) 986 if (is_my_mac(vis_packet->sender_orig))
910 return; 987 return NET_RX_DROP;
911 988
912 switch (vis_packet->vis_type) { 989 switch (vis_packet->vis_type) {
913 case VIS_TYPE_SERVER_SYNC: 990 case VIS_TYPE_SERVER_SYNC:
914 receive_server_sync_packet(vis_packet, vis_info_len); 991 /* TODO: handle fragmented skbs properly */
992 receive_server_sync_packet(vis_packet, skb_headlen(skb));
993 ret = NET_RX_SUCCESS;
915 break; 994 break;
916 995
917 case VIS_TYPE_CLIENT_UPDATE: 996 case VIS_TYPE_CLIENT_UPDATE:
918 receive_client_update_packet(vis_packet, vis_info_len); 997 /* TODO: handle fragmented skbs properly */
998 receive_client_update_packet(vis_packet, skb_headlen(skb));
999 ret = NET_RX_SUCCESS;
919 break; 1000 break;
920 1001
921 default: /* ignore unknown packet */ 1002 default: /* ignore unknown packet */
1003 ret = NET_RX_DROP;
922 break; 1004 break;
923 } 1005 }
924} 1006 return ret;
925
926static int recv_one_packet(struct batman_if *batman_if,
927 unsigned char *packet_buff)
928{
929 int result;
930 struct ethhdr *ethhdr;
931 struct batman_packet *batman_packet;
932
933 result = receive_raw_packet(batman_if->raw_sock, packet_buff,
934 PACKBUFF_SIZE);
935 if (result <= 0)
936 return result;
937
938 if (result < sizeof(struct ethhdr) + 2)
939 return 0;
940
941 ethhdr = (struct ethhdr *)packet_buff;
942 batman_packet = (struct batman_packet *)
943 (packet_buff + sizeof(struct ethhdr));
944
945 if (batman_packet->version != COMPAT_VERSION) {
946 bat_dbg(DBG_BATMAN,
947 "Drop packet: incompatible batman version (%i)\n",
948 batman_packet->version);
949 return 0;
950 }
951
952 switch (batman_packet->packet_type) {
953 /* batman originator packet */
954 case BAT_PACKET:
955 recv_bat_packet(ethhdr, packet_buff, result, batman_if);
956 break;
957
958 /* batman icmp packet */
959 case BAT_ICMP:
960 recv_icmp_packet(ethhdr, packet_buff, result, batman_if);
961 break;
962
963 /* unicast packet */
964 case BAT_UNICAST:
965 recv_unicast_packet(ethhdr, packet_buff, result, batman_if);
966 break;
967
968 /* broadcast packet */
969 case BAT_BCAST:
970 recv_bcast_packet(ethhdr,
971 packet_buff, result, batman_if);
972 break;
973
974 /* vis packet */
975 case BAT_VIS:
976 recv_vis_packet(ethhdr, packet_buff, result);
977 break;
978 }
979 return 0;
980}
981
982
983static int discard_one_packet(struct batman_if *batman_if,
984 unsigned char *packet_buff)
985{
986 int result = -EAGAIN;
987
988 if (batman_if->raw_sock) {
989 result = receive_raw_packet(batman_if->raw_sock,
990 packet_buff,
991 PACKBUFF_SIZE);
992 }
993 return result;
994}
995
996
997static bool is_interface_active(struct batman_if *batman_if)
998{
999 if (batman_if->if_active != IF_ACTIVE)
1000 return false;
1001
1002 return true;
1003}
1004
1005static void service_interface(struct batman_if *batman_if,
1006 unsigned char *packet_buff)
1007
1008{
1009 int result;
1010
1011 do {
1012 if (is_interface_active(batman_if))
1013 result = recv_one_packet(batman_if, packet_buff);
1014 else
1015 result = discard_one_packet(batman_if, packet_buff);
1016 } while (result >= 0);
1017
1018 /* we perform none blocking reads, so EAGAIN indicates there
1019 are no more packets to read. Anything else is a real
1020 error.*/
1021
1022 if ((result < 0) && (result != -EAGAIN))
1023 printk(KERN_ERR "batman-adv:Could not receive packet from interface %s: %i\n", batman_if->dev, result);
1024}
1025
1026static void service_interfaces(unsigned char *packet_buffer)
1027{
1028 struct batman_if *batman_if;
1029 rcu_read_lock();
1030 list_for_each_entry_rcu(batman_if, &if_list, list) {
1031 rcu_read_unlock();
1032 service_interface(batman_if, packet_buffer);
1033 rcu_read_lock();
1034 }
1035 rcu_read_unlock();
1036}
1037
1038
1039int packet_recv_thread(void *data)
1040{
1041 unsigned char *packet_buff;
1042
1043 atomic_set(&data_ready_cond, 0);
1044 atomic_set(&exit_cond, 0);
1045 packet_buff = kmalloc(PACKBUFF_SIZE, GFP_KERNEL);
1046 if (!packet_buff) {
1047 printk(KERN_ERR"batman-adv:Could allocate memory for the packet buffer. :(\n");
1048 return -1;
1049 }
1050
1051 while ((!kthread_should_stop()) && (!atomic_read(&exit_cond))) {
1052
1053 wait_event_interruptible(thread_wait,
1054 (atomic_read(&data_ready_cond) ||
1055 atomic_read(&exit_cond)));
1056
1057 atomic_set(&data_ready_cond, 0);
1058
1059 if (kthread_should_stop() || atomic_read(&exit_cond))
1060 break;
1061
1062 service_interfaces(packet_buff);
1063 }
1064 kfree(packet_buff);
1065
1066 /* do not exit until kthread_stop() is actually called,
1067 * otherwise it will wait for us forever. */
1068 while (!kthread_should_stop())
1069 schedule();
1070
1071 return 0;
1072}
1073
1074void batman_data_ready(struct sock *sk, int len)
1075{
1076 void (*data_ready)(struct sock *, int) = sk->sk_user_data;
1077
1078 data_ready(sk, len);
1079
1080 atomic_set(&data_ready_cond, 1);
1081 wake_up_interruptible(&thread_wait);
1082} 1007}
1083 1008