[IPSEC]: Add AF_KEY interface for encapsulation family.
Signed-off-by: Miika Komu <miika@iki.fi> Signed-off-by: Diego Beltrami <Diego.Beltrami@hiit.fi> Signed-off-by: Kazunori Miyazawa <miyazawa@linux-ipv6.org>
This commit is contained in:
parent
8511d01d7c
commit
2718aa7c55
1 changed files with 25 additions and 15 deletions
|
@ -1767,11 +1767,11 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
|
||||||
|
|
||||||
/* addresses present only in tunnel mode */
|
/* addresses present only in tunnel mode */
|
||||||
if (t->mode == XFRM_MODE_TUNNEL) {
|
if (t->mode == XFRM_MODE_TUNNEL) {
|
||||||
switch (xp->family) {
|
struct sockaddr *sa;
|
||||||
|
sa = (struct sockaddr *)(rq+1);
|
||||||
|
switch(sa->sa_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
sin = (void*)(rq+1);
|
sin = (struct sockaddr_in*)sa;
|
||||||
if (sin->sin_family != AF_INET)
|
|
||||||
return -EINVAL;
|
|
||||||
t->saddr.a4 = sin->sin_addr.s_addr;
|
t->saddr.a4 = sin->sin_addr.s_addr;
|
||||||
sin++;
|
sin++;
|
||||||
if (sin->sin_family != AF_INET)
|
if (sin->sin_family != AF_INET)
|
||||||
|
@ -1780,9 +1780,7 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
|
||||||
break;
|
break;
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
sin6 = (void *)(rq+1);
|
sin6 = (struct sockaddr_in6*)sa;
|
||||||
if (sin6->sin6_family != AF_INET6)
|
|
||||||
return -EINVAL;
|
|
||||||
memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
|
memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
|
||||||
sin6++;
|
sin6++;
|
||||||
if (sin6->sin6_family != AF_INET6)
|
if (sin6->sin6_family != AF_INET6)
|
||||||
|
@ -1793,7 +1791,10 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
t->encap_family = sa->sa_family;
|
||||||
|
} else
|
||||||
|
t->encap_family = xp->family;
|
||||||
|
|
||||||
/* No way to set this via kame pfkey */
|
/* No way to set this via kame pfkey */
|
||||||
t->aalgos = t->ealgos = t->calgos = ~0;
|
t->aalgos = t->ealgos = t->calgos = ~0;
|
||||||
xp->xfrm_nr++;
|
xp->xfrm_nr++;
|
||||||
|
@ -1830,18 +1831,25 @@ static inline int pfkey_xfrm_policy2sec_ctx_size(struct xfrm_policy *xp)
|
||||||
|
|
||||||
static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
|
static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
|
||||||
{
|
{
|
||||||
|
struct xfrm_tmpl *t;
|
||||||
int sockaddr_size = pfkey_sockaddr_size(xp->family);
|
int sockaddr_size = pfkey_sockaddr_size(xp->family);
|
||||||
int socklen = (xp->family == AF_INET ?
|
int socklen = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i<xp->xfrm_nr; i++) {
|
||||||
|
t = xp->xfrm_vec + i;
|
||||||
|
socklen += (t->encap_family == AF_INET ?
|
||||||
sizeof(struct sockaddr_in) :
|
sizeof(struct sockaddr_in) :
|
||||||
sizeof(struct sockaddr_in6));
|
sizeof(struct sockaddr_in6));
|
||||||
|
}
|
||||||
|
|
||||||
return sizeof(struct sadb_msg) +
|
return sizeof(struct sadb_msg) +
|
||||||
(sizeof(struct sadb_lifetime) * 3) +
|
(sizeof(struct sadb_lifetime) * 3) +
|
||||||
(sizeof(struct sadb_address) * 2) +
|
(sizeof(struct sadb_address) * 2) +
|
||||||
(sockaddr_size * 2) +
|
(sockaddr_size * 2) +
|
||||||
sizeof(struct sadb_x_policy) +
|
sizeof(struct sadb_x_policy) +
|
||||||
(xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) +
|
(xp->xfrm_nr * sizeof(struct sadb_x_ipsecrequest)) +
|
||||||
(socklen * 2))) +
|
(socklen * 2) +
|
||||||
pfkey_xfrm_policy2sec_ctx_size(xp);
|
pfkey_xfrm_policy2sec_ctx_size(xp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1999,7 +2007,9 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
|
||||||
|
|
||||||
req_size = sizeof(struct sadb_x_ipsecrequest);
|
req_size = sizeof(struct sadb_x_ipsecrequest);
|
||||||
if (t->mode == XFRM_MODE_TUNNEL)
|
if (t->mode == XFRM_MODE_TUNNEL)
|
||||||
req_size += 2*socklen;
|
req_size += ((t->encap_family == AF_INET ?
|
||||||
|
sizeof(struct sockaddr_in) :
|
||||||
|
sizeof(struct sockaddr_in6)) * 2);
|
||||||
else
|
else
|
||||||
size -= 2*socklen;
|
size -= 2*socklen;
|
||||||
rq = (void*)skb_put(skb, req_size);
|
rq = (void*)skb_put(skb, req_size);
|
||||||
|
@ -2015,7 +2025,7 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
|
||||||
rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE;
|
rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE;
|
||||||
rq->sadb_x_ipsecrequest_reqid = t->reqid;
|
rq->sadb_x_ipsecrequest_reqid = t->reqid;
|
||||||
if (t->mode == XFRM_MODE_TUNNEL) {
|
if (t->mode == XFRM_MODE_TUNNEL) {
|
||||||
switch (xp->family) {
|
switch (t->encap_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
sin = (void*)(rq+1);
|
sin = (void*)(rq+1);
|
||||||
sin->sin_family = AF_INET;
|
sin->sin_family = AF_INET;
|
||||||
|
|
Loading…
Reference in a new issue