aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/vis.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/vis.c')
-rw-r--r--net/batman-adv/vis.c36
1 files changed, 9 insertions, 27 deletions
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index 89722425dcb2..e8911cbb8699 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -614,7 +614,6 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
614 info->first_seen = jiffies; 614 info->first_seen = jiffies;
615 packet->vis_type = atomic_read(&bat_priv->vis_mode); 615 packet->vis_type = atomic_read(&bat_priv->vis_mode);
616 616
617 spin_lock_bh(&bat_priv->orig_hash_lock);
618 memcpy(packet->target_orig, broadcast_addr, ETH_ALEN); 617 memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
619 packet->ttl = TTL; 618 packet->ttl = TTL;
620 packet->seqno = htonl(ntohl(packet->seqno) + 1); 619 packet->seqno = htonl(ntohl(packet->seqno) + 1);
@@ -624,10 +623,8 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
624 if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) { 623 if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) {
625 best_tq = find_best_vis_server(bat_priv, info); 624 best_tq = find_best_vis_server(bat_priv, info);
626 625
627 if (best_tq < 0) { 626 if (best_tq < 0)
628 spin_unlock_bh(&bat_priv->orig_hash_lock);
629 return -1; 627 return -1;
630 }
631 } 628 }
632 629
633 for (i = 0; i < hash->size; i++) { 630 for (i = 0; i < hash->size; i++) {
@@ -659,17 +656,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
659 entry->quality = neigh_node->tq_avg; 656 entry->quality = neigh_node->tq_avg;
660 packet->entries++; 657 packet->entries++;
661 658
662 if (vis_packet_full(info)) { 659 if (vis_packet_full(info))
663 rcu_read_unlock(); 660 goto unlock;
664 spin_unlock_bh(&bat_priv->orig_hash_lock);
665 return 0;
666 }
667 } 661 }
668 rcu_read_unlock(); 662 rcu_read_unlock();
669 } 663 }
670 664
671 spin_unlock_bh(&bat_priv->orig_hash_lock);
672
673 hash = bat_priv->hna_local_hash; 665 hash = bat_priv->hna_local_hash;
674 666
675 spin_lock_bh(&bat_priv->hna_lhash_lock); 667 spin_lock_bh(&bat_priv->hna_lhash_lock);
@@ -694,6 +686,10 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
694 686
695 spin_unlock_bh(&bat_priv->hna_lhash_lock); 687 spin_unlock_bh(&bat_priv->hna_lhash_lock);
696 return 0; 688 return 0;
689
690unlock:
691 rcu_read_unlock();
692 return 0;
697} 693}
698 694
699/* free old vis packets. Must be called with this vis_hash_lock 695/* free old vis packets. Must be called with this vis_hash_lock
@@ -739,7 +735,6 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv,
739 int i; 735 int i;
740 736
741 737
742 spin_lock_bh(&bat_priv->orig_hash_lock);
743 packet = (struct vis_packet *)info->skb_packet->data; 738 packet = (struct vis_packet *)info->skb_packet->data;
744 739
745 /* send to all routers in range. */ 740 /* send to all routers in range. */
@@ -762,18 +757,14 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv,
762 memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); 757 memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
763 batman_if = orig_node->router->if_incoming; 758 batman_if = orig_node->router->if_incoming;
764 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); 759 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
765 spin_unlock_bh(&bat_priv->orig_hash_lock);
766 760
767 skb = skb_clone(info->skb_packet, GFP_ATOMIC); 761 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
768 if (skb) 762 if (skb)
769 send_skb_packet(skb, batman_if, dstaddr); 763 send_skb_packet(skb, batman_if, dstaddr);
770 764
771 spin_lock_bh(&bat_priv->orig_hash_lock);
772 } 765 }
773 rcu_read_unlock(); 766 rcu_read_unlock();
774 } 767 }
775
776 spin_unlock_bh(&bat_priv->orig_hash_lock);
777} 768}
778 769
779static void unicast_vis_packet(struct bat_priv *bat_priv, 770static void unicast_vis_packet(struct bat_priv *bat_priv,
@@ -783,12 +774,9 @@ static void unicast_vis_packet(struct bat_priv *bat_priv,
783 struct neigh_node *neigh_node = NULL; 774 struct neigh_node *neigh_node = NULL;
784 struct sk_buff *skb; 775 struct sk_buff *skb;
785 struct vis_packet *packet; 776 struct vis_packet *packet;
786 struct batman_if *batman_if;
787 uint8_t dstaddr[ETH_ALEN];
788 777
789 packet = (struct vis_packet *)info->skb_packet->data; 778 packet = (struct vis_packet *)info->skb_packet->data;
790 779
791 spin_lock_bh(&bat_priv->orig_hash_lock);
792 rcu_read_lock(); 780 rcu_read_lock();
793 orig_node = orig_hash_find(bat_priv, packet->target_orig); 781 orig_node = orig_hash_find(bat_priv, packet->target_orig);
794 782
@@ -807,21 +795,15 @@ static void unicast_vis_packet(struct bat_priv *bat_priv,
807 795
808 rcu_read_unlock(); 796 rcu_read_unlock();
809 797
810 /* don't lock while sending the packets ... we therefore
811 * copy the required data before sending */
812 batman_if = orig_node->router->if_incoming;
813 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
814 spin_unlock_bh(&bat_priv->orig_hash_lock);
815
816 skb = skb_clone(info->skb_packet, GFP_ATOMIC); 798 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
817 if (skb) 799 if (skb)
818 send_skb_packet(skb, batman_if, dstaddr); 800 send_skb_packet(skb, neigh_node->if_incoming,
801 neigh_node->addr);
819 802
820 goto out; 803 goto out;
821 804
822unlock: 805unlock:
823 rcu_read_unlock(); 806 rcu_read_unlock();
824 spin_unlock_bh(&bat_priv->orig_hash_lock);
825out: 807out:
826 if (neigh_node) 808 if (neigh_node)
827 neigh_node_free_ref(neigh_node); 809 neigh_node_free_ref(neigh_node);