summaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_user.c
diff options
context:
space:
mode:
authorNoriaki TAKAMIYA2006-08-24 03:18:55 +0200
committerDavid S. Miller2006-09-23 00:06:42 +0200
commit060f02a3bdd4d9ba8aa3c48e9b470672b1f3a585 (patch)
tree0eb60cf50ad70ceb856c82c32124470f6bce2d86 /net/xfrm/xfrm_user.c
parent[XFRM] STATE: Support non-fragment outbound transformation headers. (diff)
downloadkernel-qcow2-linux-060f02a3bdd4d9ba8aa3c48e9b470672b1f3a585.tar.gz
kernel-qcow2-linux-060f02a3bdd4d9ba8aa3c48e9b470672b1f3a585.tar.xz
kernel-qcow2-linux-060f02a3bdd4d9ba8aa3c48e9b470672b1f3a585.zip
[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: Noriaki TAKAMIYA <takamiya@po.ntts.co.jp> Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r--net/xfrm/xfrm_user.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b5f8ab71aa54..939808de9e20 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -187,11 +187,14 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
goto out;
if ((err = verify_sec_ctx_len(xfrma)))
goto out;
+ if ((err = verify_one_addr(xfrma, XFRMA_COADDR, NULL)))
+ goto out;
err = -EINVAL;
switch (p->mode) {
case XFRM_MODE_TRANSPORT:
case XFRM_MODE_TUNNEL:
+ case XFRM_MODE_ROUTEOPTIMIZATION:
break;
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);
}
+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)
{
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;
if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1])))
goto error;
-
+ if ((err = attach_one_addr(&x->coaddr, xfrma[XFRMA_COADDR-1])))
+ goto error;
err = xfrm_init_state(x);
if (err)
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;
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;
out:
sp->this_idx++;