/*
 * netfilter module to limit the number of parallel tcp
 * connections per IP address.
 *   (c) 2000 Gerd Knorr <kraxel@bytesex.org>
 *   Nov 2002: Martin Bene <martin.bene@icomedias.com>:
 *		only ignore TIME_WAIT or gone connections
 *   (C) CC Computer Consultants GmbH, 2007
 *
 * based on ...
 *
 * Kernel module to match connection tracking information.
 * GPL (C) 1999  Rusty Russell (rusty@rustcorp.com.au).
 */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/jhash.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/rbtree.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/netfilter/nf_conntrack_tcp.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_connlimit.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_tuple.h>
#include <net/netfilter/nf_conntrack_zones.h>

#define CONNLIMIT_SLOTS		256U

#ifdef CONFIG_LOCKDEP
#define CONNLIMIT_LOCK_SLOTS	8U
#else
#define CONNLIMIT_LOCK_SLOTS	256U
#endif

#define CONNLIMIT_GC_MAX_NODES	8

/* we will save the tuples of all connections we care about */
struct xt_connlimit_conn {
	struct hlist_node		node;
	struct nf_conntrack_tuple	tuple;
	struct nf_conntrack_zone	zone;
	int				cpu;
	u32				jiffies32;
};

struct xt_connlimit_rb {
	struct rb_node node;
	struct hlist_head hhead; /* connections/hosts in same subnet */
	union nf_inet_addr addr; /* search key */
};

static spinlock_t xt_connlimit_locks[CONNLIMIT_LOCK_SLOTS] __cacheline_aligned_in_smp;

struct xt_connlimit_data {
	struct rb_root climit_root[CONNLIMIT_SLOTS];
};

static u_int32_t connlimit_rnd __read_mostly;
static struct kmem_cache *connlimit_rb_cachep __read_mostly;
static struct kmem_cache *connlimit_conn_cachep __read_mostly;

static inline unsigned int connlimit_iphash(__be32 addr)
{
	return jhash_1word((__force __u32)addr,
			    connlimit_rnd) % CONNLIMIT_SLOTS;
}

static inline unsigned int
connlimit_iphash6(const union nf_inet_addr *addr,
                  const union nf_inet_addr *mask)
{
	union nf_inet_addr res;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(addr->ip6); ++i)
		res.ip6[i] = addr->ip6[i] & mask->ip6[i];

	return jhash2((u32 *)res.ip6, ARRAY_SIZE(res.ip6),
		       connlimit_rnd) % CONNLIMIT_SLOTS;
}

static inline bool already_closed(const struct nf_conn *conn)
{
	if (nf_ct_protonum(conn) == IPPROTO_TCP)
		return conn->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT ||
		       conn->proto.tcp.state == TCP_CONNTRACK_CLOSE;
	else
		return 0;
}

static int
same_source_net(const union nf_inet_addr *addr,
		const union nf_inet_addr *mask,
		const union nf_inet_addr *u3, u_int8_t family)
{
	if (family == NFPROTO_IPV4) {
		return ntohl(addr->ip & mask->ip) -
		       ntohl(u3->ip & mask->ip);
	} else {
		union nf_inet_addr lh, rh;
		unsigned int i;

		for (i = 0; i < ARRAY_SIZE(addr->ip6); ++i) {
			lh.ip6[i] = addr->ip6[i] & mask->ip6[i];
			rh.ip6[i] = u3->ip6[i] & mask->ip6[i];
		}

		return memcmp(&lh.ip6, &rh.ip6, sizeof(lh.ip6));
	}
}

bool nf_conncount_add(struct hlist_head *head,
		      const struct nf_conntrack_tuple *tuple,
		      const struct nf_conntrack_zone *zone)
{
	struct xt_connlimit_conn *conn;

	conn = kmem_cache_alloc(connlimit_conn_cachep, GFP_ATOMIC);
	if (conn == NULL)
		return false;
	conn->tuple = *tuple;
	conn->zone = *zone;
	conn->cpu = raw_smp_processor_id();
	conn->jiffies32 = (u32)jiffies;
	hlist_add_head(&conn->node, head);
	return true;
}
EXPORT_SYMBOL_GPL(nf_conncount_add);

static const struct nf_conntrack_tuple_hash *
find_or_evict(struct net *net, struct xt_connlimit_conn *conn)
{
	const struct nf_conntrack_tuple_hash *found;
	unsigned long a, b;
	int cpu = raw_smp_processor_id();
	u32 age;

	found = nf_conntrack_find_get(net, &conn->zone, &conn->tuple);
	if (found)
		return found;
	b = conn->jiffies32;
	a = (u32)jiffies;

	/* conn might have been added just before by another cpu and
	 * might still be unconfirmed.  In this case, nf_conntrack_find()
	 * returns no result.  Thus only evict if this cpu added the
	 * stale entry or if the entry is older than two jiffies.
	 */
	age = a - b;
	if (conn->cpu == cpu || age >= 2) {
		hlist_del(&conn->node);
		kmem_cache_free(connlimit_conn_cachep, conn);
		return ERR_PTR(-ENOENT);
	}

	return ERR_PTR(-EAGAIN);
}

unsigned int nf_conncount_lookup(struct net *net, struct hlist_head *head,
				 const struct nf_conntrack_tuple *tuple,
				 const struct nf_conntrack_zone *zone,
				 bool *addit)
{
	const struct nf_conntrack_tuple_hash *found;
	struct xt_connlimit_conn *conn;
	struct nf_conn *found_ct;
	struct hlist_node *n;
	unsigned int length = 0;

	*addit = true;

	/* check the saved connections */
	hlist_for_each_entry_safe(conn, n, head, node) {
		found = find_or_evict(net, conn);
		if (IS_ERR(found)) {
			/* Not found, but might be about to be confirmed */
			if (PTR_ERR(found) == -EAGAIN) {
				length++;
				if (!tuple)
					continue;

				if (nf_ct_tuple_equal(&conn->tuple, tuple) &&
				    nf_ct_zone_id(&conn->zone, conn->zone.dir) ==
				    nf_ct_zone_id(zone, zone->dir))
					*addit = false;
			}
			continue;
		}

		found_ct = nf_ct_tuplehash_to_ctrack(found);

		if (nf_ct_tuple_equal(&conn->tuple, tuple) &&
		    nf_ct_zone_equal(found_ct, zone, zone->dir)) {
			/*
			 * Just to be sure we have it only once in the list.
			 * We should not see tuples twice unless someone hooks
			 * this into a table without "-p tcp --syn".
			 */
			*addit = false;
		} else if (already_closed(found_ct)) {
			/*
			 * we do not care about connections which are
			 * closed already -> ditch it
			 */
			nf_ct_put(found_ct);
			hlist_del(&conn->node);
			kmem_cache_free(connlimit_conn_cachep, conn);
			continue;
		}

		nf_ct_put(found_ct);
		length++;
	}

	return length;
}
EXPORT_SYMBOL_GPL(nf_conncount_lookup);

static void tree_nodes_free(struct rb_root *root,
			    struct xt_connlimit_rb *gc_nodes[],
			    unsigned int gc_count)
{
	struct xt_connlimit_rb *rbconn;

	while (gc_count) {
		rbconn = gc_nodes[--gc_count];
		rb_erase(&rbconn->node, root);
		kmem_cache_free(connlimit_rb_cachep, rbconn);
	}
}

static unsigned int
count_tree(struct net *net, struct rb_root *root,
	   const struct nf_conntrack_tuple *tuple,
	   const union nf_inet_addr *addr, const union nf_inet_addr *mask,
	   u8 family, const struct nf_conntrack_zone *zone)
{
	struct xt_connlimit_rb *gc_nodes[CONNLIMIT_GC_MAX_NODES];
	struct rb_node **rbnode, *parent;
	struct xt_connlimit_rb *rbconn;
	struct xt_connlimit_conn *conn;
	unsigned int gc_count;
	bool no_gc = false;

 restart:
	gc_count = 0;
	parent = NULL;
	rbnode = &(root->rb_node);
	while (*rbnode) {
		int diff;
		bool addit;

		rbconn = rb_entry(*rbnode, struct xt_connlimit_rb, node);

		parent = *rbnode;
		diff = same_source_net(addr, mask, &rbconn->addr, family);
		if (diff < 0) {
			rbnode = &((*rbnode)->rb_left);
		} else if (diff > 0) {
			rbnode = &((*rbnode)->rb_right);
		} else {
			/* same source network -> be counted! */
			unsigned int count;

			count = nf_conncount_lookup(net, &rbconn->hhead, tuple,
						    zone, &addit);

			tree_nodes_free(root, gc_nodes, gc_count);
			if (!addit)
				return count;

			if (!nf_conncount_add(&rbconn->hhead, tuple, zone))
				return 0; /* hotdrop */

			return count + 1;
		}

		if (no_gc || gc_count >= ARRAY_SIZE(gc_nodes))
			continue;

		/* only used for GC on hhead, retval and 'addit' ignored */
		nf_conncount_lookup(net, &rbconn->hhead, tuple, zone, &addit);
		if (hlist_empty(&rbconn->hhead))
			gc_nodes[gc_count++] = rbconn;
	}

	if (gc_count) {
		no_gc = true;
		tree_nodes_free(root, gc_nodes, gc_count);
		/* tree_node_free before new allocation permits
		 * allocator to re-use newly free'd object.
		 *
		 * This is a rare event; in most cases we will find
		 * existing node to re-use. (or gc_count is 0).
		 */
		goto restart;
	}

	/* no match, need to insert new node */
	rbconn = kmem_cache_alloc(connlimit_rb_cachep, GFP_ATOMIC);
	if (rbconn == NULL)
		return 0;

	conn = kmem_cache_alloc(connlimit_conn_cachep, GFP_ATOMIC);
	if (conn == NULL) {
		kmem_cache_free(connlimit_rb_cachep, rbconn);
		return 0;
	}

	conn->tuple = *tuple;
	conn->zone = *zone;
	rbconn->addr = *addr;

	INIT_HLIST_HEAD(&rbconn->hhead);
	hlist_add_head(&conn->node, &rbconn->hhead);

	rb_link_node(&rbconn->node, parent, rbnode);
	rb_insert_color(&rbconn->node, root);
	return 1;
}

static int count_them(struct net *net,
		      struct xt_connlimit_data *data,
		      const struct nf_conntrack_tuple *tuple,
		      const union nf_inet_addr *addr,
		      const union nf_inet_addr *mask,
		      u_int8_t family,
		      const struct nf_conntrack_zone *zone)
{
	struct rb_root *root;
	int count;
	u32 hash;

	if (family == NFPROTO_IPV6)
		hash = connlimit_iphash6(addr, mask);
	else
		hash = connlimit_iphash(addr->ip & mask->ip);
	root = &data->climit_root[hash];

	spin_lock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]);

	count = count_tree(net, root, tuple, addr, mask, family, zone);

	spin_unlock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]);

	return count;
}

static bool
connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
	struct net *net = xt_net(par);
	const struct xt_connlimit_info *info = par->matchinfo;
	union nf_inet_addr addr;
	struct nf_conntrack_tuple tuple;
	const struct nf_conntrack_tuple *tuple_ptr = &tuple;
	const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt;
	enum ip_conntrack_info ctinfo;
	const struct nf_conn *ct;
	unsigned int connections;

	ct = nf_ct_get(skb, &ctinfo);
	if (ct != NULL) {
		tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
		zone = nf_ct_zone(ct);
	} else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),
				      xt_family(par), net, &tuple)) {
		goto hotdrop;
	}

	if (xt_family(par) == NFPROTO_IPV6) {
		const struct ipv6hdr *iph = ipv6_hdr(skb);
		memcpy(&addr.ip6, (info->flags & XT_CONNLIMIT_DADDR) ?
		       &iph->daddr : &iph->saddr, sizeof(addr.ip6));
	} else {
		const struct iphdr *iph = ip_hdr(skb);
		addr.ip = (info->flags & XT_CONNLIMIT_DADDR) ?
			  iph->daddr : iph->saddr;
	}

	connections = count_them(net, info->data, tuple_ptr, &addr,
	                         &info->mask, xt_family(par), zone);
	if (connections == 0)
		/* kmalloc failed, drop it entirely */
		goto hotdrop;

	return (connections > info->limit) ^
	       !!(info->flags & XT_CONNLIMIT_INVERT);

 hotdrop:
	par->hotdrop = true;
	return false;
}

static int connlimit_mt_check(const struct xt_mtchk_param *par)
{
	struct xt_connlimit_info *info = par->matchinfo;
	unsigned int i;
	int ret;

	net_get_random_once(&connlimit_rnd, sizeof(connlimit_rnd));

	ret = nf_ct_netns_get(par->net, par->family);
	if (ret < 0) {
		pr_info("cannot load conntrack support for "
			"address family %u\n", par->family);
		return ret;
	}

	/* init private data */
	info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL);
	if (info->data == NULL) {
		nf_ct_netns_put(par->net, par->family);
		return -ENOMEM;
	}

	for (i = 0; i < ARRAY_SIZE(info->data->climit_root); ++i)
		info->data->climit_root[i] = RB_ROOT;

	return 0;
}

void nf_conncount_cache_free(struct hlist_head *hhead)
{
	struct xt_connlimit_conn *conn;
	struct hlist_node *n;

	hlist_for_each_entry_safe(conn, n, hhead, node)
		kmem_cache_free(connlimit_conn_cachep, conn);
}
EXPORT_SYMBOL_GPL(nf_conncount_cache_free);

static void destroy_tree(struct rb_root *r)
{
	struct xt_connlimit_rb *rbconn;
	struct rb_node *node;

	while ((node = rb_first(r)) != NULL) {
		rbconn = rb_entry(node, struct xt_connlimit_rb, node);

		rb_erase(node, r);

		nf_conncount_cache_free(&rbconn->hhead);

		kmem_cache_free(connlimit_rb_cachep, rbconn);
	}
}

static void connlimit_mt_destroy(const struct xt_mtdtor_param *par)
{
	const struct xt_connlimit_info *info = par->matchinfo;
	unsigned int i;

	nf_ct_netns_put(par->net, par->family);

	for (i = 0; i < ARRAY_SIZE(info->data->climit_root); ++i)
		destroy_tree(&info->data->climit_root[i]);

	kfree(info->data);
}

static struct xt_match connlimit_mt_reg __read_mostly = {
	.name       = "connlimit",
	.revision   = 1,
	.family     = NFPROTO_UNSPEC,
	.checkentry = connlimit_mt_check,
	.match      = connlimit_mt,
	.matchsize  = sizeof(struct xt_connlimit_info),
	.usersize   = offsetof(struct xt_connlimit_info, data),
	.destroy    = connlimit_mt_destroy,
	.me         = THIS_MODULE,
};

static int __init connlimit_mt_init(void)
{
	int ret, i;

	BUILD_BUG_ON(CONNLIMIT_LOCK_SLOTS > CONNLIMIT_SLOTS);
	BUILD_BUG_ON((CONNLIMIT_SLOTS % CONNLIMIT_LOCK_SLOTS) != 0);

	for (i = 0; i < CONNLIMIT_LOCK_SLOTS; ++i)
		spin_lock_init(&xt_connlimit_locks[i]);

	connlimit_conn_cachep = kmem_cache_create("xt_connlimit_conn",
					   sizeof(struct xt_connlimit_conn),
					   0, 0, NULL);
	if (!connlimit_conn_cachep)
		return -ENOMEM;

	connlimit_rb_cachep = kmem_cache_create("xt_connlimit_rb",
					   sizeof(struct xt_connlimit_rb),
					   0, 0, NULL);
	if (!connlimit_rb_cachep) {
		kmem_cache_destroy(connlimit_conn_cachep);
		return -ENOMEM;
	}
	ret = xt_register_match(&connlimit_mt_reg);
	if (ret != 0) {
		kmem_cache_destroy(connlimit_conn_cachep);
		kmem_cache_destroy(connlimit_rb_cachep);
	}
	return ret;
}

static void __exit connlimit_mt_exit(void)
{
	xt_unregister_match(&connlimit_mt_reg);
	kmem_cache_destroy(connlimit_conn_cachep);
	kmem_cache_destroy(connlimit_rb_cachep);
}

module_init(connlimit_mt_init);
module_exit(connlimit_mt_exit);
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
MODULE_DESCRIPTION("Xtables: Number of connections matching");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_connlimit");
MODULE_ALIAS("ip6t_connlimit");
