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.c146
1 files changed, 80 insertions, 66 deletions
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index f90212f42082..c39f20cc1ba6 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -194,7 +194,7 @@ static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
194{ 194{
195 /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */ 195 /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
196 if (primary && entry->quality == 0) 196 if (primary && entry->quality == 0)
197 return sprintf(buff, "HNA %pM, ", entry->dest); 197 return sprintf(buff, "TT %pM, ", entry->dest);
198 else if (compare_eth(entry->src, src)) 198 else if (compare_eth(entry->src, src))
199 return sprintf(buff, "TQ %pM %d, ", entry->dest, 199 return sprintf(buff, "TQ %pM %d, ", entry->dest,
200 entry->quality); 200 entry->quality);
@@ -204,6 +204,7 @@ static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
204 204
205int vis_seq_print_text(struct seq_file *seq, void *offset) 205int vis_seq_print_text(struct seq_file *seq, void *offset)
206{ 206{
207 struct hard_iface *primary_if;
207 struct hlist_node *node; 208 struct hlist_node *node;
208 struct hlist_head *head; 209 struct hlist_head *head;
209 struct vis_info *info; 210 struct vis_info *info;
@@ -215,15 +216,18 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
215 HLIST_HEAD(vis_if_list); 216 HLIST_HEAD(vis_if_list);
216 struct if_list_entry *entry; 217 struct if_list_entry *entry;
217 struct hlist_node *pos, *n; 218 struct hlist_node *pos, *n;
218 int i, j; 219 int i, j, ret = 0;
219 int vis_server = atomic_read(&bat_priv->vis_mode); 220 int vis_server = atomic_read(&bat_priv->vis_mode);
220 size_t buff_pos, buf_size; 221 size_t buff_pos, buf_size;
221 char *buff; 222 char *buff;
222 int compare; 223 int compare;
223 224
224 if ((!bat_priv->primary_if) || 225 primary_if = primary_if_get_selected(bat_priv);
225 (vis_server == VIS_TYPE_CLIENT_UPDATE)) 226 if (!primary_if)
226 return 0; 227 goto out;
228
229 if (vis_server == VIS_TYPE_CLIENT_UPDATE)
230 goto out;
227 231
228 buf_size = 1; 232 buf_size = 1;
229 /* Estimate length */ 233 /* Estimate length */
@@ -270,7 +274,8 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
270 buff = kmalloc(buf_size, GFP_ATOMIC); 274 buff = kmalloc(buf_size, GFP_ATOMIC);
271 if (!buff) { 275 if (!buff) {
272 spin_unlock_bh(&bat_priv->vis_hash_lock); 276 spin_unlock_bh(&bat_priv->vis_hash_lock);
273 return -ENOMEM; 277 ret = -ENOMEM;
278 goto out;
274 } 279 }
275 buff[0] = '\0'; 280 buff[0] = '\0';
276 buff_pos = 0; 281 buff_pos = 0;
@@ -328,7 +333,10 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
328 seq_printf(seq, "%s", buff); 333 seq_printf(seq, "%s", buff);
329 kfree(buff); 334 kfree(buff);
330 335
331 return 0; 336out:
337 if (primary_if)
338 hardif_free_ref(primary_if);
339 return ret;
332} 340}
333 341
334/* add the info packet to the send list, if it was not 342/* add the info packet to the send list, if it was not
@@ -558,6 +566,7 @@ static int find_best_vis_server(struct bat_priv *bat_priv,
558 struct vis_info *info) 566 struct vis_info *info)
559{ 567{
560 struct hashtable_t *hash = bat_priv->orig_hash; 568 struct hashtable_t *hash = bat_priv->orig_hash;
569 struct neigh_node *router;
561 struct hlist_node *node; 570 struct hlist_node *node;
562 struct hlist_head *head; 571 struct hlist_head *head;
563 struct orig_node *orig_node; 572 struct orig_node *orig_node;
@@ -571,13 +580,17 @@ static int find_best_vis_server(struct bat_priv *bat_priv,
571 580
572 rcu_read_lock(); 581 rcu_read_lock();
573 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { 582 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
574 if ((orig_node) && (orig_node->router) && 583 router = orig_node_get_router(orig_node);
575 (orig_node->flags & VIS_SERVER) && 584 if (!router)
576 (orig_node->router->tq_avg > best_tq)) { 585 continue;
577 best_tq = orig_node->router->tq_avg; 586
587 if ((orig_node->flags & VIS_SERVER) &&
588 (router->tq_avg > best_tq)) {
589 best_tq = router->tq_avg;
578 memcpy(packet->target_orig, orig_node->orig, 590 memcpy(packet->target_orig, orig_node->orig,
579 ETH_ALEN); 591 ETH_ALEN);
580 } 592 }
593 neigh_node_free_ref(router);
581 } 594 }
582 rcu_read_unlock(); 595 rcu_read_unlock();
583 } 596 }
@@ -605,11 +618,11 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
605 struct hlist_node *node; 618 struct hlist_node *node;
606 struct hlist_head *head; 619 struct hlist_head *head;
607 struct orig_node *orig_node; 620 struct orig_node *orig_node;
608 struct neigh_node *neigh_node; 621 struct neigh_node *router;
609 struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info; 622 struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info;
610 struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data; 623 struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data;
611 struct vis_info_entry *entry; 624 struct vis_info_entry *entry;
612 struct hna_local_entry *hna_local_entry; 625 struct tt_local_entry *tt_local_entry;
613 int best_tq = -1, i; 626 int best_tq = -1, i;
614 627
615 info->first_seen = jiffies; 628 info->first_seen = jiffies;
@@ -633,59 +646,61 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
633 646
634 rcu_read_lock(); 647 rcu_read_lock();
635 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { 648 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
636 neigh_node = orig_node->router; 649 router = orig_node_get_router(orig_node);
637 650 if (!router)
638 if (!neigh_node)
639 continue; 651 continue;
640 652
641 if (!compare_eth(neigh_node->addr, orig_node->orig)) 653 if (!compare_eth(router->addr, orig_node->orig))
642 continue; 654 goto next;
643 655
644 if (neigh_node->if_incoming->if_status != IF_ACTIVE) 656 if (router->if_incoming->if_status != IF_ACTIVE)
645 continue; 657 goto next;
646 658
647 if (neigh_node->tq_avg < 1) 659 if (router->tq_avg < 1)
648 continue; 660 goto next;
649 661
650 /* fill one entry into buffer. */ 662 /* fill one entry into buffer. */
651 entry = (struct vis_info_entry *) 663 entry = (struct vis_info_entry *)
652 skb_put(info->skb_packet, sizeof(*entry)); 664 skb_put(info->skb_packet, sizeof(*entry));
653 memcpy(entry->src, 665 memcpy(entry->src,
654 neigh_node->if_incoming->net_dev->dev_addr, 666 router->if_incoming->net_dev->dev_addr,
655 ETH_ALEN); 667 ETH_ALEN);
656 memcpy(entry->dest, orig_node->orig, ETH_ALEN); 668 memcpy(entry->dest, orig_node->orig, ETH_ALEN);
657 entry->quality = neigh_node->tq_avg; 669 entry->quality = router->tq_avg;
658 packet->entries++; 670 packet->entries++;
659 671
672next:
673 neigh_node_free_ref(router);
674
660 if (vis_packet_full(info)) 675 if (vis_packet_full(info))
661 goto unlock; 676 goto unlock;
662 } 677 }
663 rcu_read_unlock(); 678 rcu_read_unlock();
664 } 679 }
665 680
666 hash = bat_priv->hna_local_hash; 681 hash = bat_priv->tt_local_hash;
667 682
668 spin_lock_bh(&bat_priv->hna_lhash_lock); 683 spin_lock_bh(&bat_priv->tt_lhash_lock);
669 for (i = 0; i < hash->size; i++) { 684 for (i = 0; i < hash->size; i++) {
670 head = &hash->table[i]; 685 head = &hash->table[i];
671 686
672 hlist_for_each_entry(hna_local_entry, node, head, hash_entry) { 687 hlist_for_each_entry(tt_local_entry, node, head, hash_entry) {
673 entry = (struct vis_info_entry *) 688 entry = (struct vis_info_entry *)
674 skb_put(info->skb_packet, 689 skb_put(info->skb_packet,
675 sizeof(*entry)); 690 sizeof(*entry));
676 memset(entry->src, 0, ETH_ALEN); 691 memset(entry->src, 0, ETH_ALEN);
677 memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN); 692 memcpy(entry->dest, tt_local_entry->addr, ETH_ALEN);
678 entry->quality = 0; /* 0 means HNA */ 693 entry->quality = 0; /* 0 means TT */
679 packet->entries++; 694 packet->entries++;
680 695
681 if (vis_packet_full(info)) { 696 if (vis_packet_full(info)) {
682 spin_unlock_bh(&bat_priv->hna_lhash_lock); 697 spin_unlock_bh(&bat_priv->tt_lhash_lock);
683 return 0; 698 return 0;
684 } 699 }
685 } 700 }
686 } 701 }
687 702
688 spin_unlock_bh(&bat_priv->hna_lhash_lock); 703 spin_unlock_bh(&bat_priv->tt_lhash_lock);
689 return 0; 704 return 0;
690 705
691unlock: 706unlock:
@@ -725,6 +740,7 @@ static void purge_vis_packets(struct bat_priv *bat_priv)
725static void broadcast_vis_packet(struct bat_priv *bat_priv, 740static void broadcast_vis_packet(struct bat_priv *bat_priv,
726 struct vis_info *info) 741 struct vis_info *info)
727{ 742{
743 struct neigh_node *router;
728 struct hashtable_t *hash = bat_priv->orig_hash; 744 struct hashtable_t *hash = bat_priv->orig_hash;
729 struct hlist_node *node; 745 struct hlist_node *node;
730 struct hlist_head *head; 746 struct hlist_head *head;
@@ -745,19 +761,26 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv,
745 rcu_read_lock(); 761 rcu_read_lock();
746 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { 762 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
747 /* if it's a vis server and reachable, send it. */ 763 /* if it's a vis server and reachable, send it. */
748 if ((!orig_node) || (!orig_node->router))
749 continue;
750 if (!(orig_node->flags & VIS_SERVER)) 764 if (!(orig_node->flags & VIS_SERVER))
751 continue; 765 continue;
766
767 router = orig_node_get_router(orig_node);
768 if (!router)
769 continue;
770
752 /* don't send it if we already received the packet from 771 /* don't send it if we already received the packet from
753 * this node. */ 772 * this node. */
754 if (recv_list_is_in(bat_priv, &info->recv_list, 773 if (recv_list_is_in(bat_priv, &info->recv_list,
755 orig_node->orig)) 774 orig_node->orig)) {
775 neigh_node_free_ref(router);
756 continue; 776 continue;
777 }
757 778
758 memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); 779 memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
759 hard_iface = orig_node->router->if_incoming; 780 hard_iface = router->if_incoming;
760 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); 781 memcpy(dstaddr, router->addr, ETH_ALEN);
782
783 neigh_node_free_ref(router);
761 784
762 skb = skb_clone(info->skb_packet, GFP_ATOMIC); 785 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
763 if (skb) 786 if (skb)
@@ -772,60 +795,48 @@ static void unicast_vis_packet(struct bat_priv *bat_priv,
772 struct vis_info *info) 795 struct vis_info *info)
773{ 796{
774 struct orig_node *orig_node; 797 struct orig_node *orig_node;
775 struct neigh_node *neigh_node = NULL; 798 struct neigh_node *router = NULL;
776 struct sk_buff *skb; 799 struct sk_buff *skb;
777 struct vis_packet *packet; 800 struct vis_packet *packet;
778 801
779 packet = (struct vis_packet *)info->skb_packet->data; 802 packet = (struct vis_packet *)info->skb_packet->data;
780 803
781 rcu_read_lock();
782 orig_node = orig_hash_find(bat_priv, packet->target_orig); 804 orig_node = orig_hash_find(bat_priv, packet->target_orig);
783
784 if (!orig_node) 805 if (!orig_node)
785 goto unlock; 806 goto out;
786
787 neigh_node = orig_node->router;
788 807
789 if (!neigh_node) 808 router = orig_node_get_router(orig_node);
790 goto unlock; 809 if (!router)
791 810 goto out;
792 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
793 neigh_node = NULL;
794 goto unlock;
795 }
796
797 rcu_read_unlock();
798 811
799 skb = skb_clone(info->skb_packet, GFP_ATOMIC); 812 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
800 if (skb) 813 if (skb)
801 send_skb_packet(skb, neigh_node->if_incoming, 814 send_skb_packet(skb, router->if_incoming, router->addr);
802 neigh_node->addr);
803 815
804 goto out;
805
806unlock:
807 rcu_read_unlock();
808out: 816out:
809 if (neigh_node) 817 if (router)
810 neigh_node_free_ref(neigh_node); 818 neigh_node_free_ref(router);
811 if (orig_node) 819 if (orig_node)
812 orig_node_free_ref(orig_node); 820 orig_node_free_ref(orig_node);
813 return;
814} 821}
815 822
816/* only send one vis packet. called from send_vis_packets() */ 823/* only send one vis packet. called from send_vis_packets() */
817static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) 824static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
818{ 825{
826 struct hard_iface *primary_if;
819 struct vis_packet *packet; 827 struct vis_packet *packet;
820 828
829 primary_if = primary_if_get_selected(bat_priv);
830 if (!primary_if)
831 goto out;
832
821 packet = (struct vis_packet *)info->skb_packet->data; 833 packet = (struct vis_packet *)info->skb_packet->data;
822 if (packet->ttl < 2) { 834 if (packet->ttl < 2) {
823 pr_debug("Error - can't send vis packet: ttl exceeded\n"); 835 pr_debug("Error - can't send vis packet: ttl exceeded\n");
824 return; 836 goto out;
825 } 837 }
826 838
827 memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr, 839 memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
828 ETH_ALEN);
829 packet->ttl--; 840 packet->ttl--;
830 841
831 if (is_broadcast_ether_addr(packet->target_orig)) 842 if (is_broadcast_ether_addr(packet->target_orig))
@@ -833,6 +844,10 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
833 else 844 else
834 unicast_vis_packet(bat_priv, info); 845 unicast_vis_packet(bat_priv, info);
835 packet->ttl++; /* restore TTL */ 846 packet->ttl++; /* restore TTL */
847
848out:
849 if (primary_if)
850 hardif_free_ref(primary_if);
836} 851}
837 852
838/* called from timer; send (and maybe generate) vis packet. */ 853/* called from timer; send (and maybe generate) vis packet. */
@@ -859,8 +874,7 @@ static void send_vis_packets(struct work_struct *work)
859 kref_get(&info->refcount); 874 kref_get(&info->refcount);
860 spin_unlock_bh(&bat_priv->vis_hash_lock); 875 spin_unlock_bh(&bat_priv->vis_hash_lock);
861 876
862 if (bat_priv->primary_if) 877 send_vis_packet(bat_priv, info);
863 send_vis_packet(bat_priv, info);
864 878
865 spin_lock_bh(&bat_priv->vis_hash_lock); 879 spin_lock_bh(&bat_priv->vis_hash_lock);
866 send_list_del(info); 880 send_list_del(info);