/*
 * Copyright (C)2003,2004 USAGI/WIDE Project
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Authors	Mitsuru KANDA  <mk@linux-ipv6.org>
 * 		YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
 *
 * Based on net/ipv4/xfrm4_tunnel.c
 *
 */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/xfrm.h>
#include <linux/list.h>
#include <net/ip.h>
#include <net/xfrm.h>
#include <net/ipv6.h>
#include <net/protocol.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
#include <linux/mutex.h>

#ifdef CONFIG_IPV6_XFRM6_TUNNEL_DEBUG
# define X6TDEBUG	3
#else
# define X6TDEBUG	1
#endif

#define X6TPRINTK(fmt, args...)		printk(fmt, ## args)
#define X6TNOPRINTK(fmt, args...)	do { ; } while(0)

#if X6TDEBUG >= 1
# define X6TPRINTK1	X6TPRINTK
#else
# define X6TPRINTK1	X6TNOPRINTK
#endif

#if X6TDEBUG >= 3
# define X6TPRINTK3	X6TPRINTK
#else
# define X6TPRINTK3	X6TNOPRINTK
#endif

/*
 * xfrm_tunnel_spi things are for allocating unique id ("spi") 
 * per xfrm_address_t.
 */
struct xfrm6_tunnel_spi {
	struct hlist_node list_byaddr;
	struct hlist_node list_byspi;
	xfrm_address_t addr;
	u32 spi;
	atomic_t refcnt;
#ifdef XFRM6_TUNNEL_SPI_MAGIC
	u32 magic;
#endif
};

#ifdef CONFIG_IPV6_XFRM6_TUNNEL_DEBUG
# define XFRM6_TUNNEL_SPI_MAGIC 0xdeadbeef
#endif

static DEFINE_RWLOCK(xfrm6_tunnel_spi_lock);

static u32 xfrm6_tunnel_spi;

#define XFRM6_TUNNEL_SPI_MIN	1
#define XFRM6_TUNNEL_SPI_MAX	0xffffffff

static kmem_cache_t *xfrm6_tunnel_spi_kmem __read_mostly;

#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256

static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];

#ifdef XFRM6_TUNNEL_SPI_MAGIC
static int x6spi_check_magic(const struct xfrm6_tunnel_spi *x6spi,
			     const char *name)
{
	if (unlikely(x6spi->magic != XFRM6_TUNNEL_SPI_MAGIC)) {
		X6TPRINTK3(KERN_DEBUG "%s(): x6spi object "
				      "at %p has corrupted magic %08x "
				      "(should be %08x)\n",
			   name, x6spi, x6spi->magic, XFRM6_TUNNEL_SPI_MAGIC);
		return -1;
	}
	return 0;
}
#else
static int inline x6spi_check_magic(const struct xfrm6_tunnel_spi *x6spi,
				    const char *name)
{
	return 0;
}
#endif

#define X6SPI_CHECK_MAGIC(x6spi) x6spi_check_magic((x6spi), __FUNCTION__)


static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
{
	unsigned h;

	X6TPRINTK3(KERN_DEBUG "%s(addr=%p)\n", __FUNCTION__, addr);

	h = addr->a6[0] ^ addr->a6[1] ^ addr->a6[2] ^ addr->a6[3];
	h ^= h >> 16;
	h ^= h >> 8;
	h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1;

	X6TPRINTK3(KERN_DEBUG "%s() = %u\n", __FUNCTION__, h);

	return h;
}

static unsigned inline xfrm6_tunnel_spi_hash_byspi(u32 spi)
{
	return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE;
}


static int xfrm6_tunnel_spi_init(void)
{
	int i;

	X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);

	xfrm6_tunnel_spi = 0;
	xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi",
						  sizeof(struct xfrm6_tunnel_spi),
						  0, SLAB_HWCACHE_ALIGN,
						  NULL, NULL);
	if (!xfrm6_tunnel_spi_kmem) {
		X6TPRINTK1(KERN_ERR
			   "%s(): failed to allocate xfrm6_tunnel_spi_kmem\n",
		           __FUNCTION__);
		return -ENOMEM;
	}

	for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
		INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byaddr[i]);
	for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++)
		INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byspi[i]);
	return 0;
}

static void xfrm6_tunnel_spi_fini(void)
{
	int i;

	X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);

	for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) {
		if (!hlist_empty(&xfrm6_tunnel_spi_byaddr[i]))
			goto err;
	}
	for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++) {
		if (!hlist_empty(&xfrm6_tunnel_spi_byspi[i]))
			goto err;
	}
	kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
	xfrm6_tunnel_spi_kmem = NULL;
	return;
err:
	X6TPRINTK1(KERN_ERR "%s(): table is not empty\n", __FUNCTION__);
	return;
}

static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
{
	struct xfrm6_tunnel_spi *x6spi;
	struct hlist_node *pos;

	X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);

	hlist_for_each_entry(x6spi, pos,
			     &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
			     list_byaddr) {
		if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) {
			X6SPI_CHECK_MAGIC(x6spi);
			X6TPRINTK3(KERN_DEBUG "%s() = %p(%u)\n", __FUNCTION__, x6spi, x6spi->spi);
			return x6spi;
		}
	}

	X6TPRINTK3(KERN_DEBUG "%s() = NULL(0)\n", __FUNCTION__);
	return NULL;
}

u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
{
	struct xfrm6_tunnel_spi *x6spi;
	u32 spi;

	X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);

	read_lock_bh(&xfrm6_tunnel_spi_lock);
	x6spi = __xfrm6_tunnel_spi_lookup(saddr);
	spi = x6spi ? x6spi->spi : 0;
	read_unlock_bh(&xfrm6_tunnel_spi_lock);
	return spi;
}

EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup);

static u32 __xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
{
	u32 spi;
	struct xfrm6_tunnel_spi *x6spi;
	struct hlist_node *pos;
	unsigned index;

	X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);

	if (xfrm6_tunnel_spi < XFRM6_TUNNEL_SPI_MIN ||
	    xfrm6_tunnel_spi >= XFRM6_TUNNEL_SPI_MAX)
		xfrm6_tunnel_spi = XFRM6_TUNNEL_SPI_MIN;
	else
		xfrm6_tunnel_spi++;

	for (spi = xfrm6_tunnel_spi; spi <= XFRM6_TUNNEL_SPI_MAX; spi++) {
		index = xfrm6_tunnel_spi_hash_byspi(spi);
		hlist_for_each_entry(x6spi, pos, 
				     &xfrm6_tunnel_spi_byspi[index], 
				     list_byspi) {
			if (x6spi->spi == spi)
				goto try_next_1;
		}
		xfrm6_tunnel_spi = spi;
		goto alloc_spi;
try_next_1:;
	}
	for (spi = XFRM6_TUNNEL_SPI_MIN; spi < xfrm6_tunnel_spi; spi++) {
		index = xfrm6_tunnel_spi_hash_byspi(spi);
		hlist_for_each_entry(x6spi, pos, 
				     &xfrm6_tunnel_spi_byspi[index], 
				     list_byspi) {
			if (x6spi->spi == spi)
				goto try_next_2;
		}
		xfrm6_tunnel_spi = spi;
		goto alloc_spi;
try_next_2:;
	}
	spi = 0;
	goto out;
alloc_spi:
	X6TPRINTK3(KERN_DEBUG "%s(): allocate new spi for " NIP6_FMT "\n",
			      __FUNCTION__, 
			      NIP6(*(struct in6_addr *)saddr));
	x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, SLAB_ATOMIC);
	if (!x6spi) {
		X6TPRINTK1(KERN_ERR "%s(): kmem_cache_alloc() failed\n", 
			   __FUNCTION__);
		goto out;
	}
#ifdef XFRM6_TUNNEL_SPI_MAGIC
	x6spi->magic = XFRM6_TUNNEL_SPI_MAGIC;
#endif
	memcpy(&x6spi->addr, saddr, sizeof(x6spi->addr));
	x6spi->spi = spi;
	atomic_set(&x6spi->refcnt, 1);

	hlist_add_head(&x6spi->list_byspi, &xfrm6_tunnel_spi_byspi[index]);

	index = xfrm6_tunnel_spi_hash_byaddr(saddr);
	hlist_add_head(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]);
	X6SPI_CHECK_MAGIC(x6spi);
out:
	X6TPRINTK3(KERN_DEBUG "%s() = %u\n", __FUNCTION__, spi);
	return spi;
}

u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
{
	struct xfrm6_tunnel_spi *x6spi;
	u32 spi;

	X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);

	write_lock_bh(&xfrm6_tunnel_spi_lock);
	x6spi = __xfrm6_tunnel_spi_lookup(saddr);
	if (x6spi) {
		atomic_inc(&x6spi->refcnt);
		spi = x6spi->spi;
	} else
		spi = __xfrm6_tunnel_alloc_spi(saddr);
	write_unlock_bh(&xfrm6_tunnel_spi_lock);

	X6TPRINTK3(KERN_DEBUG "%s() = %u\n", __FUNCTION__, spi);

	return spi;
}

EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi);

void xfrm6_tunnel_free_spi(xfrm_address_t *saddr)
{
	struct xfrm6_tunnel_spi *x6spi;
	struct hlist_node *pos, *n;

	X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);

	write_lock_bh(&xfrm6_tunnel_spi_lock);

	hlist_for_each_entry_safe(x6spi, pos, n, 
				  &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
				  list_byaddr)
	{
		if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) {
			X6TPRINTK3(KERN_DEBUG "%s(): x6spi object for " NIP6_FMT 
					      " found at %p\n",
				   __FUNCTION__, 
				   NIP6(*(struct in6_addr *)saddr),
				   x6spi);
			X6SPI_CHECK_MAGIC(x6spi);
			if (atomic_dec_and_test(&x6spi->refcnt)) {
				hlist_del(&x6spi->list_byaddr);
				hlist_del(&x6spi->list_byspi);
				kmem_cache_free(xfrm6_tunnel_spi_kmem, x6spi);
				break;
			}
		}
	}
	write_unlock_bh(&xfrm6_tunnel_spi_lock);
}

EXPORT_SYMBOL(xfrm6_tunnel_free_spi);

static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
{
	struct ipv6hdr *top_iph;

	top_iph = (struct ipv6hdr *)skb->data;
	top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));

	return 0;
}

static int xfrm6_tunnel_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
{
	return 0;
}

static struct xfrm6_tunnel *xfrm6_tunnel_handler;
static DEFINE_MUTEX(xfrm6_tunnel_mutex);

int xfrm6_tunnel_register(struct xfrm6_tunnel *handler)
{
	int ret;

	mutex_lock(&xfrm6_tunnel_mutex);
	ret = 0;
	if (xfrm6_tunnel_handler != NULL)
		ret = -EINVAL;
	if (!ret)
		xfrm6_tunnel_handler = handler;
	mutex_unlock(&xfrm6_tunnel_mutex);

	return ret;
}

EXPORT_SYMBOL(xfrm6_tunnel_register);

int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler)
{
	int ret;

	mutex_lock(&xfrm6_tunnel_mutex);
	ret = 0;
	if (xfrm6_tunnel_handler != handler)
		ret = -EINVAL;
	if (!ret)
		xfrm6_tunnel_handler = NULL;
	mutex_unlock(&xfrm6_tunnel_mutex);

	synchronize_net();

	return ret;
}

EXPORT_SYMBOL(xfrm6_tunnel_deregister);

static int xfrm6_tunnel_rcv(struct sk_buff **pskb)
{
	struct sk_buff *skb = *pskb;
	struct xfrm6_tunnel *handler = xfrm6_tunnel_handler;
	struct ipv6hdr *iph = skb->nh.ipv6h;
	u32 spi;

	/* device-like_ip6ip6_handler() */
	if (handler && handler->handler(pskb) == 0)
		return 0;

	spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
	return xfrm6_rcv_spi(pskb, spi);
}

static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
			     int type, int code, int offset, __u32 info)
{
	struct xfrm6_tunnel *handler = xfrm6_tunnel_handler;

	/* call here first for device-like ip6ip6 err handling */
	if (handler) {
		handler->err_handler(skb, opt, type, code, offset, info);
		return;
	}

	/* xfrm6_tunnel native err handling */
	switch (type) {
	case ICMPV6_DEST_UNREACH: 
		switch (code) {
		case ICMPV6_NOROUTE: 
		case ICMPV6_ADM_PROHIBITED:
		case ICMPV6_NOT_NEIGHBOUR:
		case ICMPV6_ADDR_UNREACH:
		case ICMPV6_PORT_UNREACH:
		default:
			X6TPRINTK3(KERN_DEBUG
				   "xfrm6_tunnel: Destination Unreach.\n");
			break;
		}
		break;
	case ICMPV6_PKT_TOOBIG:
			X6TPRINTK3(KERN_DEBUG 
				   "xfrm6_tunnel: Packet Too Big.\n");
		break;
	case ICMPV6_TIME_EXCEED:
		switch (code) {
		case ICMPV6_EXC_HOPLIMIT:
			X6TPRINTK3(KERN_DEBUG
				   "xfrm6_tunnel: Too small Hoplimit.\n");
			break;
		case ICMPV6_EXC_FRAGTIME:
		default: 
			break;
		}
		break;
	case ICMPV6_PARAMPROB:
		switch (code) {
		case ICMPV6_HDR_FIELD: break;
		case ICMPV6_UNK_NEXTHDR: break;
		case ICMPV6_UNK_OPTION: break;
		}
		break;
	default:
		break;
	}
	return;
}

static int xfrm6_tunnel_init_state(struct xfrm_state *x)
{
	if (!x->props.mode)
		return -EINVAL;

	if (x->encap)
		return -EINVAL;

	x->props.header_len = sizeof(struct ipv6hdr);

	return 0;
}

static void xfrm6_tunnel_destroy(struct xfrm_state *x)
{
	xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr);
}

static struct xfrm_type xfrm6_tunnel_type = {
	.description	= "IP6IP6",
	.owner          = THIS_MODULE,
	.proto		= IPPROTO_IPV6,
	.init_state	= xfrm6_tunnel_init_state,
	.destructor	= xfrm6_tunnel_destroy,
	.input		= xfrm6_tunnel_input,
	.output		= xfrm6_tunnel_output,
};

static struct inet6_protocol xfrm6_tunnel_protocol = {
	.handler	= xfrm6_tunnel_rcv,
	.err_handler	= xfrm6_tunnel_err, 
	.flags          = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
};

static int __init xfrm6_tunnel_init(void)
{
	X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);

	if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) {
		X6TPRINTK1(KERN_ERR
			   "xfrm6_tunnel init: can't add xfrm type\n");
		return -EAGAIN;
	}
	if (inet6_add_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6) < 0) {
		X6TPRINTK1(KERN_ERR
			   "xfrm6_tunnel init(): can't add protocol\n");
		xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
		return -EAGAIN;
	}
	if (xfrm6_tunnel_spi_init() < 0) {
		X6TPRINTK1(KERN_ERR
			   "xfrm6_tunnel init: failed to initialize spi\n");
		inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6);
		xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
		return -EAGAIN;
	}
	return 0;
}

static void __exit xfrm6_tunnel_fini(void)
{
	X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);

	xfrm6_tunnel_spi_fini();
	if (inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6) < 0)
		X6TPRINTK1(KERN_ERR 
			   "xfrm6_tunnel close: can't remove protocol\n");
	if (xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6) < 0)
		X6TPRINTK1(KERN_ERR
			   "xfrm6_tunnel close: can't remove xfrm type\n");
}

module_init(xfrm6_tunnel_init);
module_exit(xfrm6_tunnel_fini);
MODULE_LICENSE("GPL");
