diff options
Diffstat (limited to 'net/key/af_key.c')
-rw-r--r-- | net/key/af_key.c | 622 |
1 files changed, 168 insertions, 454 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c index 7470e367272b..f0fc46c8038d 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 | ||
582 | static int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, | 582 | static 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 | |||
595 | static | ||
596 | int 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 | |||
614 | static | ||
615 | int 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 | ||
603 | static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs) | 621 | static 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 | |||
645 | static int | 664 | static int |
646 | pfkey_sockaddr_size(sa_family_t family) | 665 | pfkey_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 | ||
661 | static inline int pfkey_mode_from_xfrm(int mode) | 670 | static 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 | ||
699 | static 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 | |||
690 | static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x, | 729 | static 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 | |||
1853 | parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) | 1826 | parse_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 |
2460 | static int pfkey_sockaddr_pair_size(sa_family_t family) | 2351 | static 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 | ||
2475 | static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq, | 2356 | static 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 | } |