Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 060f02a3 authored by Noriaki TAKAMIYA's avatar Noriaki TAKAMIYA Committed by David S. Miller
Browse files

[XFRM] STATE: Introduce care-of address.



Care-of address is carried by state as a transformation option like
IPsec encryption/authentication algorithm.

Based on MIPL2 kernel patch.

Signed-off-by: default avatarNoriaki TAKAMIYA <takamiya@po.ntts.co.jp>
Signed-off-by: default avatarMasahide NAKAMURA <nakam@linux-ipv6.org>
Signed-off-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
parent 1b5c2299
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -235,6 +235,7 @@ enum xfrm_attr_type_t {
	XFRMA_REPLAY_THRESH,
	XFRMA_REPLAY_THRESH,
	XFRMA_ETIMER_THRESH,
	XFRMA_ETIMER_THRESH,
	XFRMA_SRCADDR,		/* xfrm_address_t */
	XFRMA_SRCADDR,		/* xfrm_address_t */
	XFRMA_COADDR,		/* xfrm_address_t */
	__XFRMA_MAX
	__XFRMA_MAX


#define XFRMA_MAX (__XFRMA_MAX - 1)
#define XFRMA_MAX (__XFRMA_MAX - 1)
+3 −0
Original line number Original line Diff line number Diff line
@@ -134,6 +134,9 @@ struct xfrm_state
	/* Data for encapsulator */
	/* Data for encapsulator */
	struct xfrm_encap_tmpl	*encap;
	struct xfrm_encap_tmpl	*encap;


	/* Data for care-of address */
	xfrm_address_t	*coaddr;

	/* IPComp needs an IPIP tunnel for handling uncompressed packets */
	/* IPComp needs an IPIP tunnel for handling uncompressed packets */
	struct xfrm_state	*tunnel;
	struct xfrm_state	*tunnel;


+6 −0
Original line number Original line Diff line number Diff line
@@ -78,6 +78,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
	kfree(x->ealg);
	kfree(x->ealg);
	kfree(x->calg);
	kfree(x->calg);
	kfree(x->encap);
	kfree(x->encap);
	kfree(x->coaddr);
	if (x->mode)
	if (x->mode)
		xfrm_put_mode(x->mode);
		xfrm_put_mode(x->mode);
	if (x->type) {
	if (x->type) {
@@ -603,6 +604,11 @@ int xfrm_state_update(struct xfrm_state *x)
	if (likely(x1->km.state == XFRM_STATE_VALID)) {
	if (likely(x1->km.state == XFRM_STATE_VALID)) {
		if (x->encap && x1->encap)
		if (x->encap && x1->encap)
			memcpy(x1->encap, x->encap, sizeof(*x1->encap));
			memcpy(x1->encap, x->encap, sizeof(*x1->encap));
		if (x->coaddr && x1->coaddr) {
			memcpy(x1->coaddr, x->coaddr, sizeof(*x1->coaddr));
		}
		if (!use_spi && memcmp(&x1->sel, &x->sel, sizeof(x1->sel)))
			memcpy(&x1->sel, &x->sel, sizeof(x1->sel));
		memcpy(&x1->lft, &x->lft, sizeof(x1->lft));
		memcpy(&x1->lft, &x->lft, sizeof(x1->lft));
		x1->km.dying = 0;
		x1->km.dying = 0;


+27 −1
Original line number Original line Diff line number Diff line
@@ -187,11 +187,14 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
		goto out;
		goto out;
	if ((err = verify_sec_ctx_len(xfrma)))
	if ((err = verify_sec_ctx_len(xfrma)))
		goto out;
		goto out;
	if ((err = verify_one_addr(xfrma, XFRMA_COADDR, NULL)))
		goto out;


	err = -EINVAL;
	err = -EINVAL;
	switch (p->mode) {
	switch (p->mode) {
	case XFRM_MODE_TRANSPORT:
	case XFRM_MODE_TRANSPORT:
	case XFRM_MODE_TUNNEL:
	case XFRM_MODE_TUNNEL:
	case XFRM_MODE_ROUTEOPTIMIZATION:
		break;
		break;


	default:
	default:
@@ -276,6 +279,24 @@ static int attach_sec_ctx(struct xfrm_state *x, struct rtattr *u_arg)
	return security_xfrm_state_alloc(x, uctx);
	return security_xfrm_state_alloc(x, uctx);
}
}


static int attach_one_addr(xfrm_address_t **addrpp, struct rtattr *u_arg)
{
	struct rtattr *rta = u_arg;
	xfrm_address_t *p, *uaddrp;

	if (!rta)
		return 0;

	uaddrp = RTA_DATA(rta);
	p = kmalloc(sizeof(*p), GFP_KERNEL);
	if (!p)
		return -ENOMEM;

	memcpy(p, uaddrp, sizeof(*p));
	*addrpp = p;
	return 0;
}

static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
{
{
	memcpy(&x->id, &p->id, sizeof(x->id));
	memcpy(&x->id, &p->id, sizeof(x->id));
@@ -365,7 +386,8 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
		goto error;
		goto error;
	if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1])))
	if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1])))
		goto error;
		goto error;

	if ((err = attach_one_addr(&x->coaddr, xfrma[XFRMA_COADDR-1])))
		goto error;
	err = xfrm_init_state(x);
	err = xfrm_init_state(x);
	if (err)
	if (err)
		goto error;
		goto error;
@@ -569,6 +591,10 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
		uctx->ctx_len = x->security->ctx_len;
		uctx->ctx_len = x->security->ctx_len;
		memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len);
		memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len);
	}
	}

	if (x->coaddr)
		RTA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr);

	nlh->nlmsg_len = skb->tail - b;
	nlh->nlmsg_len = skb->tail - b;
out:
out:
	sp->this_idx++;
	sp->this_idx++;