aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/routing.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/routing.c')
-rw-r--r--net/batman-adv/routing.c61
1 files changed, 30 insertions, 31 deletions
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 9185666ab3e0..29a689ac5693 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -155,7 +155,8 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
155 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 155 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
156 struct hlist_node *node; 156 struct hlist_node *node;
157 unsigned char total_count; 157 unsigned char total_count;
158 int ret = 0; 158 uint8_t orig_eq_count, neigh_rq_count, tq_own;
159 int tq_asym_penalty, ret = 0;
159 160
160 if (orig_node == orig_neigh_node) { 161 if (orig_node == orig_neigh_node) {
161 rcu_read_lock(); 162 rcu_read_lock();
@@ -216,23 +217,25 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
216 217
217 orig_node->last_valid = jiffies; 218 orig_node->last_valid = jiffies;
218 219
220 spin_lock_bh(&orig_node->ogm_cnt_lock);
221 orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num];
222 neigh_rq_count = neigh_node->real_packet_count;
223 spin_unlock_bh(&orig_node->ogm_cnt_lock);
224
219 /* pay attention to not get a value bigger than 100 % */ 225 /* pay attention to not get a value bigger than 100 % */
220 total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > 226 total_count = (orig_eq_count > neigh_rq_count ?
221 neigh_node->real_packet_count ? 227 neigh_rq_count : orig_eq_count);
222 neigh_node->real_packet_count :
223 orig_neigh_node->bcast_own_sum[if_incoming->if_num]);
224 228
225 /* if we have too few packets (too less data) we set tq_own to zero */ 229 /* if we have too few packets (too less data) we set tq_own to zero */
226 /* if we receive too few packets it is not considered bidirectional */ 230 /* if we receive too few packets it is not considered bidirectional */
227 if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || 231 if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) ||
228 (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) 232 (neigh_rq_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
229 orig_neigh_node->tq_own = 0; 233 tq_own = 0;
230 else 234 else
231 /* neigh_node->real_packet_count is never zero as we 235 /* neigh_node->real_packet_count is never zero as we
232 * only purge old information when getting new 236 * only purge old information when getting new
233 * information */ 237 * information */
234 orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / 238 tq_own = (TQ_MAX_VALUE * total_count) / neigh_rq_count;
235 neigh_node->real_packet_count;
236 239
237 /* 240 /*
238 * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does 241 * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
@@ -240,20 +243,16 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
240 * punishes asymmetric links more. This will give a value 243 * punishes asymmetric links more. This will give a value
241 * between 0 and TQ_MAX_VALUE 244 * between 0 and TQ_MAX_VALUE
242 */ 245 */
243 orig_neigh_node->tq_asym_penalty = 246 tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE *
244 TQ_MAX_VALUE - 247 (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) *
245 (TQ_MAX_VALUE * 248 (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) *
246 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * 249 (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count)) /
247 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * 250 (TQ_LOCAL_WINDOW_SIZE *
248 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) / 251 TQ_LOCAL_WINDOW_SIZE *
249 (TQ_LOCAL_WINDOW_SIZE * 252 TQ_LOCAL_WINDOW_SIZE);
250 TQ_LOCAL_WINDOW_SIZE * 253
251 TQ_LOCAL_WINDOW_SIZE); 254 batman_packet->tq = ((batman_packet->tq * tq_own * tq_asym_penalty) /
252 255 (TQ_MAX_VALUE * TQ_MAX_VALUE));
253 batman_packet->tq = ((batman_packet->tq *
254 orig_neigh_node->tq_own *
255 orig_neigh_node->tq_asym_penalty) /
256 (TQ_MAX_VALUE * TQ_MAX_VALUE));
257 256
258 bat_dbg(DBG_BATMAN, bat_priv, 257 bat_dbg(DBG_BATMAN, bat_priv,
259 "bidirectional: " 258 "bidirectional: "
@@ -261,8 +260,7 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
261 "real recv = %2i, local tq: %3i, asym_penalty: %3i, " 260 "real recv = %2i, local tq: %3i, asym_penalty: %3i, "
262 "total tq: %3i\n", 261 "total tq: %3i\n",
263 orig_node->orig, orig_neigh_node->orig, total_count, 262 orig_node->orig, orig_neigh_node->orig, total_count,
264 neigh_node->real_packet_count, orig_neigh_node->tq_own, 263 neigh_rq_count, tq_own, tq_asym_penalty, batman_packet->tq);
265 orig_neigh_node->tq_asym_penalty, batman_packet->tq);
266 264
267 /* if link has the minimum required transmission quality 265 /* if link has the minimum required transmission quality
268 * consider it bidirectional */ 266 * consider it bidirectional */
@@ -559,18 +557,19 @@ static char count_real_packets(struct ethhdr *ethhdr,
559 char is_duplicate = 0; 557 char is_duplicate = 0;
560 int32_t seq_diff; 558 int32_t seq_diff;
561 int need_update = 0; 559 int need_update = 0;
562 int set_mark; 560 int set_mark, ret = -1;
563 561
564 orig_node = get_orig_node(bat_priv, batman_packet->orig); 562 orig_node = get_orig_node(bat_priv, batman_packet->orig);
565 if (!orig_node) 563 if (!orig_node)
566 return 0; 564 return 0;
567 565
566 spin_lock_bh(&orig_node->ogm_cnt_lock);
568 seq_diff = batman_packet->seqno - orig_node->last_real_seqno; 567 seq_diff = batman_packet->seqno - orig_node->last_real_seqno;
569 568
570 /* signalize caller that the packet is to be dropped. */ 569 /* signalize caller that the packet is to be dropped. */
571 if (window_protected(bat_priv, seq_diff, 570 if (window_protected(bat_priv, seq_diff,
572 &orig_node->batman_seqno_reset)) 571 &orig_node->batman_seqno_reset))
573 goto err; 572 goto out;
574 573
575 rcu_read_lock(); 574 rcu_read_lock();
576 hlist_for_each_entry_rcu(tmp_neigh_node, node, 575 hlist_for_each_entry_rcu(tmp_neigh_node, node,
@@ -603,12 +602,12 @@ static char count_real_packets(struct ethhdr *ethhdr,
603 orig_node->last_real_seqno = batman_packet->seqno; 602 orig_node->last_real_seqno = batman_packet->seqno;
604 } 603 }
605 604
606 kref_put(&orig_node->refcount, orig_node_free_ref); 605 ret = is_duplicate;
607 return is_duplicate;
608 606
609err: 607out:
608 spin_unlock_bh(&orig_node->ogm_cnt_lock);
610 kref_put(&orig_node->refcount, orig_node_free_ref); 609 kref_put(&orig_node->refcount, orig_node_free_ref);
611 return -1; 610 return ret;
612} 611}
613 612
614void receive_bat_packet(struct ethhdr *ethhdr, 613void receive_bat_packet(struct ethhdr *ethhdr,