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

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

[IPSEC]: Add AF_KEY interface for encapsulation family.

parent 8511d01d
Loading
Loading
Loading
Loading
+25 −15
Original line number Diff line number Diff line
@@ -1767,11 +1767,11 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)

	/* addresses present only in tunnel mode */
	if (t->mode == XFRM_MODE_TUNNEL) {
		switch (xp->family) {
		struct sockaddr *sa;
		sa = (struct sockaddr *)(rq+1);
		switch(sa->sa_family) {
		case AF_INET:
			sin = (void*)(rq+1);
			if (sin->sin_family != AF_INET)
				return -EINVAL;
			sin = (struct sockaddr_in*)sa;
			t->saddr.a4 = sin->sin_addr.s_addr;
			sin++;
			if (sin->sin_family != AF_INET)
@@ -1780,9 +1780,7 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
			break;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
		case AF_INET6:
			sin6 = (void *)(rq+1);
			if (sin6->sin6_family != AF_INET6)
				return -EINVAL;
			sin6 = (struct sockaddr_in6*)sa;
			memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
			sin6++;
			if (sin6->sin6_family != AF_INET6)
@@ -1793,7 +1791,10 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
		default:
			return -EINVAL;
		}
	}
		t->encap_family = sa->sa_family;
	} else
		t->encap_family = xp->family;

	/* No way to set this via kame pfkey */
	t->aalgos = t->ealgos = t->calgos = ~0;
	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)
{
	struct xfrm_tmpl *t;
	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_in6));
	}

	return sizeof(struct sadb_msg) +
		(sizeof(struct sadb_lifetime) * 3) +
		(sizeof(struct sadb_address) * 2) + 
		(sockaddr_size * 2) +
		sizeof(struct sadb_x_policy) +
		(xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) +
				(socklen * 2))) +
		(xp->xfrm_nr * sizeof(struct sadb_x_ipsecrequest)) +
		(socklen * 2) +
		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);
		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
			size -= 2*socklen;
		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_reqid = t->reqid;
		if (t->mode == XFRM_MODE_TUNNEL) {
			switch (xp->family) {
			switch (t->encap_family) {
			case AF_INET:
				sin = (void*)(rq+1);
				sin->sin_family = AF_INET;