/* Copyright (C) 2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
 *
 * 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.
 */

#ifndef __IP_SET_BITMAP_IP_GEN_H
#define __IP_SET_BITMAP_IP_GEN_H

#define CONCAT(a, b)		a##b
#define TOKEN(a,b)		CONCAT(a, b)

#define mtype_do_test		TOKEN(MTYPE, _do_test)
#define mtype_gc_test		TOKEN(MTYPE, _gc_test)
#define mtype_is_filled		TOKEN(MTYPE, _is_filled)
#define mtype_do_add		TOKEN(MTYPE, _do_add)
#define mtype_do_del		TOKEN(MTYPE, _do_del)
#define mtype_do_list		TOKEN(MTYPE, _do_list)
#define mtype_do_head		TOKEN(MTYPE, _do_head)
#define mtype_adt_elem		TOKEN(MTYPE, _adt_elem)
#define mtype_add_timeout	TOKEN(MTYPE, _add_timeout)
#define mtype_gc_init		TOKEN(MTYPE, _gc_init)
#define mtype_kadt		TOKEN(MTYPE, _kadt)
#define mtype_uadt		TOKEN(MTYPE, _uadt)
#define mtype_destroy		TOKEN(MTYPE, _destroy)
#define mtype_flush		TOKEN(MTYPE, _flush)
#define mtype_head		TOKEN(MTYPE, _head)
#define mtype_same_set		TOKEN(MTYPE, _same_set)
#define mtype_elem		TOKEN(MTYPE, _elem)
#define mtype_test		TOKEN(MTYPE, _test)
#define mtype_add		TOKEN(MTYPE, _add)
#define mtype_del		TOKEN(MTYPE, _del)
#define mtype_list		TOKEN(MTYPE, _list)
#define mtype_gc		TOKEN(MTYPE, _gc)
#define mtype			MTYPE

#define ext_timeout(e, m)	\
	(unsigned long *)((e) + (m)->offset[IPSET_OFFSET_TIMEOUT])
#define ext_counter(e, m)	\
	(struct ip_set_counter *)((e) + (m)->offset[IPSET_OFFSET_COUNTER])
#define get_ext(map, id)	((map)->extensions + (map)->dsize * (id))

static void
mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
{
	struct mtype *map = set->data;

	init_timer(&map->gc);
	map->gc.data = (unsigned long) set;
	map->gc.function = gc;
	map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
	add_timer(&map->gc);
}

static void
mtype_destroy(struct ip_set *set)
{
	struct mtype *map = set->data;

	if (SET_WITH_TIMEOUT(set))
		del_timer_sync(&map->gc);

	ip_set_free(map->members);
	if (map->dsize)
		ip_set_free(map->extensions);
	kfree(map);

	set->data = NULL;
}

static void
mtype_flush(struct ip_set *set)
{
	struct mtype *map = set->data;

	memset(map->members, 0, map->memsize);
}

static int
mtype_head(struct ip_set *set, struct sk_buff *skb)
{
	const struct mtype *map = set->data;
	struct nlattr *nested;

	nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
	if (!nested)
		goto nla_put_failure;
	if (mtype_do_head(skb, map) ||
	    nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
	    nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
			  htonl(sizeof(*map) +
				map->memsize +
				map->dsize * map->elements)) ||
	    (SET_WITH_TIMEOUT(set) &&
	     nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))) ||
	    (SET_WITH_COUNTER(set) &&
	     nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS,
			   htonl(IPSET_FLAG_WITH_COUNTERS))))
		goto nla_put_failure;
	ipset_nest_end(skb, nested);

	return 0;
nla_put_failure:
	return -EMSGSIZE;
}

static int
mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext,
	   struct ip_set_ext *mext, u32 flags)
{
	struct mtype *map = set->data;
	const struct mtype_adt_elem *e = value;
	void *x = get_ext(map, e->id);
	int ret = mtype_do_test(e, map);

	if (ret <= 0)
		return ret;
	if (SET_WITH_TIMEOUT(set) &&
	    ip_set_timeout_expired(ext_timeout(x, map)))
		return 0;
	if (SET_WITH_COUNTER(set))
		ip_set_update_counter(ext_counter(x, map), ext, mext, flags);
	return 1;
}

static int
mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
	  struct ip_set_ext *mext, u32 flags)
{
	struct mtype *map = set->data;
	const struct mtype_adt_elem *e = value;
	void *x = get_ext(map, e->id);
	int ret = mtype_do_add(e, map, flags);

	if (ret == IPSET_ADD_FAILED) {
		if (SET_WITH_TIMEOUT(set) &&
		    ip_set_timeout_expired(ext_timeout(x, map)))
			ret = 0;
		else if (!(flags & IPSET_FLAG_EXIST))
			return -IPSET_ERR_EXIST;
	}

	if (SET_WITH_TIMEOUT(set))
#ifdef IP_SET_BITMAP_STORED_TIMEOUT
		mtype_add_timeout(ext_timeout(x, map), e, ext, map, ret);
#else
		ip_set_timeout_set(ext_timeout(x, map), ext->timeout);
#endif

	if (SET_WITH_COUNTER(set))
		ip_set_init_counter(ext_counter(x, map), ext);
	return 0;
}

static int
mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
	  struct ip_set_ext *mext, u32 flags)
{
	struct mtype *map = set->data;
	const struct mtype_adt_elem *e = value;
	const void *x = get_ext(map, e->id);

	if (mtype_do_del(e, map) ||
	    (SET_WITH_TIMEOUT(set) &&
	     ip_set_timeout_expired(ext_timeout(x, map))))
		return -IPSET_ERR_EXIST;

	return 0;
}

static int
mtype_list(const struct ip_set *set,
	   struct sk_buff *skb, struct netlink_callback *cb)
{
	struct mtype *map = set->data;
	struct nlattr *adt, *nested;
	void *x;
	u32 id, first = cb->args[2];

	adt = ipset_nest_start(skb, IPSET_ATTR_ADT);
	if (!adt)
		return -EMSGSIZE;
	for (; cb->args[2] < map->elements; cb->args[2]++) {
		id = cb->args[2];
		x = get_ext(map, id);
		if (!test_bit(id, map->members) ||
		    (SET_WITH_TIMEOUT(set) &&
#ifdef IP_SET_BITMAP_STORED_TIMEOUT
		     mtype_is_filled((const struct mtype_elem *) x) &&
#endif
		     ip_set_timeout_expired(ext_timeout(x, map))))
			continue;
		nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
		if (!nested) {
			if (id == first) {
				nla_nest_cancel(skb, adt);
				return -EMSGSIZE;
			} else
				goto nla_put_failure;
		}
		if (mtype_do_list(skb, map, id))
			goto nla_put_failure;
		if (SET_WITH_TIMEOUT(set)) {
#ifdef IP_SET_BITMAP_STORED_TIMEOUT
			if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
					  htonl(ip_set_timeout_stored(map, id,
							ext_timeout(x, map)))))
				goto nla_put_failure;
#else
			if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
					  htonl(ip_set_timeout_get(
							ext_timeout(x, map)))))
				goto nla_put_failure;
#endif
		}
		if (SET_WITH_COUNTER(set) &&
		    ip_set_put_counter(skb, ext_counter(x, map)))
			goto nla_put_failure;
		ipset_nest_end(skb, nested);
	}
	ipset_nest_end(skb, adt);

	/* Set listing finished */
	cb->args[2] = 0;

	return 0;

nla_put_failure:
	nla_nest_cancel(skb, nested);
	ipset_nest_end(skb, adt);
	if (unlikely(id == first)) {
		cb->args[2] = 0;
		return -EMSGSIZE;
	}
	return 0;
}

static void
mtype_gc(unsigned long ul_set)
{
	struct ip_set *set = (struct ip_set *) ul_set;
	struct mtype *map = set->data;
	const void *x;
	u32 id;

	/* We run parallel with other readers (test element)
	 * but adding/deleting new entries is locked out */
	read_lock_bh(&set->lock);
	for (id = 0; id < map->elements; id++)
		if (mtype_gc_test(id, map)) {
			x = get_ext(map, id);
			if (ip_set_timeout_expired(ext_timeout(x, map)))
				clear_bit(id, map->members);
		}
	read_unlock_bh(&set->lock);

	map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
	add_timer(&map->gc);
}

static const struct ip_set_type_variant mtype = {
	.kadt	= mtype_kadt,
	.uadt	= mtype_uadt,
	.adt	= {
		[IPSET_ADD] = mtype_add,
		[IPSET_DEL] = mtype_del,
		[IPSET_TEST] = mtype_test,
	},
	.destroy = mtype_destroy,
	.flush	= mtype_flush,
	.head	= mtype_head,
	.list	= mtype_list,
	.same_set = mtype_same_set,
};

#endif /* __IP_SET_BITMAP_IP_GEN_H */
