diff options
Diffstat (limited to 'net/batman-adv/bat_iv_ogm.c')
-rw-r--r-- | net/batman-adv/bat_iv_ogm.c | 108 |
1 files changed, 81 insertions, 27 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index a2a04982a22b..0b1343dde5d2 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -87,6 +87,57 @@ static uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[]) | |||
87 | return (uint8_t)(sum / count); | 87 | return (uint8_t)(sum / count); |
88 | } | 88 | } |
89 | 89 | ||
90 | /** | ||
91 | * batadv_iv_ogm_orig_get - retrieve or create (if does not exist) an originator | ||
92 | * @bat_priv: the bat priv with all the soft interface information | ||
93 | * @addr: mac address of the originator | ||
94 | * | ||
95 | * Returns the originator object corresponding to the passed mac address or NULL | ||
96 | * on failure. | ||
97 | * If the object does not exists it is created an initialised. | ||
98 | */ | ||
99 | static struct batadv_orig_node * | ||
100 | batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const uint8_t *addr) | ||
101 | { | ||
102 | struct batadv_orig_node *orig_node; | ||
103 | int size, hash_added; | ||
104 | |||
105 | orig_node = batadv_orig_hash_find(bat_priv, addr); | ||
106 | if (orig_node) | ||
107 | return orig_node; | ||
108 | |||
109 | orig_node = batadv_orig_node_new(bat_priv, addr); | ||
110 | if (!orig_node) | ||
111 | return NULL; | ||
112 | |||
113 | spin_lock_init(&orig_node->bat_iv.ogm_cnt_lock); | ||
114 | |||
115 | size = bat_priv->num_ifaces * sizeof(unsigned long) * BATADV_NUM_WORDS; | ||
116 | orig_node->bat_iv.bcast_own = kzalloc(size, GFP_ATOMIC); | ||
117 | if (!orig_node->bat_iv.bcast_own) | ||
118 | goto free_orig_node; | ||
119 | |||
120 | size = bat_priv->num_ifaces * sizeof(uint8_t); | ||
121 | orig_node->bat_iv.bcast_own_sum = kzalloc(size, GFP_ATOMIC); | ||
122 | if (!orig_node->bat_iv.bcast_own_sum) | ||
123 | goto free_bcast_own; | ||
124 | |||
125 | hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig, | ||
126 | batadv_choose_orig, orig_node, | ||
127 | &orig_node->hash_entry); | ||
128 | if (hash_added != 0) | ||
129 | goto free_bcast_own; | ||
130 | |||
131 | return orig_node; | ||
132 | |||
133 | free_bcast_own: | ||
134 | kfree(orig_node->bat_iv.bcast_own); | ||
135 | free_orig_node: | ||
136 | batadv_orig_node_free_ref(orig_node); | ||
137 | |||
138 | return NULL; | ||
139 | } | ||
140 | |||
90 | static struct batadv_neigh_node * | 141 | static struct batadv_neigh_node * |
91 | batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, | 142 | batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, |
92 | const uint8_t *neigh_addr, | 143 | const uint8_t *neigh_addr, |
@@ -663,20 +714,22 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface) | |||
663 | uint32_t i; | 714 | uint32_t i; |
664 | size_t word_index; | 715 | size_t word_index; |
665 | uint8_t *w; | 716 | uint8_t *w; |
717 | int if_num; | ||
666 | 718 | ||
667 | for (i = 0; i < hash->size; i++) { | 719 | for (i = 0; i < hash->size; i++) { |
668 | head = &hash->table[i]; | 720 | head = &hash->table[i]; |
669 | 721 | ||
670 | rcu_read_lock(); | 722 | rcu_read_lock(); |
671 | hlist_for_each_entry_rcu(orig_node, head, hash_entry) { | 723 | hlist_for_each_entry_rcu(orig_node, head, hash_entry) { |
672 | spin_lock_bh(&orig_node->ogm_cnt_lock); | 724 | spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); |
673 | word_index = hard_iface->if_num * BATADV_NUM_WORDS; | 725 | word_index = hard_iface->if_num * BATADV_NUM_WORDS; |
674 | word = &(orig_node->bcast_own[word_index]); | 726 | word = &(orig_node->bat_iv.bcast_own[word_index]); |
675 | 727 | ||
676 | batadv_bit_get_packet(bat_priv, word, 1, 0); | 728 | batadv_bit_get_packet(bat_priv, word, 1, 0); |
677 | w = &orig_node->bcast_own_sum[hard_iface->if_num]; | 729 | if_num = hard_iface->if_num; |
730 | w = &orig_node->bat_iv.bcast_own_sum[if_num]; | ||
678 | *w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE); | 731 | *w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE); |
679 | spin_unlock_bh(&orig_node->ogm_cnt_lock); | 732 | spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); |
680 | } | 733 | } |
681 | rcu_read_unlock(); | 734 | rcu_read_unlock(); |
682 | } | 735 | } |
@@ -768,7 +821,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, | |||
768 | if (!neigh_node) { | 821 | if (!neigh_node) { |
769 | struct batadv_orig_node *orig_tmp; | 822 | struct batadv_orig_node *orig_tmp; |
770 | 823 | ||
771 | orig_tmp = batadv_get_orig_node(bat_priv, ethhdr->h_source); | 824 | orig_tmp = batadv_iv_ogm_orig_get(bat_priv, ethhdr->h_source); |
772 | if (!orig_tmp) | 825 | if (!orig_tmp) |
773 | goto unlock; | 826 | goto unlock; |
774 | 827 | ||
@@ -818,16 +871,16 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, | |||
818 | */ | 871 | */ |
819 | if (router && (neigh_node->bat_iv.tq_avg == router->bat_iv.tq_avg)) { | 872 | if (router && (neigh_node->bat_iv.tq_avg == router->bat_iv.tq_avg)) { |
820 | orig_node_tmp = router->orig_node; | 873 | orig_node_tmp = router->orig_node; |
821 | spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); | 874 | spin_lock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock); |
822 | if_num = router->if_incoming->if_num; | 875 | if_num = router->if_incoming->if_num; |
823 | sum_orig = orig_node_tmp->bcast_own_sum[if_num]; | 876 | sum_orig = orig_node_tmp->bat_iv.bcast_own_sum[if_num]; |
824 | spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); | 877 | spin_unlock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock); |
825 | 878 | ||
826 | orig_node_tmp = neigh_node->orig_node; | 879 | orig_node_tmp = neigh_node->orig_node; |
827 | spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); | 880 | spin_lock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock); |
828 | if_num = neigh_node->if_incoming->if_num; | 881 | if_num = neigh_node->if_incoming->if_num; |
829 | sum_neigh = orig_node_tmp->bcast_own_sum[if_num]; | 882 | sum_neigh = orig_node_tmp->bat_iv.bcast_own_sum[if_num]; |
830 | spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); | 883 | spin_unlock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock); |
831 | 884 | ||
832 | if (sum_orig >= sum_neigh) | 885 | if (sum_orig >= sum_neigh) |
833 | goto out; | 886 | goto out; |
@@ -855,7 +908,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, | |||
855 | uint8_t total_count; | 908 | uint8_t total_count; |
856 | uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; | 909 | uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; |
857 | unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; | 910 | unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; |
858 | int tq_asym_penalty, inv_asym_penalty, ret = 0; | 911 | int tq_asym_penalty, inv_asym_penalty, if_num, ret = 0; |
859 | unsigned int combined_tq; | 912 | unsigned int combined_tq; |
860 | 913 | ||
861 | /* find corresponding one hop neighbor */ | 914 | /* find corresponding one hop neighbor */ |
@@ -893,10 +946,11 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, | |||
893 | orig_node->last_seen = jiffies; | 946 | orig_node->last_seen = jiffies; |
894 | 947 | ||
895 | /* find packet count of corresponding one hop neighbor */ | 948 | /* find packet count of corresponding one hop neighbor */ |
896 | spin_lock_bh(&orig_node->ogm_cnt_lock); | 949 | spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); |
897 | orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num]; | 950 | if_num = if_incoming->if_num; |
951 | orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num]; | ||
898 | neigh_rq_count = neigh_node->bat_iv.real_packet_count; | 952 | neigh_rq_count = neigh_node->bat_iv.real_packet_count; |
899 | spin_unlock_bh(&orig_node->ogm_cnt_lock); | 953 | spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); |
900 | 954 | ||
901 | /* pay attention to not get a value bigger than 100 % */ | 955 | /* pay attention to not get a value bigger than 100 % */ |
902 | if (orig_eq_count > neigh_rq_count) | 956 | if (orig_eq_count > neigh_rq_count) |
@@ -980,11 +1034,11 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, | |||
980 | uint8_t packet_count; | 1034 | uint8_t packet_count; |
981 | unsigned long *bitmap; | 1035 | unsigned long *bitmap; |
982 | 1036 | ||
983 | orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); | 1037 | orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig); |
984 | if (!orig_node) | 1038 | if (!orig_node) |
985 | return BATADV_NO_DUP; | 1039 | return BATADV_NO_DUP; |
986 | 1040 | ||
987 | spin_lock_bh(&orig_node->ogm_cnt_lock); | 1041 | spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); |
988 | seq_diff = seqno - orig_node->last_real_seqno; | 1042 | seq_diff = seqno - orig_node->last_real_seqno; |
989 | 1043 | ||
990 | /* signalize caller that the packet is to be dropped. */ | 1044 | /* signalize caller that the packet is to be dropped. */ |
@@ -1033,7 +1087,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, | |||
1033 | } | 1087 | } |
1034 | 1088 | ||
1035 | out: | 1089 | out: |
1036 | spin_unlock_bh(&orig_node->ogm_cnt_lock); | 1090 | spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); |
1037 | batadv_orig_node_free_ref(orig_node); | 1091 | batadv_orig_node_free_ref(orig_node); |
1038 | return ret; | 1092 | return ret; |
1039 | } | 1093 | } |
@@ -1129,8 +1183,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1129 | int16_t if_num; | 1183 | int16_t if_num; |
1130 | uint8_t *weight; | 1184 | uint8_t *weight; |
1131 | 1185 | ||
1132 | orig_neigh_node = batadv_get_orig_node(bat_priv, | 1186 | orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv, |
1133 | ethhdr->h_source); | 1187 | ethhdr->h_source); |
1134 | if (!orig_neigh_node) | 1188 | if (!orig_neigh_node) |
1135 | return; | 1189 | return; |
1136 | 1190 | ||
@@ -1144,15 +1198,15 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1144 | if_num = if_incoming->if_num; | 1198 | if_num = if_incoming->if_num; |
1145 | offset = if_num * BATADV_NUM_WORDS; | 1199 | offset = if_num * BATADV_NUM_WORDS; |
1146 | 1200 | ||
1147 | spin_lock_bh(&orig_neigh_node->ogm_cnt_lock); | 1201 | spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock); |
1148 | word = &(orig_neigh_node->bcast_own[offset]); | 1202 | word = &(orig_neigh_node->bat_iv.bcast_own[offset]); |
1149 | bit_pos = if_incoming_seqno - 2; | 1203 | bit_pos = if_incoming_seqno - 2; |
1150 | bit_pos -= ntohl(batadv_ogm_packet->seqno); | 1204 | bit_pos -= ntohl(batadv_ogm_packet->seqno); |
1151 | batadv_set_bit(word, bit_pos); | 1205 | batadv_set_bit(word, bit_pos); |
1152 | weight = &orig_neigh_node->bcast_own_sum[if_num]; | 1206 | weight = &orig_neigh_node->bat_iv.bcast_own_sum[if_num]; |
1153 | *weight = bitmap_weight(word, | 1207 | *weight = bitmap_weight(word, |
1154 | BATADV_TQ_LOCAL_WINDOW_SIZE); | 1208 | BATADV_TQ_LOCAL_WINDOW_SIZE); |
1155 | spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock); | 1209 | spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock); |
1156 | } | 1210 | } |
1157 | 1211 | ||
1158 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | 1212 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
@@ -1175,7 +1229,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1175 | return; | 1229 | return; |
1176 | } | 1230 | } |
1177 | 1231 | ||
1178 | orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); | 1232 | orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig); |
1179 | if (!orig_node) | 1233 | if (!orig_node) |
1180 | return; | 1234 | return; |
1181 | 1235 | ||
@@ -1225,8 +1279,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1225 | if (is_single_hop_neigh) | 1279 | if (is_single_hop_neigh) |
1226 | orig_neigh_node = orig_node; | 1280 | orig_neigh_node = orig_node; |
1227 | else | 1281 | else |
1228 | orig_neigh_node = batadv_get_orig_node(bat_priv, | 1282 | orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv, |
1229 | ethhdr->h_source); | 1283 | ethhdr->h_source); |
1230 | 1284 | ||
1231 | if (!orig_neigh_node) | 1285 | if (!orig_neigh_node) |
1232 | goto out; | 1286 | goto out; |