// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) B.A.T.M.A.N. contributors:
 *
 * Edo Monticelli, Antonio Quartulli
 */

#include "tp_meter.h"
#include "main.h"

#include <linux/atomic.h>
#include <linux/build_bug.h>
#include <linux/byteorder/generic.h>
#include <linux/cache.h>
#include <linux/compiler.h>
#include <linux/err.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
#include <linux/if_ether.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/kthread.h>
#include <linux/limits.h>
#include <linux/list.h>
#include <linux/minmax.h>
#include <linux/netdevice.h>
#include <linux/param.h>
#include <linux/printk.h>
#include <linux/random.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/sched.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <uapi/linux/batadv_packet.h>
#include <uapi/linux/batman_adv.h>

#include "hard-interface.h"
#include "log.h"
#include "netlink.h"
#include "originator.h"
#include "send.h"

/**
 * BATADV_TP_DEF_TEST_LENGTH - Default test length if not specified by the user
 *  in milliseconds
 */
#define BATADV_TP_DEF_TEST_LENGTH 10000

/**
 * BATADV_TP_AWND - Advertised window by the receiver (in bytes)
 */
#define BATADV_TP_AWND 0x20000000

/**
 * BATADV_TP_RECV_TIMEOUT - Receiver activity timeout. If the receiver does not
 *  get anything for such amount of milliseconds, the connection is killed
 */
#define BATADV_TP_RECV_TIMEOUT 1000

/**
 * BATADV_TP_MAX_RTO - Maximum sender timeout. If the sender RTO gets beyond
 * such amount of milliseconds, the receiver is considered unreachable and the
 * connection is killed
 */
#define BATADV_TP_MAX_RTO 30000

/**
 * BATADV_TP_FIRST_SEQ - First seqno of each session. The number is rather high
 *  in order to immediately trigger a wrap around (test purposes)
 */
#define BATADV_TP_FIRST_SEQ ((u32)-1 - 2000)

/**
 * BATADV_TP_PLEN - length of the payload (data after the batadv_unicast header)
 *  to simulate
 */
#define BATADV_TP_PLEN (BATADV_TP_PACKET_LEN - ETH_HLEN - \
			sizeof(struct batadv_unicast_packet))

static u8 batadv_tp_prerandom[4096] __read_mostly;

/**
 * batadv_tp_session_cookie() - generate session cookie based on session ids
 * @session: TP session identifier
 * @icmp_uid: icmp pseudo uid of the tp session
 *
 * Return: 32 bit tp_meter session cookie
 */
static u32 batadv_tp_session_cookie(const u8 session[2], u8 icmp_uid)
{
	u32 cookie;

	cookie = icmp_uid << 16;
	cookie |= session[0] << 8;
	cookie |= session[1];

	return cookie;
}

/**
 * batadv_tp_cwnd() - compute the new cwnd size
 * @base: base cwnd size value
 * @increment: the value to add to base to get the new size
 * @min: minimum cwnd value (usually MSS)
 *
 * Return the new cwnd size and ensure it does not exceed the Advertised
 * Receiver Window size. It is wrapped around safely.
 * For details refer to Section 3.1 of RFC5681
 *
 * Return: new congestion window size in bytes
 */
static u32 batadv_tp_cwnd(u32 base, u32 increment, u32 min)
{
	u32 new_size = base + increment;

	/* check for wrap-around */
	if (new_size < base)
		new_size = (u32)ULONG_MAX;

	new_size = min_t(u32, new_size, BATADV_TP_AWND);

	return max_t(u32, new_size, min);
}

/**
 * batadv_tp_update_cwnd() - update the Congestion Windows
 * @tp_vars: the private data of the current TP meter session
 * @mss: maximum segment size of transmission
 *
 * 1) if the session is in Slow Start, the CWND has to be increased by 1
 * MSS every unique received ACK
 * 2) if the session is in Congestion Avoidance, the CWND has to be
 * increased by MSS * MSS / CWND for every unique received ACK
 */
static void batadv_tp_update_cwnd(struct batadv_tp_vars *tp_vars, u32 mss)
{
	spin_lock_bh(&tp_vars->cwnd_lock);

	/* slow start... */
	if (tp_vars->cwnd <= tp_vars->ss_threshold) {
		tp_vars->dec_cwnd = 0;
		tp_vars->cwnd = batadv_tp_cwnd(tp_vars->cwnd, mss, mss);
		spin_unlock_bh(&tp_vars->cwnd_lock);
		return;
	}

	/* increment CWND at least of 1 (section 3.1 of RFC5681) */
	tp_vars->dec_cwnd += max_t(u32, 1U << 3,
				   ((mss * mss) << 6) / (tp_vars->cwnd << 3));
	if (tp_vars->dec_cwnd < (mss << 3)) {
		spin_unlock_bh(&tp_vars->cwnd_lock);
		return;
	}

	tp_vars->cwnd = batadv_tp_cwnd(tp_vars->cwnd, mss, mss);
	tp_vars->dec_cwnd = 0;

	spin_unlock_bh(&tp_vars->cwnd_lock);
}

/**
 * batadv_tp_update_rto() - calculate new retransmission timeout
 * @tp_vars: the private data of the current TP meter session
 * @new_rtt: new roundtrip time in msec
 */
static void batadv_tp_update_rto(struct batadv_tp_vars *tp_vars,
				 u32 new_rtt)
{
	long m = new_rtt;

	/* RTT update
	 * Details in Section 2.2 and 2.3 of RFC6298
	 *
	 * It's tricky to understand. Don't lose hair please.
	 * Inspired by tcp_rtt_estimator() tcp_input.c
	 */
	if (tp_vars->srtt != 0) {
		m -= (tp_vars->srtt >> 3); /* m is now error in rtt est */
		tp_vars->srtt += m; /* rtt = 7/8 srtt + 1/8 new */
		if (m < 0)
			m = -m;

		m -= (tp_vars->rttvar >> 2);
		tp_vars->rttvar += m; /* mdev ~= 3/4 rttvar + 1/4 new */
	} else {
		/* first measure getting in */
		tp_vars->srtt = m << 3;	/* take the measured time to be srtt */
		tp_vars->rttvar = m << 1; /* new_rtt / 2 */
	}

	/* rto = srtt + 4 * rttvar.
	 * rttvar is scaled by 4, therefore doesn't need to be multiplied
	 */
	tp_vars->rto = (tp_vars->srtt >> 3) + tp_vars->rttvar;
}

/**
 * batadv_tp_batctl_notify() - send client status result to client
 * @reason: reason for tp meter session stop
 * @dst: destination of tp_meter session
 * @bat_priv: the bat priv with all the soft interface information
 * @start_time: start of transmission in jiffies
 * @total_sent: bytes acked to the receiver
 * @cookie: cookie of tp_meter session
 */
static void 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)
{
	u32 test_time;
	u8 result;
	u32 total_bytes;

	if (!batadv_tp_is_error(reason)) {
		result = BATADV_TP_REASON_COMPLETE;
		test_time = jiffies_to_msecs(jiffies - start_time);
		total_bytes = total_sent;
	} else {
		result = reason;
		test_time = 0;
		total_bytes = 0;
	}

	batadv_netlink_tpmeter_notify(bat_priv, dst, result, test_time,
				      total_bytes, cookie);
}

/**
 * batadv_tp_batctl_error_notify() - send client error result to client
 * @reason: reason for tp meter session stop
 * @dst: destination of tp_meter session
 * @bat_priv: the bat priv with all the soft interface information
 * @cookie: cookie of tp_meter session
 */
static void batadv_tp_batctl_error_notify(enum batadv_tp_meter_reason reason,
					  const u8 *dst,
					  struct batadv_priv *bat_priv,
					  u32 cookie)
{
	batadv_tp_batctl_notify(reason, dst, bat_priv, 0, 0, cookie);
}

/**
 * batadv_tp_list_find() - find a tp_vars object in the global list
 * @bat_priv: the bat priv with all the soft interface information
 * @dst: the other endpoint MAC address to look for
 *
 * Look for a tp_vars object matching dst as end_point and return it after
 * having increment the refcounter. Return NULL is not found
 *
 * Return: matching tp_vars or NULL when no tp_vars with @dst was found
 */
static struct batadv_tp_vars *batadv_tp_list_find(struct batadv_priv *bat_priv,
						  const u8 *dst)
{
	struct batadv_tp_vars *pos, *tp_vars = NULL;

	rcu_read_lock();
	hlist_for_each_entry_rcu(pos, &bat_priv->tp_list, list) {
		if (!batadv_compare_eth(pos->other_end, dst))
			continue;

		/* most of the time this function is invoked during the normal
		 * process..it makes sens to pay more when the session is
		 * finished and to speed the process up during the measurement
		 */
		if (unlikely(!kref_get_unless_zero(&pos->refcount)))
			continue;

		tp_vars = pos;
		break;
	}
	rcu_read_unlock();

	return tp_vars;
}

/**
 * batadv_tp_list_find_session() - find tp_vars session object in the global
 *  list
 * @bat_priv: the bat priv with all the soft interface information
 * @dst: the other endpoint MAC address to look for
 * @session: session identifier
 *
 * Look for a tp_vars object matching dst as end_point, session as tp meter
 * session and return it after having increment the refcounter. Return NULL
 * is not found
 *
 * Return: matching tp_vars or NULL when no tp_vars was found
 */
static struct batadv_tp_vars *
batadv_tp_list_find_session(struct batadv_priv *bat_priv, const u8 *dst,
			    const u8 *session)
{
	struct batadv_tp_vars *pos, *tp_vars = NULL;

	rcu_read_lock();
	hlist_for_each_entry_rcu(pos, &bat_priv->tp_list, list) {
		if (!batadv_compare_eth(pos->other_end, dst))
			continue;

		if (memcmp(pos->session, session, sizeof(pos->session)) != 0)
			continue;

		/* most of the time this function is invoked during the normal
		 * process..it makes sense to pay more when the session is
		 * finished and to speed the process up during the measurement
		 */
		if (unlikely(!kref_get_unless_zero(&pos->refcount)))
			continue;

		tp_vars = pos;
		break;
	}
	rcu_read_unlock();

	return tp_vars;
}

/**
 * batadv_tp_vars_release() - release batadv_tp_vars from lists and queue for
 *  free after rcu grace period
 * @ref: kref pointer of the batadv_tp_vars
 */
static void batadv_tp_vars_release(struct kref *ref)
{
	struct batadv_tp_vars *tp_vars;
	struct batadv_tp_unacked *un, *safe;

	tp_vars = container_of(ref, struct batadv_tp_vars, refcount);

	/* lock should not be needed because this object is now out of any
	 * context!
	 */
	spin_lock_bh(&tp_vars->unacked_lock);
	list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
		list_del(&un->list);
		kfree(un);
	}
	spin_unlock_bh(&tp_vars->unacked_lock);

	kfree_rcu(tp_vars, rcu);
}

/**
 * batadv_tp_vars_put() - decrement the batadv_tp_vars refcounter and possibly
 *  release it
 * @tp_vars: the private data of the current TP meter session to be free'd
 */
static void batadv_tp_vars_put(struct batadv_tp_vars *tp_vars)
{
	kref_put(&tp_vars->refcount, batadv_tp_vars_release);
}

/**
 * batadv_tp_sender_cleanup() - cleanup sender data and drop and timer
 * @bat_priv: the bat priv with all the soft interface information
 * @tp_vars: the private data of the current TP meter session to cleanup
 */
static void batadv_tp_sender_cleanup(struct batadv_priv *bat_priv,
				     struct batadv_tp_vars *tp_vars)
{
	cancel_delayed_work(&tp_vars->finish_work);

	spin_lock_bh(&tp_vars->bat_priv->tp_list_lock);
	hlist_del_rcu(&tp_vars->list);
	spin_unlock_bh(&tp_vars->bat_priv->tp_list_lock);

	/* drop list reference */
	batadv_tp_vars_put(tp_vars);

	atomic_dec(&tp_vars->bat_priv->tp_num);

	/* kill the timer and remove its reference */
	del_timer_sync(&tp_vars->timer);
	/* the worker might have rearmed itself therefore we kill it again. Note
	 * that if the worker should run again before invoking the following
	 * del_timer(), it would not re-arm itself once again because the status
	 * is OFF now
	 */
	del_timer(&tp_vars->timer);
	batadv_tp_vars_put(tp_vars);
}

/**
 * batadv_tp_sender_end() - print info about ended session and inform client
 * @bat_priv: the bat priv with all the soft interface information
 * @tp_vars: the private data of the current TP meter session
 */
static void batadv_tp_sender_end(struct batadv_priv *bat_priv,
				 struct batadv_tp_vars *tp_vars)
{
	u32 session_cookie;

	batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
		   "Test towards %pM finished..shutting down (reason=%d)\n",
		   tp_vars->other_end, tp_vars->reason);

	batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
		   "Last timing stats: SRTT=%ums RTTVAR=%ums RTO=%ums\n",
		   tp_vars->srtt >> 3, tp_vars->rttvar >> 2, tp_vars->rto);

	batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
		   "Final values: cwnd=%u ss_threshold=%u\n",
		   tp_vars->cwnd, tp_vars->ss_threshold);

	session_cookie = batadv_tp_session_cookie(tp_vars->session,
						  tp_vars->icmp_uid);

	batadv_tp_batctl_notify(tp_vars->reason,
				tp_vars->other_end,
				bat_priv,
				tp_vars->start_time,
				atomic64_read(&tp_vars->tot_sent),
				session_cookie);
}

/**
 * batadv_tp_sender_shutdown() - let sender thread/timer stop gracefully
 * @tp_vars: the private data of the current TP meter session
 * @reason: reason for tp meter session stop
 */
static void batadv_tp_sender_shutdown(struct batadv_tp_vars *tp_vars,
				      enum batadv_tp_meter_reason reason)
{
	if (!atomic_dec_and_test(&tp_vars->sending))
		return;

	tp_vars->reason = reason;
}

/**
 * batadv_tp_sender_finish() - stop sender session after test_length was reached
 * @work: delayed work reference of the related tp_vars
 */
static void batadv_tp_sender_finish(struct work_struct *work)
{
	struct delayed_work *delayed_work;
	struct batadv_tp_vars *tp_vars;

	delayed_work = to_delayed_work(work);
	tp_vars = container_of(delayed_work, struct batadv_tp_vars,
			       finish_work);

	batadv_tp_sender_shutdown(tp_vars, BATADV_TP_REASON_COMPLETE);
}

/**
 * batadv_tp_reset_sender_timer() - reschedule the sender timer
 * @tp_vars: the private TP meter data for this session
 *
 * Reschedule the timer using tp_vars->rto as delay
 */
static void batadv_tp_reset_sender_timer(struct batadv_tp_vars *tp_vars)
{
	/* most of the time this function is invoked while normal packet
	 * reception...
	 */
	if (unlikely(atomic_read(&tp_vars->sending) == 0))
		/* timer ref will be dropped in batadv_tp_sender_cleanup */
		return;

	mod_timer(&tp_vars->timer, jiffies + msecs_to_jiffies(tp_vars->rto));
}

/**
 * batadv_tp_sender_timeout() - timer that fires in case of packet loss
 * @t: address to timer_list inside tp_vars
 *
 * If fired it means that there was packet loss.
 * Switch to Slow Start, set the ss_threshold to half of the current cwnd and
 * reset the cwnd to 3*MSS
 */
static void batadv_tp_sender_timeout(struct timer_list *t)
{
	struct batadv_tp_vars *tp_vars = from_timer(tp_vars, t, timer);
	struct batadv_priv *bat_priv = tp_vars->bat_priv;

	if (atomic_read(&tp_vars->sending) == 0)
		return;

	/* if the user waited long enough...shutdown the test */
	if (unlikely(tp_vars->rto >= BATADV_TP_MAX_RTO)) {
		batadv_tp_sender_shutdown(tp_vars,
					  BATADV_TP_REASON_DST_UNREACHABLE);
		return;
	}

	/* RTO exponential backoff
	 * Details in Section 5.5 of RFC6298
	 */
	tp_vars->rto <<= 1;

	spin_lock_bh(&tp_vars->cwnd_lock);

	tp_vars->ss_threshold = tp_vars->cwnd >> 1;
	if (tp_vars->ss_threshold < BATADV_TP_PLEN * 2)
		tp_vars->ss_threshold = BATADV_TP_PLEN * 2;

	batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
		   "Meter: RTO fired during test towards %pM! cwnd=%u new ss_thr=%u, resetting last_sent to %u\n",
		   tp_vars->other_end, tp_vars->cwnd, tp_vars->ss_threshold,
		   atomic_read(&tp_vars->last_acked));

	tp_vars->cwnd = BATADV_TP_PLEN * 3;

	spin_unlock_bh(&tp_vars->cwnd_lock);

	/* resend the non-ACKed packets.. */
	tp_vars->last_sent = atomic_read(&tp_vars->last_acked);
	wake_up(&tp_vars->more_bytes);

	batadv_tp_reset_sender_timer(tp_vars);
}

/**
 * batadv_tp_fill_prerandom() - Fill buffer with prefetched random bytes
 * @tp_vars: the private TP meter data for this session
 * @buf: Buffer to fill with bytes
 * @nbytes: amount of pseudorandom bytes
 */
static void batadv_tp_fill_prerandom(struct batadv_tp_vars *tp_vars,
				     u8 *buf, size_t nbytes)
{
	u32 local_offset;
	size_t bytes_inbuf;
	size_t to_copy;
	size_t pos = 0;

	spin_lock_bh(&tp_vars->prerandom_lock);
	local_offset = tp_vars->prerandom_offset;
	tp_vars->prerandom_offset += nbytes;
	tp_vars->prerandom_offset %= sizeof(batadv_tp_prerandom);
	spin_unlock_bh(&tp_vars->prerandom_lock);

	while (nbytes) {
		local_offset %= sizeof(batadv_tp_prerandom);
		bytes_inbuf = sizeof(batadv_tp_prerandom) - local_offset;
		to_copy = min(nbytes, bytes_inbuf);

		memcpy(&buf[pos], &batadv_tp_prerandom[local_offset], to_copy);
		pos += to_copy;
		nbytes -= to_copy;
		local_offset = 0;
	}
}

/**
 * batadv_tp_send_msg() - send a single message
 * @tp_vars: the private TP meter data for this session
 * @src: source mac address
 * @orig_node: the originator of the destination
 * @seqno: sequence number of this packet
 * @len: length of the entire packet
 * @session: session identifier
 * @uid: local ICMP "socket" index
 * @timestamp: timestamp in jiffies which is replied in ack
 *
 * Create and send a single TP Meter message.
 *
 * Return: 0 on success, BATADV_TP_REASON_DST_UNREACHABLE if the destination is
 * not reachable, BATADV_TP_REASON_MEMORY_ERROR if the packet couldn't be
 * allocated
 */
static int batadv_tp_send_msg(struct batadv_tp_vars *tp_vars, const u8 *src,
			      struct batadv_orig_node *orig_node,
			      u32 seqno, size_t len, const u8 *session,
			      int uid, u32 timestamp)
{
	struct batadv_icmp_tp_packet *icmp;
	struct sk_buff *skb;
	int r;
	u8 *data;
	size_t data_len;

	skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
	if (unlikely(!skb))
		return BATADV_TP_REASON_MEMORY_ERROR;

	skb_reserve(skb, ETH_HLEN);
	icmp = skb_put(skb, sizeof(*icmp));

	/* fill the icmp header */
	ether_addr_copy(icmp->dst, orig_node->orig);
	ether_addr_copy(icmp->orig, src);
	icmp->version = BATADV_COMPAT_VERSION;
	icmp->packet_type = BATADV_ICMP;
	icmp->ttl = BATADV_TTL;
	icmp->msg_type = BATADV_TP;
	icmp->uid = uid;

	icmp->subtype = BATADV_TP_MSG;
	memcpy(icmp->session, session, sizeof(icmp->session));
	icmp->seqno = htonl(seqno);
	icmp->timestamp = htonl(timestamp);

	data_len = len - sizeof(*icmp);
	data = skb_put(skb, data_len);
	batadv_tp_fill_prerandom(tp_vars, data, data_len);

	r = batadv_send_skb_to_orig(skb, orig_node, NULL);
	if (r == NET_XMIT_SUCCESS)
		return 0;

	return BATADV_TP_REASON_CANT_SEND;
}

/**
 * batadv_tp_recv_ack() - ACK receiving function
 * @bat_priv: the bat priv with all the soft interface information
 * @skb: the buffer containing the received packet
 *
 * Process a received TP ACK packet
 */
static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
			       const struct sk_buff *skb)
{
	struct batadv_hard_iface *primary_if = NULL;
	struct batadv_orig_node *orig_node = NULL;
	const struct batadv_icmp_tp_packet *icmp;
	struct batadv_tp_vars *tp_vars;
	size_t packet_len, mss;
	u32 rtt, recv_ack, cwnd;
	unsigned char *dev_addr;

	packet_len = BATADV_TP_PLEN;
	mss = BATADV_TP_PLEN;
	packet_len += sizeof(struct batadv_unicast_packet);

	icmp = (struct batadv_icmp_tp_packet *)skb->data;

	/* find the tp_vars */
	tp_vars = batadv_tp_list_find_session(bat_priv, icmp->orig,
					      icmp->session);
	if (unlikely(!tp_vars))
		return;

	if (unlikely(atomic_read(&tp_vars->sending) == 0))
		goto out;

	/* old ACK? silently drop it.. */
	if (batadv_seq_before(ntohl(icmp->seqno),
			      (u32)atomic_read(&tp_vars->last_acked)))
		goto out;

	primary_if = batadv_primary_if_get_selected(bat_priv);
	if (unlikely(!primary_if))
		goto out;

	orig_node = batadv_orig_hash_find(bat_priv, icmp->orig);
	if (unlikely(!orig_node))
		goto out;

	/* update RTO with the new sampled RTT, if any */
	rtt = jiffies_to_msecs(jiffies) - ntohl(icmp->timestamp);
	if (icmp->timestamp && rtt)
		batadv_tp_update_rto(tp_vars, rtt);

	/* ACK for new data... reset the timer */
	batadv_tp_reset_sender_timer(tp_vars);

	recv_ack = ntohl(icmp->seqno);

	/* check if this ACK is a duplicate */
	if (atomic_read(&tp_vars->last_acked) == recv_ack) {
		atomic_inc(&tp_vars->dup_acks);
		if (atomic_read(&tp_vars->dup_acks) != 3)
			goto out;

		if (recv_ack >= tp_vars->recover)
			goto out;

		/* if this is the third duplicate ACK do Fast Retransmit */
		batadv_tp_send_msg(tp_vars, primary_if->net_dev->dev_addr,
				   orig_node, recv_ack, packet_len,
				   icmp->session, icmp->uid,
				   jiffies_to_msecs(jiffies));

		spin_lock_bh(&tp_vars->cwnd_lock);

		/* Fast Recovery */
		tp_vars->fast_recovery = true;
		/* Set recover to the last outstanding seqno when Fast Recovery
		 * is entered. RFC6582, Section 3.2, step 1
		 */
		tp_vars->recover = tp_vars->last_sent;
		tp_vars->ss_threshold = tp_vars->cwnd >> 1;
		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
			   "Meter: Fast Recovery, (cur cwnd=%u) ss_thr=%u last_sent=%u recv_ack=%u\n",
			   tp_vars->cwnd, tp_vars->ss_threshold,
			   tp_vars->last_sent, recv_ack);
		tp_vars->cwnd = batadv_tp_cwnd(tp_vars->ss_threshold, 3 * mss,
					       mss);
		tp_vars->dec_cwnd = 0;
		tp_vars->last_sent = recv_ack;

		spin_unlock_bh(&tp_vars->cwnd_lock);
	} else {
		/* count the acked data */
		atomic64_add(recv_ack - atomic_read(&tp_vars->last_acked),
			     &tp_vars->tot_sent);
		/* reset the duplicate ACKs counter */
		atomic_set(&tp_vars->dup_acks, 0);

		if (tp_vars->fast_recovery) {
			/* partial ACK */
			if (batadv_seq_before(recv_ack, tp_vars->recover)) {
				/* this is another hole in the window. React
				 * immediately as specified by NewReno (see
				 * Section 3.2 of RFC6582 for details)
				 */
				dev_addr = primary_if->net_dev->dev_addr;
				batadv_tp_send_msg(tp_vars, dev_addr,
						   orig_node, recv_ack,
						   packet_len, icmp->session,
						   icmp->uid,
						   jiffies_to_msecs(jiffies));
				tp_vars->cwnd = batadv_tp_cwnd(tp_vars->cwnd,
							       mss, mss);
			} else {
				tp_vars->fast_recovery = false;
				/* set cwnd to the value of ss_threshold at the
				 * moment that Fast Recovery was entered.
				 * RFC6582, Section 3.2, step 3
				 */
				cwnd = batadv_tp_cwnd(tp_vars->ss_threshold, 0,
						      mss);
				tp_vars->cwnd = cwnd;
			}
			goto move_twnd;
		}

		if (recv_ack - atomic_read(&tp_vars->last_acked) >= mss)
			batadv_tp_update_cwnd(tp_vars, mss);
move_twnd:
		/* move the Transmit Window */
		atomic_set(&tp_vars->last_acked, recv_ack);
	}

	wake_up(&tp_vars->more_bytes);
out:
	if (likely(primary_if))
		batadv_hardif_put(primary_if);
	if (likely(orig_node))
		batadv_orig_node_put(orig_node);
	if (likely(tp_vars))
		batadv_tp_vars_put(tp_vars);
}

/**
 * batadv_tp_avail() - check if congestion window is not full
 * @tp_vars: the private data of the current TP meter session
 * @payload_len: size of the payload of a single message
 *
 * Return: true when congestion window is not full, false otherwise
 */
static bool batadv_tp_avail(struct batadv_tp_vars *tp_vars,
			    size_t payload_len)
{
	u32 win_left, win_limit;

	win_limit = atomic_read(&tp_vars->last_acked) + tp_vars->cwnd;
	win_left = win_limit - tp_vars->last_sent;

	return win_left >= payload_len;
}

/**
 * batadv_tp_wait_available() - wait until congestion window becomes free or
 *  timeout is reached
 * @tp_vars: the private data of the current TP meter session
 * @plen: size of the payload of a single message
 *
 * Return: 0 if the condition evaluated to false after the timeout elapsed,
 *  1 if the condition evaluated to true after the timeout elapsed, the
 *  remaining jiffies (at least 1) if the condition evaluated to true before
 *  the timeout elapsed, or -ERESTARTSYS if it was interrupted by a signal.
 */
static int batadv_tp_wait_available(struct batadv_tp_vars *tp_vars, size_t plen)
{
	int ret;

	ret = wait_event_interruptible_timeout(tp_vars->more_bytes,
					       batadv_tp_avail(tp_vars, plen),
					       HZ / 10);

	return ret;
}

/**
 * batadv_tp_send() - main sending thread of a tp meter session
 * @arg: address of the related tp_vars
 *
 * Return: nothing, this function never returns
 */
static int batadv_tp_send(void *arg)
{
	struct batadv_tp_vars *tp_vars = arg;
	struct batadv_priv *bat_priv = tp_vars->bat_priv;
	struct batadv_hard_iface *primary_if = NULL;
	struct batadv_orig_node *orig_node = NULL;
	size_t payload_len, packet_len;
	int err = 0;

	if (unlikely(tp_vars->role != BATADV_TP_SENDER)) {
		err = BATADV_TP_REASON_DST_UNREACHABLE;
		tp_vars->reason = err;
		goto out;
	}

	orig_node = batadv_orig_hash_find(bat_priv, tp_vars->other_end);
	if (unlikely(!orig_node)) {
		err = BATADV_TP_REASON_DST_UNREACHABLE;
		tp_vars->reason = err;
		goto out;
	}

	primary_if = batadv_primary_if_get_selected(bat_priv);
	if (unlikely(!primary_if)) {
		err = BATADV_TP_REASON_DST_UNREACHABLE;
		tp_vars->reason = err;
		goto out;
	}

	/* assume that all the hard_interfaces have a correctly
	 * configured MTU, so use the soft_iface MTU as MSS.
	 * This might not be true and in that case the fragmentation
	 * should be used.
	 * Now, try to send the packet as it is
	 */
	payload_len = BATADV_TP_PLEN;
	BUILD_BUG_ON(sizeof(struct batadv_icmp_tp_packet) > BATADV_TP_PLEN);

	batadv_tp_reset_sender_timer(tp_vars);

	/* queue the worker in charge of terminating the test */
	queue_delayed_work(batadv_event_workqueue, &tp_vars->finish_work,
			   msecs_to_jiffies(tp_vars->test_length));

	while (atomic_read(&tp_vars->sending) != 0) {
		if (unlikely(!batadv_tp_avail(tp_vars, payload_len))) {
			batadv_tp_wait_available(tp_vars, payload_len);
			continue;
		}

		/* to emulate normal unicast traffic, add to the payload len
		 * the size of the unicast header
		 */
		packet_len = payload_len + sizeof(struct batadv_unicast_packet);

		err = batadv_tp_send_msg(tp_vars, primary_if->net_dev->dev_addr,
					 orig_node, tp_vars->last_sent,
					 packet_len,
					 tp_vars->session, tp_vars->icmp_uid,
					 jiffies_to_msecs(jiffies));

		/* something went wrong during the preparation/transmission */
		if (unlikely(err && err != BATADV_TP_REASON_CANT_SEND)) {
			batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
				   "Meter: %s() cannot send packets (%d)\n",
				   __func__, err);
			/* ensure nobody else tries to stop the thread now */
			if (atomic_dec_and_test(&tp_vars->sending))
				tp_vars->reason = err;
			break;
		}

		/* right-shift the TWND */
		if (!err)
			tp_vars->last_sent += payload_len;

		cond_resched();
	}

out:
	if (likely(primary_if))
		batadv_hardif_put(primary_if);
	if (likely(orig_node))
		batadv_orig_node_put(orig_node);

	batadv_tp_sender_end(bat_priv, tp_vars);
	batadv_tp_sender_cleanup(bat_priv, tp_vars);

	batadv_tp_vars_put(tp_vars);

	do_exit(0);
}

/**
 * batadv_tp_start_kthread() - start new thread which manages the tp meter
 *  sender
 * @tp_vars: the private data of the current TP meter session
 */
static void batadv_tp_start_kthread(struct batadv_tp_vars *tp_vars)
{
	struct task_struct *kthread;
	struct batadv_priv *bat_priv = tp_vars->bat_priv;
	u32 session_cookie;

	kref_get(&tp_vars->refcount);
	kthread = kthread_create(batadv_tp_send, tp_vars, "kbatadv_tp_meter");
	if (IS_ERR(kthread)) {
		session_cookie = batadv_tp_session_cookie(tp_vars->session,
							  tp_vars->icmp_uid);
		pr_err("batadv: cannot create tp meter kthread\n");
		batadv_tp_batctl_error_notify(BATADV_TP_REASON_MEMORY_ERROR,
					      tp_vars->other_end,
					      bat_priv, session_cookie);

		/* drop reserved reference for kthread */
		batadv_tp_vars_put(tp_vars);

		/* cleanup of failed tp meter variables */
		batadv_tp_sender_cleanup(bat_priv, tp_vars);
		return;
	}

	wake_up_process(kthread);
}

/**
 * batadv_tp_start() - start a new tp meter session
 * @bat_priv: the bat priv with all the soft interface information
 * @dst: the receiver MAC address
 * @test_length: test length in milliseconds
 * @cookie: session cookie
 */
void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
		     u32 test_length, u32 *cookie)
{
	struct batadv_tp_vars *tp_vars;
	u8 session_id[2];
	u8 icmp_uid;
	u32 session_cookie;

	get_random_bytes(session_id, sizeof(session_id));
	get_random_bytes(&icmp_uid, 1);
	session_cookie = batadv_tp_session_cookie(session_id, icmp_uid);
	*cookie = session_cookie;

	/* look for an already existing test towards this node */
	spin_lock_bh(&bat_priv->tp_list_lock);
	tp_vars = batadv_tp_list_find(bat_priv, dst);
	if (tp_vars) {
		spin_unlock_bh(&bat_priv->tp_list_lock);
		batadv_tp_vars_put(tp_vars);
		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
			   "Meter: test to or from the same node already ongoing, aborting\n");
		batadv_tp_batctl_error_notify(BATADV_TP_REASON_ALREADY_ONGOING,
					      dst, bat_priv, session_cookie);
		return;
	}

	if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM)) {
		spin_unlock_bh(&bat_priv->tp_list_lock);
		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
			   "Meter: too many ongoing sessions, aborting (SEND)\n");
		batadv_tp_batctl_error_notify(BATADV_TP_REASON_TOO_MANY, dst,
					      bat_priv, session_cookie);
		return;
	}

	tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC);
	if (!tp_vars) {
		spin_unlock_bh(&bat_priv->tp_list_lock);
		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
			   "Meter: %s cannot allocate list elements\n",
			   __func__);
		batadv_tp_batctl_error_notify(BATADV_TP_REASON_MEMORY_ERROR,
					      dst, bat_priv, session_cookie);
		return;
	}

	/* initialize tp_vars */
	ether_addr_copy(tp_vars->other_end, dst);
	kref_init(&tp_vars->refcount);
	tp_vars->role = BATADV_TP_SENDER;
	atomic_set(&tp_vars->sending, 1);
	memcpy(tp_vars->session, session_id, sizeof(session_id));
	tp_vars->icmp_uid = icmp_uid;

	tp_vars->last_sent = BATADV_TP_FIRST_SEQ;
	atomic_set(&tp_vars->last_acked, BATADV_TP_FIRST_SEQ);
	tp_vars->fast_recovery = false;
	tp_vars->recover = BATADV_TP_FIRST_SEQ;

	/* initialise the CWND to 3*MSS (Section 3.1 in RFC5681).
	 * For batman-adv the MSS is the size of the payload received by the
	 * soft_interface, hence its MTU
	 */
	tp_vars->cwnd = BATADV_TP_PLEN * 3;
	/* at the beginning initialise the SS threshold to the biggest possible
	 * window size, hence the AWND size
	 */
	tp_vars->ss_threshold = BATADV_TP_AWND;

	/* RTO initial value is 3 seconds.
	 * Details in Section 2.1 of RFC6298
	 */
	tp_vars->rto = 1000;
	tp_vars->srtt = 0;
	tp_vars->rttvar = 0;

	atomic64_set(&tp_vars->tot_sent, 0);

	kref_get(&tp_vars->refcount);
	timer_setup(&tp_vars->timer, batadv_tp_sender_timeout, 0);

	tp_vars->bat_priv = bat_priv;
	tp_vars->start_time = jiffies;

	init_waitqueue_head(&tp_vars->more_bytes);

	spin_lock_init(&tp_vars->unacked_lock);
	INIT_LIST_HEAD(&tp_vars->unacked_list);

	spin_lock_init(&tp_vars->cwnd_lock);

	tp_vars->prerandom_offset = 0;
	spin_lock_init(&tp_vars->prerandom_lock);

	kref_get(&tp_vars->refcount);
	hlist_add_head_rcu(&tp_vars->list, &bat_priv->tp_list);
	spin_unlock_bh(&bat_priv->tp_list_lock);

	tp_vars->test_length = test_length;
	if (!tp_vars->test_length)
		tp_vars->test_length = BATADV_TP_DEF_TEST_LENGTH;

	batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
		   "Meter: starting throughput meter towards %pM (length=%ums)\n",
		   dst, test_length);

	/* init work item for finished tp tests */
	INIT_DELAYED_WORK(&tp_vars->finish_work, batadv_tp_sender_finish);

	/* start tp kthread. This way the write() call issued from userspace can
	 * happily return and avoid to block
	 */
	batadv_tp_start_kthread(tp_vars);

	/* don't return reference to new tp_vars */
	batadv_tp_vars_put(tp_vars);
}

/**
 * batadv_tp_stop() - stop currently running tp meter session
 * @bat_priv: the bat priv with all the soft interface information
 * @dst: the receiver MAC address
 * @return_value: reason for tp meter session stop
 */
void batadv_tp_stop(struct batadv_priv *bat_priv, const u8 *dst,
		    u8 return_value)
{
	struct batadv_orig_node *orig_node;
	struct batadv_tp_vars *tp_vars;

	batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
		   "Meter: stopping test towards %pM\n", dst);

	orig_node = batadv_orig_hash_find(bat_priv, dst);
	if (!orig_node)
		return;

	tp_vars = batadv_tp_list_find(bat_priv, orig_node->orig);
	if (!tp_vars) {
		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
			   "Meter: trying to interrupt an already over connection\n");
		goto out;
	}

	batadv_tp_sender_shutdown(tp_vars, return_value);
	batadv_tp_vars_put(tp_vars);
out:
	batadv_orig_node_put(orig_node);
}

/**
 * batadv_tp_reset_receiver_timer() - reset the receiver shutdown timer
 * @tp_vars: the private data of the current TP meter session
 *
 * start the receiver shutdown timer or reset it if already started
 */
static void batadv_tp_reset_receiver_timer(struct batadv_tp_vars *tp_vars)
{
	mod_timer(&tp_vars->timer,
		  jiffies + msecs_to_jiffies(BATADV_TP_RECV_TIMEOUT));
}

/**
 * batadv_tp_receiver_shutdown() - stop a tp meter receiver when timeout is
 *  reached without received ack
 * @t: address to timer_list inside tp_vars
 */
static void batadv_tp_receiver_shutdown(struct timer_list *t)
{
	struct batadv_tp_vars *tp_vars = from_timer(tp_vars, t, timer);
	struct batadv_tp_unacked *un, *safe;
	struct batadv_priv *bat_priv;

	bat_priv = tp_vars->bat_priv;

	/* if there is recent activity rearm the timer */
	if (!batadv_has_timed_out(tp_vars->last_recv_time,
				  BATADV_TP_RECV_TIMEOUT)) {
		/* reset the receiver shutdown timer */
		batadv_tp_reset_receiver_timer(tp_vars);
		return;
	}

	batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
		   "Shutting down for inactivity (more than %dms) from %pM\n",
		   BATADV_TP_RECV_TIMEOUT, tp_vars->other_end);

	spin_lock_bh(&tp_vars->bat_priv->tp_list_lock);
	hlist_del_rcu(&tp_vars->list);
	spin_unlock_bh(&tp_vars->bat_priv->tp_list_lock);

	/* drop list reference */
	batadv_tp_vars_put(tp_vars);

	atomic_dec(&bat_priv->tp_num);

	spin_lock_bh(&tp_vars->unacked_lock);
	list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
		list_del(&un->list);
		kfree(un);
	}
	spin_unlock_bh(&tp_vars->unacked_lock);

	/* drop reference of timer */
	batadv_tp_vars_put(tp_vars);
}

/**
 * batadv_tp_send_ack() - send an ACK packet
 * @bat_priv: the bat priv with all the soft interface information
 * @dst: the mac address of the destination originator
 * @seq: the sequence number to ACK
 * @timestamp: the timestamp to echo back in the ACK
 * @session: session identifier
 * @socket_index: local ICMP socket identifier
 *
 * Return: 0 on success, a positive integer representing the reason of the
 * failure otherwise
 */
static int batadv_tp_send_ack(struct batadv_priv *bat_priv, const u8 *dst,
			      u32 seq, __be32 timestamp, const u8 *session,
			      int socket_index)
{
	struct batadv_hard_iface *primary_if = NULL;
	struct batadv_orig_node *orig_node;
	struct batadv_icmp_tp_packet *icmp;
	struct sk_buff *skb;
	int r, ret;

	orig_node = batadv_orig_hash_find(bat_priv, dst);
	if (unlikely(!orig_node)) {
		ret = BATADV_TP_REASON_DST_UNREACHABLE;
		goto out;
	}

	primary_if = batadv_primary_if_get_selected(bat_priv);
	if (unlikely(!primary_if)) {
		ret = BATADV_TP_REASON_DST_UNREACHABLE;
		goto out;
	}

	skb = netdev_alloc_skb_ip_align(NULL, sizeof(*icmp) + ETH_HLEN);
	if (unlikely(!skb)) {
		ret = BATADV_TP_REASON_MEMORY_ERROR;
		goto out;
	}

	skb_reserve(skb, ETH_HLEN);
	icmp = skb_put(skb, sizeof(*icmp));
	icmp->packet_type = BATADV_ICMP;
	icmp->version = BATADV_COMPAT_VERSION;
	icmp->ttl = BATADV_TTL;
	icmp->msg_type = BATADV_TP;
	ether_addr_copy(icmp->dst, orig_node->orig);
	ether_addr_copy(icmp->orig, primary_if->net_dev->dev_addr);
	icmp->uid = socket_index;

	icmp->subtype = BATADV_TP_ACK;
	memcpy(icmp->session, session, sizeof(icmp->session));
	icmp->seqno = htonl(seq);
	icmp->timestamp = timestamp;

	/* send the ack */
	r = batadv_send_skb_to_orig(skb, orig_node, NULL);
	if (unlikely(r < 0) || r == NET_XMIT_DROP) {
		ret = BATADV_TP_REASON_DST_UNREACHABLE;
		goto out;
	}
	ret = 0;

out:
	if (likely(orig_node))
		batadv_orig_node_put(orig_node);
	if (likely(primary_if))
		batadv_hardif_put(primary_if);

	return ret;
}

/**
 * batadv_tp_handle_out_of_order() - store an out of order packet
 * @tp_vars: the private data of the current TP meter session
 * @skb: the buffer containing the received packet
 *
 * Store the out of order packet in the unacked list for late processing. This
 * packets are kept in this list so that they can be ACKed at once as soon as
 * all the previous packets have been received
 *
 * Return: true if the packed has been successfully processed, false otherwise
 */
static bool batadv_tp_handle_out_of_order(struct batadv_tp_vars *tp_vars,
					  const struct sk_buff *skb)
{
	const struct batadv_icmp_tp_packet *icmp;
	struct batadv_tp_unacked *un, *new;
	u32 payload_len;
	bool added = false;

	new = kmalloc(sizeof(*new), GFP_ATOMIC);
	if (unlikely(!new))
		return false;

	icmp = (struct batadv_icmp_tp_packet *)skb->data;

	new->seqno = ntohl(icmp->seqno);
	payload_len = skb->len - sizeof(struct batadv_unicast_packet);
	new->len = payload_len;

	spin_lock_bh(&tp_vars->unacked_lock);
	/* if the list is empty immediately attach this new object */
	if (list_empty(&tp_vars->unacked_list)) {
		list_add(&new->list, &tp_vars->unacked_list);
		goto out;
	}

	/* otherwise loop over the list and either drop the packet because this
	 * is a duplicate or store it at the right position.
	 *
	 * The iteration is done in the reverse way because it is likely that
	 * the last received packet (the one being processed now) has a bigger
	 * seqno than all the others already stored.
	 */
	list_for_each_entry_reverse(un, &tp_vars->unacked_list, list) {
		/* check for duplicates */
		if (new->seqno == un->seqno) {
			if (new->len > un->len)
				un->len = new->len;
			kfree(new);
			added = true;
			break;
		}

		/* look for the right position */
		if (batadv_seq_before(new->seqno, un->seqno))
			continue;

		/* as soon as an entry having a bigger seqno is found, the new
		 * one is attached _after_ it. In this way the list is kept in
		 * ascending order
		 */
		list_add_tail(&new->list, &un->list);
		added = true;
		break;
	}

	/* received packet with smallest seqno out of order; add it to front */
	if (!added)
		list_add(&new->list, &tp_vars->unacked_list);

out:
	spin_unlock_bh(&tp_vars->unacked_lock);

	return true;
}

/**
 * batadv_tp_ack_unordered() - update number received bytes in current stream
 *  without gaps
 * @tp_vars: the private data of the current TP meter session
 */
static void batadv_tp_ack_unordered(struct batadv_tp_vars *tp_vars)
{
	struct batadv_tp_unacked *un, *safe;
	u32 to_ack;

	/* go through the unacked packet list and possibly ACK them as
	 * well
	 */
	spin_lock_bh(&tp_vars->unacked_lock);
	list_for_each_entry_safe(un, safe, &tp_vars->unacked_list, list) {
		/* the list is ordered, therefore it is possible to stop as soon
		 * there is a gap between the last acked seqno and the seqno of
		 * the packet under inspection
		 */
		if (batadv_seq_before(tp_vars->last_recv, un->seqno))
			break;

		to_ack = un->seqno + un->len - tp_vars->last_recv;

		if (batadv_seq_before(tp_vars->last_recv, un->seqno + un->len))
			tp_vars->last_recv += to_ack;

		list_del(&un->list);
		kfree(un);
	}
	spin_unlock_bh(&tp_vars->unacked_lock);
}

/**
 * batadv_tp_init_recv() - return matching or create new receiver tp_vars
 * @bat_priv: the bat priv with all the soft interface information
 * @icmp: received icmp tp msg
 *
 * Return: corresponding tp_vars or NULL on errors
 */
static struct batadv_tp_vars *
batadv_tp_init_recv(struct batadv_priv *bat_priv,
		    const struct batadv_icmp_tp_packet *icmp)
{
	struct batadv_tp_vars *tp_vars;

	spin_lock_bh(&bat_priv->tp_list_lock);
	tp_vars = batadv_tp_list_find_session(bat_priv, icmp->orig,
					      icmp->session);
	if (tp_vars)
		goto out_unlock;

	if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM)) {
		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
			   "Meter: too many ongoing sessions, aborting (RECV)\n");
		goto out_unlock;
	}

	tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC);
	if (!tp_vars)
		goto out_unlock;

	ether_addr_copy(tp_vars->other_end, icmp->orig);
	tp_vars->role = BATADV_TP_RECEIVER;
	memcpy(tp_vars->session, icmp->session, sizeof(tp_vars->session));
	tp_vars->last_recv = BATADV_TP_FIRST_SEQ;
	tp_vars->bat_priv = bat_priv;
	kref_init(&tp_vars->refcount);

	spin_lock_init(&tp_vars->unacked_lock);
	INIT_LIST_HEAD(&tp_vars->unacked_list);

	kref_get(&tp_vars->refcount);
	hlist_add_head_rcu(&tp_vars->list, &bat_priv->tp_list);

	kref_get(&tp_vars->refcount);
	timer_setup(&tp_vars->timer, batadv_tp_receiver_shutdown, 0);

	batadv_tp_reset_receiver_timer(tp_vars);

out_unlock:
	spin_unlock_bh(&bat_priv->tp_list_lock);

	return tp_vars;
}

/**
 * batadv_tp_recv_msg() - process a single data message
 * @bat_priv: the bat priv with all the soft interface information
 * @skb: the buffer containing the received packet
 *
 * Process a received TP MSG packet
 */
static void batadv_tp_recv_msg(struct batadv_priv *bat_priv,
			       const struct sk_buff *skb)
{
	const struct batadv_icmp_tp_packet *icmp;
	struct batadv_tp_vars *tp_vars;
	size_t packet_size;
	u32 seqno;

	icmp = (struct batadv_icmp_tp_packet *)skb->data;

	seqno = ntohl(icmp->seqno);
	/* check if this is the first seqno. This means that if the
	 * first packet is lost, the tp meter does not work anymore!
	 */
	if (seqno == BATADV_TP_FIRST_SEQ) {
		tp_vars = batadv_tp_init_recv(bat_priv, icmp);
		if (!tp_vars) {
			batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
				   "Meter: seqno != BATADV_TP_FIRST_SEQ cannot initiate connection\n");
			goto out;
		}
	} else {
		tp_vars = batadv_tp_list_find_session(bat_priv, icmp->orig,
						      icmp->session);
		if (!tp_vars) {
			batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
				   "Unexpected packet from %pM!\n",
				   icmp->orig);
			goto out;
		}
	}

	if (unlikely(tp_vars->role != BATADV_TP_RECEIVER)) {
		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
			   "Meter: dropping packet: not expected (role=%u)\n",
			   tp_vars->role);
		goto out;
	}

	tp_vars->last_recv_time = jiffies;

	/* if the packet is a duplicate, it may be the case that an ACK has been
	 * lost. Resend the ACK
	 */
	if (batadv_seq_before(seqno, tp_vars->last_recv))
		goto send_ack;

	/* if the packet is out of order enqueue it */
	if (ntohl(icmp->seqno) != tp_vars->last_recv) {
		/* exit immediately (and do not send any ACK) if the packet has
		 * not been enqueued correctly
		 */
		if (!batadv_tp_handle_out_of_order(tp_vars, skb))
			goto out;

		/* send a duplicate ACK */
		goto send_ack;
	}

	/* if everything was fine count the ACKed bytes */
	packet_size = skb->len - sizeof(struct batadv_unicast_packet);
	tp_vars->last_recv += packet_size;

	/* check if this ordered message filled a gap.... */
	batadv_tp_ack_unordered(tp_vars);

send_ack:
	/* send the ACK. If the received packet was out of order, the ACK that
	 * is going to be sent is a duplicate (the sender will count them and
	 * possibly enter Fast Retransmit as soon as it has reached 3)
	 */
	batadv_tp_send_ack(bat_priv, icmp->orig, tp_vars->last_recv,
			   icmp->timestamp, icmp->session, icmp->uid);
out:
	if (likely(tp_vars))
		batadv_tp_vars_put(tp_vars);
}

/**
 * batadv_tp_meter_recv() - main TP Meter receiving function
 * @bat_priv: the bat priv with all the soft interface information
 * @skb: the buffer containing the received packet
 */
void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb)
{
	struct batadv_icmp_tp_packet *icmp;

	icmp = (struct batadv_icmp_tp_packet *)skb->data;

	switch (icmp->subtype) {
	case BATADV_TP_MSG:
		batadv_tp_recv_msg(bat_priv, skb);
		break;
	case BATADV_TP_ACK:
		batadv_tp_recv_ack(bat_priv, skb);
		break;
	default:
		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
			   "Received unknown TP Metric packet type %u\n",
			   icmp->subtype);
	}
	consume_skb(skb);
}

/**
 * batadv_tp_meter_init() - initialize global tp_meter structures
 */
void __init batadv_tp_meter_init(void)
{
	get_random_bytes(batadv_tp_prerandom, sizeof(batadv_tp_prerandom));
}
