/* Copyright (C) 2012-2017  B.A.T.M.A.N. contributors:
 *
 * Edo Monticelli, Antonio Quartulli
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

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

#include <linux/atomic.h>
#include <linux/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/fs.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/list.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/batman_adv.h>

#include "hard-interface.h"
#include "log.h"
#include "netlink.h"
#include "originator.h"
#include "packet.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 amound 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: minumim cwnd value (usually MSS)
 *
 * Return the new cwnd size and ensures it does not exceed the Advertised
 * Receiver Window size. It is wrap around safe.
 * 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_updated_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 incremented 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 incremented 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
 * @arg: address of the related 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(unsigned long arg)
{
	struct batadv_tp_vars *tp_vars = (struct batadv_tp_vars *)arg;
	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);
	setup_timer(&tp_vars->timer, batadv_tp_sender_timeout,
		    (unsigned long)tp_vars);

	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
 * @arg: address of the related tp_vars
 */
static void batadv_tp_receiver_shutdown(unsigned long arg)
{
	struct batadv_tp_vars *tp_vars = (struct batadv_tp_vars *)arg;
	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);
	setup_timer(&tp_vars->timer, batadv_tp_receiver_shutdown,
		    (unsigned long)tp_vars);

	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));
}
