// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2008, 2009 open80211s Ltd.
 * Author:     Luis Carlos Cobo <luisca@cozybit.com>
 */

#include <linux/etherdevice.h>
#include <linux/list.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <net/mac80211.h>
#include "wme.h"
#include "ieee80211_i.h"
#include "mesh.h"
#include "driver-ops.h"
#include <linux/rhashtable.h>

static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath);

static u32 mesh_table_hash(const void *addr, u32 len, u32 seed)
{
	/* Use last four bytes of hw addr as hash index */
	return jhash_1word(__get_unaligned_cpu32((u8 *)addr + 2), seed);
}

static const struct rhashtable_params mesh_rht_params = {
	.nelem_hint = 2,
	.automatic_shrinking = true,
	.key_len = ETH_ALEN,
	.key_offset = offsetof(struct mesh_path, dst),
	.head_offset = offsetof(struct mesh_path, rhash),
	.hashfn = mesh_table_hash,
};

static const struct rhashtable_params mesh_hdr_rht_params = {
	.nelem_hint = 10,
	.automatic_shrinking = true,
	.key_len =  ETH_ALEN,
	.key_offset = offsetof(struct mhdr_cache_entry, addr_key),
	.head_offset = offsetof(struct mhdr_cache_entry, rhash),
	.hashfn = mesh_table_hash,
};

static void mesh_hdr_cache_entry_free(void *ptr, void *tblptr)
{
	struct mhdr_cache_entry *mhdr = ptr;

	kfree_rcu(mhdr, rcu);
}

static void mesh_hdr_cache_deinit(struct ieee80211_sub_if_data *sdata)
{
	struct mesh_hdr_cache *cache;

	cache = sdata->u.mesh.hdr_cache;

	if (!cache)
		return;

	rhashtable_free_and_destroy(&cache->rhead,
				    mesh_hdr_cache_entry_free, NULL);

	kfree(sdata->u.mesh.hdr_cache);
	sdata->u.mesh.hdr_cache = NULL;
}

static void mesh_hdr_cache_init(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	struct mesh_hdr_cache *cache;

	sdata->u.mesh.hdr_cache = NULL;

	if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT))
		return;

	if (ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD))
		return;

	cache = kmalloc(sizeof(struct mesh_hdr_cache), GFP_ATOMIC);

	if (!cache)
		return;

	sdata->u.mesh.hdr_cache = cache;
	rhashtable_init(&cache->rhead, &mesh_hdr_rht_params);
	INIT_HLIST_HEAD(&cache->walk_head);
	spin_lock_init(&cache->walk_lock);
	atomic_set(&cache->size, 0);
}

static inline bool mpath_expired(struct mesh_path *mpath)
{
	return (mpath->flags & MESH_PATH_ACTIVE) &&
	       time_after(jiffies, mpath->exp_time) &&
	       !(mpath->flags & MESH_PATH_FIXED);
}

static void mesh_path_rht_free(void *ptr, void *tblptr)
{
	struct mesh_path *mpath = ptr;
	struct mesh_table *tbl = tblptr;

	mesh_path_free_rcu(tbl, mpath);
}

static struct mesh_table *mesh_table_alloc(void)
{
	struct mesh_table *newtbl;

	newtbl = kmalloc(sizeof(struct mesh_table), GFP_ATOMIC);
	if (!newtbl)
		return NULL;

	INIT_HLIST_HEAD(&newtbl->known_gates);
	INIT_HLIST_HEAD(&newtbl->walk_head);
	atomic_set(&newtbl->entries,  0);
	spin_lock_init(&newtbl->gates_lock);
	spin_lock_init(&newtbl->walk_lock);
	rhashtable_init(&newtbl->rhead, &mesh_rht_params);

	return newtbl;
}

static void mesh_table_free(struct mesh_table *tbl)
{
	rhashtable_free_and_destroy(&tbl->rhead,
				    mesh_path_rht_free, tbl);
	kfree(tbl);
}

void mesh_nss_offld_path_update(struct mesh_path *mpath, bool is_mpath)
{
	struct ieee80211_mesh_path_offld path = {0};
	struct sta_info *next_hop;
	struct ieee80211_sub_if_data *sdata = mpath->sdata;


	path.metric = mpath->metric;
	if (time_before(jiffies, mpath->exp_time))
		path.exp_time = jiffies_to_msecs(mpath->exp_time - jiffies);

	path.hop_count = mpath->hop_count;
	path.flags = mpath->flags;
	path.mesh_gate = mpath->is_gate;
	if (is_mpath) {
		ether_addr_copy(path.mesh_da, mpath->dst);
	} else {
		ether_addr_copy(path.mesh_da, mpath->mpp);
		ether_addr_copy(path.da, mpath->dst);
	}

	next_hop = rcu_dereference(mpath->next_hop);
	if (next_hop)
		ether_addr_copy(path.next_hop, next_hop->addr);

	drv_config_mesh_offload_path(sdata->local, sdata,
				     is_mpath ? IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPATH :
						IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPP,
				     &path);
}

/**
 * mesh_path_assign_nexthop - update mesh path next hop
 *
 * @mpath: mesh path to update
 * @sta: next hop to assign
 *
 * Locking: mpath->state_lock must be held when calling this function
 */
void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
{
	struct sk_buff *skb;
	struct ieee80211_hdr *hdr;
	unsigned long flags;

	rcu_assign_pointer(mpath->next_hop, sta);

	spin_lock_irqsave(&mpath->frame_queue.lock, flags);
	skb_queue_walk(&mpath->frame_queue, skb) {
		hdr = (struct ieee80211_hdr *) skb->data;
		memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN);
		memcpy(hdr->addr2, mpath->sdata->vif.addr, ETH_ALEN);
		ieee80211_mps_set_frame_flags(sta->sdata, sta, hdr);
	}

	spin_unlock_irqrestore(&mpath->frame_queue.lock, flags);
}

static void prepare_for_gate(struct sk_buff *skb, char *dst_addr,
			     struct mesh_path *gate_mpath)
{
	struct ieee80211_hdr *hdr;
	struct ieee80211s_hdr *mshdr;
	int mesh_hdrlen, hdrlen;
	char *next_hop;

	hdr = (struct ieee80211_hdr *) skb->data;
	hdrlen = ieee80211_hdrlen(hdr->frame_control);
	mshdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);

	if (!(mshdr->flags & MESH_FLAGS_AE)) {
		/* size of the fixed part of the mesh header */
		mesh_hdrlen = 6;

		/* make room for the two extended addresses */
		skb_push(skb, 2 * ETH_ALEN);
		memmove(skb->data, hdr, hdrlen + mesh_hdrlen);

		hdr = (struct ieee80211_hdr *) skb->data;

		/* we preserve the previous mesh header and only add
		 * the new addreses */
		mshdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
		mshdr->flags = MESH_FLAGS_AE_A5_A6;
		memcpy(mshdr->eaddr1, hdr->addr3, ETH_ALEN);
		memcpy(mshdr->eaddr2, hdr->addr4, ETH_ALEN);
	}

	/* update next hop */
	hdr = (struct ieee80211_hdr *) skb->data;
	rcu_read_lock();
	next_hop = rcu_dereference(gate_mpath->next_hop)->sta.addr;
	memcpy(hdr->addr1, next_hop, ETH_ALEN);
	rcu_read_unlock();
	memcpy(hdr->addr2, gate_mpath->sdata->vif.addr, ETH_ALEN);
	memcpy(hdr->addr3, dst_addr, ETH_ALEN);
}

/**
 * mesh_path_move_to_queue - Move or copy frames from one mpath queue to another
 *
 * This function is used to transfer or copy frames from an unresolved mpath to
 * a gate mpath.  The function also adds the Address Extension field and
 * updates the next hop.
 *
 * If a frame already has an Address Extension field, only the next hop and
 * destination addresses are updated.
 *
 * The gate mpath must be an active mpath with a valid mpath->next_hop.
 *
 * @gate_mpath: An active mpath the frames will be sent to (i.e. the gate)
 * @from_mpath: The failed mpath
 * @copy: When true, copy all the frames to the new mpath queue.  When false,
 * move them.
 */
static void mesh_path_move_to_queue(struct mesh_path *gate_mpath,
				    struct mesh_path *from_mpath,
				    bool copy)
{
	struct sk_buff *skb, *fskb, *tmp;
	struct sk_buff_head failq;
	unsigned long flags;

	if (WARN_ON(gate_mpath == from_mpath))
		return;
	if (WARN_ON(!gate_mpath->next_hop))
		return;

	__skb_queue_head_init(&failq);

	spin_lock_irqsave(&from_mpath->frame_queue.lock, flags);
	skb_queue_splice_init(&from_mpath->frame_queue, &failq);
	spin_unlock_irqrestore(&from_mpath->frame_queue.lock, flags);

	skb_queue_walk_safe(&failq, fskb, tmp) {
		if (skb_queue_len(&gate_mpath->frame_queue) >=
				  MESH_FRAME_QUEUE_LEN) {
			mpath_dbg(gate_mpath->sdata, "mpath queue full!\n");
			break;
		}

		skb = skb_copy(fskb, GFP_ATOMIC);
		if (WARN_ON(!skb))
			break;

		prepare_for_gate(skb, gate_mpath->dst, gate_mpath);
		skb_queue_tail(&gate_mpath->frame_queue, skb);

		if (copy)
			continue;

		__skb_unlink(fskb, &failq);
		kfree_skb(fskb);
	}

	mpath_dbg(gate_mpath->sdata, "Mpath queue for gate %pM has %d frames\n",
		  gate_mpath->dst, skb_queue_len(&gate_mpath->frame_queue));

	if (!copy)
		return;

	spin_lock_irqsave(&from_mpath->frame_queue.lock, flags);
	skb_queue_splice(&failq, &from_mpath->frame_queue);
	spin_unlock_irqrestore(&from_mpath->frame_queue.lock, flags);
}


static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst,
				      struct ieee80211_sub_if_data *sdata,
				      bool is_mpath)
{
	struct mesh_path *mpath;
	bool update;

	mpath = rhashtable_lookup(&tbl->rhead, dst, mesh_rht_params);

	if (mpath && mpath_expired(mpath)) {
		spin_lock_bh(&mpath->state_lock);
		update = !!(mpath->flags & MESH_PATH_ACTIVE);
		mpath->flags &= ~MESH_PATH_ACTIVE;
		spin_unlock_bh(&mpath->state_lock);
		if (update && is_mpath)
			mesh_nss_offld_path_update(mpath, true);
	}
	return mpath;
}

/**
 * mesh_path_lookup - look up a path in the mesh path table
 * @sdata: local subif
 * @dst: hardware address (ETH_ALEN length) of destination
 *
 * Returns: pointer to the mesh path structure, or NULL if not found
 *
 * Locking: must be called within a read rcu section.
 */
struct mesh_path *
mesh_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
{
	return mpath_lookup(sdata->u.mesh.mesh_paths, dst, sdata, true);
}

struct mesh_path *
mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
{
	return mpath_lookup(sdata->u.mesh.mpp_paths, dst, sdata, false);
}

static struct mesh_path *
__mesh_path_lookup_by_idx(struct mesh_table *tbl, int idx)
{
	int i = 0;
	struct mesh_path *mpath;

	hlist_for_each_entry_rcu(mpath, &tbl->walk_head, walk_list) {
		if (i++ == idx)
			break;
	}

	if (!mpath)
		return NULL;

	if (mpath_expired(mpath)) {
		spin_lock_bh(&mpath->state_lock);
		mpath->flags &= ~MESH_PATH_ACTIVE;
		spin_unlock_bh(&mpath->state_lock);
	}
	return mpath;
}

/**
 * mesh_path_lookup_by_idx - look up a path in the mesh path table by its index
 * @idx: index
 * @sdata: local subif, or NULL for all entries
 *
 * Returns: pointer to the mesh path structure, or NULL if not found.
 *
 * Locking: must be called within a read rcu section.
 */
struct mesh_path *
mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
{
	return __mesh_path_lookup_by_idx(sdata->u.mesh.mesh_paths, idx);
}

/**
 * mpp_path_lookup_by_idx - look up a path in the proxy path table by its index
 * @idx: index
 * @sdata: local subif, or NULL for all entries
 *
 * Returns: pointer to the proxy path structure, or NULL if not found.
 *
 * Locking: must be called within a read rcu section.
 */
struct mesh_path *
mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
{
	return __mesh_path_lookup_by_idx(sdata->u.mesh.mpp_paths, idx);
}

/**
 * mesh_path_add_gate - add the given mpath to a mesh gate to our path table
 * @mpath: gate path to add to table
 */
int mesh_path_add_gate(struct mesh_path *mpath)
{
	struct mesh_table *tbl;
	int err;

	rcu_read_lock();
	tbl = mpath->sdata->u.mesh.mesh_paths;

	spin_lock_bh(&mpath->state_lock);
	if (mpath->is_gate) {
		err = -EEXIST;
		spin_unlock_bh(&mpath->state_lock);
		goto err_rcu;
	}
	mpath->is_gate = true;
	mpath->sdata->u.mesh.num_gates++;

	spin_lock(&tbl->gates_lock);
	hlist_add_head_rcu(&mpath->gate_list, &tbl->known_gates);
	spin_unlock(&tbl->gates_lock);

	spin_unlock_bh(&mpath->state_lock);

	mesh_nss_offld_path_update(mpath, true);

	mpath_dbg(mpath->sdata,
		  "Mesh path: Recorded new gate: %pM. %d known gates\n",
		  mpath->dst, mpath->sdata->u.mesh.num_gates);
	err = 0;
err_rcu:
	rcu_read_unlock();
	return err;
}

/**
 * mesh_gate_del - remove a mesh gate from the list of known gates
 * @tbl: table which holds our list of known gates
 * @mpath: gate mpath
 */
static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath)
{
	lockdep_assert_held(&mpath->state_lock);
	if (!mpath->is_gate)
		return;

	mpath->is_gate = false;
	spin_lock_bh(&tbl->gates_lock);
	hlist_del_rcu(&mpath->gate_list);
	mpath->sdata->u.mesh.num_gates--;
	spin_unlock_bh(&tbl->gates_lock);

	mesh_nss_offld_path_update(mpath, true);

	mpath_dbg(mpath->sdata,
		  "Mesh path: Deleted gate: %pM. %d known gates\n",
		  mpath->dst, mpath->sdata->u.mesh.num_gates);
}

/**
 * mesh_gate_num - number of gates known to this interface
 * @sdata: subif data
 */
int mesh_gate_num(struct ieee80211_sub_if_data *sdata)
{
	return sdata->u.mesh.num_gates;
}

static
struct mesh_path *mesh_path_new(struct ieee80211_sub_if_data *sdata,
				const u8 *dst, gfp_t gfp_flags)
{
	struct mesh_path *new_mpath;

	new_mpath = kzalloc(sizeof(struct mesh_path), gfp_flags);
	if (!new_mpath)
		return NULL;

	memcpy(new_mpath->dst, dst, ETH_ALEN);
	eth_broadcast_addr(new_mpath->rann_snd_addr);
	new_mpath->is_root = false;
	new_mpath->sdata = sdata;
	new_mpath->flags = 0;
	skb_queue_head_init(&new_mpath->frame_queue);
	new_mpath->exp_time = jiffies;
	spin_lock_init(&new_mpath->state_lock);
	timer_setup(&new_mpath->timer, mesh_path_timer, 0);

	return new_mpath;
}

/**
 * Replaces the Ethernet header with fully formed mac+mesh header
 * which was stored for this DA:SA combination. Also necessary
 * checks are done for checking freshness of the header
 */
struct mhdr_cache_entry *mesh_fill_cached_hdr(struct ieee80211_sub_if_data *sdata,
					      struct sk_buff *skb)
{
	struct mesh_hdr_cache *cache;
	struct mhdr_cache_entry *entry;
	struct mesh_path *mpath, *mppath;
	struct ieee80211s_hdr *meshhdr;
	struct ieee80211_hdr *hdr;
	struct sta_info *new_nhop;
	struct ieee80211_key *key;
	struct ethhdr *eth;
	u8 sa[ETH_ALEN];

	u8 tid;

	cache = sdata->u.mesh.hdr_cache;

	if (!cache)
		return NULL;

	entry = rhashtable_lookup(&cache->rhead, skb->data,
				  mesh_hdr_rht_params);
	if (!entry)
		return NULL;

	/* Avoid extra work in this path */
	if (skb_headroom(skb) < (entry->hdrlen - ETH_HLEN + 2))
		return NULL;


	mpath = rcu_dereference(entry->mpath);
	if (!mpath)
		return NULL;

	/* This check is with assumption that only 6addr frames are
	 * supported currently for caching
	 */
	mppath = rcu_dereference(entry->mppath);
	if (!mppath)
		return NULL;

	if (!(mpath->flags & MESH_PATH_ACTIVE))
		return NULL;

	if (mpath_expired(mpath))
		return NULL;

	/* In case there was a path refresh and update after we last used
	 * update the next hop addr.
	 */
	spin_lock_bh(&mpath->state_lock);
	if (entry->path_change_count != mpath->path_change_count) {
		new_nhop = rcu_dereference(mpath->next_hop);
		if (!new_nhop) {
			spin_unlock_bh(&mpath->state_lock);
			return NULL;
		}
		memcpy(&entry->hdr[4], new_nhop->sta.addr, ETH_ALEN);

		/* update key. pn_offs will be same */
		if (entry->key)	{
			key = rcu_access_pointer(new_nhop->ptk[new_nhop->ptk_idx]);
			if (!key)
				key = rcu_access_pointer(sdata->default_unicast_key);
			rcu_assign_pointer(entry->key, key);
		}
		entry->path_change_count = mpath->path_change_count;
	}
	spin_unlock_bh(&mpath->state_lock);

	/* backup eth SA to copy as eaddr2/SA in the mesh header */
	eth = (struct ethhdr *)skb->data;
	ether_addr_copy(sa, eth->h_source);

	/* Pull DA:SA */
	skb_pull(skb, ETH_HLEN - 2);

	memcpy(skb_push(skb, entry->hdrlen), entry->hdr, entry->hdrlen);

	meshhdr = (struct ieee80211s_hdr *)(skb->data + entry->machdr_len);
	hdr = (struct ieee80211_hdr *)skb->data;

	/* Update mutables */
	tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
	*ieee80211_get_qos_ctl(hdr) = tid;

	put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
	sdata->u.mesh.mesh_seqnum++;

	memcpy(meshhdr->eaddr2, sa, ETH_ALEN);
	meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;

	if (mpath->flags & (MESH_PATH_REQ_QUEUED | MESH_PATH_FIXED))
		goto out;

	/* Refresh the path, in case there is a change in nexthop after refresh
	 * hdr will be updated on next lookup
	 */
	if (time_after(jiffies,
		       mpath->exp_time -
		       msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
	    !(mpath->flags & MESH_PATH_RESOLVING) &&
	    !(mpath->flags & MESH_PATH_FIXED)) {
		mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
	}

out:
	mppath->exp_time = jiffies;
	entry->timestamp = jiffies;

	return entry;
}

/**
 * We store the created header here and save necessary states
 * and data so as to use them directly when same DA:SA is used
 * Before using this header we also check in mesh_fill_cached_hdr
 * whether the path hasnt changed, etc before using
 */
void mesh_cache_hdr(struct ieee80211_sub_if_data *sdata,
		    struct sk_buff *skb, struct mesh_path *mpath)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	struct mesh_hdr_cache *cache;
	struct mhdr_cache_entry *mhdr, *old_mhdr;
	struct ieee80211s_hdr *meshhdr;
	struct sta_info *next_hop;
	struct ieee80211_key *key;
	u8 band, pn_offs = 0, crypto_len = 0;
	struct mesh_path *mppath;
	u16 mshhdr_len;
	int hdrlen;

	cache = sdata->u.mesh.hdr_cache;

	if (!cache)
		return;

	if (!(info->control.flags & IEEE80211_TX_CTRL_CHECK_FAST_MESH))
		return;

	band = info->band;

	if (atomic_read(&cache->size) > MESH_HDR_CACHE_SIZE)
		return;


	hdrlen = ieee80211_hdrlen(hdr->frame_control);

	meshhdr = (struct ieee80211s_hdr *)(skb->data + hdrlen);

	/* TODO Currently supporting only 6addr hdr
	 */
	if (!(meshhdr->flags & MESH_FLAGS_AE_A5_A6))
		return;

	next_hop = rcu_dereference(mpath->next_hop);
	if (!next_hop)
		return;

	/* This is required to keep the mppath alive */
	mppath = mpp_path_lookup(sdata, meshhdr->eaddr1);

	if (!mppath)
		return;

	/*TODO avoid if peers if they are PS peer and use regulat path */

	pn_offs = 0;
	key = rcu_access_pointer(next_hop->ptk[next_hop->ptk_idx]);
	if (!key)
		key = rcu_access_pointer(sdata->default_unicast_key);

	if (key) {
		bool gen_iv, iv_spc;

		gen_iv = key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV;
		iv_spc = key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE;

		if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
			return;;

		if (key->flags & KEY_FLAG_TAINTED)
			return;

		switch (key->conf.cipher) {
		case WLAN_CIPHER_SUITE_CCMP:
		case WLAN_CIPHER_SUITE_CCMP_256:
			if (gen_iv)
				pn_offs = hdrlen;
			if (gen_iv || iv_spc)
				crypto_len = IEEE80211_CCMP_HDR_LEN;
			break;
		default:
			/* Limiting supported ciphers for testing */
			return;
		}
		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
	}

	mhdr = kzalloc(sizeof(struct mhdr_cache_entry), GFP_KERNEL);
	if (!mhdr)
		return;

	memcpy(mhdr->addr_key, meshhdr->eaddr1, ETH_ALEN);

	mhdr->machdr_len = hdrlen + crypto_len;
	mshhdr_len = ieee80211_get_mesh_hdrlen(meshhdr);
	mhdr->hdrlen =  mhdr->machdr_len + mshhdr_len + sizeof(rfc1042_header);
	rcu_assign_pointer(mhdr->mpath, mpath);
	rcu_assign_pointer(mhdr->mppath, mppath);
	rcu_assign_pointer(mhdr->key, key);
	mhdr->timestamp = jiffies;
	mhdr->band = band;
	mhdr->pn_offs = pn_offs;

	if (pn_offs) {
		/* ignore the invalid data getting copied to pn location since it will
		 * be overwritten dring tx
		 */
		memcpy(mhdr->hdr, skb->data, mhdr->machdr_len);

		/* copy remaining hdr */
		memcpy(mhdr->hdr + mhdr->machdr_len,
		       skb->data + mhdr->machdr_len - crypto_len,
		       mhdr->hdrlen - mhdr->machdr_len);
	} else {
		memcpy(mhdr->hdr, skb->data, mhdr->hdrlen);
	}

	if (key) {
		hdr = (struct ieee80211_hdr *)mhdr->hdr;
		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
	}

	spin_lock_bh(&cache->walk_lock);
	old_mhdr = rhashtable_lookup_get_insert_fast(&cache->rhead,
						     &mhdr->rhash,
						     mesh_hdr_rht_params);
	if (old_mhdr) {
		spin_unlock_bh(&cache->walk_lock);
		kfree(mhdr);
		return;
	}

	hlist_add_head(&mhdr->walk_list, &cache->walk_head);
	spin_unlock_bh(&cache->walk_lock);

	atomic_inc(&cache->size);
}

void mesh_hdr_cache_manage(struct ieee80211_sub_if_data *sdata)
{
	struct mesh_hdr_cache *cache;
	struct mhdr_cache_entry *entry;
	struct hlist_node *n;

	cache = sdata->u.mesh.hdr_cache;

	if (!cache)
		return;

	if (atomic_read(&cache->size) < MESH_HDR_CACHE_HIGH_THRESHOLD)
		return;

	spin_lock_bh(&cache->walk_lock);
	hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) {
		if (time_before(jiffies,
			       entry->timestamp +
			       msecs_to_jiffies(MESH_HDR_CACHE_TIMEOUT)))
			continue;

		hlist_del_rcu(&entry->walk_list);
		rhashtable_remove_fast(&cache->rhead, &entry->rhash, mesh_hdr_rht_params);
		kfree_rcu(entry, rcu);
		atomic_dec(&cache->size);
	}
	spin_unlock_bh(&cache->walk_lock);
}

void mesh_hdr_cache_flush(struct mesh_path *mpath, bool is_mpp)
{
	struct ieee80211_sub_if_data *sdata = mpath->sdata;
	struct mesh_hdr_cache *cache;
	struct mhdr_cache_entry *entry;
	struct hlist_node *n;
	struct mesh_path *entry_mpath;

	cache = sdata->u.mesh.hdr_cache;

	if (!cache)
		return;

	spin_lock_bh(&cache->walk_lock);
	/* Only one header per mpp address is expected in the header cache */
	if (is_mpp) {
		entry = rhashtable_lookup(&cache->rhead, mpath->dst, mesh_hdr_rht_params);
		if (entry) {
			hlist_del_rcu(&entry->walk_list);
			rhashtable_remove_fast(&cache->rhead, &entry->rhash, mesh_hdr_rht_params);
			kfree_rcu(entry, rcu);
			atomic_dec(&cache->size);
		}
		spin_unlock_bh(&cache->walk_lock);
		return;
	}

	hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) {
		entry_mpath = rcu_dereference(entry->mpath);

		if (!entry_mpath)
			continue;

		if (ether_addr_equal(entry_mpath->dst, mpath->dst)) {
			hlist_del_rcu(&entry->walk_list);
			rhashtable_remove_fast(&cache->rhead, &entry->rhash, mesh_hdr_rht_params);
			kfree_rcu(entry, rcu);
			atomic_dec(&cache->size);
		}
	}
	spin_unlock_bh(&cache->walk_lock);
}

struct mesh_path *__mesh_path_add(struct ieee80211_sub_if_data *sdata,
				  const u8 *dst)
{
	struct mesh_table *tbl;
	struct mesh_path *mpath, *new_mpath;

	if (ether_addr_equal(dst, sdata->vif.addr))
		/* never add ourselves as neighbours */
		return ERR_PTR(-ENOTSUPP);

	if (is_multicast_ether_addr(dst))
		return ERR_PTR(-ENOTSUPP);

	if (atomic_add_unless(&sdata->u.mesh.mpaths, 1, MESH_MAX_MPATHS) == 0)
		return ERR_PTR(-ENOSPC);

	new_mpath = mesh_path_new(sdata, dst, GFP_ATOMIC);
	if (!new_mpath)
		return ERR_PTR(-ENOMEM);

	tbl = sdata->u.mesh.mesh_paths;
	spin_lock_bh(&tbl->walk_lock);
	mpath = rhashtable_lookup_get_insert_fast(&tbl->rhead,
						  &new_mpath->rhash,
						  mesh_rht_params);
	if (!mpath)
		hlist_add_head(&new_mpath->walk_list, &tbl->walk_head);

	spin_unlock_bh(&tbl->walk_lock);

	if (mpath) {
		kfree(new_mpath);

		if (IS_ERR(mpath))
			return mpath;

		new_mpath = mpath;
	}

	sdata->u.mesh.mesh_paths_generation++;
	return new_mpath;
}

/**
 * mesh_path_add - allocate and add a new path to the mesh path table
 * @dst: destination address of the path (ETH_ALEN length)
 * @sdata: local subif
 *
 * Returns: 0 on success
 *
 * State: the initial state of the new path is set to 0
 */
struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata,
				const u8 *dst)
{
	struct mesh_path *new_path;
	struct ieee80211_mesh_path_offld path = {0};

	new_path = __mesh_path_add(sdata, dst);
	if (IS_ERR(new_path))
		return new_path;

	ether_addr_copy(path.mesh_da, dst);

	drv_config_mesh_offload_path(sdata->local, sdata,
				     IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPATH,
				     &path);

	return new_path;
}

int __mpp_path_add(struct ieee80211_sub_if_data *sdata,
		   const u8 *dst, const u8 *mpp)
{
	struct mesh_table *tbl;
	struct mesh_path *new_mpath;
	int ret;

	if (ether_addr_equal(dst, sdata->vif.addr))
		/* never add ourselves as neighbours */
		return -ENOTSUPP;

	if (is_multicast_ether_addr(dst))
		return -ENOTSUPP;

	new_mpath = mesh_path_new(sdata, dst, GFP_ATOMIC);

	if (!new_mpath)
		return -ENOMEM;

	memcpy(new_mpath->mpp, mpp, ETH_ALEN);
	tbl = sdata->u.mesh.mpp_paths;

	spin_lock_bh(&tbl->walk_lock);
	ret = rhashtable_lookup_insert_fast(&tbl->rhead,
					    &new_mpath->rhash,
					    mesh_rht_params);
	if (!ret)
		hlist_add_head_rcu(&new_mpath->walk_list, &tbl->walk_head);
	spin_unlock_bh(&tbl->walk_lock);

	if (ret)
		kfree(new_mpath);

	sdata->u.mesh.mpp_paths_generation++;
	return ret;
}

int mpp_path_add(struct ieee80211_sub_if_data *sdata,
		 const u8 *dst, const u8 *mpp)
{
	struct ieee80211_mesh_path_offld path = {0};
	int ret;

	ret = __mpp_path_add(sdata, dst, mpp);
	if (ret)
		return ret;

	ether_addr_copy(path.mesh_da, mpp);
	ether_addr_copy(path.da, dst);

	drv_config_mesh_offload_path(sdata->local, sdata,
				     IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPP,
				     &path);

	return 0;
}

/**
 * mesh_plink_broken - deactivates paths and sends perr when a link breaks
 *
 * @sta: broken peer link
 *
 * This function must be called from the rate control algorithm if enough
 * delivery errors suggest that a peer link is no longer usable.
 */
void mesh_plink_broken(struct sta_info *sta)
{
	struct ieee80211_sub_if_data *sdata = sta->sdata;
	struct mesh_table *tbl = sdata->u.mesh.mesh_paths;
	static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
	struct mesh_path *mpath;
	int paths_deactivated = 0, signal_avg;

	rcu_read_lock();
	hlist_for_each_entry_rcu(mpath, &tbl->walk_head, walk_list) {
		if (rcu_access_pointer(mpath->next_hop) == sta &&
		    mpath->flags & MESH_PATH_ACTIVE &&
		    !(mpath->flags & MESH_PATH_FIXED)) {
			spin_lock_bh(&mpath->state_lock);
			mpath->flags &= ~MESH_PATH_ACTIVE;
			++mpath->sn;
			spin_unlock_bh(&mpath->state_lock);
			mesh_path_error_tx(sdata,
				sdata->u.mesh.mshcfg.element_ttl,
				mpath->dst, mpath->sn,
				WLAN_REASON_MESH_PATH_DEST_UNREACHABLE, bcast);
			++paths_deactivated;
		}
	}
	rcu_read_unlock();
	if (paths_deactivated > 0) {
		signal_avg = -ewma_signal_read(&sta->rx_stats_avg.signal);
		sdata_info(sta->sdata, " MESH MPL the link to %pM is broken and %d path deactivated signal %d dbm signal_avg %d dbm medium_busy : %u\n",
			   sta->addr, paths_deactivated,
			   sta->rx_stats.last_signal,
			   signal_avg, sta->local->hw.medium_busy);
		mesh_continuous_tx_fail_cnt(sta, NL80211_MPATH_BROKEN_NOTIFY);
	}
}

static void mesh_path_free_rcu(struct mesh_table *tbl,
			       struct mesh_path *mpath)
{
	struct ieee80211_sub_if_data *sdata = mpath->sdata;

	spin_lock_bh(&mpath->state_lock);
	mpath->flags |= MESH_PATH_RESOLVING | MESH_PATH_DELETED;
	mesh_gate_del(tbl, mpath);
	spin_unlock_bh(&mpath->state_lock);
	del_timer_sync(&mpath->timer);
	atomic_dec(&sdata->u.mesh.mpaths);
	atomic_dec(&tbl->entries);
	mesh_path_flush_pending(mpath);
	kfree_rcu(mpath, rcu);
}

static void __mesh_path_del(struct mesh_table *tbl, struct mesh_path *mpath,
			    bool is_mpath_tbl)
{
	struct ieee80211_mesh_path_offld path = {0};
	struct sta_info *next_hop;
	struct ieee80211_sub_if_data *sdata = mpath->sdata;


	path.metric = mpath->metric;
	path.exp_time = mpath->exp_time;
	path.hop_count = mpath->hop_count;
	path.flags = mpath->flags;
	if (is_mpath_tbl) {
		ether_addr_copy(path.mesh_da, mpath->dst);
	} else {
		ether_addr_copy(path.mesh_da, mpath->mpp);
		ether_addr_copy(path.da, mpath->dst);
	}

	next_hop = rcu_dereference(mpath->next_hop);
	if (next_hop)
		ether_addr_copy(path.next_hop, next_hop->addr);

	mesh_hdr_cache_flush(mpath, !is_mpath_tbl);

	hlist_del_rcu(&mpath->walk_list);
	rhashtable_remove_fast(&tbl->rhead, &mpath->rhash, mesh_rht_params);

	mesh_path_free_rcu(tbl, mpath);

	drv_config_mesh_offload_path(sdata->local, sdata,
				     is_mpath_tbl ? IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPATH :
					            IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPP,
				     &path);
}

/**
 * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches
 *
 * @sta: mesh peer to match
 *
 * RCU notes: this function is called when a mesh plink transitions from
 * PLINK_ESTAB to any other state, since PLINK_ESTAB state is the only one that
 * allows path creation. This will happen before the sta can be freed (because
 * sta_info_destroy() calls this) so any reader in a rcu read block will be
 * protected against the plink disappearing.
 */
void mesh_path_flush_by_nexthop(struct sta_info *sta)
{
	struct ieee80211_sub_if_data *sdata = sta->sdata;
	struct mesh_table *tbl = sdata->u.mesh.mesh_paths;
	struct mesh_path *mpath;
	struct hlist_node *n;

	spin_lock_bh(&tbl->walk_lock);
	hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) {
		if (rcu_access_pointer(mpath->next_hop) == sta)
			__mesh_path_del(tbl, mpath, true);
	}
	spin_unlock_bh(&tbl->walk_lock);
}

static void mpp_flush_by_proxy(struct ieee80211_sub_if_data *sdata,
			       const u8 *proxy)
{
	struct mesh_table *tbl = sdata->u.mesh.mpp_paths;
	struct mesh_path *mpath;
	struct hlist_node *n;

	spin_lock_bh(&tbl->walk_lock);
	hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) {
		if (ether_addr_equal(mpath->mpp, proxy))
			__mesh_path_del(tbl, mpath, false);
	}
	spin_unlock_bh(&tbl->walk_lock);
}

static void table_flush_by_iface(struct mesh_table *tbl, bool is_mpath_tbl)
{
	struct mesh_path *mpath;
	struct hlist_node *n;

	spin_lock_bh(&tbl->walk_lock);
	hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) {
		__mesh_path_del(tbl, mpath, is_mpath_tbl);
	}
	spin_unlock_bh(&tbl->walk_lock);
}

/**
 * mesh_path_flush_by_iface - Deletes all mesh paths associated with a given iface
 *
 * This function deletes both mesh paths as well as mesh portal paths.
 *
 * @sdata: interface data to match
 *
 */
void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
{
	table_flush_by_iface(sdata->u.mesh.mesh_paths, true);
	table_flush_by_iface(sdata->u.mesh.mpp_paths, false);
}

/**
 * table_path_del - delete a path from the mesh or mpp table
 *
 * @tbl: mesh or mpp path table
 * @sdata: local subif
 * @addr: dst address (ETH_ALEN length)
 *
 * Returns: 0 if successful
 */
static int table_path_del(struct mesh_table *tbl,
			  struct ieee80211_sub_if_data *sdata,
			  const u8 *addr, bool is_mpath_tbl)
{
	struct mesh_path *mpath;

	spin_lock_bh(&tbl->walk_lock);
	mpath = rhashtable_lookup_fast(&tbl->rhead, addr, mesh_rht_params);
	if (!mpath) {
		spin_unlock_bh(&tbl->walk_lock);
		return -ENXIO;
	}

	__mesh_path_del(tbl, mpath, is_mpath_tbl);
	spin_unlock_bh(&tbl->walk_lock);
	return 0;
}


/**
 * mesh_path_del - delete a mesh path from the table
 *
 * @addr: dst address (ETH_ALEN length)
 * @sdata: local subif
 *
 * Returns: 0 if successful
 */
int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
{
	int err;

	/* flush relevant mpp entries first */
	mpp_flush_by_proxy(sdata, addr);

	err = table_path_del(sdata->u.mesh.mesh_paths, sdata, addr, true);
	sdata->u.mesh.mesh_paths_generation++;
	return err;
}

/**
 * mesh_path_tx_pending - sends pending frames in a mesh path queue
 *
 * @mpath: mesh path to activate
 *
 * Locking: the state_lock of the mpath structure must NOT be held when calling
 * this function.
 */
void mesh_path_tx_pending(struct mesh_path *mpath)
{
	if (mpath->flags & MESH_PATH_ACTIVE)
		ieee80211_add_pending_skbs(mpath->sdata->local,
				&mpath->frame_queue);
}

/**
 * mesh_path_send_to_gates - sends pending frames to all known mesh gates
 *
 * @mpath: mesh path whose queue will be emptied
 *
 * If there is only one gate, the frames are transferred from the failed mpath
 * queue to that gate's queue.  If there are more than one gates, the frames
 * are copied from each gate to the next.  After frames are copied, the
 * mpath queues are emptied onto the transmission queue.
 */
int mesh_path_send_to_gates(struct mesh_path *mpath)
{
	struct ieee80211_sub_if_data *sdata = mpath->sdata;
	struct mesh_table *tbl;
	struct mesh_path *from_mpath = mpath;
	struct mesh_path *gate;
	bool copy = false;

	tbl = sdata->u.mesh.mesh_paths;

	rcu_read_lock();
	hlist_for_each_entry_rcu(gate, &tbl->known_gates, gate_list) {
		if (gate->flags & MESH_PATH_ACTIVE) {
			mpath_dbg(sdata, "Forwarding to %pM\n", gate->dst);
			mesh_path_move_to_queue(gate, from_mpath, copy);
			from_mpath = gate;
			copy = true;
		} else {
			mpath_dbg(sdata,
				  "Not forwarding to %pM (flags %#x)\n",
				  gate->dst, gate->flags);
		}
	}

	hlist_for_each_entry_rcu(gate, &tbl->known_gates, gate_list) {
		mpath_dbg(sdata, "Sending to %pM\n", gate->dst);
		mesh_path_tx_pending(gate);
	}
	rcu_read_unlock();

	return (from_mpath == mpath) ? -EHOSTUNREACH : 0;
}

/**
 * mesh_path_discard_frame - discard a frame whose path could not be resolved
 *
 * @skb: frame to discard
 * @sdata: network subif the frame was to be sent through
 *
 * Locking: the function must me called within a rcu_read_lock region
 */
void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
			     struct sk_buff *skb)
{
	kfree_skb(skb);
	sdata->u.mesh.mshstats.dropped_frames_no_route++;
}

/**
 * mesh_path_flush_pending - free the pending queue of a mesh path
 *
 * @mpath: mesh path whose queue has to be freed
 *
 * Locking: the function must me called within a rcu_read_lock region
 */
void mesh_path_flush_pending(struct mesh_path *mpath)
{
	struct sk_buff *skb;

	while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL)
		mesh_path_discard_frame(mpath->sdata, skb);
}

/**
 * mesh_path_fix_nexthop - force a specific next hop for a mesh path
 *
 * @mpath: the mesh path to modify
 * @next_hop: the next hop to force
 *
 * Locking: this function must be called holding mpath->state_lock
 */
void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop)
{
	struct sta_info *old_next_hop;

	spin_lock_bh(&mpath->state_lock);
	old_next_hop = rcu_dereference(mpath->next_hop);
	mesh_path_assign_nexthop(mpath, next_hop);
	mpath->sn = 0xffff;
	mpath->metric = 0;
	mpath->hop_count = 0;
	mpath->exp_time = 0;
	mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID;
	mesh_path_activate(mpath);
	if (!old_next_hop || !ether_addr_equal(old_next_hop->addr, next_hop->addr))
		mpath->path_change_count++;
	spin_unlock_bh(&mpath->state_lock);
	ewma_mesh_fail_avg_init(&next_hop->mesh->fail_avg);
	/* init it at a low value - 0 start is tricky */
	ewma_mesh_fail_avg_add(&next_hop->mesh->fail_avg, 1);
	mesh_path_tx_pending(mpath);

	mesh_nss_offld_path_update(mpath, true);
}

int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata)
{
	struct mesh_table *tbl_path, *tbl_mpp;
	int ret;

	atomic_add(sizeof(struct mesh_table),
		   &sdata->local->memory_stats.malloc_size);

	tbl_path = mesh_table_alloc();
	if (!tbl_path)
		return -ENOMEM;

	tbl_mpp = mesh_table_alloc();
	if (!tbl_mpp) {
		ret = -ENOMEM;
		goto free_path;
	}

	atomic_add(sizeof(struct mesh_table),
		   &sdata->local->memory_stats.malloc_size);

	mesh_hdr_cache_init(sdata);

	sdata->u.mesh.mesh_paths = tbl_path;
	sdata->u.mesh.mpp_paths = tbl_mpp;

	return 0;

free_path:
	atomic_sub(sizeof(struct mesh_table),
		   &sdata->local->memory_stats.malloc_size);
	mesh_table_free(tbl_path);
	return ret;
}

static
void mesh_path_tbl_expire(struct ieee80211_sub_if_data *sdata,
			  struct mesh_table *tbl, bool is_mpath_tbl)
{
	struct mesh_path *mpath;
	struct hlist_node *n;

	spin_lock_bh(&tbl->walk_lock);
	hlist_for_each_entry_safe(mpath, n, &tbl->walk_head, walk_list) {
		if ((!(mpath->flags & MESH_PATH_RESOLVING)) &&
		    (!(mpath->flags & MESH_PATH_FIXED)) &&
		     time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE))
			__mesh_path_del(tbl, mpath, is_mpath_tbl);
	}
	spin_unlock_bh(&tbl->walk_lock);
}

void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
{
	mesh_path_tbl_expire(sdata, sdata->u.mesh.mesh_paths, true);
	mesh_path_tbl_expire(sdata, sdata->u.mesh.mpp_paths, false);
}

void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata)
{
	atomic_sub(sizeof(struct mesh_table),
		   &sdata->local->memory_stats.malloc_size);
	atomic_sub(sizeof(struct mesh_table),
		   &sdata->local->memory_stats.malloc_size);
	mesh_table_free(sdata->u.mesh.mesh_paths);
	mesh_table_free(sdata->u.mesh.mpp_paths);
	mesh_hdr_cache_deinit(sdata);
}
