1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) B.A.T.M.A.N. contributors:
3 *
4 * Edo Monticelli, Antonio Quartulli
5 */
6
7 #include "tp_meter.h"
8 #include "main.h"
9
10 #include <linux/atomic.h>
11 #include <linux/bug.h>
12 #include <linux/build_bug.h>
13 #include <linux/byteorder/generic.h>
14 #include <linux/cache.h>
15 #include <linux/compiler.h>
16 #include <linux/completion.h>
17 #include <linux/container_of.h>
18 #include <linux/err.h>
19 #include <linux/etherdevice.h>
20 #include <linux/gfp.h>
21 #include <linux/if_ether.h>
22 #include <linux/init.h>
23 #include <linux/jiffies.h>
24 #include <linux/kref.h>
25 #include <linux/kthread.h>
26 #include <linux/limits.h>
27 #include <linux/list.h>
28 #include <linux/minmax.h>
29 #include <linux/netdevice.h>
30 #include <linux/param.h>
31 #include <linux/printk.h>
32 #include <linux/random.h>
33 #include <linux/rculist.h>
34 #include <linux/rcupdate.h>
35 #include <linux/sched.h>
36 #include <linux/skbuff.h>
37 #include <linux/slab.h>
38 #include <linux/spinlock.h>
39 #include <linux/stddef.h>
40 #include <linux/string.h>
41 #include <linux/timer.h>
42 #include <linux/wait.h>
43 #include <linux/workqueue.h>
44 #include <uapi/linux/batadv_packet.h>
45 #include <uapi/linux/batman_adv.h>
46
47 #include "hard-interface.h"
48 #include "log.h"
49 #include "netlink.h"
50 #include "originator.h"
51 #include "send.h"
52
53 /**
54 * BATADV_TP_DEF_TEST_LENGTH - Default test length if not specified by the user
55 * in milliseconds
56 */
57 #define BATADV_TP_DEF_TEST_LENGTH 10000
58
59 /**
60 * BATADV_TP_AWND - Advertised window by the receiver (in bytes)
61 */
62 #define BATADV_TP_AWND 0x20000000
63
64 /**
65 * BATADV_TP_RECV_TIMEOUT - Receiver activity timeout. If the receiver does not
66 * get anything for such amount of milliseconds, the connection is killed
67 */
68 #define BATADV_TP_RECV_TIMEOUT 1000
69
70 /**
71 * BATADV_TP_MAX_RTO - Maximum sender timeout. If the sender RTO gets beyond
72 * such amount of milliseconds, the receiver is considered unreachable and the
73 * connection is killed
74 */
75 #define BATADV_TP_MAX_RTO 30000
76
77 /**
78 * BATADV_TP_FIRST_SEQ - First seqno of each session. The number is rather high
79 * in order to immediately trigger a wrap around (test purposes)
80 */
81 #define BATADV_TP_FIRST_SEQ ((u32)-1 - 2000)
82
83 /**
84 * BATADV_TP_PLEN - length of the payload (data after the batadv_unicast header)
85 * to simulate
86 */
87 #define BATADV_TP_PLEN (BATADV_TP_PACKET_LEN - ETH_HLEN - \
88 sizeof(struct batadv_unicast_packet))
89
90 /**
91 * BATADV_TP_MAX_UNACKED - maximum number of packets a receiver didn't yet ack
92 */
93 #define BATADV_TP_MAX_UNACKED 100
94
95 static u8 batadv_tp_prerandom[4096] __read_mostly;
96
97 /**
98 * batadv_tp_session_cookie() - generate session cookie based on session ids
99 * @session: TP session identifier
100 * @icmp_uid: icmp pseudo uid of the tp session
101 *
102 * Return: 32 bit tp_meter session cookie
103 */
batadv_tp_session_cookie(const u8 session[2],u8 icmp_uid)104 static u32 batadv_tp_session_cookie(const u8 session[2], u8 icmp_uid)
105 {
106 u32 cookie;
107
108 cookie = icmp_uid << 16;
109 cookie |= session[0] << 8;
110 cookie |= session[1];
111
112 return cookie;
113 }
114
115 /**
116 * batadv_tp_cwnd() - compute the new cwnd size
117 * @base: base cwnd size value
118 * @increment: the value to add to base to get the new size
119 * @min: minimum cwnd value (usually MSS)
120 *
121 * Return the new cwnd size and ensure it does not exceed the Advertised
122 * Receiver Window size. It is wrapped around safely.
123 * For details refer to Section 3.1 of RFC5681
124 *
125 * Return: new congestion window size in bytes
126 */
batadv_tp_cwnd(u32 base,u32 increment,u32 min)127 static u32 batadv_tp_cwnd(u32 base, u32 increment, u32 min)
128 {
129 u32 new_size = base + increment;
130
131 /* check for wrap-around */
132 if (new_size < base)
133 new_size = (u32)ULONG_MAX;
134
135 new_size = min_t(u32, new_size, BATADV_TP_AWND);
136
137 return max_t(u32, new_size, min);
138 }
139
140 /**
141 * batadv_tp_update_cwnd() - update the Congestion Windows
142 * @tp_vars: the private data of the current TP meter session
143 * @mss: maximum segment size of transmission
144 *
145 * 1) if the session is in Slow Start, the CWND has to be increased by 1
146 * MSS every unique received ACK
147 * 2) if the session is in Congestion Avoidance, the CWND has to be
148 * increased by MSS * MSS / CWND for every unique received ACK
149 */
batadv_tp_update_cwnd(struct batadv_tp_sender * tp_vars,u32 mss)150 static void batadv_tp_update_cwnd(struct batadv_tp_sender *tp_vars, u32 mss)
151 __must_hold(&tp_vars->cc_lock)
152 {
153 /* slow start... */
154 if (tp_vars->cc.cwnd <= tp_vars->cc.ss_threshold) {
155 tp_vars->cc.dec_cwnd = 0;
156 tp_vars->cc.cwnd = batadv_tp_cwnd(tp_vars->cc.cwnd, mss, mss);
157 return;
158 }
159
160 /* prevent overflow in (mss * mss) << 3 */
161 mss = min_t(u32, mss, (1U << 14) - 1);
162
163 /* increment CWND at least of 1 (section 3.1 of RFC5681) */
164 tp_vars->cc.dec_cwnd += max_t(u32, 1U << 3,
165 ((mss * mss) << 3) / tp_vars->cc.cwnd);
166 if (tp_vars->cc.dec_cwnd < (mss << 3))
167 return;
168
169 tp_vars->cc.cwnd = batadv_tp_cwnd(tp_vars->cc.cwnd, mss, mss);
170 tp_vars->cc.dec_cwnd = 0;
171 }
172
173 /**
174 * batadv_tp_update_rto() - calculate new retransmission timeout
175 * @tp_vars: the private data of the current TP meter session
176 * @new_rtt: new roundtrip time in msec
177 */
batadv_tp_update_rto(struct batadv_tp_sender * tp_vars,u32 new_rtt)178 static void batadv_tp_update_rto(struct batadv_tp_sender *tp_vars,
179 u32 new_rtt)
180 __must_hold(&tp_vars->cc_lock)
181 {
182 long m = new_rtt;
183
184 /* RTT update
185 * Details in Section 2.2 and 2.3 of RFC6298
186 *
187 * It's tricky to understand. Don't lose hair please.
188 * Inspired by tcp_rtt_estimator() tcp_input.c
189 */
190 if (tp_vars->cc.srtt != 0) {
191 m -= (tp_vars->cc.srtt >> 3); /* m is now error in rtt est */
192 tp_vars->cc.srtt += m; /* rtt = 7/8 srtt + 1/8 new */
193 if (m < 0)
194 m = -m;
195
196 m -= (tp_vars->cc.rttvar >> 2);
197 tp_vars->cc.rttvar += m; /* mdev ~= 3/4 rttvar + 1/4 new */
198 } else {
199 /* first measure getting in */
200 tp_vars->cc.srtt = m << 3; /* take the measured time to be srtt */
201 tp_vars->cc.rttvar = m << 1; /* new_rtt / 2 */
202 }
203
204 /* rto = srtt + 4 * rttvar.
205 * rttvar is scaled by 4, therefore doesn't need to be multiplied
206 */
207 WRITE_ONCE(tp_vars->cc.rto, (tp_vars->cc.srtt >> 3) + tp_vars->cc.rttvar);
208 }
209
210 /**
211 * batadv_tp_batctl_notify() - send client status result to client
212 * @reason: reason for tp meter session stop
213 * @dst: destination of tp_meter session
214 * @bat_priv: the bat priv with all the mesh interface information
215 * @start_time: start of transmission in jiffies
216 * @total_sent: bytes acked to the receiver
217 * @cookie: cookie of tp_meter session
218 */
batadv_tp_batctl_notify(enum batadv_tp_meter_reason reason,const u8 * dst,struct batadv_priv * bat_priv,unsigned long start_time,u64 total_sent,u32 cookie)219 static void batadv_tp_batctl_notify(enum batadv_tp_meter_reason reason,
220 const u8 *dst, struct batadv_priv *bat_priv,
221 unsigned long start_time, u64 total_sent,
222 u32 cookie)
223 {
224 u32 total_bytes;
225 u32 test_time;
226 u8 result;
227
228 if (!batadv_tp_is_error(reason)) {
229 result = BATADV_TP_REASON_COMPLETE;
230 test_time = jiffies_to_msecs(jiffies - start_time);
231 total_bytes = total_sent;
232 } else {
233 result = reason;
234 test_time = 0;
235 total_bytes = 0;
236 }
237
238 batadv_netlink_tpmeter_notify(bat_priv, dst, result, test_time,
239 total_bytes, cookie);
240 }
241
242 /**
243 * batadv_tp_batctl_error_notify() - send client error result to client
244 * @reason: reason for tp meter session stop
245 * @dst: destination of tp_meter session
246 * @bat_priv: the bat priv with all the mesh interface information
247 * @cookie: cookie of tp_meter session
248 */
batadv_tp_batctl_error_notify(enum batadv_tp_meter_reason reason,const u8 * dst,struct batadv_priv * bat_priv,u32 cookie)249 static void batadv_tp_batctl_error_notify(enum batadv_tp_meter_reason reason,
250 const u8 *dst,
251 struct batadv_priv *bat_priv,
252 u32 cookie)
253 {
254 batadv_tp_batctl_notify(reason, dst, bat_priv, 0, 0, cookie);
255 }
256
257 /**
258 * batadv_tp_list_find_sender() - find a sender tp_vars object in the global list
259 * @bat_priv: the bat priv with all the mesh interface information
260 * @dst: the other endpoint MAC address to look for
261 *
262 * Look for a tp_vars object matching dst as end_point and return it after
263 * having increment the refcounter. Return NULL is not found
264 *
265 * Return: matching tp_vars or NULL when no tp_vars with @dst was found
266 */
267 static struct batadv_tp_sender *
batadv_tp_list_find_sender(struct batadv_priv * bat_priv,const u8 * dst)268 batadv_tp_list_find_sender(struct batadv_priv *bat_priv, const u8 *dst)
269 {
270 struct batadv_tp_sender *tp_vars = NULL;
271 struct batadv_tp_sender *pos;
272
273 rcu_read_lock();
274 hlist_for_each_entry_rcu(pos, &bat_priv->tp_sender_list, common.list) {
275 if (!batadv_compare_eth(pos->common.other_end, dst))
276 continue;
277
278 /* most of the time this function is invoked during the normal
279 * process..it makes sens to pay more when the session is
280 * finished and to speed the process up during the measurement
281 */
282 if (unlikely(!kref_get_unless_zero(&pos->common.refcount)))
283 continue;
284
285 tp_vars = pos;
286 break;
287 }
288 rcu_read_unlock();
289
290 return tp_vars;
291 }
292
293 /**
294 * batadv_tp_list_active() - check if session from/to destination is ongoing
295 * @bat_priv: the bat priv with all the mesh interface information
296 * @dst: the other endpoint MAC address to look for
297 *
298 * Return: true if a matching session with @dst was found, false otherwise
299 */
batadv_tp_list_active(struct batadv_priv * bat_priv,const u8 * dst)300 static bool batadv_tp_list_active(struct batadv_priv *bat_priv, const u8 *dst)
301 __must_hold(&bat_priv->tp_list_lock)
302 {
303 struct batadv_tp_receiver *tp_receiver;
304 struct batadv_tp_sender *tp_sender;
305
306 hlist_for_each_entry_rcu(tp_sender, &bat_priv->tp_sender_list, common.list) {
307 if (batadv_compare_eth(tp_sender->common.other_end, dst))
308 return true;
309 }
310
311 hlist_for_each_entry_rcu(tp_receiver, &bat_priv->tp_receiver_list, common.list) {
312 if (batadv_compare_eth(tp_receiver->common.other_end, dst))
313 return true;
314 }
315
316 return false;
317 }
318
319 /**
320 * batadv_tp_list_find_sender_session() - find tp_vars sender session
321 * object in the global list
322 * @bat_priv: the bat priv with all the mesh interface information
323 * @dst: the other endpoint MAC address to look for
324 * @session: session identifier
325 *
326 * Look for a tp_vars object matching dst as end_point, session as tp meter
327 * session and return it after having increment the refcounter. Return NULL
328 * is not found
329 *
330 * Return: matching tp_vars or NULL when no tp_vars was found
331 */
332 static struct batadv_tp_sender *
batadv_tp_list_find_sender_session(struct batadv_priv * bat_priv,const u8 * dst,const u8 * session)333 batadv_tp_list_find_sender_session(struct batadv_priv *bat_priv, const u8 *dst,
334 const u8 *session)
335 {
336 struct batadv_tp_sender *tp_vars = NULL;
337 struct batadv_tp_sender *pos;
338
339 rcu_read_lock();
340 hlist_for_each_entry_rcu(pos, &bat_priv->tp_sender_list, common.list) {
341 if (!batadv_compare_eth(pos->common.other_end, dst))
342 continue;
343
344 if (memcmp(pos->common.session, session, sizeof(pos->common.session)) != 0)
345 continue;
346
347 /* most of the time this function is invoked during the normal
348 * process..it makes sense to pay more when the session is
349 * finished and to speed the process up during the measurement
350 */
351 if (unlikely(!kref_get_unless_zero(&pos->common.refcount)))
352 continue;
353
354 tp_vars = pos;
355 break;
356 }
357 rcu_read_unlock();
358
359 return tp_vars;
360 }
361
362 /**
363 * batadv_tp_sender_release() - release batadv_tp_sender
364 * and queue for free after rcu grace period
365 * @ref: kref pointer of the batadv_tp_sender
366 */
batadv_tp_sender_release(struct kref * ref)367 static void batadv_tp_sender_release(struct kref *ref)
368 {
369 struct batadv_tp_sender *tp_vars;
370
371 tp_vars = container_of(ref, struct batadv_tp_sender, common.refcount);
372 kfree_rcu(tp_vars, common.rcu);
373 }
374
375 /**
376 * batadv_tp_sender_put() - decrement the batadv_tp_sender
377 * refcounter and possibly release it
378 * @tp_vars: the private data of the current TP meter session to be free'd
379 */
batadv_tp_sender_put(struct batadv_tp_sender * tp_vars)380 static void batadv_tp_sender_put(struct batadv_tp_sender *tp_vars)
381 {
382 if (!tp_vars)
383 return;
384
385 kref_put(&tp_vars->common.refcount, batadv_tp_sender_release);
386 }
387
388 /**
389 * batadv_tp_list_detach() - remove tp session from mesh session list once
390 * @tp_vars: the private data of the current TP meter session
391 *
392 * Return: whether tp_vars was detached from list and reference must be freed
393 */
batadv_tp_list_detach(struct batadv_tp_vars_common * tp_vars)394 static bool batadv_tp_list_detach(struct batadv_tp_vars_common *tp_vars)
395 {
396 bool detached = false;
397
398 spin_lock_bh(&tp_vars->bat_priv->tp_list_lock);
399 if (!hlist_unhashed(&tp_vars->list)) {
400 hlist_del_init_rcu(&tp_vars->list);
401 detached = true;
402 }
403 spin_unlock_bh(&tp_vars->bat_priv->tp_list_lock);
404
405 if (!detached)
406 return false;
407
408 atomic_dec(&tp_vars->bat_priv->tp_num);
409
410 return true;
411 }
412
413 /**
414 * batadv_tp_sender_cleanup() - cleanup sender data and drop and timer
415 * @tp_vars: the private data of the current TP meter session to cleanup
416 */
batadv_tp_sender_cleanup(struct batadv_tp_sender * tp_vars)417 static void batadv_tp_sender_cleanup(struct batadv_tp_sender *tp_vars)
418 {
419 disable_delayed_work_sync(&tp_vars->finish_work);
420
421 if (batadv_tp_list_detach(&tp_vars->common))
422 batadv_tp_sender_put(tp_vars);
423
424 /* kill the timer and remove its reference */
425 timer_shutdown_sync(&tp_vars->common.timer);
426 batadv_tp_sender_put(tp_vars);
427 }
428
429 /**
430 * batadv_tp_sender_end() - print info about ended session and inform client
431 * @bat_priv: the bat priv with all the mesh interface information
432 * @tp_vars: the private data of the current TP meter session
433 */
batadv_tp_sender_end(struct batadv_priv * bat_priv,struct batadv_tp_sender * tp_vars)434 static void batadv_tp_sender_end(struct batadv_priv *bat_priv,
435 struct batadv_tp_sender *tp_vars)
436 {
437 enum batadv_tp_meter_reason reason;
438 u32 session_cookie;
439
440 reason = atomic_read(&tp_vars->send_result);
441
442 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
443 "Test towards %pM finished..shutting down (reason=%d)\n",
444 tp_vars->common.other_end, reason);
445
446 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
447 "Last timing stats: SRTT=%ums RTTVAR=%ums RTO=%ums\n",
448 tp_vars->cc.srtt >> 3, tp_vars->cc.rttvar >> 2, tp_vars->cc.rto);
449
450 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
451 "Final values: cwnd=%u ss_threshold=%u\n",
452 tp_vars->cc.cwnd, tp_vars->cc.ss_threshold);
453
454 session_cookie = batadv_tp_session_cookie(tp_vars->common.session,
455 tp_vars->icmp_uid);
456
457 batadv_tp_batctl_notify(reason,
458 tp_vars->common.other_end,
459 bat_priv,
460 tp_vars->start_time,
461 atomic64_read(&tp_vars->tot_sent),
462 session_cookie);
463 }
464
465 /**
466 * batadv_tp_sender_shutdown() - let sender thread/timer stop gracefully
467 * @tp_vars: the private data of the current TP meter session
468 * @reason: reason for tp meter session stop
469 */
batadv_tp_sender_shutdown(struct batadv_tp_sender * tp_vars,enum batadv_tp_meter_reason reason)470 static void batadv_tp_sender_shutdown(struct batadv_tp_sender *tp_vars,
471 enum batadv_tp_meter_reason reason)
472 {
473 atomic_cmpxchg(&tp_vars->send_result, 0, reason);
474 }
475
476 /**
477 * batadv_tp_sender_stopped() - check if tp session was stopped with reason
478 * @tp_vars: the private data of the current TP meter session
479 *
480 * Return: whether stop reason was found
481 */
batadv_tp_sender_stopped(struct batadv_tp_sender * tp_vars)482 static bool batadv_tp_sender_stopped(struct batadv_tp_sender *tp_vars)
483 {
484 return atomic_read(&tp_vars->send_result) != 0;
485 }
486
487 /**
488 * batadv_tp_sender_finish() - stop sender session after test_length was reached
489 * @work: delayed work reference of the related tp_vars
490 */
batadv_tp_sender_finish(struct work_struct * work)491 static void batadv_tp_sender_finish(struct work_struct *work)
492 {
493 struct delayed_work *delayed_work;
494 struct batadv_tp_sender *tp_vars;
495
496 delayed_work = to_delayed_work(work);
497 tp_vars = container_of(delayed_work, struct batadv_tp_sender,
498 finish_work);
499
500 batadv_tp_sender_shutdown(tp_vars, BATADV_TP_REASON_COMPLETE);
501 }
502
503 /**
504 * batadv_tp_reset_sender_timer() - reschedule the sender timer
505 * @tp_vars: the private TP meter data for this session
506 *
507 * Reschedule the timer using tp_vars->cc.rto as delay
508 */
batadv_tp_reset_sender_timer(struct batadv_tp_sender * tp_vars)509 static void batadv_tp_reset_sender_timer(struct batadv_tp_sender *tp_vars)
510 {
511 /* most of the time this function is invoked while normal packet
512 * reception...
513 */
514 if (unlikely(batadv_tp_sender_stopped(tp_vars)))
515 /* timer ref will be dropped in batadv_tp_sender_cleanup */
516 return;
517
518 mod_timer(&tp_vars->common.timer,
519 jiffies + msecs_to_jiffies(READ_ONCE(tp_vars->cc.rto)));
520 }
521
522 /**
523 * batadv_tp_sender_timeout() - timer that fires in case of packet loss
524 * @t: address to timer_list inside tp_vars
525 *
526 * If fired it means that there was packet loss.
527 * Switch to Slow Start, set the ss_threshold to half of the current cwnd and
528 * reset the cwnd to 3*MSS
529 */
batadv_tp_sender_timeout(struct timer_list * t)530 static void batadv_tp_sender_timeout(struct timer_list *t)
531 {
532 struct batadv_tp_sender *tp_vars = timer_container_of(tp_vars, t, common.timer);
533 struct batadv_priv *bat_priv = tp_vars->common.bat_priv;
534
535 if (batadv_tp_sender_stopped(tp_vars))
536 return;
537
538 spin_lock_bh(&tp_vars->cc_lock);
539
540 /* if the user waited long enough...shutdown the test */
541 if (unlikely(tp_vars->cc.rto >= BATADV_TP_MAX_RTO)) {
542 spin_unlock_bh(&tp_vars->cc_lock);
543 batadv_tp_sender_shutdown(tp_vars,
544 BATADV_TP_REASON_DST_UNREACHABLE);
545 return;
546 }
547
548 /* RTO exponential backoff
549 * Details in Section 5.5 of RFC6298
550 */
551 WRITE_ONCE(tp_vars->cc.rto, tp_vars->cc.rto * 2);
552
553 tp_vars->cc.ss_threshold = tp_vars->cc.cwnd >> 1;
554 if (tp_vars->cc.ss_threshold < BATADV_TP_PLEN * 2)
555 tp_vars->cc.ss_threshold = BATADV_TP_PLEN * 2;
556
557 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
558 "Meter: RTO fired during test towards %pM! cwnd=%u new ss_thr=%u, resetting last_sent to %u\n",
559 tp_vars->common.other_end, tp_vars->cc.cwnd, tp_vars->cc.ss_threshold,
560 tp_vars->cc.last_acked);
561
562 tp_vars->cc.cwnd = BATADV_TP_PLEN * 3;
563
564 WRITE_ONCE(tp_vars->cc.last_sent, tp_vars->cc.last_acked);
565
566 spin_unlock_bh(&tp_vars->cc_lock);
567
568 /* resend the non-ACKed packets.. */
569 wake_up(&tp_vars->more_bytes);
570
571 batadv_tp_reset_sender_timer(tp_vars);
572 }
573
574 /**
575 * batadv_tp_fill_prerandom() - Fill buffer with prefetched random bytes
576 * @tp_vars: the private TP meter data for this session
577 * @buf: Buffer to fill with bytes
578 * @nbytes: amount of pseudorandom bytes
579 */
batadv_tp_fill_prerandom(struct batadv_tp_sender * tp_vars,u8 * buf,size_t nbytes)580 static void batadv_tp_fill_prerandom(struct batadv_tp_sender *tp_vars,
581 u8 *buf, size_t nbytes)
582 {
583 size_t bytes_inbuf;
584 u32 local_offset;
585 size_t to_copy;
586 size_t pos = 0;
587
588 spin_lock_bh(&tp_vars->prerandom_lock);
589 local_offset = tp_vars->prerandom_offset;
590 tp_vars->prerandom_offset += nbytes;
591 tp_vars->prerandom_offset %= sizeof(batadv_tp_prerandom);
592 spin_unlock_bh(&tp_vars->prerandom_lock);
593
594 while (nbytes) {
595 local_offset %= sizeof(batadv_tp_prerandom);
596 bytes_inbuf = sizeof(batadv_tp_prerandom) - local_offset;
597 to_copy = min(nbytes, bytes_inbuf);
598
599 memcpy(&buf[pos], &batadv_tp_prerandom[local_offset], to_copy);
600 pos += to_copy;
601 nbytes -= to_copy;
602 local_offset = 0;
603 }
604 }
605
606 /**
607 * batadv_tp_send_msg() - send a single message
608 * @tp_vars: the private TP meter data for this session
609 * @src: source mac address
610 * @orig_node: the originator of the destination
611 * @seqno: sequence number of this packet
612 * @len: length of the entire packet
613 * @session: session identifier
614 * @uid: local ICMP "socket" index
615 * @timestamp: timestamp in jiffies which is replied in ack
616 *
617 * Create and send a single TP Meter message.
618 *
619 * Return: 0 on success, BATADV_TP_REASON_MEMORY_ERROR if the packet couldn't
620 * be allocated, BATADV_TP_REASON_CANT_SEND if the packet could not be
621 * transmitted
622 */
batadv_tp_send_msg(struct batadv_tp_sender * tp_vars,const u8 * src,struct batadv_orig_node * orig_node,u32 seqno,size_t len,const u8 * session,int uid,u32 timestamp)623 static int batadv_tp_send_msg(struct batadv_tp_sender *tp_vars, const u8 *src,
624 struct batadv_orig_node *orig_node,
625 u32 seqno, size_t len, const u8 *session,
626 int uid, u32 timestamp)
627 {
628 struct batadv_icmp_tp_packet *icmp;
629 struct sk_buff *skb;
630 size_t data_len;
631 u8 *data;
632 int r;
633
634 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
635 if (unlikely(!skb))
636 return BATADV_TP_REASON_MEMORY_ERROR;
637
638 skb_reserve(skb, ETH_HLEN);
639 icmp = skb_put(skb, sizeof(*icmp));
640
641 /* fill the icmp header */
642 ether_addr_copy(icmp->dst, orig_node->orig);
643 ether_addr_copy(icmp->orig, src);
644 icmp->version = BATADV_COMPAT_VERSION;
645 icmp->packet_type = BATADV_ICMP;
646 icmp->ttl = BATADV_TTL;
647 icmp->msg_type = BATADV_TP;
648 icmp->uid = uid;
649
650 icmp->subtype = BATADV_TP_MSG;
651 memcpy(icmp->session, session, sizeof(icmp->session));
652 icmp->seqno = htonl(seqno);
653 icmp->timestamp = htonl(timestamp);
654
655 data_len = len - sizeof(*icmp);
656 data = skb_put(skb, data_len);
657 batadv_tp_fill_prerandom(tp_vars, data, data_len);
658
659 r = batadv_send_skb_to_orig(skb, orig_node, NULL);
660 if (r == NET_XMIT_SUCCESS)
661 return 0;
662
663 return BATADV_TP_REASON_CANT_SEND;
664 }
665
666 /**
667 * enum batadv_tp_ack_reaction - expected reaction to ack packet
668 */
669 enum batadv_tp_ack_reaction {
670 /** @BATADV_TP_ACK_REACTION_OLD_ACK: ignore old ack packet */
671 BATADV_TP_ACK_REACTION_OLD_ACK,
672
673 /** @BATADV_TP_ACK_REACTION_IGNORE: ignore duplicated ack but reset timer */
674 BATADV_TP_ACK_REACTION_IGNORE,
675
676 /** @BATADV_TP_ACK_REACTION_RESEND_WAKEUP: resend data and wakeup "more_bytes" */
677 BATADV_TP_ACK_REACTION_RESEND_WAKEUP,
678
679 /** @BATADV_TP_ACK_REACTION_WAKEUP: wakeup "more_bytes" */
680 BATADV_TP_ACK_REACTION_WAKEUP,
681 };
682
683 /**
684 * batadv_tp_handle_ack() - Calculate reaction to ACK and update congestion control
685 * @bat_priv: the bat priv with all the mesh interface information
686 * @tp_vars: the private data of the current TP meter session
687 * @recv_ack: received ACK seqno
688 * @mss: maximum segment size for transmission
689 *
690 * Return: expected reaction to this ack
691 */
692 static enum batadv_tp_ack_reaction
batadv_tp_handle_ack(struct batadv_priv * bat_priv,struct batadv_tp_sender * tp_vars,u32 recv_ack,size_t mss)693 batadv_tp_handle_ack(struct batadv_priv *bat_priv,
694 struct batadv_tp_sender *tp_vars,
695 u32 recv_ack, size_t mss)
696 __must_hold(&tp_vars->cc_lock)
697 {
698 enum batadv_tp_ack_reaction reaction;
699
700 if (batadv_seq_before(recv_ack, tp_vars->cc.last_acked))
701 return BATADV_TP_ACK_REACTION_OLD_ACK;
702
703 /* check if this ACK is a duplicate */
704 if (tp_vars->cc.last_acked == recv_ack) {
705 /* if this is the third duplicate ACK do Fast Retransmit */
706 if (tp_vars->cc.dup_acks > 3)
707 return BATADV_TP_ACK_REACTION_IGNORE;
708
709 tp_vars->cc.dup_acks++;
710 if (tp_vars->cc.dup_acks != 3)
711 return BATADV_TP_ACK_REACTION_IGNORE;
712
713 if (!batadv_seq_before(tp_vars->cc.recover, recv_ack))
714 return BATADV_TP_ACK_REACTION_IGNORE;
715
716 /* Fast Recovery */
717 tp_vars->cc.fast_recovery = true;
718
719 /* Set recover to the last outstanding seqno when Fast Recovery
720 * is entered. RFC6582, Section 3.2, step 1
721 */
722 tp_vars->cc.recover = tp_vars->cc.last_sent;
723 tp_vars->cc.ss_threshold = tp_vars->cc.cwnd >> 1;
724 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
725 "Meter: Fast Recovery, (cur cwnd=%u) ss_thr=%u last_sent=%u recv_ack=%u\n",
726 tp_vars->cc.cwnd, tp_vars->cc.ss_threshold,
727 tp_vars->cc.last_sent, recv_ack);
728 tp_vars->cc.cwnd = batadv_tp_cwnd(tp_vars->cc.ss_threshold, 3 * mss,
729 mss);
730 tp_vars->cc.dec_cwnd = 0;
731 WRITE_ONCE(tp_vars->cc.last_sent, recv_ack);
732
733 return BATADV_TP_ACK_REACTION_RESEND_WAKEUP;
734 }
735
736 /* count the acked data */
737 atomic64_add(recv_ack - tp_vars->cc.last_acked, &tp_vars->tot_sent);
738
739 /* reset the duplicate ACKs counter */
740 tp_vars->cc.dup_acks = 0;
741
742 if (tp_vars->cc.fast_recovery) {
743 /* partial ACK */
744 if (batadv_seq_before(recv_ack, tp_vars->cc.recover)) {
745 /* this is another hole in the window. React
746 * immediately as specified by NewReno (see
747 * Section 3.2 of RFC6582 for details)
748 */
749 reaction = BATADV_TP_ACK_REACTION_RESEND_WAKEUP;
750 tp_vars->cc.cwnd = batadv_tp_cwnd(tp_vars->cc.cwnd,
751 mss, mss);
752 } else {
753 tp_vars->cc.fast_recovery = false;
754 /* set cwnd to the value of ss_threshold at the
755 * moment that Fast Recovery was entered.
756 * RFC6582, Section 3.2, step 3
757 */
758 tp_vars->cc.cwnd = batadv_tp_cwnd(tp_vars->cc.ss_threshold,
759 0, mss);
760 reaction = BATADV_TP_ACK_REACTION_WAKEUP;
761 }
762 } else {
763 if (recv_ack - tp_vars->cc.last_acked >= mss)
764 batadv_tp_update_cwnd(tp_vars, mss);
765
766 reaction = BATADV_TP_ACK_REACTION_WAKEUP;
767 }
768
769 /* move the Transmit Window */
770 WRITE_ONCE(tp_vars->cc.last_acked, recv_ack);
771
772 return reaction;
773 }
774
775 /**
776 * batadv_tp_recv_ack() - ACK receiving function
777 * @bat_priv: the bat priv with all the mesh interface information
778 * @skb: the buffer containing the received packet
779 *
780 * Process a received TP ACK packet
781 */
batadv_tp_recv_ack(struct batadv_priv * bat_priv,const struct sk_buff * skb)782 static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
783 const struct sk_buff *skb)
784 {
785 struct batadv_hard_iface *primary_if = NULL;
786 struct batadv_orig_node *orig_node = NULL;
787 const struct batadv_icmp_tp_packet *icmp;
788 enum batadv_tp_ack_reaction reaction;
789 struct batadv_tp_sender *tp_vars;
790 size_t packet_len;
791 u32 recv_ack;
792 size_t mss;
793 u32 rtt;
794
795 packet_len = BATADV_TP_PLEN;
796 mss = BATADV_TP_PLEN;
797 packet_len += sizeof(struct batadv_unicast_packet);
798
799 icmp = (struct batadv_icmp_tp_packet *)skb->data;
800 recv_ack = ntohl(icmp->seqno);
801
802 /* find the tp_vars */
803 tp_vars = batadv_tp_list_find_sender_session(bat_priv, icmp->orig,
804 icmp->session);
805 if (unlikely(!tp_vars))
806 return;
807
808 if (unlikely(batadv_tp_sender_stopped(tp_vars)))
809 goto out;
810
811 /* old ACK? silently drop it.. */
812 if (batadv_seq_before(recv_ack, READ_ONCE(tp_vars->cc.last_acked)))
813 goto out;
814
815 primary_if = batadv_primary_if_get_selected(bat_priv);
816 if (unlikely(!primary_if))
817 goto out;
818
819 orig_node = batadv_orig_hash_find(bat_priv, icmp->orig);
820 if (unlikely(!orig_node))
821 goto out;
822
823 spin_lock_bh(&tp_vars->cc_lock);
824 /* update RTO with the new sampled RTT, if any */
825 rtt = jiffies_to_msecs(jiffies) - ntohl(icmp->timestamp);
826 if (icmp->timestamp && rtt)
827 batadv_tp_update_rto(tp_vars, rtt);
828
829 reaction = batadv_tp_handle_ack(bat_priv, tp_vars, recv_ack, mss);
830 spin_unlock_bh(&tp_vars->cc_lock);
831
832 if (reaction == BATADV_TP_ACK_REACTION_OLD_ACK)
833 goto out;
834
835 /* ACK for new data... reset the timer */
836 batadv_tp_reset_sender_timer(tp_vars);
837
838 switch (reaction) {
839 default:
840 case BATADV_TP_ACK_REACTION_IGNORE:
841 goto out;
842 case BATADV_TP_ACK_REACTION_RESEND_WAKEUP:
843 batadv_tp_send_msg(tp_vars, primary_if->net_dev->dev_addr,
844 orig_node, recv_ack, packet_len,
845 icmp->session, icmp->uid,
846 jiffies_to_msecs(jiffies));
847 fallthrough;
848 case BATADV_TP_ACK_REACTION_WAKEUP:
849 wake_up(&tp_vars->more_bytes);
850 break;
851 }
852
853 out:
854 batadv_hardif_put(primary_if);
855 batadv_orig_node_put(orig_node);
856 batadv_tp_sender_put(tp_vars);
857 }
858
859 /**
860 * batadv_tp_avail() - check if congestion window is not full
861 * @tp_vars: the private data of the current TP meter session
862 * @payload_len: size of the payload of a single message
863 *
864 * Return: true when congestion window is not full, false otherwise
865 */
batadv_tp_avail(struct batadv_tp_sender * tp_vars,size_t payload_len)866 static bool batadv_tp_avail(struct batadv_tp_sender *tp_vars,
867 size_t payload_len)
868 {
869 u32 win_limit;
870 u32 win_left;
871
872 spin_lock_bh(&tp_vars->cc_lock);
873
874 win_limit = tp_vars->cc.last_acked + tp_vars->cc.cwnd;
875
876 if (batadv_seq_before(tp_vars->cc.last_sent, win_limit))
877 win_left = win_limit - tp_vars->cc.last_sent;
878 else
879 win_left = 0;
880
881 spin_unlock_bh(&tp_vars->cc_lock);
882
883 return win_left >= payload_len;
884 }
885
886 /**
887 * batadv_tp_wait_available() - wait until congestion window becomes free or
888 * timeout is reached
889 * @tp_vars: the private data of the current TP meter session
890 * @plen: size of the payload of a single message
891 *
892 * Return: 0 if the condition evaluated to false after the timeout elapsed,
893 * 1 if the condition evaluated to true after the timeout elapsed, the
894 * remaining jiffies (at least 1) if the condition evaluated to true before
895 * the timeout elapsed, or -ERESTARTSYS if it was interrupted by a signal.
896 */
batadv_tp_wait_available(struct batadv_tp_sender * tp_vars,size_t plen)897 static int batadv_tp_wait_available(struct batadv_tp_sender *tp_vars, size_t plen)
898 {
899 int ret;
900
901 ret = wait_event_interruptible_timeout(tp_vars->more_bytes,
902 batadv_tp_avail(tp_vars, plen),
903 HZ / 10);
904
905 return ret;
906 }
907
908 /**
909 * batadv_tp_send() - main sending thread of a tp meter session
910 * @arg: address of the related tp_vars
911 *
912 * Return: 0
913 */
batadv_tp_send(void * arg)914 static int batadv_tp_send(void *arg)
915 {
916 struct batadv_hard_iface *primary_if = NULL;
917 struct batadv_orig_node *orig_node = NULL;
918 struct batadv_tp_sender *tp_vars = arg;
919 struct batadv_priv *bat_priv;
920 size_t payload_len;
921 size_t packet_len;
922 u32 last_sent;
923 int err = 0;
924
925 bat_priv = tp_vars->common.bat_priv;
926 orig_node = batadv_orig_hash_find(bat_priv, tp_vars->common.other_end);
927 if (unlikely(!orig_node)) {
928 err = BATADV_TP_REASON_DST_UNREACHABLE;
929 batadv_tp_sender_shutdown(tp_vars, err);
930 goto out;
931 }
932
933 primary_if = batadv_primary_if_get_selected(bat_priv);
934 if (unlikely(!primary_if)) {
935 err = BATADV_TP_REASON_DST_UNREACHABLE;
936 batadv_tp_sender_shutdown(tp_vars, err);
937 goto out;
938 }
939
940 /* assume that all the hard_interfaces have a correctly
941 * configured MTU, so use the mesh_iface MTU as MSS.
942 * This might not be true and in that case the fragmentation
943 * should be used.
944 * Now, try to send the packet as it is
945 */
946 payload_len = BATADV_TP_PLEN;
947 BUILD_BUG_ON(sizeof(struct batadv_icmp_tp_packet) > BATADV_TP_PLEN);
948
949 batadv_tp_reset_sender_timer(tp_vars);
950
951 /* queue the worker in charge of terminating the test */
952 queue_delayed_work(batadv_event_workqueue, &tp_vars->finish_work,
953 msecs_to_jiffies(tp_vars->test_length));
954
955 while (!batadv_tp_sender_stopped(tp_vars)) {
956 if (unlikely(!batadv_tp_avail(tp_vars, payload_len))) {
957 batadv_tp_wait_available(tp_vars, payload_len);
958 continue;
959 }
960
961 /* to emulate normal unicast traffic, add to the payload len
962 * the size of the unicast header
963 */
964 packet_len = payload_len + sizeof(struct batadv_unicast_packet);
965 last_sent = READ_ONCE(tp_vars->cc.last_sent);
966
967 err = batadv_tp_send_msg(tp_vars, primary_if->net_dev->dev_addr,
968 orig_node, last_sent, packet_len,
969 tp_vars->common.session, tp_vars->icmp_uid,
970 jiffies_to_msecs(jiffies));
971
972 /* something went wrong during the preparation/transmission */
973 if (unlikely(err && err != BATADV_TP_REASON_CANT_SEND)) {
974 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
975 "Meter: %s() cannot send packets (%d)\n",
976 __func__, err);
977 /* ensure nobody else tries to stop the thread now */
978 batadv_tp_sender_shutdown(tp_vars, err);
979 break;
980 }
981
982 /* right-shift the TWND */
983 if (!err) {
984 spin_lock_bh(&tp_vars->cc_lock);
985 if (tp_vars->cc.last_sent == last_sent)
986 WRITE_ONCE(tp_vars->cc.last_sent, last_sent + payload_len);
987 spin_unlock_bh(&tp_vars->cc_lock);
988 }
989
990 cond_resched();
991 }
992
993 out:
994 batadv_hardif_put(primary_if);
995 batadv_orig_node_put(orig_node);
996
997 batadv_tp_sender_end(bat_priv, tp_vars);
998 batadv_tp_sender_cleanup(tp_vars);
999 complete(&tp_vars->finished);
1000
1001 batadv_tp_sender_put(tp_vars);
1002
1003 return 0;
1004 }
1005
1006 /**
1007 * batadv_tp_start_kthread() - start new thread which manages the tp meter
1008 * sender
1009 * @tp_vars: the private data of the current TP meter session
1010 */
batadv_tp_start_kthread(struct batadv_tp_sender * tp_vars)1011 static void batadv_tp_start_kthread(struct batadv_tp_sender *tp_vars)
1012 {
1013 struct batadv_priv *bat_priv = tp_vars->common.bat_priv;
1014 struct task_struct *kthread;
1015 u32 session_cookie;
1016
1017 kref_get(&tp_vars->common.refcount);
1018 kthread = kthread_create(batadv_tp_send, tp_vars, "kbatadv_tp_meter");
1019 if (IS_ERR(kthread)) {
1020 session_cookie = batadv_tp_session_cookie(tp_vars->common.session,
1021 tp_vars->icmp_uid);
1022 pr_err("batadv: cannot create tp meter kthread\n");
1023 batadv_tp_batctl_error_notify(BATADV_TP_REASON_MEMORY_ERROR,
1024 tp_vars->common.other_end,
1025 bat_priv, session_cookie);
1026
1027 /* drop reserved reference for kthread */
1028 batadv_tp_sender_put(tp_vars);
1029
1030 /* cleanup of failed tp meter variables */
1031 batadv_tp_sender_cleanup(tp_vars);
1032 complete(&tp_vars->finished);
1033 return;
1034 }
1035
1036 wake_up_process(kthread);
1037 }
1038
1039 /**
1040 * batadv_tp_start() - start a new tp meter session
1041 * @bat_priv: the bat priv with all the mesh interface information
1042 * @dst: the receiver MAC address
1043 * @test_length: test length in milliseconds
1044 * @cookie: session cookie
1045 */
batadv_tp_start(struct batadv_priv * bat_priv,const u8 * dst,u32 test_length,u32 * cookie)1046 void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
1047 u32 test_length, u32 *cookie)
1048 {
1049 struct batadv_tp_sender *tp_vars;
1050 u32 session_cookie;
1051 u8 session_id[2];
1052 u8 icmp_uid;
1053
1054 get_random_bytes(session_id, sizeof(session_id));
1055 get_random_bytes(&icmp_uid, 1);
1056 session_cookie = batadv_tp_session_cookie(session_id, icmp_uid);
1057 *cookie = session_cookie;
1058
1059 /* look for an already existing test towards this node */
1060 spin_lock_bh(&bat_priv->tp_list_lock);
1061 if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE) {
1062 spin_unlock_bh(&bat_priv->tp_list_lock);
1063 batadv_tp_batctl_error_notify(BATADV_TP_REASON_DST_UNREACHABLE,
1064 dst, bat_priv, session_cookie);
1065 return;
1066 }
1067
1068 if (batadv_tp_list_active(bat_priv, dst)) {
1069 spin_unlock_bh(&bat_priv->tp_list_lock);
1070 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1071 "Meter: test to or from the same node already ongoing, aborting\n");
1072 batadv_tp_batctl_error_notify(BATADV_TP_REASON_ALREADY_ONGOING,
1073 dst, bat_priv, session_cookie);
1074 return;
1075 }
1076
1077 if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM)) {
1078 spin_unlock_bh(&bat_priv->tp_list_lock);
1079 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1080 "Meter: too many ongoing sessions, aborting (SEND)\n");
1081 batadv_tp_batctl_error_notify(BATADV_TP_REASON_TOO_MANY, dst,
1082 bat_priv, session_cookie);
1083 return;
1084 }
1085
1086 tp_vars = kmalloc_obj(*tp_vars, GFP_ATOMIC);
1087 if (!tp_vars) {
1088 atomic_dec(&bat_priv->tp_num);
1089 spin_unlock_bh(&bat_priv->tp_list_lock);
1090 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1091 "Meter: %s cannot allocate list elements\n",
1092 __func__);
1093 batadv_tp_batctl_error_notify(BATADV_TP_REASON_MEMORY_ERROR,
1094 dst, bat_priv, session_cookie);
1095 return;
1096 }
1097
1098 /* initialize tp_vars */
1099 ether_addr_copy(tp_vars->common.other_end, dst);
1100 kref_init(&tp_vars->common.refcount);
1101 atomic_set(&tp_vars->send_result, 0);
1102 memcpy(tp_vars->common.session, session_id, sizeof(session_id));
1103 tp_vars->icmp_uid = icmp_uid;
1104
1105 WRITE_ONCE(tp_vars->cc.last_sent, BATADV_TP_FIRST_SEQ);
1106 WRITE_ONCE(tp_vars->cc.dup_acks, 0);
1107 WRITE_ONCE(tp_vars->cc.last_acked, BATADV_TP_FIRST_SEQ);
1108 tp_vars->cc.fast_recovery = false;
1109 tp_vars->cc.recover = BATADV_TP_FIRST_SEQ;
1110
1111 /* initialise the CWND to 3*MSS (Section 3.1 in RFC5681).
1112 * For batman-adv the MSS is the size of the payload received by the
1113 * mesh_interface, hence its MTU
1114 */
1115 tp_vars->cc.cwnd = BATADV_TP_PLEN * 3;
1116 tp_vars->cc.dec_cwnd = 0;
1117
1118 /* at the beginning initialise the SS threshold to the biggest possible
1119 * window size, hence the AWND size
1120 */
1121 tp_vars->cc.ss_threshold = BATADV_TP_AWND;
1122
1123 /* RTO initial value is 3 seconds.
1124 * Details in Section 2.1 of RFC6298
1125 */
1126 WRITE_ONCE(tp_vars->cc.rto, 1000);
1127 tp_vars->cc.srtt = 0;
1128 tp_vars->cc.rttvar = 0;
1129
1130 atomic64_set(&tp_vars->tot_sent, 0);
1131
1132 kref_get(&tp_vars->common.refcount);
1133 timer_setup(&tp_vars->common.timer, batadv_tp_sender_timeout, 0);
1134
1135 tp_vars->common.bat_priv = bat_priv;
1136 tp_vars->start_time = jiffies;
1137
1138 init_waitqueue_head(&tp_vars->more_bytes);
1139 init_completion(&tp_vars->finished);
1140
1141 spin_lock_init(&tp_vars->cc_lock);
1142
1143 tp_vars->prerandom_offset = 0;
1144 spin_lock_init(&tp_vars->prerandom_lock);
1145
1146 tp_vars->test_length = test_length;
1147 if (!tp_vars->test_length)
1148 tp_vars->test_length = BATADV_TP_DEF_TEST_LENGTH;
1149
1150 /* init work item for finished tp tests */
1151 INIT_DELAYED_WORK(&tp_vars->finish_work, batadv_tp_sender_finish);
1152
1153 kref_get(&tp_vars->common.refcount);
1154 hlist_add_head_rcu(&tp_vars->common.list, &bat_priv->tp_sender_list);
1155 spin_unlock_bh(&bat_priv->tp_list_lock);
1156
1157 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1158 "Meter: starting throughput meter towards %pM (length=%ums)\n",
1159 dst, test_length);
1160
1161 /* start tp kthread. This way the write() call issued from userspace can
1162 * happily return and avoid to block
1163 */
1164 batadv_tp_start_kthread(tp_vars);
1165
1166 /* don't return reference to new tp_vars */
1167 batadv_tp_sender_put(tp_vars);
1168 }
1169
1170 /**
1171 * batadv_tp_stop() - stop currently running tp meter session
1172 * @bat_priv: the bat priv with all the mesh interface information
1173 * @dst: the receiver MAC address
1174 * @return_value: reason for tp meter session stop
1175 */
batadv_tp_stop(struct batadv_priv * bat_priv,const u8 * dst,u8 return_value)1176 void batadv_tp_stop(struct batadv_priv *bat_priv, const u8 *dst,
1177 u8 return_value)
1178 {
1179 struct batadv_orig_node *orig_node;
1180 struct batadv_tp_sender *tp_vars;
1181
1182 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1183 "Meter: stopping test towards %pM\n", dst);
1184
1185 orig_node = batadv_orig_hash_find(bat_priv, dst);
1186 if (!orig_node)
1187 return;
1188
1189 tp_vars = batadv_tp_list_find_sender(bat_priv, orig_node->orig);
1190 if (!tp_vars) {
1191 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1192 "Meter: trying to interrupt an already over connection\n");
1193 goto out_put_orig_node;
1194 }
1195
1196 batadv_tp_sender_shutdown(tp_vars, return_value);
1197 batadv_tp_sender_put(tp_vars);
1198 out_put_orig_node:
1199 batadv_orig_node_put(orig_node);
1200 }
1201
1202 /**
1203 * batadv_tp_list_find_receiver_session() - find tp_vars receiver session
1204 * object in the global list
1205 * @bat_priv: the bat priv with all the mesh interface information
1206 * @dst: the other endpoint MAC address to look for
1207 * @session: session identifier
1208 *
1209 * Look for a tp_vars object matching dst as end_point, session as tp meter
1210 * session and return it after having increment the refcounter. Return NULL
1211 * is not found
1212 *
1213 * Return: matching tp_vars or NULL when no tp_vars was found
1214 */
1215 static struct batadv_tp_receiver *
batadv_tp_list_find_receiver_session(struct batadv_priv * bat_priv,const u8 * dst,const u8 * session)1216 batadv_tp_list_find_receiver_session(struct batadv_priv *bat_priv, const u8 *dst,
1217 const u8 *session)
1218 {
1219 struct batadv_tp_receiver *tp_vars = NULL;
1220 struct batadv_tp_receiver *pos;
1221
1222 rcu_read_lock();
1223 hlist_for_each_entry_rcu(pos, &bat_priv->tp_receiver_list, common.list) {
1224 if (!batadv_compare_eth(pos->common.other_end, dst))
1225 continue;
1226
1227 if (memcmp(pos->common.session, session, sizeof(pos->common.session)) != 0)
1228 continue;
1229
1230 /* most of the time this function is invoked during the normal
1231 * process..it makes sense to pay more when the session is
1232 * finished and to speed the process up during the measurement
1233 */
1234 if (unlikely(!kref_get_unless_zero(&pos->common.refcount)))
1235 continue;
1236
1237 tp_vars = pos;
1238 break;
1239 }
1240 rcu_read_unlock();
1241
1242 return tp_vars;
1243 }
1244
1245 /**
1246 * batadv_tp_receiver_release() - release batadv_tp_receiver
1247 * and queue for free after rcu grace period
1248 * @ref: kref pointer of the batadv_tp_receiver
1249 */
batadv_tp_receiver_release(struct kref * ref)1250 static void batadv_tp_receiver_release(struct kref *ref)
1251 {
1252 struct batadv_tp_receiver *tp_vars;
1253 struct batadv_tp_unacked *safe;
1254 struct batadv_tp_unacked *un;
1255
1256 tp_vars = container_of(ref, struct batadv_tp_receiver, common.refcount);
1257
1258 /* lock should not be needed because this object is now out of any
1259 * context!
1260 */
1261 spin_lock_bh(&tp_vars->ack_seqno_lock);
1262 list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
1263 list_del(&un->list);
1264 kfree(un);
1265 tp_vars->unacked_count--;
1266 }
1267 spin_unlock_bh(&tp_vars->ack_seqno_lock);
1268
1269 kfree_rcu(tp_vars, common.rcu);
1270 }
1271
1272 /**
1273 * batadv_tp_receiver_put() - decrement the batadv_tp_receiver
1274 * refcounter and possibly release it
1275 * @tp_vars: the private data of the current TP meter session to be free'd
1276 */
batadv_tp_receiver_put(struct batadv_tp_receiver * tp_vars)1277 static void batadv_tp_receiver_put(struct batadv_tp_receiver *tp_vars)
1278 {
1279 if (!tp_vars)
1280 return;
1281
1282 kref_put(&tp_vars->common.refcount, batadv_tp_receiver_release);
1283 }
1284
1285 /**
1286 * batadv_tp_reset_receiver_timer() - reset the receiver shutdown timer
1287 * @tp_vars: the private data of the current TP meter session
1288 *
1289 * start the receiver shutdown timer or reset it if already started
1290 */
batadv_tp_reset_receiver_timer(struct batadv_tp_receiver * tp_vars)1291 static void batadv_tp_reset_receiver_timer(struct batadv_tp_receiver *tp_vars)
1292 {
1293 mod_timer(&tp_vars->common.timer,
1294 jiffies + msecs_to_jiffies(BATADV_TP_RECV_TIMEOUT));
1295 }
1296
1297 /**
1298 * batadv_tp_receiver_shutdown() - stop a tp meter receiver when timeout is
1299 * reached without received ack
1300 * @t: address to timer_list inside tp_vars
1301 */
batadv_tp_receiver_shutdown(struct timer_list * t)1302 static void batadv_tp_receiver_shutdown(struct timer_list *t)
1303 {
1304 struct batadv_tp_receiver *tp_vars = timer_container_of(tp_vars, t, common.timer);
1305 struct batadv_tp_unacked *safe;
1306 struct batadv_tp_unacked *un;
1307 struct batadv_priv *bat_priv;
1308
1309 bat_priv = tp_vars->common.bat_priv;
1310
1311 /* if there is recent activity rearm the timer */
1312 if (!batadv_has_timed_out(READ_ONCE(tp_vars->last_recv_time),
1313 BATADV_TP_RECV_TIMEOUT)) {
1314 /* reset the receiver shutdown timer */
1315 batadv_tp_reset_receiver_timer(tp_vars);
1316 return;
1317 }
1318
1319 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1320 "Shutting down for inactivity (more than %dms) from %pM\n",
1321 BATADV_TP_RECV_TIMEOUT, tp_vars->common.other_end);
1322
1323 if (batadv_tp_list_detach(&tp_vars->common))
1324 batadv_tp_receiver_put(tp_vars);
1325
1326 spin_lock_bh(&tp_vars->ack_seqno_lock);
1327 list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
1328 list_del(&un->list);
1329 kfree(un);
1330 tp_vars->unacked_count--;
1331 }
1332 spin_unlock_bh(&tp_vars->ack_seqno_lock);
1333
1334 /* drop reference of timer */
1335 if (WARN_ON(atomic_xchg(&tp_vars->receiving, 0) != 1))
1336 return;
1337
1338 batadv_tp_receiver_put(tp_vars);
1339 }
1340
1341 /**
1342 * batadv_tp_send_ack() - send an ACK packet
1343 * @bat_priv: the bat priv with all the mesh interface information
1344 * @dst: the mac address of the destination originator
1345 * @seq: the sequence number to ACK
1346 * @timestamp: the timestamp to echo back in the ACK
1347 * @session: session identifier
1348 * @socket_index: local ICMP socket identifier
1349 *
1350 * Return: 0 on success, a positive integer representing the reason of the
1351 * failure otherwise
1352 */
batadv_tp_send_ack(struct batadv_priv * bat_priv,const u8 * dst,u32 seq,__be32 timestamp,const u8 * session,int socket_index)1353 static int batadv_tp_send_ack(struct batadv_priv *bat_priv, const u8 *dst,
1354 u32 seq, __be32 timestamp, const u8 *session,
1355 int socket_index)
1356 {
1357 struct batadv_hard_iface *primary_if = NULL;
1358 struct batadv_orig_node *orig_node;
1359 struct batadv_icmp_tp_packet *icmp;
1360 struct sk_buff *skb;
1361 int ret;
1362 int r;
1363
1364 orig_node = batadv_orig_hash_find(bat_priv, dst);
1365 if (unlikely(!orig_node)) {
1366 ret = BATADV_TP_REASON_DST_UNREACHABLE;
1367 goto out;
1368 }
1369
1370 primary_if = batadv_primary_if_get_selected(bat_priv);
1371 if (unlikely(!primary_if)) {
1372 ret = BATADV_TP_REASON_DST_UNREACHABLE;
1373 goto out;
1374 }
1375
1376 skb = netdev_alloc_skb_ip_align(NULL, sizeof(*icmp) + ETH_HLEN);
1377 if (unlikely(!skb)) {
1378 ret = BATADV_TP_REASON_MEMORY_ERROR;
1379 goto out;
1380 }
1381
1382 skb_reserve(skb, ETH_HLEN);
1383 icmp = skb_put(skb, sizeof(*icmp));
1384 icmp->packet_type = BATADV_ICMP;
1385 icmp->version = BATADV_COMPAT_VERSION;
1386 icmp->ttl = BATADV_TTL;
1387 icmp->msg_type = BATADV_TP;
1388 ether_addr_copy(icmp->dst, orig_node->orig);
1389 ether_addr_copy(icmp->orig, primary_if->net_dev->dev_addr);
1390 icmp->uid = socket_index;
1391
1392 icmp->subtype = BATADV_TP_ACK;
1393 memcpy(icmp->session, session, sizeof(icmp->session));
1394 icmp->seqno = htonl(seq);
1395 icmp->timestamp = timestamp;
1396
1397 /* send the ack */
1398 r = batadv_send_skb_to_orig(skb, orig_node, NULL);
1399 if (unlikely(r < 0) || r == NET_XMIT_DROP) {
1400 ret = BATADV_TP_REASON_DST_UNREACHABLE;
1401 goto out;
1402 }
1403 ret = 0;
1404
1405 out:
1406 batadv_orig_node_put(orig_node);
1407 batadv_hardif_put(primary_if);
1408
1409 return ret;
1410 }
1411
1412 /**
1413 * batadv_tp_handle_out_of_order() - store an out of order packet
1414 * @tp_vars: the private data of the current TP meter session
1415 * @seqno: sequence number of new received packet
1416 * @payload_len: length of the received packet
1417 *
1418 * Store the out of order packet in the unacked list for late processing. This
1419 * packets are kept in this list so that they can be ACKed at once as soon as
1420 * all the previous packets have been received
1421 *
1422 * Return: true if the packed has been successfully processed, false otherwise
1423 */
batadv_tp_handle_out_of_order(struct batadv_tp_receiver * tp_vars,u32 seqno,u32 payload_len)1424 static bool batadv_tp_handle_out_of_order(struct batadv_tp_receiver *tp_vars,
1425 u32 seqno, u32 payload_len)
1426 __must_hold(&tp_vars->ack_seqno_lock)
1427 {
1428 struct list_head *pos = &tp_vars->unacked_list;
1429 struct batadv_tp_unacked *new = NULL;
1430 u32 end_seqno = seqno + payload_len;
1431 struct batadv_tp_unacked *safe;
1432 struct batadv_tp_unacked *un;
1433
1434 /* loop over the list to find either an existing entry which the new
1435 * seqno range can be merged with or the position at which a new entry
1436 * has to be inserted.
1437 *
1438 * The iteration is done in the reverse way because it is likely that
1439 * the last received packet (the one being processed now) has a bigger
1440 * seqno than all the others already stored.
1441 */
1442 list_for_each_entry_reverse(un, &tp_vars->unacked_list, list) {
1443 /* look for the right position - an un which is smaller */
1444 if (batadv_seq_before(seqno, un->seqno))
1445 continue;
1446
1447 /* smaller/equal seqno was found but they might be directly
1448 * after another or overlapping. keep only a single entry
1449 *
1450 * It is already known that:
1451 *
1452 * un->seqno <= seqno
1453 *
1454 * When establishing that:
1455 *
1456 * seqno <= un->seqno + un->len
1457 *
1458 * Then it is not necessary to add a new entry because the
1459 * smaller/equal seqno of un might already contain the new
1460 * received packet or we only add new data directly after
1461 * the end of un. The latter can be identified using:
1462 *
1463 * un->seqno + un->len <= end_seqno
1464 */
1465 if (!batadv_seq_before(un->seqno + un->len, seqno)) {
1466 /* new data directly after un? */
1467 if (!batadv_seq_before(end_seqno, un->seqno + un->len))
1468 un->len = end_seqno - un->seqno;
1469
1470 /* un now represents both old un + new range and has to
1471 * be used to check if the gap to the next seqno range
1472 * was closed
1473 */
1474 new = un;
1475 } else {
1476 /* as soon as an entry having a smaller seqno is found,
1477 * the new one is attached _after_ it. In this way the
1478 * list is kept in ascending order
1479 */
1480 pos = &un->list;
1481 }
1482
1483 break;
1484 }
1485
1486 /* no entry to merge with was found; insert a new one after the entry
1487 * with the next smaller seqno (or at the front of the list when the
1488 * new seqno is the smallest or the list is empty)
1489 */
1490 if (!new) {
1491 new = kmalloc_obj(*new, GFP_ATOMIC);
1492 if (unlikely(!new))
1493 return false;
1494
1495 new->seqno = seqno;
1496 new->len = payload_len;
1497
1498 list_add(&new->list, pos);
1499 tp_vars->unacked_count++;
1500 }
1501
1502 /* check if new filled the gap to the next list entries */
1503 un = new;
1504 list_for_each_entry_safe_continue(un, safe, &tp_vars->unacked_list, list) {
1505 if (batadv_seq_before(end_seqno, un->seqno))
1506 break;
1507
1508 /* next entry is overlapping or adjacent - combine both */
1509 if (batadv_seq_before(end_seqno, un->seqno + un->len)) {
1510 end_seqno = un->seqno + un->len;
1511 new->len = end_seqno - new->seqno;
1512 }
1513
1514 list_del(&un->list);
1515 kfree(un);
1516 tp_vars->unacked_count--;
1517 }
1518
1519 /* remove the last (biggest) unacked seqno when list is too large */
1520 if (tp_vars->unacked_count > BATADV_TP_MAX_UNACKED) {
1521 un = list_last_entry(&tp_vars->unacked_list,
1522 struct batadv_tp_unacked, list);
1523 list_del(&un->list);
1524 kfree(un);
1525 tp_vars->unacked_count--;
1526 }
1527
1528 return true;
1529 }
1530
1531 /**
1532 * batadv_tp_ack_unordered() - update number received bytes in current stream
1533 * without gaps
1534 * @tp_vars: the private data of the current TP meter session
1535 */
batadv_tp_ack_unordered(struct batadv_tp_receiver * tp_vars)1536 static void batadv_tp_ack_unordered(struct batadv_tp_receiver *tp_vars)
1537 __must_hold(&tp_vars->ack_seqno_lock)
1538 {
1539 struct batadv_tp_unacked *safe;
1540 struct batadv_tp_unacked *un;
1541 u32 to_ack;
1542
1543 /* go through the unacked packet list and possibly ACK them as
1544 * well
1545 */
1546 list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
1547 /* the list is ordered, therefore it is possible to stop as soon
1548 * there is a gap between the last acked seqno and the seqno of
1549 * the packet under inspection
1550 */
1551 if (batadv_seq_before(tp_vars->last_recv, un->seqno))
1552 break;
1553
1554 to_ack = un->seqno + un->len;
1555
1556 if (batadv_seq_before(tp_vars->last_recv, to_ack))
1557 tp_vars->last_recv = to_ack;
1558
1559 list_del(&un->list);
1560 kfree(un);
1561 tp_vars->unacked_count--;
1562 }
1563 }
1564
1565 /**
1566 * batadv_tp_init_recv() - return matching or create new receiver tp_vars
1567 * @bat_priv: the bat priv with all the mesh interface information
1568 * @icmp: received icmp tp msg
1569 *
1570 * Return: corresponding tp_vars or NULL on errors
1571 */
1572 static struct batadv_tp_receiver *
batadv_tp_init_recv(struct batadv_priv * bat_priv,const struct batadv_icmp_tp_packet * icmp)1573 batadv_tp_init_recv(struct batadv_priv *bat_priv,
1574 const struct batadv_icmp_tp_packet *icmp)
1575 {
1576 struct batadv_tp_receiver *tp_vars = NULL;
1577
1578 spin_lock_bh(&bat_priv->tp_list_lock);
1579 if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
1580 goto out_unlock;
1581
1582 tp_vars = batadv_tp_list_find_receiver_session(bat_priv, icmp->orig,
1583 icmp->session);
1584 if (tp_vars) {
1585 WRITE_ONCE(tp_vars->last_recv_time, jiffies);
1586 goto out_unlock;
1587 }
1588
1589 if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM)) {
1590 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1591 "Meter: too many ongoing sessions, aborting (RECV)\n");
1592 goto out_unlock;
1593 }
1594
1595 tp_vars = kmalloc_obj(*tp_vars, GFP_ATOMIC);
1596 if (!tp_vars) {
1597 atomic_dec(&bat_priv->tp_num);
1598 goto out_unlock;
1599 }
1600
1601 ether_addr_copy(tp_vars->common.other_end, icmp->orig);
1602 atomic_set(&tp_vars->receiving, 1);
1603 memcpy(tp_vars->common.session, icmp->session, sizeof(tp_vars->common.session));
1604 tp_vars->last_recv = BATADV_TP_FIRST_SEQ;
1605 tp_vars->common.bat_priv = bat_priv;
1606 kref_init(&tp_vars->common.refcount);
1607
1608 spin_lock_init(&tp_vars->ack_seqno_lock);
1609 INIT_LIST_HEAD(&tp_vars->unacked_list);
1610 tp_vars->unacked_count = 0;
1611
1612 kref_get(&tp_vars->common.refcount);
1613 timer_setup(&tp_vars->common.timer, batadv_tp_receiver_shutdown, 0);
1614
1615 WRITE_ONCE(tp_vars->last_recv_time, jiffies);
1616
1617 kref_get(&tp_vars->common.refcount);
1618 hlist_add_head_rcu(&tp_vars->common.list, &bat_priv->tp_receiver_list);
1619
1620 batadv_tp_reset_receiver_timer(tp_vars);
1621
1622 out_unlock:
1623 spin_unlock_bh(&bat_priv->tp_list_lock);
1624
1625 return tp_vars;
1626 }
1627
1628 /**
1629 * batadv_tp_recv_msg() - process a single data message
1630 * @bat_priv: the bat priv with all the mesh interface information
1631 * @skb: the buffer containing the received packet
1632 *
1633 * Process a received TP MSG packet
1634 */
batadv_tp_recv_msg(struct batadv_priv * bat_priv,const struct sk_buff * skb)1635 static void batadv_tp_recv_msg(struct batadv_priv *bat_priv,
1636 const struct sk_buff *skb)
1637 {
1638 const struct batadv_icmp_tp_packet *icmp;
1639 struct batadv_tp_receiver *tp_vars;
1640 u32 payload_len;
1641 u32 to_ack;
1642 u32 seqno;
1643
1644 icmp = (struct batadv_icmp_tp_packet *)skb->data;
1645
1646 seqno = ntohl(icmp->seqno);
1647 /* check if this is the first seqno. This means that if the
1648 * first packet is lost, the tp meter does not work anymore!
1649 */
1650 if (seqno == BATADV_TP_FIRST_SEQ) {
1651 tp_vars = batadv_tp_init_recv(bat_priv, icmp);
1652 if (!tp_vars) {
1653 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1654 "Meter: seqno != BATADV_TP_FIRST_SEQ cannot initiate connection\n");
1655 goto out;
1656 }
1657 } else {
1658 tp_vars = batadv_tp_list_find_receiver_session(bat_priv, icmp->orig,
1659 icmp->session);
1660 if (!tp_vars) {
1661 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1662 "Unexpected packet from %pM!\n",
1663 icmp->orig);
1664 goto out;
1665 }
1666
1667 WRITE_ONCE(tp_vars->last_recv_time, jiffies);
1668 }
1669
1670 spin_lock_bh(&tp_vars->ack_seqno_lock);
1671
1672 /* if the packet is a duplicate, it may be the case that an ACK has been
1673 * lost. Resend the ACK
1674 */
1675 payload_len = skb->len - sizeof(struct batadv_unicast_packet);
1676 to_ack = seqno + payload_len;
1677 if (batadv_seq_before(to_ack, tp_vars->last_recv))
1678 goto send_ack;
1679
1680 /* if the packet is out of order enqueue it */
1681 if (batadv_seq_before(tp_vars->last_recv, seqno)) {
1682 /* exit immediately (and do not send any ACK) if the packet has
1683 * not been enqueued correctly
1684 */
1685 if (!batadv_tp_handle_out_of_order(tp_vars, seqno, payload_len)) {
1686 spin_unlock_bh(&tp_vars->ack_seqno_lock);
1687 goto out;
1688 }
1689
1690 /* send a duplicate ACK */
1691 goto send_ack;
1692 }
1693
1694 /* if everything was fine count the ACKed bytes */
1695 tp_vars->last_recv = to_ack;
1696
1697 /* check if this ordered message filled a gap.... */
1698 batadv_tp_ack_unordered(tp_vars);
1699
1700 send_ack:
1701 to_ack = tp_vars->last_recv;
1702 spin_unlock_bh(&tp_vars->ack_seqno_lock);
1703
1704 /* send the ACK. If the received packet was out of order, the ACK that
1705 * is going to be sent is a duplicate (the sender will count them and
1706 * possibly enter Fast Retransmit as soon as it has reached 3)
1707 */
1708 batadv_tp_send_ack(bat_priv, icmp->orig, to_ack,
1709 icmp->timestamp, icmp->session, icmp->uid);
1710 out:
1711 batadv_tp_receiver_put(tp_vars);
1712 }
1713
1714 /**
1715 * batadv_tp_meter_recv() - main TP Meter receiving function
1716 * @bat_priv: the bat priv with all the mesh interface information
1717 * @skb: the buffer containing the received packet
1718 */
batadv_tp_meter_recv(struct batadv_priv * bat_priv,struct sk_buff * skb)1719 void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb)
1720 {
1721 struct batadv_icmp_tp_packet *icmp;
1722
1723 if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
1724 goto out;
1725
1726 icmp = (struct batadv_icmp_tp_packet *)skb->data;
1727
1728 switch (icmp->subtype) {
1729 case BATADV_TP_MSG:
1730 batadv_tp_recv_msg(bat_priv, skb);
1731 break;
1732 case BATADV_TP_ACK:
1733 batadv_tp_recv_ack(bat_priv, skb);
1734 break;
1735 default:
1736 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1737 "Received unknown TP Metric packet type %u\n",
1738 icmp->subtype);
1739 }
1740
1741 out:
1742 consume_skb(skb);
1743 }
1744
1745 /**
1746 * batadv_tp_stop_all() - stop all currently running tp meter sessions
1747 * @bat_priv: the bat priv with all the mesh interface information
1748 */
batadv_tp_stop_all(struct batadv_priv * bat_priv)1749 void batadv_tp_stop_all(struct batadv_priv *bat_priv)
1750 {
1751 struct batadv_tp_receiver *tp_receivers[BATADV_TP_MAX_NUM];
1752 struct batadv_tp_sender *tp_senders[BATADV_TP_MAX_NUM];
1753 struct batadv_tp_receiver *tp_receiver;
1754 struct batadv_tp_sender *tp_sender;
1755 size_t receiver_count = 0;
1756 size_t sender_count = 0;
1757 size_t i;
1758
1759 spin_lock_bh(&bat_priv->tp_list_lock);
1760 hlist_for_each_entry(tp_receiver, &bat_priv->tp_receiver_list, common.list) {
1761 if (WARN_ON_ONCE(receiver_count >= BATADV_TP_MAX_NUM))
1762 break;
1763
1764 if (!kref_get_unless_zero(&tp_receiver->common.refcount))
1765 continue;
1766
1767 tp_receivers[receiver_count++] = tp_receiver;
1768 }
1769
1770 hlist_for_each_entry(tp_sender, &bat_priv->tp_sender_list, common.list) {
1771 if (WARN_ON_ONCE(sender_count >= BATADV_TP_MAX_NUM))
1772 break;
1773
1774 if (!kref_get_unless_zero(&tp_sender->common.refcount))
1775 continue;
1776
1777 tp_senders[sender_count++] = tp_sender;
1778 }
1779 spin_unlock_bh(&bat_priv->tp_list_lock);
1780
1781 for (i = 0; i < receiver_count; i++) {
1782 tp_receiver = tp_receivers[i];
1783
1784 if (batadv_tp_list_detach(&tp_receiver->common))
1785 batadv_tp_receiver_put(tp_receiver);
1786
1787 timer_shutdown_sync(&tp_receiver->common.timer);
1788
1789 if (atomic_xchg(&tp_receiver->receiving, 0) != 0)
1790 batadv_tp_receiver_put(tp_receiver);
1791
1792 batadv_tp_receiver_put(tp_receiver);
1793 }
1794
1795 for (i = 0; i < sender_count; i++) {
1796 tp_sender = tp_senders[i];
1797
1798 batadv_tp_sender_shutdown(tp_sender, BATADV_TP_REASON_CANCEL);
1799 wake_up(&tp_sender->more_bytes);
1800 wait_for_completion(&tp_sender->finished);
1801
1802 batadv_tp_sender_put(tp_sender);
1803 }
1804
1805 synchronize_net();
1806 }
1807
1808 /**
1809 * batadv_tp_meter_init() - initialize global tp_meter structures
1810 */
batadv_tp_meter_init(void)1811 void __init batadv_tp_meter_init(void)
1812 {
1813 get_random_bytes(batadv_tp_prerandom, sizeof(batadv_tp_prerandom));
1814 }
1815