Commit 2718aa7c authored by Miika Komu's avatar Miika Komu Committed by David S. Miller

[IPSEC]: Add AF_KEY interface for encapsulation family.

Signed-off-by: default avatarMiika Komu <miika@iki.fi>
Signed-off-by: default avatarDiego Beltrami <Diego.Beltrami@hiit.fi>
Signed-off-by: default avatarKazunori Miyazawa <miyazawa@linux-ipv6.org>
parent 8511d01d
...@@ -1767,11 +1767,11 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
sizeof(struct sockaddr_in) : int i;
sizeof(struct sockaddr_in6));
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_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 ...@@ -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 ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment