/*
 * Copyright (c) 2008-2014 Patrick McHardy <kaber@trash.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Development of this code funded by Astaro AG (http://www.astaro.com/)
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/jhash.h>
#include <linux/netlink.h>
#include <linux/vmalloc.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h>

#define NFT_HASH_MIN_SIZE	4

struct nft_hash {
	struct nft_hash_table __rcu	*tbl;
};

struct nft_hash_table {
	unsigned int			size;
	unsigned int			elements;
	struct nft_hash_elem __rcu	*buckets[];
};

struct nft_hash_elem {
	struct nft_hash_elem __rcu	*next;
	struct nft_data			key;
	struct nft_data			data[];
};

#define nft_hash_for_each_entry(i, head) \
	for (i = nft_dereference(head); i != NULL; i = nft_dereference(i->next))
#define nft_hash_for_each_entry_rcu(i, head) \
	for (i = rcu_dereference(head); i != NULL; i = rcu_dereference(i->next))

static u32 nft_hash_rnd __read_mostly;
static bool nft_hash_rnd_initted __read_mostly;

static unsigned int nft_hash_data(const struct nft_data *data,
				  unsigned int hsize, unsigned int len)
{
	unsigned int h;

	h = jhash(data->data, len, nft_hash_rnd);
	return h & (hsize - 1);
}

static bool nft_hash_lookup(const struct nft_set *set,
			    const struct nft_data *key,
			    struct nft_data *data)
{
	const struct nft_hash *priv = nft_set_priv(set);
	const struct nft_hash_table *tbl = rcu_dereference(priv->tbl);
	const struct nft_hash_elem *he;
	unsigned int h;

	h = nft_hash_data(key, tbl->size, set->klen);
	nft_hash_for_each_entry_rcu(he, tbl->buckets[h]) {
		if (nft_data_cmp(&he->key, key, set->klen))
			continue;
		if (set->flags & NFT_SET_MAP)
			nft_data_copy(data, he->data);
		return true;
	}
	return false;
}

static void nft_hash_tbl_free(const struct nft_hash_table *tbl)
{
	if (is_vmalloc_addr(tbl))
		vfree(tbl);
	else
		kfree(tbl);
}

static struct nft_hash_table *nft_hash_tbl_alloc(unsigned int nbuckets)
{
	struct nft_hash_table *tbl;
	size_t size;

	size = sizeof(*tbl) + nbuckets * sizeof(tbl->buckets[0]);
	tbl = kzalloc(size, GFP_KERNEL | __GFP_REPEAT | __GFP_NOWARN);
	if (tbl == NULL)
		tbl = vzalloc(size);
	if (tbl == NULL)
		return NULL;
	tbl->size = nbuckets;

	return tbl;
}

static void nft_hash_chain_unzip(const struct nft_set *set,
				 const struct nft_hash_table *ntbl,
				 struct nft_hash_table *tbl, unsigned int n)
{
	struct nft_hash_elem *he, *last, *next;
	unsigned int h;

	he = nft_dereference(tbl->buckets[n]);
	if (he == NULL)
		return;
	h = nft_hash_data(&he->key, ntbl->size, set->klen);

	/* Find last element of first chain hashing to bucket h */
	last = he;
	nft_hash_for_each_entry(he, he->next) {
		if (nft_hash_data(&he->key, ntbl->size, set->klen) != h)
			break;
		last = he;
	}

	/* Unlink first chain from the old table */
	RCU_INIT_POINTER(tbl->buckets[n], last->next);

	/* If end of chain reached, done */
	if (he == NULL)
		return;

	/* Find first element of second chain hashing to bucket h */
	next = NULL;
	nft_hash_for_each_entry(he, he->next) {
		if (nft_hash_data(&he->key, ntbl->size, set->klen) != h)
			continue;
		next = he;
		break;
	}

	/* Link the two chains */
	RCU_INIT_POINTER(last->next, next);
}

static int nft_hash_tbl_expand(const struct nft_set *set, struct nft_hash *priv)
{
	struct nft_hash_table *tbl = nft_dereference(priv->tbl), *ntbl;
	struct nft_hash_elem *he;
	unsigned int i, h;
	bool complete;

	ntbl = nft_hash_tbl_alloc(tbl->size * 2);
	if (ntbl == NULL)
		return -ENOMEM;

	/* Link new table's buckets to first element in the old table
	 * hashing to the new bucket.
	 */
	for (i = 0; i < ntbl->size; i++) {
		h = i < tbl->size ? i : i - tbl->size;
		nft_hash_for_each_entry(he, tbl->buckets[h]) {
			if (nft_hash_data(&he->key, ntbl->size, set->klen) != i)
				continue;
			RCU_INIT_POINTER(ntbl->buckets[i], he);
			break;
		}
	}
	ntbl->elements = tbl->elements;

	/* Publish new table */
	rcu_assign_pointer(priv->tbl, ntbl);

	/* Unzip interleaved hash chains */
	do {
		/* Wait for readers to use new table/unzipped chains */
		synchronize_rcu();

		complete = true;
		for (i = 0; i < tbl->size; i++) {
			nft_hash_chain_unzip(set, ntbl, tbl, i);
			if (tbl->buckets[i] != NULL)
				complete = false;
		}
	} while (!complete);

	nft_hash_tbl_free(tbl);
	return 0;
}

static int nft_hash_tbl_shrink(const struct nft_set *set, struct nft_hash *priv)
{
	struct nft_hash_table *tbl = nft_dereference(priv->tbl), *ntbl;
	struct nft_hash_elem __rcu **pprev;
	unsigned int i;

	ntbl = nft_hash_tbl_alloc(tbl->size / 2);
	if (ntbl == NULL)
		return -ENOMEM;

	for (i = 0; i < ntbl->size; i++) {
		ntbl->buckets[i] = tbl->buckets[i];

		for (pprev = &ntbl->buckets[i]; *pprev != NULL;
		     pprev = &nft_dereference(*pprev)->next)
			;
		RCU_INIT_POINTER(*pprev, tbl->buckets[i + ntbl->size]);
	}
	ntbl->elements = tbl->elements;

	/* Publish new table */
	rcu_assign_pointer(priv->tbl, ntbl);
	synchronize_rcu();

	nft_hash_tbl_free(tbl);
	return 0;
}

static int nft_hash_insert(const struct nft_set *set,
			   const struct nft_set_elem *elem)
{
	struct nft_hash *priv = nft_set_priv(set);
	struct nft_hash_table *tbl = nft_dereference(priv->tbl);
	struct nft_hash_elem *he;
	unsigned int size, h;

	if (elem->flags != 0)
		return -EINVAL;

	size = sizeof(*he);
	if (set->flags & NFT_SET_MAP)
		size += sizeof(he->data[0]);

	he = kzalloc(size, GFP_KERNEL);
	if (he == NULL)
		return -ENOMEM;

	nft_data_copy(&he->key, &elem->key);
	if (set->flags & NFT_SET_MAP)
		nft_data_copy(he->data, &elem->data);

	h = nft_hash_data(&he->key, tbl->size, set->klen);
	RCU_INIT_POINTER(he->next, tbl->buckets[h]);
	rcu_assign_pointer(tbl->buckets[h], he);
	tbl->elements++;

	/* Expand table when exceeding 75% load */
	if (tbl->elements > tbl->size / 4 * 3)
		nft_hash_tbl_expand(set, priv);

	return 0;
}

static void nft_hash_elem_destroy(const struct nft_set *set,
				  struct nft_hash_elem *he)
{
	nft_data_uninit(&he->key, NFT_DATA_VALUE);
	if (set->flags & NFT_SET_MAP)
		nft_data_uninit(he->data, set->dtype);
	kfree(he);
}

static void nft_hash_remove(const struct nft_set *set,
			    const struct nft_set_elem *elem)
{
	struct nft_hash *priv = nft_set_priv(set);
	struct nft_hash_table *tbl = nft_dereference(priv->tbl);
	struct nft_hash_elem *he, __rcu **pprev;

	pprev = elem->cookie;
	he = nft_dereference((*pprev));

	RCU_INIT_POINTER(*pprev, he->next);
	synchronize_rcu();
	kfree(he);
	tbl->elements--;

	/* Shrink table beneath 30% load */
	if (tbl->elements < tbl->size * 3 / 10 &&
	    tbl->size > NFT_HASH_MIN_SIZE)
		nft_hash_tbl_shrink(set, priv);
}

static int nft_hash_get(const struct nft_set *set, struct nft_set_elem *elem)
{
	const struct nft_hash *priv = nft_set_priv(set);
	const struct nft_hash_table *tbl = nft_dereference(priv->tbl);
	struct nft_hash_elem __rcu * const *pprev;
	struct nft_hash_elem *he;
	unsigned int h;

	h = nft_hash_data(&elem->key, tbl->size, set->klen);
	pprev = &tbl->buckets[h];
	nft_hash_for_each_entry(he, tbl->buckets[h]) {
		if (nft_data_cmp(&he->key, &elem->key, set->klen)) {
			pprev = &he->next;
			continue;
		}

		elem->cookie = (void *)pprev;
		elem->flags = 0;
		if (set->flags & NFT_SET_MAP)
			nft_data_copy(&elem->data, he->data);
		return 0;
	}
	return -ENOENT;
}

static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set,
			  struct nft_set_iter *iter)
{
	const struct nft_hash *priv = nft_set_priv(set);
	const struct nft_hash_table *tbl = nft_dereference(priv->tbl);
	const struct nft_hash_elem *he;
	struct nft_set_elem elem;
	unsigned int i;

	for (i = 0; i < tbl->size; i++) {
		nft_hash_for_each_entry(he, tbl->buckets[i]) {
			if (iter->count < iter->skip)
				goto cont;

			memcpy(&elem.key, &he->key, sizeof(elem.key));
			if (set->flags & NFT_SET_MAP)
				memcpy(&elem.data, he->data, sizeof(elem.data));
			elem.flags = 0;

			iter->err = iter->fn(ctx, set, iter, &elem);
			if (iter->err < 0)
				return;
cont:
			iter->count++;
		}
	}
}

static unsigned int nft_hash_privsize(const struct nlattr * const nla[])
{
	return sizeof(struct nft_hash);
}

static int nft_hash_init(const struct nft_set *set,
			 const struct nlattr * const tb[])
{
	struct nft_hash *priv = nft_set_priv(set);
	struct nft_hash_table *tbl;

	if (unlikely(!nft_hash_rnd_initted)) {
		get_random_bytes(&nft_hash_rnd, 4);
		nft_hash_rnd_initted = true;
	}

	tbl = nft_hash_tbl_alloc(NFT_HASH_MIN_SIZE);
	if (tbl == NULL)
		return -ENOMEM;
	RCU_INIT_POINTER(priv->tbl, tbl);
	return 0;
}

static void nft_hash_destroy(const struct nft_set *set)
{
	const struct nft_hash *priv = nft_set_priv(set);
	const struct nft_hash_table *tbl = nft_dereference(priv->tbl);
	struct nft_hash_elem *he, *next;
	unsigned int i;

	for (i = 0; i < tbl->size; i++) {
		for (he = nft_dereference(tbl->buckets[i]); he != NULL;
		     he = next) {
			next = nft_dereference(he->next);
			nft_hash_elem_destroy(set, he);
		}
	}
	kfree(tbl);
}

static struct nft_set_ops nft_hash_ops __read_mostly = {
	.privsize       = nft_hash_privsize,
	.init		= nft_hash_init,
	.destroy	= nft_hash_destroy,
	.get		= nft_hash_get,
	.insert		= nft_hash_insert,
	.remove		= nft_hash_remove,
	.lookup		= nft_hash_lookup,
	.walk		= nft_hash_walk,
	.features	= NFT_SET_MAP,
	.owner		= THIS_MODULE,
};

static int __init nft_hash_module_init(void)
{
	return nft_register_set(&nft_hash_ops);
}

static void __exit nft_hash_module_exit(void)
{
	nft_unregister_set(&nft_hash_ops);
}

module_init(nft_hash_module_init);
module_exit(nft_hash_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_ALIAS_NFT_SET();
