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.c458
1 files changed, 111 insertions, 347 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 02c8aba4239e..2b05cb6c15c6 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -691,6 +691,36 @@ static inline int pfkey_mode_to_xfrm(int mode)
691 } 691 }
692} 692}
693 693
694static unsigned int pfkey_sockaddr_fill(xfrm_address_t *xaddr, __be16 port,
695 struct sockaddr *sa,
696 unsigned short family)
697{
698 switch (family) {
699 case AF_INET:
700 {
701 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
702 sin->sin_family = AF_INET;
703 sin->sin_port = port;
704 sin->sin_addr.s_addr = xaddr->a4;
705 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
706 return 32;
707 }
708#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
709 case AF_INET6:
710 {
711 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
712 sin6->sin6_family = AF_INET6;
713 sin6->sin6_port = port;
714 sin6->sin6_flowinfo = 0;
715 ipv6_addr_copy(&sin6->sin6_addr, (struct in6_addr *)xaddr->a6);
716 sin6->sin6_scope_id = 0;
717 return 128;
718 }
719#endif
720 }
721 return 0;
722}
723
694static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x, 724static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
695 int add_keys, int hsc) 725 int add_keys, int hsc)
696{ 726{
@@ -701,13 +731,9 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
701 struct sadb_address *addr; 731 struct sadb_address *addr;
702 struct sadb_key *key; 732 struct sadb_key *key;
703 struct sadb_x_sa2 *sa2; 733 struct sadb_x_sa2 *sa2;
704 struct sockaddr_in *sin;
705 struct sadb_x_sec_ctx *sec_ctx; 734 struct sadb_x_sec_ctx *sec_ctx;
706 struct xfrm_sec_ctx *xfrm_ctx; 735 struct xfrm_sec_ctx *xfrm_ctx;
707 int ctx_size = 0; 736 int ctx_size = 0;
708#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
709 struct sockaddr_in6 *sin6;
710#endif
711 int size; 737 int size;
712 int auth_key_size = 0; 738 int auth_key_size = 0;
713 int encrypt_key_size = 0; 739 int encrypt_key_size = 0;
@@ -865,29 +891,12 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
865 protocol's number." - RFC2367 */ 891 protocol's number." - RFC2367 */
866 addr->sadb_address_proto = 0; 892 addr->sadb_address_proto = 0;
867 addr->sadb_address_reserved = 0; 893 addr->sadb_address_reserved = 0;
868 if (x->props.family == AF_INET) {
869 addr->sadb_address_prefixlen = 32;
870 894
871 sin = (struct sockaddr_in *) (addr + 1); 895 addr->sadb_address_prefixlen =
872 sin->sin_family = AF_INET; 896 pfkey_sockaddr_fill(&x->props.saddr, 0,
873 sin->sin_addr.s_addr = x->props.saddr.a4; 897 (struct sockaddr *) (addr + 1),
874 sin->sin_port = 0; 898 x->props.family);
875 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 899 if (!addr->sadb_address_prefixlen)
876 }
877#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
878 else if (x->props.family == AF_INET6) {
879 addr->sadb_address_prefixlen = 128;
880
881 sin6 = (struct sockaddr_in6 *) (addr + 1);
882 sin6->sin6_family = AF_INET6;
883 sin6->sin6_port = 0;
884 sin6->sin6_flowinfo = 0;
885 memcpy(&sin6->sin6_addr, x->props.saddr.a6,
886 sizeof(struct in6_addr));
887 sin6->sin6_scope_id = 0;
888 }
889#endif
890 else
891 BUG(); 900 BUG();
892 901
893 /* dst address */ 902 /* dst address */
@@ -898,70 +907,32 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
898 sizeof(uint64_t); 907 sizeof(uint64_t);
899 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 908 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
900 addr->sadb_address_proto = 0; 909 addr->sadb_address_proto = 0;
901 addr->sadb_address_prefixlen = 32; /* XXX */
902 addr->sadb_address_reserved = 0; 910 addr->sadb_address_reserved = 0;
903 if (x->props.family == AF_INET) {
904 sin = (struct sockaddr_in *) (addr + 1);
905 sin->sin_family = AF_INET;
906 sin->sin_addr.s_addr = x->id.daddr.a4;
907 sin->sin_port = 0;
908 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
909 911
910 if (x->sel.saddr.a4 != x->props.saddr.a4) { 912 addr->sadb_address_prefixlen =
911 addr = (struct sadb_address*) skb_put(skb, 913 pfkey_sockaddr_fill(&x->id.daddr, 0,
912 sizeof(struct sadb_address)+sockaddr_size); 914 (struct sockaddr *) (addr + 1),
913 addr->sadb_address_len = 915 x->props.family);
914 (sizeof(struct sadb_address)+sockaddr_size)/ 916 if (!addr->sadb_address_prefixlen)
915 sizeof(uint64_t); 917 BUG();
916 addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
917 addr->sadb_address_proto =
918 pfkey_proto_from_xfrm(x->sel.proto);
919 addr->sadb_address_prefixlen = x->sel.prefixlen_s;
920 addr->sadb_address_reserved = 0;
921
922 sin = (struct sockaddr_in *) (addr + 1);
923 sin->sin_family = AF_INET;
924 sin->sin_addr.s_addr = x->sel.saddr.a4;
925 sin->sin_port = x->sel.sport;
926 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
927 }
928 }
929#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
930 else if (x->props.family == AF_INET6) {
931 addr->sadb_address_prefixlen = 128;
932 918
933 sin6 = (struct sockaddr_in6 *) (addr + 1); 919 if (xfrm_addr_cmp(&x->sel.saddr, &x->props.saddr,
934 sin6->sin6_family = AF_INET6; 920 x->props.family)) {
935 sin6->sin6_port = 0; 921 addr = (struct sadb_address*) skb_put(skb,
936 sin6->sin6_flowinfo = 0; 922 sizeof(struct sadb_address)+sockaddr_size);
937 memcpy(&sin6->sin6_addr, x->id.daddr.a6, sizeof(struct in6_addr)); 923 addr->sadb_address_len =
938 sin6->sin6_scope_id = 0; 924 (sizeof(struct sadb_address)+sockaddr_size)/
925 sizeof(uint64_t);
926 addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
927 addr->sadb_address_proto =
928 pfkey_proto_from_xfrm(x->sel.proto);
929 addr->sadb_address_prefixlen = x->sel.prefixlen_s;
930 addr->sadb_address_reserved = 0;
939 931
940 if (memcmp (x->sel.saddr.a6, x->props.saddr.a6, 932 pfkey_sockaddr_fill(&x->sel.saddr, x->sel.sport,
941 sizeof(struct in6_addr))) { 933 (struct sockaddr *) (addr + 1),
942 addr = (struct sadb_address *) skb_put(skb, 934 x->props.family);
943 sizeof(struct sadb_address)+sockaddr_size);
944 addr->sadb_address_len =
945 (sizeof(struct sadb_address)+sockaddr_size)/
946 sizeof(uint64_t);
947 addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
948 addr->sadb_address_proto =
949 pfkey_proto_from_xfrm(x->sel.proto);
950 addr->sadb_address_prefixlen = x->sel.prefixlen_s;
951 addr->sadb_address_reserved = 0;
952
953 sin6 = (struct sockaddr_in6 *) (addr + 1);
954 sin6->sin6_family = AF_INET6;
955 sin6->sin6_port = x->sel.sport;
956 sin6->sin6_flowinfo = 0;
957 memcpy(&sin6->sin6_addr, x->sel.saddr.a6,
958 sizeof(struct in6_addr));
959 sin6->sin6_scope_id = 0;
960 }
961 } 935 }
962#endif
963 else
964 BUG();
965 936
966 /* auth key */ 937 /* auth key */
967 if (add_keys && auth_key_size) { 938 if (add_keys && auth_key_size) {
@@ -1989,12 +1960,8 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
1989 struct sadb_address *addr; 1960 struct sadb_address *addr;
1990 struct sadb_lifetime *lifetime; 1961 struct sadb_lifetime *lifetime;
1991 struct sadb_x_policy *pol; 1962 struct sadb_x_policy *pol;
1992 struct sockaddr_in *sin;
1993 struct sadb_x_sec_ctx *sec_ctx; 1963 struct sadb_x_sec_ctx *sec_ctx;
1994 struct xfrm_sec_ctx *xfrm_ctx; 1964 struct xfrm_sec_ctx *xfrm_ctx;
1995#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1996 struct sockaddr_in6 *sin6;
1997#endif
1998 int i; 1965 int i;
1999 int size; 1966 int size;
2000 int sockaddr_size = pfkey_sockaddr_size(xp->family); 1967 int sockaddr_size = pfkey_sockaddr_size(xp->family);
@@ -2016,26 +1983,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); 1983 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
2017 addr->sadb_address_prefixlen = xp->selector.prefixlen_s; 1984 addr->sadb_address_prefixlen = xp->selector.prefixlen_s;
2018 addr->sadb_address_reserved = 0; 1985 addr->sadb_address_reserved = 0;
2019 /* src address */ 1986 if (!pfkey_sockaddr_fill(&xp->selector.saddr,
2020 if (xp->family == AF_INET) { 1987 xp->selector.sport,
2021 sin = (struct sockaddr_in *) (addr + 1); 1988 (struct sockaddr *) (addr + 1),
2022 sin->sin_family = AF_INET; 1989 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(); 1990 BUG();
2040 1991
2041 /* dst address */ 1992 /* dst address */
@@ -2048,26 +1999,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); 1999 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
2049 addr->sadb_address_prefixlen = xp->selector.prefixlen_d; 2000 addr->sadb_address_prefixlen = xp->selector.prefixlen_d;
2050 addr->sadb_address_reserved = 0; 2001 addr->sadb_address_reserved = 0;
2051 if (xp->family == AF_INET) { 2002
2052 sin = (struct sockaddr_in *) (addr + 1); 2003 pfkey_sockaddr_fill(&xp->selector.daddr, xp->selector.dport,
2053 sin->sin_family = AF_INET; 2004 (struct sockaddr *) (addr + 1),
2054 sin->sin_addr.s_addr = xp->selector.daddr.a4; 2005 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 2006
2072 /* hard time */ 2007 /* hard time */
2073 lifetime = (struct sadb_lifetime *) skb_put(skb, 2008 lifetime = (struct sadb_lifetime *) skb_put(skb,
@@ -2121,10 +2056,13 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2121 int mode; 2056 int mode;
2122 2057
2123 req_size = sizeof(struct sadb_x_ipsecrequest); 2058 req_size = sizeof(struct sadb_x_ipsecrequest);
2124 if (t->mode == XFRM_MODE_TUNNEL) 2059 if (t->mode == XFRM_MODE_TUNNEL) {
2125 req_size += pfkey_sockaddr_len(t->encap_family) * 2; 2060 socklen = pfkey_sockaddr_len(t->encap_family);
2126 else 2061 req_size += socklen * 2;
2062 } else {
2127 size -= 2*socklen; 2063 size -= 2*socklen;
2064 socklen = 0;
2065 }
2128 rq = (void*)skb_put(skb, req_size); 2066 rq = (void*)skb_put(skb, req_size);
2129 pol->sadb_x_policy_len += req_size/8; 2067 pol->sadb_x_policy_len += req_size/8;
2130 memset(rq, 0, sizeof(*rq)); 2068 memset(rq, 0, sizeof(*rq));
@@ -2139,42 +2077,15 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2139 if (t->optional) 2077 if (t->optional)
2140 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE; 2078 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE;
2141 rq->sadb_x_ipsecrequest_reqid = t->reqid; 2079 rq->sadb_x_ipsecrequest_reqid = t->reqid;
2080
2142 if (t->mode == XFRM_MODE_TUNNEL) { 2081 if (t->mode == XFRM_MODE_TUNNEL) {
2143 switch (t->encap_family) { 2082 u8 *sa = (void *)(rq + 1);
2144 case AF_INET: 2083 pfkey_sockaddr_fill(&t->saddr, 0,
2145 sin = (void*)(rq+1); 2084 (struct sockaddr *)sa,
2146 sin->sin_family = AF_INET; 2085 t->encap_family);
2147 sin->sin_addr.s_addr = t->saddr.a4; 2086 pfkey_sockaddr_fill(&t->id.daddr, 0,
2148 sin->sin_port = 0; 2087 (struct sockaddr *) (sa + socklen),
2149 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 2088 t->encap_family);
2150 sin++;
2151 sin->sin_family = AF_INET;
2152 sin->sin_addr.s_addr = t->id.daddr.a4;
2153 sin->sin_port = 0;
2154 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
2155 break;
2156#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2157 case AF_INET6:
2158 sin6 = (void*)(rq+1);
2159 sin6->sin6_family = AF_INET6;
2160 sin6->sin6_port = 0;
2161 sin6->sin6_flowinfo = 0;
2162 memcpy(&sin6->sin6_addr, t->saddr.a6,
2163 sizeof(struct in6_addr));
2164 sin6->sin6_scope_id = 0;
2165
2166 sin6++;
2167 sin6->sin6_family = AF_INET6;
2168 sin6->sin6_port = 0;
2169 sin6->sin6_flowinfo = 0;
2170 memcpy(&sin6->sin6_addr, t->id.daddr.a6,
2171 sizeof(struct in6_addr));
2172 sin6->sin6_scope_id = 0;
2173 break;
2174#endif
2175 default:
2176 break;
2177 }
2178 } 2089 }
2179 } 2090 }
2180 2091
@@ -3079,10 +2990,6 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
3079 struct sadb_msg *hdr; 2990 struct sadb_msg *hdr;
3080 struct sadb_address *addr; 2991 struct sadb_address *addr;
3081 struct sadb_x_policy *pol; 2992 struct sadb_x_policy *pol;
3082 struct sockaddr_in *sin;
3083#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3084 struct sockaddr_in6 *sin6;
3085#endif
3086 int sockaddr_size; 2993 int sockaddr_size;
3087 int size; 2994 int size;
3088 struct sadb_x_sec_ctx *sec_ctx; 2995 struct sadb_x_sec_ctx *sec_ctx;
@@ -3131,29 +3038,11 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
3131 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 3038 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
3132 addr->sadb_address_proto = 0; 3039 addr->sadb_address_proto = 0;
3133 addr->sadb_address_reserved = 0; 3040 addr->sadb_address_reserved = 0;
3134 if (x->props.family == AF_INET) { 3041 addr->sadb_address_prefixlen =
3135 addr->sadb_address_prefixlen = 32; 3042 pfkey_sockaddr_fill(&x->props.saddr, 0,
3136 3043 (struct sockaddr *) (addr + 1),
3137 sin = (struct sockaddr_in *) (addr + 1); 3044 x->props.family);
3138 sin->sin_family = AF_INET; 3045 if (!addr->sadb_address_prefixlen)
3139 sin->sin_addr.s_addr = x->props.saddr.a4;
3140 sin->sin_port = 0;
3141 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3142 }
3143#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3144 else if (x->props.family == AF_INET6) {
3145 addr->sadb_address_prefixlen = 128;
3146
3147 sin6 = (struct sockaddr_in6 *) (addr + 1);
3148 sin6->sin6_family = AF_INET6;
3149 sin6->sin6_port = 0;
3150 sin6->sin6_flowinfo = 0;
3151 memcpy(&sin6->sin6_addr,
3152 x->props.saddr.a6, sizeof(struct in6_addr));
3153 sin6->sin6_scope_id = 0;
3154 }
3155#endif
3156 else
3157 BUG(); 3046 BUG();
3158 3047
3159 /* dst address */ 3048 /* dst address */
@@ -3165,29 +3054,11 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
3165 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 3054 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
3166 addr->sadb_address_proto = 0; 3055 addr->sadb_address_proto = 0;
3167 addr->sadb_address_reserved = 0; 3056 addr->sadb_address_reserved = 0;
3168 if (x->props.family == AF_INET) { 3057 addr->sadb_address_prefixlen =
3169 addr->sadb_address_prefixlen = 32; 3058 pfkey_sockaddr_fill(&x->id.daddr, 0,
3170 3059 (struct sockaddr *) (addr + 1),
3171 sin = (struct sockaddr_in *) (addr + 1); 3060 x->props.family);
3172 sin->sin_family = AF_INET; 3061 if (!addr->sadb_address_prefixlen)
3173 sin->sin_addr.s_addr = x->id.daddr.a4;
3174 sin->sin_port = 0;
3175 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3176 }
3177#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3178 else if (x->props.family == AF_INET6) {
3179 addr->sadb_address_prefixlen = 128;
3180
3181 sin6 = (struct sockaddr_in6 *) (addr + 1);
3182 sin6->sin6_family = AF_INET6;
3183 sin6->sin6_port = 0;
3184 sin6->sin6_flowinfo = 0;
3185 memcpy(&sin6->sin6_addr,
3186 x->id.daddr.a6, sizeof(struct in6_addr));
3187 sin6->sin6_scope_id = 0;
3188 }
3189#endif
3190 else
3191 BUG(); 3062 BUG();
3192 3063
3193 pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy)); 3064 pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy));
@@ -3313,10 +3184,6 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
3313 struct sadb_sa *sa; 3184 struct sadb_sa *sa;
3314 struct sadb_address *addr; 3185 struct sadb_address *addr;
3315 struct sadb_x_nat_t_port *n_port; 3186 struct sadb_x_nat_t_port *n_port;
3316 struct sockaddr_in *sin;
3317#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3318 struct sockaddr_in6 *sin6;
3319#endif
3320 int sockaddr_size; 3187 int sockaddr_size;
3321 int size; 3188 int size;
3322 __u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0); 3189 __u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0);
@@ -3380,29 +3247,11 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
3380 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 3247 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
3381 addr->sadb_address_proto = 0; 3248 addr->sadb_address_proto = 0;
3382 addr->sadb_address_reserved = 0; 3249 addr->sadb_address_reserved = 0;
3383 if (x->props.family == AF_INET) { 3250 addr->sadb_address_prefixlen =
3384 addr->sadb_address_prefixlen = 32; 3251 pfkey_sockaddr_fill(&x->props.saddr, 0,
3385 3252 (struct sockaddr *) (addr + 1),
3386 sin = (struct sockaddr_in *) (addr + 1); 3253 x->props.family);
3387 sin->sin_family = AF_INET; 3254 if (!addr->sadb_address_prefixlen)
3388 sin->sin_addr.s_addr = x->props.saddr.a4;
3389 sin->sin_port = 0;
3390 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3391 }
3392#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3393 else if (x->props.family == AF_INET6) {
3394 addr->sadb_address_prefixlen = 128;
3395
3396 sin6 = (struct sockaddr_in6 *) (addr + 1);
3397 sin6->sin6_family = AF_INET6;
3398 sin6->sin6_port = 0;
3399 sin6->sin6_flowinfo = 0;
3400 memcpy(&sin6->sin6_addr,
3401 x->props.saddr.a6, sizeof(struct in6_addr));
3402 sin6->sin6_scope_id = 0;
3403 }
3404#endif
3405 else
3406 BUG(); 3255 BUG();
3407 3256
3408 /* NAT_T_SPORT (old port) */ 3257 /* NAT_T_SPORT (old port) */
@@ -3421,28 +3270,11 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
3421 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 3270 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
3422 addr->sadb_address_proto = 0; 3271 addr->sadb_address_proto = 0;
3423 addr->sadb_address_reserved = 0; 3272 addr->sadb_address_reserved = 0;
3424 if (x->props.family == AF_INET) { 3273 addr->sadb_address_prefixlen =
3425 addr->sadb_address_prefixlen = 32; 3274 pfkey_sockaddr_fill(ipaddr, 0,
3426 3275 (struct sockaddr *) (addr + 1),
3427 sin = (struct sockaddr_in *) (addr + 1); 3276 x->props.family);
3428 sin->sin_family = AF_INET; 3277 if (!addr->sadb_address_prefixlen)
3429 sin->sin_addr.s_addr = ipaddr->a4;
3430 sin->sin_port = 0;
3431 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3432 }
3433#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3434 else if (x->props.family == AF_INET6) {
3435 addr->sadb_address_prefixlen = 128;
3436
3437 sin6 = (struct sockaddr_in6 *) (addr + 1);
3438 sin6->sin6_family = AF_INET6;
3439 sin6->sin6_port = 0;
3440 sin6->sin6_flowinfo = 0;
3441 memcpy(&sin6->sin6_addr, &ipaddr->a6, sizeof(struct in6_addr));
3442 sin6->sin6_scope_id = 0;
3443 }
3444#endif
3445 else
3446 BUG(); 3278 BUG();
3447 3279
3448 /* NAT_T_DPORT (new port) */ 3280 /* NAT_T_DPORT (new port) */
@@ -3460,10 +3292,6 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,
3460 struct xfrm_selector *sel) 3292 struct xfrm_selector *sel)
3461{ 3293{
3462 struct sadb_address *addr; 3294 struct sadb_address *addr;
3463 struct sockaddr_in *sin;
3464#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3465 struct sockaddr_in6 *sin6;
3466#endif
3467 addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize); 3295 addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize);
3468 addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8; 3296 addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8;
3469 addr->sadb_address_exttype = type; 3297 addr->sadb_address_exttype = type;
@@ -3472,50 +3300,16 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,
3472 3300
3473 switch (type) { 3301 switch (type) {
3474 case SADB_EXT_ADDRESS_SRC: 3302 case SADB_EXT_ADDRESS_SRC:
3475 if (sel->family == AF_INET) { 3303 addr->sadb_address_prefixlen = sel->prefixlen_s;
3476 addr->sadb_address_prefixlen = sel->prefixlen_s; 3304 pfkey_sockaddr_fill(&sel->saddr, 0,
3477 sin = (struct sockaddr_in *)(addr + 1); 3305 (struct sockaddr *)(addr + 1),
3478 sin->sin_family = AF_INET; 3306 sel->family);
3479 memcpy(&sin->sin_addr.s_addr, &sel->saddr,
3480 sizeof(sin->sin_addr.s_addr));
3481 sin->sin_port = 0;
3482 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3483 }
3484#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3485 else if (sel->family == AF_INET6) {
3486 addr->sadb_address_prefixlen = sel->prefixlen_s;
3487 sin6 = (struct sockaddr_in6 *)(addr + 1);
3488 sin6->sin6_family = AF_INET6;
3489 sin6->sin6_port = 0;
3490 sin6->sin6_flowinfo = 0;
3491 sin6->sin6_scope_id = 0;
3492 memcpy(&sin6->sin6_addr.s6_addr, &sel->saddr,
3493 sizeof(sin6->sin6_addr.s6_addr));
3494 }
3495#endif
3496 break; 3307 break;
3497 case SADB_EXT_ADDRESS_DST: 3308 case SADB_EXT_ADDRESS_DST:
3498 if (sel->family == AF_INET) { 3309 addr->sadb_address_prefixlen = sel->prefixlen_d;
3499 addr->sadb_address_prefixlen = sel->prefixlen_d; 3310 pfkey_sockaddr_fill(&sel->daddr, 0,
3500 sin = (struct sockaddr_in *)(addr + 1); 3311 (struct sockaddr *)(addr + 1),
3501 sin->sin_family = AF_INET; 3312 sel->family);
3502 memcpy(&sin->sin_addr.s_addr, &sel->daddr,
3503 sizeof(sin->sin_addr.s_addr));
3504 sin->sin_port = 0;
3505 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3506 }
3507#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3508 else if (sel->family == AF_INET6) {
3509 addr->sadb_address_prefixlen = sel->prefixlen_d;
3510 sin6 = (struct sockaddr_in6 *)(addr + 1);
3511 sin6->sin6_family = AF_INET6;
3512 sin6->sin6_port = 0;
3513 sin6->sin6_flowinfo = 0;
3514 sin6->sin6_scope_id = 0;
3515 memcpy(&sin6->sin6_addr.s6_addr, &sel->daddr,
3516 sizeof(sin6->sin6_addr.s6_addr));
3517 }
3518#endif
3519 break; 3313 break;
3520 default: 3314 default:
3521 return -EINVAL; 3315 return -EINVAL;
@@ -3530,10 +3324,8 @@ static int set_ipsecrequest(struct sk_buff *skb,
3530 xfrm_address_t *src, xfrm_address_t *dst) 3324 xfrm_address_t *src, xfrm_address_t *dst)
3531{ 3325{
3532 struct sadb_x_ipsecrequest *rq; 3326 struct sadb_x_ipsecrequest *rq;
3533 struct sockaddr_in *sin; 3327 u8 *sa;
3534#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3328 int socklen = pfkey_sockaddr_len(family);
3535 struct sockaddr_in6 *sin6;
3536#endif
3537 int size_req; 3329 int size_req;
3538 3330
3539 size_req = sizeof(struct sadb_x_ipsecrequest) + 3331 size_req = sizeof(struct sadb_x_ipsecrequest) +
@@ -3547,38 +3339,10 @@ static int set_ipsecrequest(struct sk_buff *skb,
3547 rq->sadb_x_ipsecrequest_level = level; 3339 rq->sadb_x_ipsecrequest_level = level;
3548 rq->sadb_x_ipsecrequest_reqid = reqid; 3340 rq->sadb_x_ipsecrequest_reqid = reqid;
3549 3341
3550 switch (family) { 3342 sa = (u8 *) (rq + 1);
3551 case AF_INET: 3343 if (!pfkey_sockaddr_fill(src, 0, (struct sockaddr *)sa, family) ||
3552 sin = (struct sockaddr_in *)(rq + 1); 3344 !pfkey_sockaddr_fill(dst, 0, (struct sockaddr *)(sa + socklen), family))
3553 sin->sin_family = AF_INET;
3554 memcpy(&sin->sin_addr.s_addr, src,
3555 sizeof(sin->sin_addr.s_addr));
3556 sin++;
3557 sin->sin_family = AF_INET;
3558 memcpy(&sin->sin_addr.s_addr, dst,
3559 sizeof(sin->sin_addr.s_addr));
3560 break;
3561#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3562 case AF_INET6:
3563 sin6 = (struct sockaddr_in6 *)(rq + 1);
3564 sin6->sin6_family = AF_INET6;
3565 sin6->sin6_port = 0;
3566 sin6->sin6_flowinfo = 0;
3567 sin6->sin6_scope_id = 0;
3568 memcpy(&sin6->sin6_addr.s6_addr, src,
3569 sizeof(sin6->sin6_addr.s6_addr));
3570 sin6++;
3571 sin6->sin6_family = AF_INET6;
3572 sin6->sin6_port = 0;
3573 sin6->sin6_flowinfo = 0;
3574 sin6->sin6_scope_id = 0;
3575 memcpy(&sin6->sin6_addr.s6_addr, dst,
3576 sizeof(sin6->sin6_addr.s6_addr));
3577 break;
3578#endif
3579 default:
3580 return -EINVAL; 3345 return -EINVAL;
3581 }
3582 3346
3583 return 0; 3347 return 0;
3584} 3348}