diff options
Diffstat (limited to 'net/key/af_key.c')
-rw-r--r-- | net/key/af_key.c | 458 |
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 | ||
694 | static 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 | |||
694 | static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x, | 724 | static 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 | } |