aboutsummaryrefslogtreecommitdiffstats
path: root/net/key/af_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/key/af_key.c')
-rw-r--r--net/key/af_key.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 4e1830999482..0e1dbfbb9b10 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1767,11 +1767,11 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1767 1767
1768 /* addresses present only in tunnel mode */ 1768 /* addresses present only in tunnel mode */
1769 if (t->mode == XFRM_MODE_TUNNEL) { 1769 if (t->mode == XFRM_MODE_TUNNEL) {
1770 switch (xp->family) { 1770 struct sockaddr *sa;
1771 sa = (struct sockaddr *)(rq+1);
1772 switch(sa->sa_family) {
1771 case AF_INET: 1773 case AF_INET:
1772 sin = (void*)(rq+1); 1774 sin = (struct sockaddr_in*)sa;
1773 if (sin->sin_family != AF_INET)
1774 return -EINVAL;
1775 t->saddr.a4 = sin->sin_addr.s_addr; 1775 t->saddr.a4 = sin->sin_addr.s_addr;
1776 sin++; 1776 sin++;
1777 if (sin->sin_family != AF_INET) 1777 if (sin->sin_family != AF_INET)
@@ -1780,9 +1780,7 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1780 break; 1780 break;
1781#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1781#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1782 case AF_INET6: 1782 case AF_INET6:
1783 sin6 = (void *)(rq+1); 1783 sin6 = (struct sockaddr_in6*)sa;
1784 if (sin6->sin6_family != AF_INET6)
1785 return -EINVAL;
1786 memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr)); 1784 memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
1787 sin6++; 1785 sin6++;
1788 if (sin6->sin6_family != AF_INET6) 1786 if (sin6->sin6_family != AF_INET6)
@@ -1793,7 +1791,10 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1793 default: 1791 default:
1794 return -EINVAL; 1792 return -EINVAL;
1795 } 1793 }
1796 } 1794 t->encap_family = sa->sa_family;
1795 } else
1796 t->encap_family = xp->family;
1797
1797 /* No way to set this via kame pfkey */ 1798 /* No way to set this via kame pfkey */
1798 t->aalgos = t->ealgos = t->calgos = ~0; 1799 t->aalgos = t->ealgos = t->calgos = ~0;
1799 xp->xfrm_nr++; 1800 xp->xfrm_nr++;
@@ -1830,18 +1831,25 @@ static inline int pfkey_xfrm_policy2sec_ctx_size(struct xfrm_policy *xp)
1830 1831
1831static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp) 1832static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
1832{ 1833{
1834 struct xfrm_tmpl *t;
1833 int sockaddr_size = pfkey_sockaddr_size(xp->family); 1835 int sockaddr_size = pfkey_sockaddr_size(xp->family);
1834 int socklen = (xp->family == AF_INET ? 1836 int socklen = 0;
1835 sizeof(struct sockaddr_in) : 1837 int i;
1836 sizeof(struct sockaddr_in6)); 1838
1839 for (i=0; i<xp->xfrm_nr; i++) {
1840 t = xp->xfrm_vec + i;
1841 socklen += (t->encap_family == AF_INET ?
1842 sizeof(struct sockaddr_in) :
1843 sizeof(struct sockaddr_in6));
1844 }
1837 1845
1838 return sizeof(struct sadb_msg) + 1846 return sizeof(struct sadb_msg) +
1839 (sizeof(struct sadb_lifetime) * 3) + 1847 (sizeof(struct sadb_lifetime) * 3) +
1840 (sizeof(struct sadb_address) * 2) + 1848 (sizeof(struct sadb_address) * 2) +
1841 (sockaddr_size * 2) + 1849 (sockaddr_size * 2) +
1842 sizeof(struct sadb_x_policy) + 1850 sizeof(struct sadb_x_policy) +
1843 (xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) + 1851 (xp->xfrm_nr * sizeof(struct sadb_x_ipsecrequest)) +
1844 (socklen * 2))) + 1852 (socklen * 2) +
1845 pfkey_xfrm_policy2sec_ctx_size(xp); 1853 pfkey_xfrm_policy2sec_ctx_size(xp);
1846} 1854}
1847 1855
@@ -1999,7 +2007,9 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
1999 2007
2000 req_size = sizeof(struct sadb_x_ipsecrequest); 2008 req_size = sizeof(struct sadb_x_ipsecrequest);
2001 if (t->mode == XFRM_MODE_TUNNEL) 2009 if (t->mode == XFRM_MODE_TUNNEL)
2002 req_size += 2*socklen; 2010 req_size += ((t->encap_family == AF_INET ?
2011 sizeof(struct sockaddr_in) :
2012 sizeof(struct sockaddr_in6)) * 2);
2003 else 2013 else
2004 size -= 2*socklen; 2014 size -= 2*socklen;
2005 rq = (void*)skb_put(skb, req_size); 2015 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 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE; 2025 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE;
2016 rq->sadb_x_ipsecrequest_reqid = t->reqid; 2026 rq->sadb_x_ipsecrequest_reqid = t->reqid;
2017 if (t->mode == XFRM_MODE_TUNNEL) { 2027 if (t->mode == XFRM_MODE_TUNNEL) {
2018 switch (xp->family) { 2028 switch (t->encap_family) {
2019 case AF_INET: 2029 case AF_INET:
2020 sin = (void*)(rq+1); 2030 sin = (void*)(rq+1);
2021 sin->sin_family = AF_INET; 2031 sin->sin_family = AF_INET;