diff options
Diffstat (limited to 'net/batman-adv/vis.c')
-rw-r--r-- | net/batman-adv/vis.c | 36 |
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 | |||
690 | unlock: | ||
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 | ||
779 | static void unicast_vis_packet(struct bat_priv *bat_priv, | 770 | static 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 | ||
822 | unlock: | 805 | unlock: |
823 | rcu_read_unlock(); | 806 | rcu_read_unlock(); |
824 | spin_unlock_bh(&bat_priv->orig_hash_lock); | ||
825 | out: | 807 | out: |
826 | if (neigh_node) | 808 | if (neigh_node) |
827 | neigh_node_free_ref(neigh_node); | 809 | neigh_node_free_ref(neigh_node); |