0001
0002
0003
0004
0005
0006
0007 #include "tp_meter.h"
0008 #include "main.h"
0009
0010 #include <linux/atomic.h>
0011 #include <linux/build_bug.h>
0012 #include <linux/byteorder/generic.h>
0013 #include <linux/cache.h>
0014 #include <linux/compiler.h>
0015 #include <linux/container_of.h>
0016 #include <linux/err.h>
0017 #include <linux/etherdevice.h>
0018 #include <linux/gfp.h>
0019 #include <linux/if_ether.h>
0020 #include <linux/init.h>
0021 #include <linux/jiffies.h>
0022 #include <linux/kref.h>
0023 #include <linux/kthread.h>
0024 #include <linux/limits.h>
0025 #include <linux/list.h>
0026 #include <linux/minmax.h>
0027 #include <linux/netdevice.h>
0028 #include <linux/param.h>
0029 #include <linux/printk.h>
0030 #include <linux/random.h>
0031 #include <linux/rculist.h>
0032 #include <linux/rcupdate.h>
0033 #include <linux/sched.h>
0034 #include <linux/skbuff.h>
0035 #include <linux/slab.h>
0036 #include <linux/spinlock.h>
0037 #include <linux/stddef.h>
0038 #include <linux/string.h>
0039 #include <linux/timer.h>
0040 #include <linux/wait.h>
0041 #include <linux/workqueue.h>
0042 #include <uapi/linux/batadv_packet.h>
0043 #include <uapi/linux/batman_adv.h>
0044
0045 #include "hard-interface.h"
0046 #include "log.h"
0047 #include "netlink.h"
0048 #include "originator.h"
0049 #include "send.h"
0050
0051
0052
0053
0054
0055 #define BATADV_TP_DEF_TEST_LENGTH 10000
0056
0057
0058
0059
0060 #define BATADV_TP_AWND 0x20000000
0061
0062
0063
0064
0065
0066 #define BATADV_TP_RECV_TIMEOUT 1000
0067
0068
0069
0070
0071
0072
0073 #define BATADV_TP_MAX_RTO 30000
0074
0075
0076
0077
0078
0079 #define BATADV_TP_FIRST_SEQ ((u32)-1 - 2000)
0080
0081
0082
0083
0084
0085 #define BATADV_TP_PLEN (BATADV_TP_PACKET_LEN - ETH_HLEN - \
0086 sizeof(struct batadv_unicast_packet))
0087
0088 static u8 batadv_tp_prerandom[4096] __read_mostly;
0089
0090
0091
0092
0093
0094
0095
0096
0097 static u32 batadv_tp_session_cookie(const u8 session[2], u8 icmp_uid)
0098 {
0099 u32 cookie;
0100
0101 cookie = icmp_uid << 16;
0102 cookie |= session[0] << 8;
0103 cookie |= session[1];
0104
0105 return cookie;
0106 }
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 static u32 batadv_tp_cwnd(u32 base, u32 increment, u32 min)
0121 {
0122 u32 new_size = base + increment;
0123
0124
0125 if (new_size < base)
0126 new_size = (u32)ULONG_MAX;
0127
0128 new_size = min_t(u32, new_size, BATADV_TP_AWND);
0129
0130 return max_t(u32, new_size, min);
0131 }
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143 static void batadv_tp_update_cwnd(struct batadv_tp_vars *tp_vars, u32 mss)
0144 {
0145 spin_lock_bh(&tp_vars->cwnd_lock);
0146
0147
0148 if (tp_vars->cwnd <= tp_vars->ss_threshold) {
0149 tp_vars->dec_cwnd = 0;
0150 tp_vars->cwnd = batadv_tp_cwnd(tp_vars->cwnd, mss, mss);
0151 spin_unlock_bh(&tp_vars->cwnd_lock);
0152 return;
0153 }
0154
0155
0156 tp_vars->dec_cwnd += max_t(u32, 1U << 3,
0157 ((mss * mss) << 6) / (tp_vars->cwnd << 3));
0158 if (tp_vars->dec_cwnd < (mss << 3)) {
0159 spin_unlock_bh(&tp_vars->cwnd_lock);
0160 return;
0161 }
0162
0163 tp_vars->cwnd = batadv_tp_cwnd(tp_vars->cwnd, mss, mss);
0164 tp_vars->dec_cwnd = 0;
0165
0166 spin_unlock_bh(&tp_vars->cwnd_lock);
0167 }
0168
0169
0170
0171
0172
0173
0174 static void batadv_tp_update_rto(struct batadv_tp_vars *tp_vars,
0175 u32 new_rtt)
0176 {
0177 long m = new_rtt;
0178
0179
0180
0181
0182
0183
0184
0185 if (tp_vars->srtt != 0) {
0186 m -= (tp_vars->srtt >> 3);
0187 tp_vars->srtt += m;
0188 if (m < 0)
0189 m = -m;
0190
0191 m -= (tp_vars->rttvar >> 2);
0192 tp_vars->rttvar += m;
0193 } else {
0194
0195 tp_vars->srtt = m << 3;
0196 tp_vars->rttvar = m << 1;
0197 }
0198
0199
0200
0201
0202 tp_vars->rto = (tp_vars->srtt >> 3) + tp_vars->rttvar;
0203 }
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 static void batadv_tp_batctl_notify(enum batadv_tp_meter_reason reason,
0215 const u8 *dst, struct batadv_priv *bat_priv,
0216 unsigned long start_time, u64 total_sent,
0217 u32 cookie)
0218 {
0219 u32 test_time;
0220 u8 result;
0221 u32 total_bytes;
0222
0223 if (!batadv_tp_is_error(reason)) {
0224 result = BATADV_TP_REASON_COMPLETE;
0225 test_time = jiffies_to_msecs(jiffies - start_time);
0226 total_bytes = total_sent;
0227 } else {
0228 result = reason;
0229 test_time = 0;
0230 total_bytes = 0;
0231 }
0232
0233 batadv_netlink_tpmeter_notify(bat_priv, dst, result, test_time,
0234 total_bytes, cookie);
0235 }
0236
0237
0238
0239
0240
0241
0242
0243
0244 static void batadv_tp_batctl_error_notify(enum batadv_tp_meter_reason reason,
0245 const u8 *dst,
0246 struct batadv_priv *bat_priv,
0247 u32 cookie)
0248 {
0249 batadv_tp_batctl_notify(reason, dst, bat_priv, 0, 0, cookie);
0250 }
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262 static struct batadv_tp_vars *batadv_tp_list_find(struct batadv_priv *bat_priv,
0263 const u8 *dst)
0264 {
0265 struct batadv_tp_vars *pos, *tp_vars = NULL;
0266
0267 rcu_read_lock();
0268 hlist_for_each_entry_rcu(pos, &bat_priv->tp_list, list) {
0269 if (!batadv_compare_eth(pos->other_end, dst))
0270 continue;
0271
0272
0273
0274
0275
0276 if (unlikely(!kref_get_unless_zero(&pos->refcount)))
0277 continue;
0278
0279 tp_vars = pos;
0280 break;
0281 }
0282 rcu_read_unlock();
0283
0284 return tp_vars;
0285 }
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300 static struct batadv_tp_vars *
0301 batadv_tp_list_find_session(struct batadv_priv *bat_priv, const u8 *dst,
0302 const u8 *session)
0303 {
0304 struct batadv_tp_vars *pos, *tp_vars = NULL;
0305
0306 rcu_read_lock();
0307 hlist_for_each_entry_rcu(pos, &bat_priv->tp_list, list) {
0308 if (!batadv_compare_eth(pos->other_end, dst))
0309 continue;
0310
0311 if (memcmp(pos->session, session, sizeof(pos->session)) != 0)
0312 continue;
0313
0314
0315
0316
0317
0318 if (unlikely(!kref_get_unless_zero(&pos->refcount)))
0319 continue;
0320
0321 tp_vars = pos;
0322 break;
0323 }
0324 rcu_read_unlock();
0325
0326 return tp_vars;
0327 }
0328
0329
0330
0331
0332
0333
0334 static void batadv_tp_vars_release(struct kref *ref)
0335 {
0336 struct batadv_tp_vars *tp_vars;
0337 struct batadv_tp_unacked *un, *safe;
0338
0339 tp_vars = container_of(ref, struct batadv_tp_vars, refcount);
0340
0341
0342
0343
0344 spin_lock_bh(&tp_vars->unacked_lock);
0345 list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
0346 list_del(&un->list);
0347 kfree(un);
0348 }
0349 spin_unlock_bh(&tp_vars->unacked_lock);
0350
0351 kfree_rcu(tp_vars, rcu);
0352 }
0353
0354
0355
0356
0357
0358
0359 static void batadv_tp_vars_put(struct batadv_tp_vars *tp_vars)
0360 {
0361 if (!tp_vars)
0362 return;
0363
0364 kref_put(&tp_vars->refcount, batadv_tp_vars_release);
0365 }
0366
0367
0368
0369
0370
0371
0372 static void batadv_tp_sender_cleanup(struct batadv_priv *bat_priv,
0373 struct batadv_tp_vars *tp_vars)
0374 {
0375 cancel_delayed_work(&tp_vars->finish_work);
0376
0377 spin_lock_bh(&tp_vars->bat_priv->tp_list_lock);
0378 hlist_del_rcu(&tp_vars->list);
0379 spin_unlock_bh(&tp_vars->bat_priv->tp_list_lock);
0380
0381
0382 batadv_tp_vars_put(tp_vars);
0383
0384 atomic_dec(&tp_vars->bat_priv->tp_num);
0385
0386
0387 del_timer_sync(&tp_vars->timer);
0388
0389
0390
0391
0392
0393 del_timer(&tp_vars->timer);
0394 batadv_tp_vars_put(tp_vars);
0395 }
0396
0397
0398
0399
0400
0401
0402 static void batadv_tp_sender_end(struct batadv_priv *bat_priv,
0403 struct batadv_tp_vars *tp_vars)
0404 {
0405 u32 session_cookie;
0406
0407 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
0408 "Test towards %pM finished..shutting down (reason=%d)\n",
0409 tp_vars->other_end, tp_vars->reason);
0410
0411 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
0412 "Last timing stats: SRTT=%ums RTTVAR=%ums RTO=%ums\n",
0413 tp_vars->srtt >> 3, tp_vars->rttvar >> 2, tp_vars->rto);
0414
0415 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
0416 "Final values: cwnd=%u ss_threshold=%u\n",
0417 tp_vars->cwnd, tp_vars->ss_threshold);
0418
0419 session_cookie = batadv_tp_session_cookie(tp_vars->session,
0420 tp_vars->icmp_uid);
0421
0422 batadv_tp_batctl_notify(tp_vars->reason,
0423 tp_vars->other_end,
0424 bat_priv,
0425 tp_vars->start_time,
0426 atomic64_read(&tp_vars->tot_sent),
0427 session_cookie);
0428 }
0429
0430
0431
0432
0433
0434
0435 static void batadv_tp_sender_shutdown(struct batadv_tp_vars *tp_vars,
0436 enum batadv_tp_meter_reason reason)
0437 {
0438 if (!atomic_dec_and_test(&tp_vars->sending))
0439 return;
0440
0441 tp_vars->reason = reason;
0442 }
0443
0444
0445
0446
0447
0448 static void batadv_tp_sender_finish(struct work_struct *work)
0449 {
0450 struct delayed_work *delayed_work;
0451 struct batadv_tp_vars *tp_vars;
0452
0453 delayed_work = to_delayed_work(work);
0454 tp_vars = container_of(delayed_work, struct batadv_tp_vars,
0455 finish_work);
0456
0457 batadv_tp_sender_shutdown(tp_vars, BATADV_TP_REASON_COMPLETE);
0458 }
0459
0460
0461
0462
0463
0464
0465
0466 static void batadv_tp_reset_sender_timer(struct batadv_tp_vars *tp_vars)
0467 {
0468
0469
0470
0471 if (unlikely(atomic_read(&tp_vars->sending) == 0))
0472
0473 return;
0474
0475 mod_timer(&tp_vars->timer, jiffies + msecs_to_jiffies(tp_vars->rto));
0476 }
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486 static void batadv_tp_sender_timeout(struct timer_list *t)
0487 {
0488 struct batadv_tp_vars *tp_vars = from_timer(tp_vars, t, timer);
0489 struct batadv_priv *bat_priv = tp_vars->bat_priv;
0490
0491 if (atomic_read(&tp_vars->sending) == 0)
0492 return;
0493
0494
0495 if (unlikely(tp_vars->rto >= BATADV_TP_MAX_RTO)) {
0496 batadv_tp_sender_shutdown(tp_vars,
0497 BATADV_TP_REASON_DST_UNREACHABLE);
0498 return;
0499 }
0500
0501
0502
0503
0504 tp_vars->rto <<= 1;
0505
0506 spin_lock_bh(&tp_vars->cwnd_lock);
0507
0508 tp_vars->ss_threshold = tp_vars->cwnd >> 1;
0509 if (tp_vars->ss_threshold < BATADV_TP_PLEN * 2)
0510 tp_vars->ss_threshold = BATADV_TP_PLEN * 2;
0511
0512 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
0513 "Meter: RTO fired during test towards %pM! cwnd=%u new ss_thr=%u, resetting last_sent to %u\n",
0514 tp_vars->other_end, tp_vars->cwnd, tp_vars->ss_threshold,
0515 atomic_read(&tp_vars->last_acked));
0516
0517 tp_vars->cwnd = BATADV_TP_PLEN * 3;
0518
0519 spin_unlock_bh(&tp_vars->cwnd_lock);
0520
0521
0522 tp_vars->last_sent = atomic_read(&tp_vars->last_acked);
0523 wake_up(&tp_vars->more_bytes);
0524
0525 batadv_tp_reset_sender_timer(tp_vars);
0526 }
0527
0528
0529
0530
0531
0532
0533
0534 static void batadv_tp_fill_prerandom(struct batadv_tp_vars *tp_vars,
0535 u8 *buf, size_t nbytes)
0536 {
0537 u32 local_offset;
0538 size_t bytes_inbuf;
0539 size_t to_copy;
0540 size_t pos = 0;
0541
0542 spin_lock_bh(&tp_vars->prerandom_lock);
0543 local_offset = tp_vars->prerandom_offset;
0544 tp_vars->prerandom_offset += nbytes;
0545 tp_vars->prerandom_offset %= sizeof(batadv_tp_prerandom);
0546 spin_unlock_bh(&tp_vars->prerandom_lock);
0547
0548 while (nbytes) {
0549 local_offset %= sizeof(batadv_tp_prerandom);
0550 bytes_inbuf = sizeof(batadv_tp_prerandom) - local_offset;
0551 to_copy = min(nbytes, bytes_inbuf);
0552
0553 memcpy(&buf[pos], &batadv_tp_prerandom[local_offset], to_copy);
0554 pos += to_copy;
0555 nbytes -= to_copy;
0556 local_offset = 0;
0557 }
0558 }
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577 static int batadv_tp_send_msg(struct batadv_tp_vars *tp_vars, const u8 *src,
0578 struct batadv_orig_node *orig_node,
0579 u32 seqno, size_t len, const u8 *session,
0580 int uid, u32 timestamp)
0581 {
0582 struct batadv_icmp_tp_packet *icmp;
0583 struct sk_buff *skb;
0584 int r;
0585 u8 *data;
0586 size_t data_len;
0587
0588 skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
0589 if (unlikely(!skb))
0590 return BATADV_TP_REASON_MEMORY_ERROR;
0591
0592 skb_reserve(skb, ETH_HLEN);
0593 icmp = skb_put(skb, sizeof(*icmp));
0594
0595
0596 ether_addr_copy(icmp->dst, orig_node->orig);
0597 ether_addr_copy(icmp->orig, src);
0598 icmp->version = BATADV_COMPAT_VERSION;
0599 icmp->packet_type = BATADV_ICMP;
0600 icmp->ttl = BATADV_TTL;
0601 icmp->msg_type = BATADV_TP;
0602 icmp->uid = uid;
0603
0604 icmp->subtype = BATADV_TP_MSG;
0605 memcpy(icmp->session, session, sizeof(icmp->session));
0606 icmp->seqno = htonl(seqno);
0607 icmp->timestamp = htonl(timestamp);
0608
0609 data_len = len - sizeof(*icmp);
0610 data = skb_put(skb, data_len);
0611 batadv_tp_fill_prerandom(tp_vars, data, data_len);
0612
0613 r = batadv_send_skb_to_orig(skb, orig_node, NULL);
0614 if (r == NET_XMIT_SUCCESS)
0615 return 0;
0616
0617 return BATADV_TP_REASON_CANT_SEND;
0618 }
0619
0620
0621
0622
0623
0624
0625
0626
0627 static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
0628 const struct sk_buff *skb)
0629 {
0630 struct batadv_hard_iface *primary_if = NULL;
0631 struct batadv_orig_node *orig_node = NULL;
0632 const struct batadv_icmp_tp_packet *icmp;
0633 struct batadv_tp_vars *tp_vars;
0634 const unsigned char *dev_addr;
0635 size_t packet_len, mss;
0636 u32 rtt, recv_ack, cwnd;
0637
0638 packet_len = BATADV_TP_PLEN;
0639 mss = BATADV_TP_PLEN;
0640 packet_len += sizeof(struct batadv_unicast_packet);
0641
0642 icmp = (struct batadv_icmp_tp_packet *)skb->data;
0643
0644
0645 tp_vars = batadv_tp_list_find_session(bat_priv, icmp->orig,
0646 icmp->session);
0647 if (unlikely(!tp_vars))
0648 return;
0649
0650 if (unlikely(atomic_read(&tp_vars->sending) == 0))
0651 goto out;
0652
0653
0654 if (batadv_seq_before(ntohl(icmp->seqno),
0655 (u32)atomic_read(&tp_vars->last_acked)))
0656 goto out;
0657
0658 primary_if = batadv_primary_if_get_selected(bat_priv);
0659 if (unlikely(!primary_if))
0660 goto out;
0661
0662 orig_node = batadv_orig_hash_find(bat_priv, icmp->orig);
0663 if (unlikely(!orig_node))
0664 goto out;
0665
0666
0667 rtt = jiffies_to_msecs(jiffies) - ntohl(icmp->timestamp);
0668 if (icmp->timestamp && rtt)
0669 batadv_tp_update_rto(tp_vars, rtt);
0670
0671
0672 batadv_tp_reset_sender_timer(tp_vars);
0673
0674 recv_ack = ntohl(icmp->seqno);
0675
0676
0677 if (atomic_read(&tp_vars->last_acked) == recv_ack) {
0678 atomic_inc(&tp_vars->dup_acks);
0679 if (atomic_read(&tp_vars->dup_acks) != 3)
0680 goto out;
0681
0682 if (recv_ack >= tp_vars->recover)
0683 goto out;
0684
0685
0686 batadv_tp_send_msg(tp_vars, primary_if->net_dev->dev_addr,
0687 orig_node, recv_ack, packet_len,
0688 icmp->session, icmp->uid,
0689 jiffies_to_msecs(jiffies));
0690
0691 spin_lock_bh(&tp_vars->cwnd_lock);
0692
0693
0694 tp_vars->fast_recovery = true;
0695
0696
0697
0698 tp_vars->recover = tp_vars->last_sent;
0699 tp_vars->ss_threshold = tp_vars->cwnd >> 1;
0700 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
0701 "Meter: Fast Recovery, (cur cwnd=%u) ss_thr=%u last_sent=%u recv_ack=%u\n",
0702 tp_vars->cwnd, tp_vars->ss_threshold,
0703 tp_vars->last_sent, recv_ack);
0704 tp_vars->cwnd = batadv_tp_cwnd(tp_vars->ss_threshold, 3 * mss,
0705 mss);
0706 tp_vars->dec_cwnd = 0;
0707 tp_vars->last_sent = recv_ack;
0708
0709 spin_unlock_bh(&tp_vars->cwnd_lock);
0710 } else {
0711
0712 atomic64_add(recv_ack - atomic_read(&tp_vars->last_acked),
0713 &tp_vars->tot_sent);
0714
0715 atomic_set(&tp_vars->dup_acks, 0);
0716
0717 if (tp_vars->fast_recovery) {
0718
0719 if (batadv_seq_before(recv_ack, tp_vars->recover)) {
0720
0721
0722
0723
0724 dev_addr = primary_if->net_dev->dev_addr;
0725 batadv_tp_send_msg(tp_vars, dev_addr,
0726 orig_node, recv_ack,
0727 packet_len, icmp->session,
0728 icmp->uid,
0729 jiffies_to_msecs(jiffies));
0730 tp_vars->cwnd = batadv_tp_cwnd(tp_vars->cwnd,
0731 mss, mss);
0732 } else {
0733 tp_vars->fast_recovery = false;
0734
0735
0736
0737
0738 cwnd = batadv_tp_cwnd(tp_vars->ss_threshold, 0,
0739 mss);
0740 tp_vars->cwnd = cwnd;
0741 }
0742 goto move_twnd;
0743 }
0744
0745 if (recv_ack - atomic_read(&tp_vars->last_acked) >= mss)
0746 batadv_tp_update_cwnd(tp_vars, mss);
0747 move_twnd:
0748
0749 atomic_set(&tp_vars->last_acked, recv_ack);
0750 }
0751
0752 wake_up(&tp_vars->more_bytes);
0753 out:
0754 batadv_hardif_put(primary_if);
0755 batadv_orig_node_put(orig_node);
0756 batadv_tp_vars_put(tp_vars);
0757 }
0758
0759
0760
0761
0762
0763
0764
0765
0766 static bool batadv_tp_avail(struct batadv_tp_vars *tp_vars,
0767 size_t payload_len)
0768 {
0769 u32 win_left, win_limit;
0770
0771 win_limit = atomic_read(&tp_vars->last_acked) + tp_vars->cwnd;
0772 win_left = win_limit - tp_vars->last_sent;
0773
0774 return win_left >= payload_len;
0775 }
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788 static int batadv_tp_wait_available(struct batadv_tp_vars *tp_vars, size_t plen)
0789 {
0790 int ret;
0791
0792 ret = wait_event_interruptible_timeout(tp_vars->more_bytes,
0793 batadv_tp_avail(tp_vars, plen),
0794 HZ / 10);
0795
0796 return ret;
0797 }
0798
0799
0800
0801
0802
0803
0804
0805 static int batadv_tp_send(void *arg)
0806 {
0807 struct batadv_tp_vars *tp_vars = arg;
0808 struct batadv_priv *bat_priv = tp_vars->bat_priv;
0809 struct batadv_hard_iface *primary_if = NULL;
0810 struct batadv_orig_node *orig_node = NULL;
0811 size_t payload_len, packet_len;
0812 int err = 0;
0813
0814 if (unlikely(tp_vars->role != BATADV_TP_SENDER)) {
0815 err = BATADV_TP_REASON_DST_UNREACHABLE;
0816 tp_vars->reason = err;
0817 goto out;
0818 }
0819
0820 orig_node = batadv_orig_hash_find(bat_priv, tp_vars->other_end);
0821 if (unlikely(!orig_node)) {
0822 err = BATADV_TP_REASON_DST_UNREACHABLE;
0823 tp_vars->reason = err;
0824 goto out;
0825 }
0826
0827 primary_if = batadv_primary_if_get_selected(bat_priv);
0828 if (unlikely(!primary_if)) {
0829 err = BATADV_TP_REASON_DST_UNREACHABLE;
0830 tp_vars->reason = err;
0831 goto out;
0832 }
0833
0834
0835
0836
0837
0838
0839
0840 payload_len = BATADV_TP_PLEN;
0841 BUILD_BUG_ON(sizeof(struct batadv_icmp_tp_packet) > BATADV_TP_PLEN);
0842
0843 batadv_tp_reset_sender_timer(tp_vars);
0844
0845
0846 queue_delayed_work(batadv_event_workqueue, &tp_vars->finish_work,
0847 msecs_to_jiffies(tp_vars->test_length));
0848
0849 while (atomic_read(&tp_vars->sending) != 0) {
0850 if (unlikely(!batadv_tp_avail(tp_vars, payload_len))) {
0851 batadv_tp_wait_available(tp_vars, payload_len);
0852 continue;
0853 }
0854
0855
0856
0857
0858 packet_len = payload_len + sizeof(struct batadv_unicast_packet);
0859
0860 err = batadv_tp_send_msg(tp_vars, primary_if->net_dev->dev_addr,
0861 orig_node, tp_vars->last_sent,
0862 packet_len,
0863 tp_vars->session, tp_vars->icmp_uid,
0864 jiffies_to_msecs(jiffies));
0865
0866
0867 if (unlikely(err && err != BATADV_TP_REASON_CANT_SEND)) {
0868 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
0869 "Meter: %s() cannot send packets (%d)\n",
0870 __func__, err);
0871
0872 if (atomic_dec_and_test(&tp_vars->sending))
0873 tp_vars->reason = err;
0874 break;
0875 }
0876
0877
0878 if (!err)
0879 tp_vars->last_sent += payload_len;
0880
0881 cond_resched();
0882 }
0883
0884 out:
0885 batadv_hardif_put(primary_if);
0886 batadv_orig_node_put(orig_node);
0887
0888 batadv_tp_sender_end(bat_priv, tp_vars);
0889 batadv_tp_sender_cleanup(bat_priv, tp_vars);
0890
0891 batadv_tp_vars_put(tp_vars);
0892
0893 return 0;
0894 }
0895
0896
0897
0898
0899
0900
0901 static void batadv_tp_start_kthread(struct batadv_tp_vars *tp_vars)
0902 {
0903 struct task_struct *kthread;
0904 struct batadv_priv *bat_priv = tp_vars->bat_priv;
0905 u32 session_cookie;
0906
0907 kref_get(&tp_vars->refcount);
0908 kthread = kthread_create(batadv_tp_send, tp_vars, "kbatadv_tp_meter");
0909 if (IS_ERR(kthread)) {
0910 session_cookie = batadv_tp_session_cookie(tp_vars->session,
0911 tp_vars->icmp_uid);
0912 pr_err("batadv: cannot create tp meter kthread\n");
0913 batadv_tp_batctl_error_notify(BATADV_TP_REASON_MEMORY_ERROR,
0914 tp_vars->other_end,
0915 bat_priv, session_cookie);
0916
0917
0918 batadv_tp_vars_put(tp_vars);
0919
0920
0921 batadv_tp_sender_cleanup(bat_priv, tp_vars);
0922 return;
0923 }
0924
0925 wake_up_process(kthread);
0926 }
0927
0928
0929
0930
0931
0932
0933
0934
0935 void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
0936 u32 test_length, u32 *cookie)
0937 {
0938 struct batadv_tp_vars *tp_vars;
0939 u8 session_id[2];
0940 u8 icmp_uid;
0941 u32 session_cookie;
0942
0943 get_random_bytes(session_id, sizeof(session_id));
0944 get_random_bytes(&icmp_uid, 1);
0945 session_cookie = batadv_tp_session_cookie(session_id, icmp_uid);
0946 *cookie = session_cookie;
0947
0948
0949 spin_lock_bh(&bat_priv->tp_list_lock);
0950 tp_vars = batadv_tp_list_find(bat_priv, dst);
0951 if (tp_vars) {
0952 spin_unlock_bh(&bat_priv->tp_list_lock);
0953 batadv_tp_vars_put(tp_vars);
0954 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
0955 "Meter: test to or from the same node already ongoing, aborting\n");
0956 batadv_tp_batctl_error_notify(BATADV_TP_REASON_ALREADY_ONGOING,
0957 dst, bat_priv, session_cookie);
0958 return;
0959 }
0960
0961 if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM)) {
0962 spin_unlock_bh(&bat_priv->tp_list_lock);
0963 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
0964 "Meter: too many ongoing sessions, aborting (SEND)\n");
0965 batadv_tp_batctl_error_notify(BATADV_TP_REASON_TOO_MANY, dst,
0966 bat_priv, session_cookie);
0967 return;
0968 }
0969
0970 tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC);
0971 if (!tp_vars) {
0972 spin_unlock_bh(&bat_priv->tp_list_lock);
0973 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
0974 "Meter: %s cannot allocate list elements\n",
0975 __func__);
0976 batadv_tp_batctl_error_notify(BATADV_TP_REASON_MEMORY_ERROR,
0977 dst, bat_priv, session_cookie);
0978 return;
0979 }
0980
0981
0982 ether_addr_copy(tp_vars->other_end, dst);
0983 kref_init(&tp_vars->refcount);
0984 tp_vars->role = BATADV_TP_SENDER;
0985 atomic_set(&tp_vars->sending, 1);
0986 memcpy(tp_vars->session, session_id, sizeof(session_id));
0987 tp_vars->icmp_uid = icmp_uid;
0988
0989 tp_vars->last_sent = BATADV_TP_FIRST_SEQ;
0990 atomic_set(&tp_vars->last_acked, BATADV_TP_FIRST_SEQ);
0991 tp_vars->fast_recovery = false;
0992 tp_vars->recover = BATADV_TP_FIRST_SEQ;
0993
0994
0995
0996
0997
0998 tp_vars->cwnd = BATADV_TP_PLEN * 3;
0999
1000
1001
1002 tp_vars->ss_threshold = BATADV_TP_AWND;
1003
1004
1005
1006
1007 tp_vars->rto = 1000;
1008 tp_vars->srtt = 0;
1009 tp_vars->rttvar = 0;
1010
1011 atomic64_set(&tp_vars->tot_sent, 0);
1012
1013 kref_get(&tp_vars->refcount);
1014 timer_setup(&tp_vars->timer, batadv_tp_sender_timeout, 0);
1015
1016 tp_vars->bat_priv = bat_priv;
1017 tp_vars->start_time = jiffies;
1018
1019 init_waitqueue_head(&tp_vars->more_bytes);
1020
1021 spin_lock_init(&tp_vars->unacked_lock);
1022 INIT_LIST_HEAD(&tp_vars->unacked_list);
1023
1024 spin_lock_init(&tp_vars->cwnd_lock);
1025
1026 tp_vars->prerandom_offset = 0;
1027 spin_lock_init(&tp_vars->prerandom_lock);
1028
1029 kref_get(&tp_vars->refcount);
1030 hlist_add_head_rcu(&tp_vars->list, &bat_priv->tp_list);
1031 spin_unlock_bh(&bat_priv->tp_list_lock);
1032
1033 tp_vars->test_length = test_length;
1034 if (!tp_vars->test_length)
1035 tp_vars->test_length = BATADV_TP_DEF_TEST_LENGTH;
1036
1037 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1038 "Meter: starting throughput meter towards %pM (length=%ums)\n",
1039 dst, test_length);
1040
1041
1042 INIT_DELAYED_WORK(&tp_vars->finish_work, batadv_tp_sender_finish);
1043
1044
1045
1046
1047 batadv_tp_start_kthread(tp_vars);
1048
1049
1050 batadv_tp_vars_put(tp_vars);
1051 }
1052
1053
1054
1055
1056
1057
1058
1059 void batadv_tp_stop(struct batadv_priv *bat_priv, const u8 *dst,
1060 u8 return_value)
1061 {
1062 struct batadv_orig_node *orig_node;
1063 struct batadv_tp_vars *tp_vars;
1064
1065 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1066 "Meter: stopping test towards %pM\n", dst);
1067
1068 orig_node = batadv_orig_hash_find(bat_priv, dst);
1069 if (!orig_node)
1070 return;
1071
1072 tp_vars = batadv_tp_list_find(bat_priv, orig_node->orig);
1073 if (!tp_vars) {
1074 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1075 "Meter: trying to interrupt an already over connection\n");
1076 goto out;
1077 }
1078
1079 batadv_tp_sender_shutdown(tp_vars, return_value);
1080 batadv_tp_vars_put(tp_vars);
1081 out:
1082 batadv_orig_node_put(orig_node);
1083 }
1084
1085
1086
1087
1088
1089
1090
1091 static void batadv_tp_reset_receiver_timer(struct batadv_tp_vars *tp_vars)
1092 {
1093 mod_timer(&tp_vars->timer,
1094 jiffies + msecs_to_jiffies(BATADV_TP_RECV_TIMEOUT));
1095 }
1096
1097
1098
1099
1100
1101
1102 static void batadv_tp_receiver_shutdown(struct timer_list *t)
1103 {
1104 struct batadv_tp_vars *tp_vars = from_timer(tp_vars, t, timer);
1105 struct batadv_tp_unacked *un, *safe;
1106 struct batadv_priv *bat_priv;
1107
1108 bat_priv = tp_vars->bat_priv;
1109
1110
1111 if (!batadv_has_timed_out(tp_vars->last_recv_time,
1112 BATADV_TP_RECV_TIMEOUT)) {
1113
1114 batadv_tp_reset_receiver_timer(tp_vars);
1115 return;
1116 }
1117
1118 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1119 "Shutting down for inactivity (more than %dms) from %pM\n",
1120 BATADV_TP_RECV_TIMEOUT, tp_vars->other_end);
1121
1122 spin_lock_bh(&tp_vars->bat_priv->tp_list_lock);
1123 hlist_del_rcu(&tp_vars->list);
1124 spin_unlock_bh(&tp_vars->bat_priv->tp_list_lock);
1125
1126
1127 batadv_tp_vars_put(tp_vars);
1128
1129 atomic_dec(&bat_priv->tp_num);
1130
1131 spin_lock_bh(&tp_vars->unacked_lock);
1132 list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
1133 list_del(&un->list);
1134 kfree(un);
1135 }
1136 spin_unlock_bh(&tp_vars->unacked_lock);
1137
1138
1139 batadv_tp_vars_put(tp_vars);
1140 }
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154 static int batadv_tp_send_ack(struct batadv_priv *bat_priv, const u8 *dst,
1155 u32 seq, __be32 timestamp, const u8 *session,
1156 int socket_index)
1157 {
1158 struct batadv_hard_iface *primary_if = NULL;
1159 struct batadv_orig_node *orig_node;
1160 struct batadv_icmp_tp_packet *icmp;
1161 struct sk_buff *skb;
1162 int r, ret;
1163
1164 orig_node = batadv_orig_hash_find(bat_priv, dst);
1165 if (unlikely(!orig_node)) {
1166 ret = BATADV_TP_REASON_DST_UNREACHABLE;
1167 goto out;
1168 }
1169
1170 primary_if = batadv_primary_if_get_selected(bat_priv);
1171 if (unlikely(!primary_if)) {
1172 ret = BATADV_TP_REASON_DST_UNREACHABLE;
1173 goto out;
1174 }
1175
1176 skb = netdev_alloc_skb_ip_align(NULL, sizeof(*icmp) + ETH_HLEN);
1177 if (unlikely(!skb)) {
1178 ret = BATADV_TP_REASON_MEMORY_ERROR;
1179 goto out;
1180 }
1181
1182 skb_reserve(skb, ETH_HLEN);
1183 icmp = skb_put(skb, sizeof(*icmp));
1184 icmp->packet_type = BATADV_ICMP;
1185 icmp->version = BATADV_COMPAT_VERSION;
1186 icmp->ttl = BATADV_TTL;
1187 icmp->msg_type = BATADV_TP;
1188 ether_addr_copy(icmp->dst, orig_node->orig);
1189 ether_addr_copy(icmp->orig, primary_if->net_dev->dev_addr);
1190 icmp->uid = socket_index;
1191
1192 icmp->subtype = BATADV_TP_ACK;
1193 memcpy(icmp->session, session, sizeof(icmp->session));
1194 icmp->seqno = htonl(seq);
1195 icmp->timestamp = timestamp;
1196
1197
1198 r = batadv_send_skb_to_orig(skb, orig_node, NULL);
1199 if (unlikely(r < 0) || r == NET_XMIT_DROP) {
1200 ret = BATADV_TP_REASON_DST_UNREACHABLE;
1201 goto out;
1202 }
1203 ret = 0;
1204
1205 out:
1206 batadv_orig_node_put(orig_node);
1207 batadv_hardif_put(primary_if);
1208
1209 return ret;
1210 }
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223 static bool batadv_tp_handle_out_of_order(struct batadv_tp_vars *tp_vars,
1224 const struct sk_buff *skb)
1225 {
1226 const struct batadv_icmp_tp_packet *icmp;
1227 struct batadv_tp_unacked *un, *new;
1228 u32 payload_len;
1229 bool added = false;
1230
1231 new = kmalloc(sizeof(*new), GFP_ATOMIC);
1232 if (unlikely(!new))
1233 return false;
1234
1235 icmp = (struct batadv_icmp_tp_packet *)skb->data;
1236
1237 new->seqno = ntohl(icmp->seqno);
1238 payload_len = skb->len - sizeof(struct batadv_unicast_packet);
1239 new->len = payload_len;
1240
1241 spin_lock_bh(&tp_vars->unacked_lock);
1242
1243 if (list_empty(&tp_vars->unacked_list)) {
1244 list_add(&new->list, &tp_vars->unacked_list);
1245 goto out;
1246 }
1247
1248
1249
1250
1251
1252
1253
1254
1255 list_for_each_entry_reverse(un, &tp_vars->unacked_list, list) {
1256
1257 if (new->seqno == un->seqno) {
1258 if (new->len > un->len)
1259 un->len = new->len;
1260 kfree(new);
1261 added = true;
1262 break;
1263 }
1264
1265
1266 if (batadv_seq_before(new->seqno, un->seqno))
1267 continue;
1268
1269
1270
1271
1272
1273 list_add_tail(&new->list, &un->list);
1274 added = true;
1275 break;
1276 }
1277
1278
1279 if (!added)
1280 list_add(&new->list, &tp_vars->unacked_list);
1281
1282 out:
1283 spin_unlock_bh(&tp_vars->unacked_lock);
1284
1285 return true;
1286 }
1287
1288
1289
1290
1291
1292
1293 static void batadv_tp_ack_unordered(struct batadv_tp_vars *tp_vars)
1294 {
1295 struct batadv_tp_unacked *un, *safe;
1296 u32 to_ack;
1297
1298
1299
1300
1301 spin_lock_bh(&tp_vars->unacked_lock);
1302 list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
1303
1304
1305
1306
1307 if (batadv_seq_before(tp_vars->last_recv, un->seqno))
1308 break;
1309
1310 to_ack = un->seqno + un->len - tp_vars->last_recv;
1311
1312 if (batadv_seq_before(tp_vars->last_recv, un->seqno + un->len))
1313 tp_vars->last_recv += to_ack;
1314
1315 list_del(&un->list);
1316 kfree(un);
1317 }
1318 spin_unlock_bh(&tp_vars->unacked_lock);
1319 }
1320
1321
1322
1323
1324
1325
1326
1327
1328 static struct batadv_tp_vars *
1329 batadv_tp_init_recv(struct batadv_priv *bat_priv,
1330 const struct batadv_icmp_tp_packet *icmp)
1331 {
1332 struct batadv_tp_vars *tp_vars;
1333
1334 spin_lock_bh(&bat_priv->tp_list_lock);
1335 tp_vars = batadv_tp_list_find_session(bat_priv, icmp->orig,
1336 icmp->session);
1337 if (tp_vars)
1338 goto out_unlock;
1339
1340 if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM)) {
1341 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1342 "Meter: too many ongoing sessions, aborting (RECV)\n");
1343 goto out_unlock;
1344 }
1345
1346 tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC);
1347 if (!tp_vars)
1348 goto out_unlock;
1349
1350 ether_addr_copy(tp_vars->other_end, icmp->orig);
1351 tp_vars->role = BATADV_TP_RECEIVER;
1352 memcpy(tp_vars->session, icmp->session, sizeof(tp_vars->session));
1353 tp_vars->last_recv = BATADV_TP_FIRST_SEQ;
1354 tp_vars->bat_priv = bat_priv;
1355 kref_init(&tp_vars->refcount);
1356
1357 spin_lock_init(&tp_vars->unacked_lock);
1358 INIT_LIST_HEAD(&tp_vars->unacked_list);
1359
1360 kref_get(&tp_vars->refcount);
1361 hlist_add_head_rcu(&tp_vars->list, &bat_priv->tp_list);
1362
1363 kref_get(&tp_vars->refcount);
1364 timer_setup(&tp_vars->timer, batadv_tp_receiver_shutdown, 0);
1365
1366 batadv_tp_reset_receiver_timer(tp_vars);
1367
1368 out_unlock:
1369 spin_unlock_bh(&bat_priv->tp_list_lock);
1370
1371 return tp_vars;
1372 }
1373
1374
1375
1376
1377
1378
1379
1380
1381 static void batadv_tp_recv_msg(struct batadv_priv *bat_priv,
1382 const struct sk_buff *skb)
1383 {
1384 const struct batadv_icmp_tp_packet *icmp;
1385 struct batadv_tp_vars *tp_vars;
1386 size_t packet_size;
1387 u32 seqno;
1388
1389 icmp = (struct batadv_icmp_tp_packet *)skb->data;
1390
1391 seqno = ntohl(icmp->seqno);
1392
1393
1394
1395 if (seqno == BATADV_TP_FIRST_SEQ) {
1396 tp_vars = batadv_tp_init_recv(bat_priv, icmp);
1397 if (!tp_vars) {
1398 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1399 "Meter: seqno != BATADV_TP_FIRST_SEQ cannot initiate connection\n");
1400 goto out;
1401 }
1402 } else {
1403 tp_vars = batadv_tp_list_find_session(bat_priv, icmp->orig,
1404 icmp->session);
1405 if (!tp_vars) {
1406 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1407 "Unexpected packet from %pM!\n",
1408 icmp->orig);
1409 goto out;
1410 }
1411 }
1412
1413 if (unlikely(tp_vars->role != BATADV_TP_RECEIVER)) {
1414 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1415 "Meter: dropping packet: not expected (role=%u)\n",
1416 tp_vars->role);
1417 goto out;
1418 }
1419
1420 tp_vars->last_recv_time = jiffies;
1421
1422
1423
1424
1425 if (batadv_seq_before(seqno, tp_vars->last_recv))
1426 goto send_ack;
1427
1428
1429 if (ntohl(icmp->seqno) != tp_vars->last_recv) {
1430
1431
1432
1433 if (!batadv_tp_handle_out_of_order(tp_vars, skb))
1434 goto out;
1435
1436
1437 goto send_ack;
1438 }
1439
1440
1441 packet_size = skb->len - sizeof(struct batadv_unicast_packet);
1442 tp_vars->last_recv += packet_size;
1443
1444
1445 batadv_tp_ack_unordered(tp_vars);
1446
1447 send_ack:
1448
1449
1450
1451
1452 batadv_tp_send_ack(bat_priv, icmp->orig, tp_vars->last_recv,
1453 icmp->timestamp, icmp->session, icmp->uid);
1454 out:
1455 batadv_tp_vars_put(tp_vars);
1456 }
1457
1458
1459
1460
1461
1462
1463 void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb)
1464 {
1465 struct batadv_icmp_tp_packet *icmp;
1466
1467 icmp = (struct batadv_icmp_tp_packet *)skb->data;
1468
1469 switch (icmp->subtype) {
1470 case BATADV_TP_MSG:
1471 batadv_tp_recv_msg(bat_priv, skb);
1472 break;
1473 case BATADV_TP_ACK:
1474 batadv_tp_recv_ack(bat_priv, skb);
1475 break;
1476 default:
1477 batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
1478 "Received unknown TP Metric packet type %u\n",
1479 icmp->subtype);
1480 }
1481 consume_skb(skb);
1482 }
1483
1484
1485
1486
1487 void __init batadv_tp_meter_init(void)
1488 {
1489 get_random_bytes(batadv_tp_prerandom, sizeof(batadv_tp_prerandom));
1490 }