/*
 * xfrm4_state.c
 *
 * Changes:
 * 	YOSHIFUJI Hideaki @USAGI
 * 		Split up af-specific portion
 *
 */

#include <net/xfrm.h>
#include <linux/pfkeyv2.h>
#include <linux/ipsec.h>

static struct xfrm_state_afinfo xfrm4_state_afinfo;

static void
__xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
		     struct xfrm_tmpl *tmpl,
		     xfrm_address_t *daddr, xfrm_address_t *saddr)
{
	x->sel.daddr.a4 = fl->fl4_dst;
	x->sel.saddr.a4 = fl->fl4_src;
	x->sel.dport = xfrm_flowi_dport(fl);
	x->sel.dport_mask = ~0;
	x->sel.sport = xfrm_flowi_sport(fl);
	x->sel.sport_mask = ~0;
	x->sel.prefixlen_d = 32;
	x->sel.prefixlen_s = 32;
	x->sel.proto = fl->proto;
	x->sel.ifindex = fl->oif;
	x->id = tmpl->id;
	if (x->id.daddr.a4 == 0)
		x->id.daddr.a4 = daddr->a4;
	x->props.saddr = tmpl->saddr;
	if (x->props.saddr.a4 == 0)
		x->props.saddr.a4 = saddr->a4;
	x->props.mode = tmpl->mode;
	x->props.reqid = tmpl->reqid;
	x->props.family = AF_INET;
}

static struct xfrm_state *
__xfrm4_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto)
{
	unsigned h = __xfrm4_spi_hash(daddr, spi, proto);
	struct xfrm_state *x;

	list_for_each_entry(x, xfrm4_state_afinfo.state_byspi+h, byspi) {
		if (x->props.family == AF_INET &&
		    spi == x->id.spi &&
		    daddr->a4 == x->id.daddr.a4 &&
		    proto == x->id.proto) {
			xfrm_state_hold(x);
			return x;
		}
	}
	return NULL;
}

static struct xfrm_state *
__xfrm4_find_acq(u8 mode, u32 reqid, u8 proto, 
		 xfrm_address_t *daddr, xfrm_address_t *saddr, 
		 int create)
{
	struct xfrm_state *x, *x0;
	unsigned h = __xfrm4_dst_hash(daddr);

	x0 = NULL;

	list_for_each_entry(x, xfrm4_state_afinfo.state_bydst+h, bydst) {
		if (x->props.family == AF_INET &&
		    daddr->a4 == x->id.daddr.a4 &&
		    mode == x->props.mode &&
		    proto == x->id.proto &&
		    saddr->a4 == x->props.saddr.a4 &&
		    reqid == x->props.reqid &&
		    x->km.state == XFRM_STATE_ACQ &&
		    !x->id.spi) {
			    x0 = x;
			    break;
		    }
	}
	if (!x0 && create && (x0 = xfrm_state_alloc()) != NULL) {
		x0->sel.daddr.a4 = daddr->a4;
		x0->sel.saddr.a4 = saddr->a4;
		x0->sel.prefixlen_d = 32;
		x0->sel.prefixlen_s = 32;
		x0->props.saddr.a4 = saddr->a4;
		x0->km.state = XFRM_STATE_ACQ;
		x0->id.daddr.a4 = daddr->a4;
		x0->id.proto = proto;
		x0->props.family = AF_INET;
		x0->props.mode = mode;
		x0->props.reqid = reqid;
		x0->props.family = AF_INET;
		x0->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
		xfrm_state_hold(x0);
		x0->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
		add_timer(&x0->timer);
		xfrm_state_hold(x0);
		list_add_tail(&x0->bydst, xfrm4_state_afinfo.state_bydst+h);
		wake_up(&km_waitq);
	}
	if (x0)
		xfrm_state_hold(x0);
	return x0;
}

static struct xfrm_state_afinfo xfrm4_state_afinfo = {
	.family			= AF_INET,
	.lock			= RW_LOCK_UNLOCKED,
	.init_tempsel		= __xfrm4_init_tempsel,
	.state_lookup		= __xfrm4_state_lookup,
	.find_acq		= __xfrm4_find_acq,
};

void __init xfrm4_state_init(void)
{
	xfrm_state_register_afinfo(&xfrm4_state_afinfo);
}

void __exit xfrm4_state_fini(void)
{
	xfrm_state_unregister_afinfo(&xfrm4_state_afinfo);
}

