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.c622
1 files changed, 168 insertions, 454 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 7470e367272..f0fc46c8038 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -579,25 +579,43 @@ static uint8_t pfkey_proto_from_xfrm(uint8_t proto)
579 return (proto ? proto : IPSEC_PROTO_ANY); 579 return (proto ? proto : IPSEC_PROTO_ANY);
580} 580}
581 581
582static int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, 582static inline int pfkey_sockaddr_len(sa_family_t family)
583 xfrm_address_t *xaddr)
584{ 583{
585 switch (((struct sockaddr*)(addr + 1))->sa_family) { 584 switch (family) {
585 case AF_INET:
586 return sizeof(struct sockaddr_in);
587#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
588 case AF_INET6:
589 return sizeof(struct sockaddr_in6);
590#endif
591 }
592 return 0;
593}
594
595static
596int pfkey_sockaddr_extract(const struct sockaddr *sa, xfrm_address_t *xaddr)
597{
598 switch (sa->sa_family) {
586 case AF_INET: 599 case AF_INET:
587 xaddr->a4 = 600 xaddr->a4 =
588 ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr; 601 ((struct sockaddr_in *)sa)->sin_addr.s_addr;
589 return AF_INET; 602 return AF_INET;
590#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 603#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
591 case AF_INET6: 604 case AF_INET6:
592 memcpy(xaddr->a6, 605 memcpy(xaddr->a6,
593 &((struct sockaddr_in6 *)(addr + 1))->sin6_addr, 606 &((struct sockaddr_in6 *)sa)->sin6_addr,
594 sizeof(struct in6_addr)); 607 sizeof(struct in6_addr));
595 return AF_INET6; 608 return AF_INET6;
596#endif 609#endif
597 default:
598 return 0;
599 } 610 }
600 /* NOTREACHED */ 611 return 0;
612}
613
614static
615int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, xfrm_address_t *xaddr)
616{
617 return pfkey_sockaddr_extract((struct sockaddr *)(addr + 1),
618 xaddr);
601} 619}
602 620
603static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs) 621static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs)
@@ -642,20 +660,11 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **
642} 660}
643 661
644#define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) 662#define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
663
645static int 664static int
646pfkey_sockaddr_size(sa_family_t family) 665pfkey_sockaddr_size(sa_family_t family)
647{ 666{
648 switch (family) { 667 return PFKEY_ALIGN8(pfkey_sockaddr_len(family));
649 case AF_INET:
650 return PFKEY_ALIGN8(sizeof(struct sockaddr_in));
651#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
652 case AF_INET6:
653 return PFKEY_ALIGN8(sizeof(struct sockaddr_in6));
654#endif
655 default:
656 return 0;
657 }
658 /* NOTREACHED */
659} 668}
660 669
661static inline int pfkey_mode_from_xfrm(int mode) 670static inline int pfkey_mode_from_xfrm(int mode)
@@ -687,6 +696,36 @@ static inline int pfkey_mode_to_xfrm(int mode)
687 } 696 }
688} 697}
689 698
699static unsigned int pfkey_sockaddr_fill(xfrm_address_t *xaddr, __be16 port,
700 struct sockaddr *sa,
701 unsigned short family)
702{
703 switch (family) {
704 case AF_INET:
705 {
706 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
707 sin->sin_family = AF_INET;
708 sin->sin_port = port;
709 sin->sin_addr.s_addr = xaddr->a4;
710 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
711 return 32;
712 }
713#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
714 case AF_INET6:
715 {
716 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
717 sin6->sin6_family = AF_INET6;
718 sin6->sin6_port = port;
719 sin6->sin6_flowinfo = 0;
720 ipv6_addr_copy(&sin6->sin6_addr, (struct in6_addr *)xaddr->a6);
721 sin6->sin6_scope_id = 0;
722 return 128;
723 }
724#endif
725 }
726 return 0;
727}
728
690static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x, 729static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
691 int add_keys, int hsc) 730 int add_keys, int hsc)
692{ 731{
@@ -697,13 +736,9 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
697 struct sadb_address *addr; 736 struct sadb_address *addr;
698 struct sadb_key *key; 737 struct sadb_key *key;
699 struct sadb_x_sa2 *sa2; 738 struct sadb_x_sa2 *sa2;
700 struct sockaddr_in *sin;
701 struct sadb_x_sec_ctx *sec_ctx; 739 struct sadb_x_sec_ctx *sec_ctx;
702 struct xfrm_sec_ctx *xfrm_ctx; 740 struct xfrm_sec_ctx *xfrm_ctx;
703 int ctx_size = 0; 741 int ctx_size = 0;
704#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
705 struct sockaddr_in6 *sin6;
706#endif
707 int size; 742 int size;
708 int auth_key_size = 0; 743 int auth_key_size = 0;
709 int encrypt_key_size = 0; 744 int encrypt_key_size = 0;
@@ -732,14 +767,7 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
732 } 767 }
733 768
734 /* identity & sensitivity */ 769 /* identity & sensitivity */
735 770 if (xfrm_addr_cmp(&x->sel.saddr, &x->props.saddr, x->props.family))
736 if ((x->props.family == AF_INET &&
737 x->sel.saddr.a4 != x->props.saddr.a4)
738#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
739 || (x->props.family == AF_INET6 &&
740 memcmp (x->sel.saddr.a6, x->props.saddr.a6, sizeof (struct in6_addr)))
741#endif
742 )
743 size += sizeof(struct sadb_address) + sockaddr_size; 771 size += sizeof(struct sadb_address) + sockaddr_size;
744 772
745 if (add_keys) { 773 if (add_keys) {
@@ -861,29 +889,12 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
861 protocol's number." - RFC2367 */ 889 protocol's number." - RFC2367 */
862 addr->sadb_address_proto = 0; 890 addr->sadb_address_proto = 0;
863 addr->sadb_address_reserved = 0; 891 addr->sadb_address_reserved = 0;
864 if (x->props.family == AF_INET) {
865 addr->sadb_address_prefixlen = 32;
866 892
867 sin = (struct sockaddr_in *) (addr + 1); 893 addr->sadb_address_prefixlen =
868 sin->sin_family = AF_INET; 894 pfkey_sockaddr_fill(&x->props.saddr, 0,
869 sin->sin_addr.s_addr = x->props.saddr.a4; 895 (struct sockaddr *) (addr + 1),
870 sin->sin_port = 0; 896 x->props.family);
871 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 897 if (!addr->sadb_address_prefixlen)
872 }
873#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
874 else if (x->props.family == AF_INET6) {
875 addr->sadb_address_prefixlen = 128;
876
877 sin6 = (struct sockaddr_in6 *) (addr + 1);
878 sin6->sin6_family = AF_INET6;
879 sin6->sin6_port = 0;
880 sin6->sin6_flowinfo = 0;
881 memcpy(&sin6->sin6_addr, x->props.saddr.a6,
882 sizeof(struct in6_addr));
883 sin6->sin6_scope_id = 0;
884 }
885#endif
886 else
887 BUG(); 898 BUG();
888 899
889 /* dst address */ 900 /* dst address */
@@ -894,70 +905,32 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
894 sizeof(uint64_t); 905 sizeof(uint64_t);
895 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 906 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
896 addr->sadb_address_proto = 0; 907 addr->sadb_address_proto = 0;
897 addr->sadb_address_prefixlen = 32; /* XXX */
898 addr->sadb_address_reserved = 0; 908 addr->sadb_address_reserved = 0;
899 if (x->props.family == AF_INET) {
900 sin = (struct sockaddr_in *) (addr + 1);
901 sin->sin_family = AF_INET;
902 sin->sin_addr.s_addr = x->id.daddr.a4;
903 sin->sin_port = 0;
904 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
905 909
906 if (x->sel.saddr.a4 != x->props.saddr.a4) { 910 addr->sadb_address_prefixlen =
907 addr = (struct sadb_address*) skb_put(skb, 911 pfkey_sockaddr_fill(&x->id.daddr, 0,
908 sizeof(struct sadb_address)+sockaddr_size); 912 (struct sockaddr *) (addr + 1),
909 addr->sadb_address_len = 913 x->props.family);
910 (sizeof(struct sadb_address)+sockaddr_size)/ 914 if (!addr->sadb_address_prefixlen)
911 sizeof(uint64_t); 915 BUG();
912 addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
913 addr->sadb_address_proto =
914 pfkey_proto_from_xfrm(x->sel.proto);
915 addr->sadb_address_prefixlen = x->sel.prefixlen_s;
916 addr->sadb_address_reserved = 0;
917
918 sin = (struct sockaddr_in *) (addr + 1);
919 sin->sin_family = AF_INET;
920 sin->sin_addr.s_addr = x->sel.saddr.a4;
921 sin->sin_port = x->sel.sport;
922 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
923 }
924 }
925#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
926 else if (x->props.family == AF_INET6) {
927 addr->sadb_address_prefixlen = 128;
928 916
929 sin6 = (struct sockaddr_in6 *) (addr + 1); 917 if (xfrm_addr_cmp(&x->sel.saddr, &x->props.saddr,
930 sin6->sin6_family = AF_INET6; 918 x->props.family)) {
931 sin6->sin6_port = 0; 919 addr = (struct sadb_address*) skb_put(skb,
932 sin6->sin6_flowinfo = 0; 920 sizeof(struct sadb_address)+sockaddr_size);
933 memcpy(&sin6->sin6_addr, x->id.daddr.a6, sizeof(struct in6_addr)); 921 addr->sadb_address_len =
934 sin6->sin6_scope_id = 0; 922 (sizeof(struct sadb_address)+sockaddr_size)/
923 sizeof(uint64_t);
924 addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
925 addr->sadb_address_proto =
926 pfkey_proto_from_xfrm(x->sel.proto);
927 addr->sadb_address_prefixlen = x->sel.prefixlen_s;
928 addr->sadb_address_reserved = 0;
935 929
936 if (memcmp (x->sel.saddr.a6, x->props.saddr.a6, 930 pfkey_sockaddr_fill(&x->sel.saddr, x->sel.sport,
937 sizeof(struct in6_addr))) { 931 (struct sockaddr *) (addr + 1),
938 addr = (struct sadb_address *) skb_put(skb, 932 x->props.family);
939 sizeof(struct sadb_address)+sockaddr_size);
940 addr->sadb_address_len =
941 (sizeof(struct sadb_address)+sockaddr_size)/
942 sizeof(uint64_t);
943 addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
944 addr->sadb_address_proto =
945 pfkey_proto_from_xfrm(x->sel.proto);
946 addr->sadb_address_prefixlen = x->sel.prefixlen_s;
947 addr->sadb_address_reserved = 0;
948
949 sin6 = (struct sockaddr_in6 *) (addr + 1);
950 sin6->sin6_family = AF_INET6;
951 sin6->sin6_port = x->sel.sport;
952 sin6->sin6_flowinfo = 0;
953 memcpy(&sin6->sin6_addr, x->sel.saddr.a6,
954 sizeof(struct in6_addr));
955 sin6->sin6_scope_id = 0;
956 }
957 } 933 }
958#endif
959 else
960 BUG();
961 934
962 /* auth key */ 935 /* auth key */
963 if (add_keys && auth_key_size) { 936 if (add_keys && auth_key_size) {
@@ -1853,10 +1826,6 @@ static int
1853parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) 1826parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1854{ 1827{
1855 struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; 1828 struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr;
1856 struct sockaddr_in *sin;
1857#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1858 struct sockaddr_in6 *sin6;
1859#endif
1860 int mode; 1829 int mode;
1861 1830
1862 if (xp->xfrm_nr >= XFRM_MAX_DEPTH) 1831 if (xp->xfrm_nr >= XFRM_MAX_DEPTH)
@@ -1881,31 +1850,19 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1881 1850
1882 /* addresses present only in tunnel mode */ 1851 /* addresses present only in tunnel mode */
1883 if (t->mode == XFRM_MODE_TUNNEL) { 1852 if (t->mode == XFRM_MODE_TUNNEL) {
1884 struct sockaddr *sa; 1853 u8 *sa = (u8 *) (rq + 1);
1885 sa = (struct sockaddr *)(rq+1); 1854 int family, socklen;
1886 switch(sa->sa_family) { 1855
1887 case AF_INET: 1856 family = pfkey_sockaddr_extract((struct sockaddr *)sa,
1888 sin = (struct sockaddr_in*)sa; 1857 &t->saddr);
1889 t->saddr.a4 = sin->sin_addr.s_addr; 1858 if (!family)
1890 sin++;
1891 if (sin->sin_family != AF_INET)
1892 return -EINVAL;
1893 t->id.daddr.a4 = sin->sin_addr.s_addr;
1894 break;
1895#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1896 case AF_INET6:
1897 sin6 = (struct sockaddr_in6*)sa;
1898 memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
1899 sin6++;
1900 if (sin6->sin6_family != AF_INET6)
1901 return -EINVAL;
1902 memcpy(t->id.daddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
1903 break;
1904#endif
1905 default:
1906 return -EINVAL; 1859 return -EINVAL;
1907 } 1860
1908 t->encap_family = sa->sa_family; 1861 socklen = pfkey_sockaddr_len(family);
1862 if (pfkey_sockaddr_extract((struct sockaddr *)(sa + socklen),
1863 &t->id.daddr) != family)
1864 return -EINVAL;
1865 t->encap_family = family;
1909 } else 1866 } else
1910 t->encap_family = xp->family; 1867 t->encap_family = xp->family;
1911 1868
@@ -1952,9 +1909,7 @@ static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
1952 1909
1953 for (i=0; i<xp->xfrm_nr; i++) { 1910 for (i=0; i<xp->xfrm_nr; i++) {
1954 t = xp->xfrm_vec + i; 1911 t = xp->xfrm_vec + i;
1955 socklen += (t->encap_family == AF_INET ? 1912 socklen += pfkey_sockaddr_len(t->encap_family);
1956 sizeof(struct sockaddr_in) :
1957 sizeof(struct sockaddr_in6));
1958 } 1913 }
1959 1914
1960 return sizeof(struct sadb_msg) + 1915 return sizeof(struct sadb_msg) +
@@ -1987,18 +1942,12 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
1987 struct sadb_address *addr; 1942 struct sadb_address *addr;
1988 struct sadb_lifetime *lifetime; 1943 struct sadb_lifetime *lifetime;
1989 struct sadb_x_policy *pol; 1944 struct sadb_x_policy *pol;
1990 struct sockaddr_in *sin;
1991 struct sadb_x_sec_ctx *sec_ctx; 1945 struct sadb_x_sec_ctx *sec_ctx;
1992 struct xfrm_sec_ctx *xfrm_ctx; 1946 struct xfrm_sec_ctx *xfrm_ctx;
1993#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1994 struct sockaddr_in6 *sin6;
1995#endif
1996 int i; 1947 int i;
1997 int size; 1948 int size;
1998 int sockaddr_size = pfkey_sockaddr_size(xp->family); 1949 int sockaddr_size = pfkey_sockaddr_size(xp->family);
1999 int socklen = (xp->family == AF_INET ? 1950 int socklen = pfkey_sockaddr_len(xp->family);
2000 sizeof(struct sockaddr_in) :
2001 sizeof(struct sockaddr_in6));
2002 1951
2003 size = pfkey_xfrm_policy2msg_size(xp); 1952 size = pfkey_xfrm_policy2msg_size(xp);
2004 1953
@@ -2016,26 +1965,10 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2016 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); 1965 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
2017 addr->sadb_address_prefixlen = xp->selector.prefixlen_s; 1966 addr->sadb_address_prefixlen = xp->selector.prefixlen_s;
2018 addr->sadb_address_reserved = 0; 1967 addr->sadb_address_reserved = 0;
2019 /* src address */ 1968 if (!pfkey_sockaddr_fill(&xp->selector.saddr,
2020 if (xp->family == AF_INET) { 1969 xp->selector.sport,
2021 sin = (struct sockaddr_in *) (addr + 1); 1970 (struct sockaddr *) (addr + 1),
2022 sin->sin_family = AF_INET; 1971 xp->family))
2023 sin->sin_addr.s_addr = xp->selector.saddr.a4;
2024 sin->sin_port = xp->selector.sport;
2025 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
2026 }
2027#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2028 else if (xp->family == AF_INET6) {
2029 sin6 = (struct sockaddr_in6 *) (addr + 1);
2030 sin6->sin6_family = AF_INET6;
2031 sin6->sin6_port = xp->selector.sport;
2032 sin6->sin6_flowinfo = 0;
2033 memcpy(&sin6->sin6_addr, xp->selector.saddr.a6,
2034 sizeof(struct in6_addr));
2035 sin6->sin6_scope_id = 0;
2036 }
2037#endif
2038 else
2039 BUG(); 1972 BUG();
2040 1973
2041 /* dst address */ 1974 /* dst address */
@@ -2048,26 +1981,10 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2048 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); 1981 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
2049 addr->sadb_address_prefixlen = xp->selector.prefixlen_d; 1982 addr->sadb_address_prefixlen = xp->selector.prefixlen_d;
2050 addr->sadb_address_reserved = 0; 1983 addr->sadb_address_reserved = 0;
2051 if (xp->family == AF_INET) { 1984
2052 sin = (struct sockaddr_in *) (addr + 1); 1985 pfkey_sockaddr_fill(&xp->selector.daddr, xp->selector.dport,
2053 sin->sin_family = AF_INET; 1986 (struct sockaddr *) (addr + 1),
2054 sin->sin_addr.s_addr = xp->selector.daddr.a4; 1987 xp->family);
2055 sin->sin_port = xp->selector.dport;
2056 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
2057 }
2058#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2059 else if (xp->family == AF_INET6) {
2060 sin6 = (struct sockaddr_in6 *) (addr + 1);
2061 sin6->sin6_family = AF_INET6;
2062 sin6->sin6_port = xp->selector.dport;
2063 sin6->sin6_flowinfo = 0;
2064 memcpy(&sin6->sin6_addr, xp->selector.daddr.a6,
2065 sizeof(struct in6_addr));
2066 sin6->sin6_scope_id = 0;
2067 }
2068#endif
2069 else
2070 BUG();
2071 1988
2072 /* hard time */ 1989 /* hard time */
2073 lifetime = (struct sadb_lifetime *) skb_put(skb, 1990 lifetime = (struct sadb_lifetime *) skb_put(skb,
@@ -2121,12 +2038,13 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2121 int mode; 2038 int mode;
2122 2039
2123 req_size = sizeof(struct sadb_x_ipsecrequest); 2040 req_size = sizeof(struct sadb_x_ipsecrequest);
2124 if (t->mode == XFRM_MODE_TUNNEL) 2041 if (t->mode == XFRM_MODE_TUNNEL) {
2125 req_size += ((t->encap_family == AF_INET ? 2042 socklen = pfkey_sockaddr_len(t->encap_family);
2126 sizeof(struct sockaddr_in) : 2043 req_size += socklen * 2;
2127 sizeof(struct sockaddr_in6)) * 2); 2044 } else {
2128 else
2129 size -= 2*socklen; 2045 size -= 2*socklen;
2046 socklen = 0;
2047 }
2130 rq = (void*)skb_put(skb, req_size); 2048 rq = (void*)skb_put(skb, req_size);
2131 pol->sadb_x_policy_len += req_size/8; 2049 pol->sadb_x_policy_len += req_size/8;
2132 memset(rq, 0, sizeof(*rq)); 2050 memset(rq, 0, sizeof(*rq));
@@ -2141,42 +2059,15 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2141 if (t->optional) 2059 if (t->optional)
2142 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE; 2060 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE;
2143 rq->sadb_x_ipsecrequest_reqid = t->reqid; 2061 rq->sadb_x_ipsecrequest_reqid = t->reqid;
2062
2144 if (t->mode == XFRM_MODE_TUNNEL) { 2063 if (t->mode == XFRM_MODE_TUNNEL) {
2145 switch (t->encap_family) { 2064 u8 *sa = (void *)(rq + 1);
2146 case AF_INET: 2065 pfkey_sockaddr_fill(&t->saddr, 0,
2147 sin = (void*)(rq+1); 2066 (struct sockaddr *)sa,
2148 sin->sin_family = AF_INET; 2067 t->encap_family);
2149 sin->sin_addr.s_addr = t->saddr.a4; 2068 pfkey_sockaddr_fill(&t->id.daddr, 0,
2150 sin->sin_port = 0; 2069 (struct sockaddr *) (sa + socklen),
2151 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 2070 t->encap_family);
2152 sin++;
2153 sin->sin_family = AF_INET;
2154 sin->sin_addr.s_addr = t->id.daddr.a4;
2155 sin->sin_port = 0;
2156 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
2157 break;
2158#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2159 case AF_INET6:
2160 sin6 = (void*)(rq+1);
2161 sin6->sin6_family = AF_INET6;
2162 sin6->sin6_port = 0;
2163 sin6->sin6_flowinfo = 0;
2164 memcpy(&sin6->sin6_addr, t->saddr.a6,
2165 sizeof(struct in6_addr));
2166 sin6->sin6_scope_id = 0;
2167
2168 sin6++;
2169 sin6->sin6_family = AF_INET6;
2170 sin6->sin6_port = 0;
2171 sin6->sin6_flowinfo = 0;
2172 memcpy(&sin6->sin6_addr, t->id.daddr.a6,
2173 sizeof(struct in6_addr));
2174 sin6->sin6_scope_id = 0;
2175 break;
2176#endif
2177 default:
2178 break;
2179 }
2180 } 2071 }
2181 } 2072 }
2182 2073
@@ -2459,61 +2350,31 @@ out:
2459#ifdef CONFIG_NET_KEY_MIGRATE 2350#ifdef CONFIG_NET_KEY_MIGRATE
2460static int pfkey_sockaddr_pair_size(sa_family_t family) 2351static int pfkey_sockaddr_pair_size(sa_family_t family)
2461{ 2352{
2462 switch (family) { 2353 return PFKEY_ALIGN8(pfkey_sockaddr_len(family) * 2);
2463 case AF_INET:
2464 return PFKEY_ALIGN8(sizeof(struct sockaddr_in) * 2);
2465#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2466 case AF_INET6:
2467 return PFKEY_ALIGN8(sizeof(struct sockaddr_in6) * 2);
2468#endif
2469 default:
2470 return 0;
2471 }
2472 /* NOTREACHED */
2473} 2354}
2474 2355
2475static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq, 2356static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq,
2476 xfrm_address_t *saddr, xfrm_address_t *daddr, 2357 xfrm_address_t *saddr, xfrm_address_t *daddr,
2477 u16 *family) 2358 u16 *family)
2478{ 2359{
2479 struct sockaddr *sa = (struct sockaddr *)(rq + 1); 2360 u8 *sa = (u8 *) (rq + 1);
2361 int af, socklen;
2362
2480 if (rq->sadb_x_ipsecrequest_len < 2363 if (rq->sadb_x_ipsecrequest_len <
2481 pfkey_sockaddr_pair_size(sa->sa_family)) 2364 pfkey_sockaddr_pair_size(((struct sockaddr *)sa)->sa_family))
2482 return -EINVAL; 2365 return -EINVAL;
2483 2366
2484 switch (sa->sa_family) { 2367 af = pfkey_sockaddr_extract((struct sockaddr *) sa,
2485 case AF_INET: 2368 saddr);
2486 { 2369 if (!af)
2487 struct sockaddr_in *sin;
2488 sin = (struct sockaddr_in *)sa;
2489 if ((sin+1)->sin_family != AF_INET)
2490 return -EINVAL;
2491 memcpy(&saddr->a4, &sin->sin_addr, sizeof(saddr->a4));
2492 sin++;
2493 memcpy(&daddr->a4, &sin->sin_addr, sizeof(daddr->a4));
2494 *family = AF_INET;
2495 break;
2496 }
2497#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2498 case AF_INET6:
2499 {
2500 struct sockaddr_in6 *sin6;
2501 sin6 = (struct sockaddr_in6 *)sa;
2502 if ((sin6+1)->sin6_family != AF_INET6)
2503 return -EINVAL;
2504 memcpy(&saddr->a6, &sin6->sin6_addr,
2505 sizeof(saddr->a6));
2506 sin6++;
2507 memcpy(&daddr->a6, &sin6->sin6_addr,
2508 sizeof(daddr->a6));
2509 *family = AF_INET6;
2510 break;
2511 }
2512#endif
2513 default:
2514 return -EINVAL; 2370 return -EINVAL;
2515 }
2516 2371
2372 socklen = pfkey_sockaddr_len(af);
2373 if (pfkey_sockaddr_extract((struct sockaddr *) (sa + socklen),
2374 daddr) != af)
2375 return -EINVAL;
2376
2377 *family = af;
2517 return 0; 2378 return 0;
2518} 2379}
2519 2380
@@ -3094,10 +2955,6 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
3094 struct sadb_msg *hdr; 2955 struct sadb_msg *hdr;
3095 struct sadb_address *addr; 2956 struct sadb_address *addr;
3096 struct sadb_x_policy *pol; 2957 struct sadb_x_policy *pol;
3097 struct sockaddr_in *sin;
3098#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3099 struct sockaddr_in6 *sin6;
3100#endif
3101 int sockaddr_size; 2958 int sockaddr_size;
3102 int size; 2959 int size;
3103 struct sadb_x_sec_ctx *sec_ctx; 2960 struct sadb_x_sec_ctx *sec_ctx;
@@ -3146,29 +3003,11 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
3146 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 3003 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
3147 addr->sadb_address_proto = 0; 3004 addr->sadb_address_proto = 0;
3148 addr->sadb_address_reserved = 0; 3005 addr->sadb_address_reserved = 0;
3149 if (x->props.family == AF_INET) { 3006 addr->sadb_address_prefixlen =
3150 addr->sadb_address_prefixlen = 32; 3007 pfkey_sockaddr_fill(&x->props.saddr, 0,
3151 3008 (struct sockaddr *) (addr + 1),
3152 sin = (struct sockaddr_in *) (addr + 1); 3009 x->props.family);
3153 sin->sin_family = AF_INET; 3010 if (!addr->sadb_address_prefixlen)
3154 sin->sin_addr.s_addr = x->props.saddr.a4;
3155 sin->sin_port = 0;
3156 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3157 }
3158#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3159 else if (x->props.family == AF_INET6) {
3160 addr->sadb_address_prefixlen = 128;
3161
3162 sin6 = (struct sockaddr_in6 *) (addr + 1);
3163 sin6->sin6_family = AF_INET6;
3164 sin6->sin6_port = 0;
3165 sin6->sin6_flowinfo = 0;
3166 memcpy(&sin6->sin6_addr,
3167 x->props.saddr.a6, sizeof(struct in6_addr));
3168 sin6->sin6_scope_id = 0;
3169 }
3170#endif
3171 else
3172 BUG(); 3011 BUG();
3173 3012
3174 /* dst address */ 3013 /* dst address */
@@ -3180,29 +3019,11 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
3180 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 3019 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
3181 addr->sadb_address_proto = 0; 3020 addr->sadb_address_proto = 0;
3182 addr->sadb_address_reserved = 0; 3021 addr->sadb_address_reserved = 0;
3183 if (x->props.family == AF_INET) { 3022 addr->sadb_address_prefixlen =
3184 addr->sadb_address_prefixlen = 32; 3023 pfkey_sockaddr_fill(&x->id.daddr, 0,
3185 3024 (struct sockaddr *) (addr + 1),
3186 sin = (struct sockaddr_in *) (addr + 1); 3025 x->props.family);
3187 sin->sin_family = AF_INET; 3026 if (!addr->sadb_address_prefixlen)
3188 sin->sin_addr.s_addr = x->id.daddr.a4;
3189 sin->sin_port = 0;
3190 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3191 }
3192#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3193 else if (x->props.family == AF_INET6) {
3194 addr->sadb_address_prefixlen = 128;
3195
3196 sin6 = (struct sockaddr_in6 *) (addr + 1);
3197 sin6->sin6_family = AF_INET6;
3198 sin6->sin6_port = 0;
3199 sin6->sin6_flowinfo = 0;
3200 memcpy(&sin6->sin6_addr,
3201 x->id.daddr.a6, sizeof(struct in6_addr));
3202 sin6->sin6_scope_id = 0;
3203 }
3204#endif
3205 else
3206 BUG(); 3027 BUG();
3207 3028
3208 pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy)); 3029 pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy));
@@ -3328,10 +3149,6 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
3328 struct sadb_sa *sa; 3149 struct sadb_sa *sa;
3329 struct sadb_address *addr; 3150 struct sadb_address *addr;
3330 struct sadb_x_nat_t_port *n_port; 3151 struct sadb_x_nat_t_port *n_port;
3331 struct sockaddr_in *sin;
3332#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3333 struct sockaddr_in6 *sin6;
3334#endif
3335 int sockaddr_size; 3152 int sockaddr_size;
3336 int size; 3153 int size;
3337 __u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0); 3154 __u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0);
@@ -3395,29 +3212,11 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
3395 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 3212 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
3396 addr->sadb_address_proto = 0; 3213 addr->sadb_address_proto = 0;
3397 addr->sadb_address_reserved = 0; 3214 addr->sadb_address_reserved = 0;
3398 if (x->props.family == AF_INET) { 3215 addr->sadb_address_prefixlen =
3399 addr->sadb_address_prefixlen = 32; 3216 pfkey_sockaddr_fill(&x->props.saddr, 0,
3400 3217 (struct sockaddr *) (addr + 1),
3401 sin = (struct sockaddr_in *) (addr + 1); 3218 x->props.family);
3402 sin->sin_family = AF_INET; 3219 if (!addr->sadb_address_prefixlen)
3403 sin->sin_addr.s_addr = x->props.saddr.a4;
3404 sin->sin_port = 0;
3405 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3406 }
3407#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3408 else if (x->props.family == AF_INET6) {
3409 addr->sadb_address_prefixlen = 128;
3410
3411 sin6 = (struct sockaddr_in6 *) (addr + 1);
3412 sin6->sin6_family = AF_INET6;
3413 sin6->sin6_port = 0;
3414 sin6->sin6_flowinfo = 0;
3415 memcpy(&sin6->sin6_addr,
3416 x->props.saddr.a6, sizeof(struct in6_addr));
3417 sin6->sin6_scope_id = 0;
3418 }
3419#endif
3420 else
3421 BUG(); 3220 BUG();
3422 3221
3423 /* NAT_T_SPORT (old port) */ 3222 /* NAT_T_SPORT (old port) */
@@ -3436,28 +3235,11 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
3436 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 3235 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
3437 addr->sadb_address_proto = 0; 3236 addr->sadb_address_proto = 0;
3438 addr->sadb_address_reserved = 0; 3237 addr->sadb_address_reserved = 0;
3439 if (x->props.family == AF_INET) { 3238 addr->sadb_address_prefixlen =
3440 addr->sadb_address_prefixlen = 32; 3239 pfkey_sockaddr_fill(ipaddr, 0,
3441 3240 (struct sockaddr *) (addr + 1),
3442 sin = (struct sockaddr_in *) (addr + 1); 3241 x->props.family);
3443 sin->sin_family = AF_INET; 3242 if (!addr->sadb_address_prefixlen)
3444 sin->sin_addr.s_addr = ipaddr->a4;
3445 sin->sin_port = 0;
3446 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3447 }
3448#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3449 else if (x->props.family == AF_INET6) {
3450 addr->sadb_address_prefixlen = 128;
3451
3452 sin6 = (struct sockaddr_in6 *) (addr + 1);
3453 sin6->sin6_family = AF_INET6;
3454 sin6->sin6_port = 0;
3455 sin6->sin6_flowinfo = 0;
3456 memcpy(&sin6->sin6_addr, &ipaddr->a6, sizeof(struct in6_addr));
3457 sin6->sin6_scope_id = 0;
3458 }
3459#endif
3460 else
3461 BUG(); 3243 BUG();
3462 3244
3463 /* NAT_T_DPORT (new port) */ 3245 /* NAT_T_DPORT (new port) */
@@ -3475,10 +3257,6 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,
3475 struct xfrm_selector *sel) 3257 struct xfrm_selector *sel)
3476{ 3258{
3477 struct sadb_address *addr; 3259 struct sadb_address *addr;
3478 struct sockaddr_in *sin;
3479#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3480 struct sockaddr_in6 *sin6;
3481#endif
3482 addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize); 3260 addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize);
3483 addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8; 3261 addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8;
3484 addr->sadb_address_exttype = type; 3262 addr->sadb_address_exttype = type;
@@ -3487,50 +3265,16 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,
3487 3265
3488 switch (type) { 3266 switch (type) {
3489 case SADB_EXT_ADDRESS_SRC: 3267 case SADB_EXT_ADDRESS_SRC:
3490 if (sel->family == AF_INET) { 3268 addr->sadb_address_prefixlen = sel->prefixlen_s;
3491 addr->sadb_address_prefixlen = sel->prefixlen_s; 3269 pfkey_sockaddr_fill(&sel->saddr, 0,
3492 sin = (struct sockaddr_in *)(addr + 1); 3270 (struct sockaddr *)(addr + 1),
3493 sin->sin_family = AF_INET; 3271 sel->family);
3494 memcpy(&sin->sin_addr.s_addr, &sel->saddr,
3495 sizeof(sin->sin_addr.s_addr));
3496 sin->sin_port = 0;
3497 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3498 }
3499#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3500 else if (sel->family == AF_INET6) {
3501 addr->sadb_address_prefixlen = sel->prefixlen_s;
3502 sin6 = (struct sockaddr_in6 *)(addr + 1);
3503 sin6->sin6_family = AF_INET6;
3504 sin6->sin6_port = 0;
3505 sin6->sin6_flowinfo = 0;
3506 sin6->sin6_scope_id = 0;
3507 memcpy(&sin6->sin6_addr.s6_addr, &sel->saddr,
3508 sizeof(sin6->sin6_addr.s6_addr));
3509 }
3510#endif
3511 break; 3272 break;
3512 case SADB_EXT_ADDRESS_DST: 3273 case SADB_EXT_ADDRESS_DST:
3513 if (sel->family == AF_INET) { 3274 addr->sadb_address_prefixlen = sel->prefixlen_d;
3514 addr->sadb_address_prefixlen = sel->prefixlen_d; 3275 pfkey_sockaddr_fill(&sel->daddr, 0,
3515 sin = (struct sockaddr_in *)(addr + 1); 3276 (struct sockaddr *)(addr + 1),
3516 sin->sin_family = AF_INET; 3277 sel->family);
3517 memcpy(&sin->sin_addr.s_addr, &sel->daddr,
3518 sizeof(sin->sin_addr.s_addr));
3519 sin->sin_port = 0;
3520 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3521 }
3522#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3523 else if (sel->family == AF_INET6) {
3524 addr->sadb_address_prefixlen = sel->prefixlen_d;
3525 sin6 = (struct sockaddr_in6 *)(addr + 1);
3526 sin6->sin6_family = AF_INET6;
3527 sin6->sin6_port = 0;
3528 sin6->sin6_flowinfo = 0;
3529 sin6->sin6_scope_id = 0;
3530 memcpy(&sin6->sin6_addr.s6_addr, &sel->daddr,
3531 sizeof(sin6->sin6_addr.s6_addr));
3532 }
3533#endif
3534 break; 3278 break;
3535 default: 3279 default:
3536 return -EINVAL; 3280 return -EINVAL;
@@ -3545,10 +3289,8 @@ static int set_ipsecrequest(struct sk_buff *skb,
3545 xfrm_address_t *src, xfrm_address_t *dst) 3289 xfrm_address_t *src, xfrm_address_t *dst)
3546{ 3290{
3547 struct sadb_x_ipsecrequest *rq; 3291 struct sadb_x_ipsecrequest *rq;
3548 struct sockaddr_in *sin; 3292 u8 *sa;
3549#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3293 int socklen = pfkey_sockaddr_len(family);
3550 struct sockaddr_in6 *sin6;
3551#endif
3552 int size_req; 3294 int size_req;
3553 3295
3554 size_req = sizeof(struct sadb_x_ipsecrequest) + 3296 size_req = sizeof(struct sadb_x_ipsecrequest) +
@@ -3562,38 +3304,10 @@ static int set_ipsecrequest(struct sk_buff *skb,
3562 rq->sadb_x_ipsecrequest_level = level; 3304 rq->sadb_x_ipsecrequest_level = level;
3563 rq->sadb_x_ipsecrequest_reqid = reqid; 3305 rq->sadb_x_ipsecrequest_reqid = reqid;
3564 3306
3565 switch (family) { 3307 sa = (u8 *) (rq + 1);
3566 case AF_INET: 3308 if (!pfkey_sockaddr_fill(src, 0, (struct sockaddr *)sa, family) ||
3567 sin = (struct sockaddr_in *)(rq + 1); 3309 !pfkey_sockaddr_fill(dst, 0, (struct sockaddr *)(sa + socklen), family))
3568 sin->sin_family = AF_INET;
3569 memcpy(&sin->sin_addr.s_addr, src,
3570 sizeof(sin->sin_addr.s_addr));
3571 sin++;
3572 sin->sin_family = AF_INET;
3573 memcpy(&sin->sin_addr.s_addr, dst,
3574 sizeof(sin->sin_addr.s_addr));
3575 break;
3576#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3577 case AF_INET6:
3578 sin6 = (struct sockaddr_in6 *)(rq + 1);
3579 sin6->sin6_family = AF_INET6;
3580 sin6->sin6_port = 0;
3581 sin6->sin6_flowinfo = 0;
3582 sin6->sin6_scope_id = 0;
3583 memcpy(&sin6->sin6_addr.s6_addr, src,
3584 sizeof(sin6->sin6_addr.s6_addr));
3585 sin6++;
3586 sin6->sin6_family = AF_INET6;
3587 sin6->sin6_port = 0;
3588 sin6->sin6_flowinfo = 0;
3589 sin6->sin6_scope_id = 0;
3590 memcpy(&sin6->sin6_addr.s6_addr, dst,
3591 sizeof(sin6->sin6_addr.s6_addr));
3592 break;
3593#endif
3594 default:
3595 return -EINVAL; 3310 return -EINVAL;
3596 }
3597 3311
3598 return 0; 3312 return 0;
3599} 3313}