aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/sctp.h2
-rw-r--r--include/net/sctp/structs.h8
-rw-r--r--net/sctp/ipv6.c156
-rw-r--r--net/sctp/protocol.c12
-rw-r--r--net/sctp/socket.c33
-rw-r--r--net/sctp/transport.c4
-rw-r--r--net/sctp/ulpevent.c2
7 files changed, 112 insertions, 105 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 90c1cccd164d..f6e7397e799d 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -554,6 +554,8 @@ static inline void sctp_v6_map_v4(union sctp_addr *addr)
554static inline void sctp_v4_map_v6(union sctp_addr *addr) 554static inline void sctp_v4_map_v6(union sctp_addr *addr)
555{ 555{
556 addr->v6.sin6_family = AF_INET6; 556 addr->v6.sin6_family = AF_INET6;
557 addr->v6.sin6_flowinfo = 0;
558 addr->v6.sin6_scope_id = 0;
557 addr->v6.sin6_port = addr->v4.sin_port; 559 addr->v6.sin6_port = addr->v4.sin_port;
558 addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr; 560 addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr;
559 addr->v6.sin6_addr.s6_addr32[0] = 0; 561 addr->v6.sin6_addr.s6_addr32[0] = 0;
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 7741d1b66967..4ff3f67be62c 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -465,10 +465,6 @@ struct sctp_af {
465 int saddr); 465 int saddr);
466 void (*from_sk) (union sctp_addr *, 466 void (*from_sk) (union sctp_addr *,
467 struct sock *sk); 467 struct sock *sk);
468 void (*to_sk_saddr) (union sctp_addr *,
469 struct sock *sk);
470 void (*to_sk_daddr) (union sctp_addr *,
471 struct sock *sk);
472 void (*from_addr_param) (union sctp_addr *, 468 void (*from_addr_param) (union sctp_addr *,
473 union sctp_addr_param *, 469 union sctp_addr_param *,
474 __be16 port, int iif); 470 __be16 port, int iif);
@@ -509,7 +505,9 @@ struct sctp_pf {
509 int (*supported_addrs)(const struct sctp_sock *, __be16 *); 505 int (*supported_addrs)(const struct sctp_sock *, __be16 *);
510 struct sock *(*create_accept_sk) (struct sock *sk, 506 struct sock *(*create_accept_sk) (struct sock *sk,
511 struct sctp_association *asoc); 507 struct sctp_association *asoc);
512 void (*addr_v4map) (struct sctp_sock *, union sctp_addr *); 508 int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
509 void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
510 void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
513 struct sctp_af *af; 511 struct sctp_af *af;
514}; 512};
515 513
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 1999592ba88c..0e4198ee2370 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -434,7 +434,7 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
434/* Initialize sk->sk_rcv_saddr from sctp_addr. */ 434/* Initialize sk->sk_rcv_saddr from sctp_addr. */
435static void sctp_v6_to_sk_saddr(union sctp_addr *addr, struct sock *sk) 435static void sctp_v6_to_sk_saddr(union sctp_addr *addr, struct sock *sk)
436{ 436{
437 if (addr->sa.sa_family == AF_INET && sctp_sk(sk)->v4mapped) { 437 if (addr->sa.sa_family == AF_INET) {
438 sk->sk_v6_rcv_saddr.s6_addr32[0] = 0; 438 sk->sk_v6_rcv_saddr.s6_addr32[0] = 0;
439 sk->sk_v6_rcv_saddr.s6_addr32[1] = 0; 439 sk->sk_v6_rcv_saddr.s6_addr32[1] = 0;
440 sk->sk_v6_rcv_saddr.s6_addr32[2] = htonl(0x0000ffff); 440 sk->sk_v6_rcv_saddr.s6_addr32[2] = htonl(0x0000ffff);
@@ -448,7 +448,7 @@ static void sctp_v6_to_sk_saddr(union sctp_addr *addr, struct sock *sk)
448/* Initialize sk->sk_daddr from sctp_addr. */ 448/* Initialize sk->sk_daddr from sctp_addr. */
449static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk) 449static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk)
450{ 450{
451 if (addr->sa.sa_family == AF_INET && sctp_sk(sk)->v4mapped) { 451 if (addr->sa.sa_family == AF_INET) {
452 sk->sk_v6_daddr.s6_addr32[0] = 0; 452 sk->sk_v6_daddr.s6_addr32[0] = 0;
453 sk->sk_v6_daddr.s6_addr32[1] = 0; 453 sk->sk_v6_daddr.s6_addr32[1] = 0;
454 sk->sk_v6_daddr.s6_addr32[2] = htonl(0x0000ffff); 454 sk->sk_v6_daddr.s6_addr32[2] = htonl(0x0000ffff);
@@ -556,8 +556,6 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
556 if (IPV6_ADDR_ANY == type) 556 if (IPV6_ADDR_ANY == type)
557 return 1; 557 return 1;
558 if (type == IPV6_ADDR_MAPPED) { 558 if (type == IPV6_ADDR_MAPPED) {
559 if (sp && !sp->v4mapped)
560 return 0;
561 if (sp && ipv6_only_sock(sctp_opt2sk(sp))) 559 if (sp && ipv6_only_sock(sctp_opt2sk(sp)))
562 return 0; 560 return 0;
563 sctp_v6_map_v4(addr); 561 sctp_v6_map_v4(addr);
@@ -587,8 +585,6 @@ static int sctp_v6_addr_valid(union sctp_addr *addr,
587 /* Note: This routine is used in input, so v4-mapped-v6 585 /* Note: This routine is used in input, so v4-mapped-v6
588 * are disallowed here when there is no sctp_sock. 586 * are disallowed here when there is no sctp_sock.
589 */ 587 */
590 if (!sp || !sp->v4mapped)
591 return 0;
592 if (sp && ipv6_only_sock(sctp_opt2sk(sp))) 588 if (sp && ipv6_only_sock(sctp_opt2sk(sp)))
593 return 0; 589 return 0;
594 sctp_v6_map_v4(addr); 590 sctp_v6_map_v4(addr);
@@ -675,11 +671,23 @@ out:
675 return newsk; 671 return newsk;
676} 672}
677 673
678/* Map v4 address to mapped v6 address */ 674/* Format a sockaddr for return to user space. This makes sure the return is
679static void sctp_v6_addr_v4map(struct sctp_sock *sp, union sctp_addr *addr) 675 * AF_INET or AF_INET6 depending on the SCTP_I_WANT_MAPPED_V4_ADDR option.
676 */
677static int sctp_v6_addr_to_user(struct sctp_sock *sp, union sctp_addr *addr)
680{ 678{
681 if (sp->v4mapped && AF_INET == addr->sa.sa_family) 679 if (sp->v4mapped) {
682 sctp_v4_map_v6(addr); 680 if (addr->sa.sa_family == AF_INET)
681 sctp_v4_map_v6(addr);
682 } else {
683 if (addr->sa.sa_family == AF_INET6 &&
684 ipv6_addr_v4mapped(&addr->v6.sin6_addr))
685 sctp_v6_map_v4(addr);
686 }
687
688 if (addr->sa.sa_family == AF_INET)
689 return sizeof(struct sockaddr_in);
690 return sizeof(struct sockaddr_in6);
683} 691}
684 692
685/* Where did this skb come from? */ 693/* Where did this skb come from? */
@@ -706,82 +714,68 @@ static void sctp_v6_ecn_capable(struct sock *sk)
706 inet6_sk(sk)->tclass |= INET_ECN_ECT_0; 714 inet6_sk(sk)->tclass |= INET_ECN_ECT_0;
707} 715}
708 716
709/* Initialize a PF_INET6 socket msg_name. */
710static void sctp_inet6_msgname(char *msgname, int *addr_len)
711{
712 struct sockaddr_in6 *sin6;
713
714 sin6 = (struct sockaddr_in6 *)msgname;
715 sin6->sin6_family = AF_INET6;
716 sin6->sin6_flowinfo = 0;
717 sin6->sin6_scope_id = 0; /*FIXME */
718 *addr_len = sizeof(struct sockaddr_in6);
719}
720
721/* Initialize a PF_INET msgname from a ulpevent. */ 717/* Initialize a PF_INET msgname from a ulpevent. */
722static void sctp_inet6_event_msgname(struct sctp_ulpevent *event, 718static void sctp_inet6_event_msgname(struct sctp_ulpevent *event,
723 char *msgname, int *addrlen) 719 char *msgname, int *addrlen)
724{ 720{
725 struct sockaddr_in6 *sin6, *sin6from; 721 union sctp_addr *addr;
726 722 struct sctp_association *asoc;
727 if (msgname) { 723 union sctp_addr *paddr;
728 union sctp_addr *addr;
729 struct sctp_association *asoc;
730
731 asoc = event->asoc;
732 sctp_inet6_msgname(msgname, addrlen);
733 sin6 = (struct sockaddr_in6 *)msgname;
734 sin6->sin6_port = htons(asoc->peer.port);
735 addr = &asoc->peer.primary_addr;
736 724
737 /* Note: If we go to a common v6 format, this code 725 if (!msgname)
738 * will change. 726 return;
739 */
740 727
741 /* Map ipv4 address into v4-mapped-on-v6 address. */ 728 addr = (union sctp_addr *)msgname;
742 if (sctp_sk(asoc->base.sk)->v4mapped && 729 asoc = event->asoc;
743 AF_INET == addr->sa.sa_family) { 730 paddr = &asoc->peer.primary_addr;
744 sctp_v4_map_v6((union sctp_addr *)sin6);
745 sin6->sin6_addr.s6_addr32[3] =
746 addr->v4.sin_addr.s_addr;
747 return;
748 }
749 731
750 sin6from = &asoc->peer.primary_addr.v6; 732 if (paddr->sa.sa_family == AF_INET) {
751 sin6->sin6_addr = sin6from->sin6_addr; 733 addr->v4.sin_family = AF_INET;
752 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) 734 addr->v4.sin_port = htons(asoc->peer.port);
753 sin6->sin6_scope_id = sin6from->sin6_scope_id; 735 addr->v4.sin_addr = paddr->v4.sin_addr;
736 } else {
737 addr->v6.sin6_family = AF_INET6;
738 addr->v6.sin6_flowinfo = 0;
739 if (ipv6_addr_type(&paddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
740 addr->v6.sin6_scope_id = paddr->v6.sin6_scope_id;
741 else
742 addr->v6.sin6_scope_id = 0;
743 addr->v6.sin6_port = htons(asoc->peer.port);
744 addr->v6.sin6_addr = paddr->v6.sin6_addr;
754 } 745 }
746
747 *addrlen = sctp_v6_addr_to_user(sctp_sk(asoc->base.sk), addr);
755} 748}
756 749
757/* Initialize a msg_name from an inbound skb. */ 750/* Initialize a msg_name from an inbound skb. */
758static void sctp_inet6_skb_msgname(struct sk_buff *skb, char *msgname, 751static void sctp_inet6_skb_msgname(struct sk_buff *skb, char *msgname,
759 int *addr_len) 752 int *addr_len)
760{ 753{
754 union sctp_addr *addr;
761 struct sctphdr *sh; 755 struct sctphdr *sh;
762 struct sockaddr_in6 *sin6;
763
764 if (msgname) {
765 sctp_inet6_msgname(msgname, addr_len);
766 sin6 = (struct sockaddr_in6 *)msgname;
767 sh = sctp_hdr(skb);
768 sin6->sin6_port = sh->source;
769
770 /* Map ipv4 address into v4-mapped-on-v6 address. */
771 if (sctp_sk(skb->sk)->v4mapped &&
772 ip_hdr(skb)->version == 4) {
773 sctp_v4_map_v6((union sctp_addr *)sin6);
774 sin6->sin6_addr.s6_addr32[3] = ip_hdr(skb)->saddr;
775 return;
776 }
777 756
778 /* Otherwise, just copy the v6 address. */ 757 if (!msgname)
779 sin6->sin6_addr = ipv6_hdr(skb)->saddr; 758 return;
780 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) { 759
760 addr = (union sctp_addr *)msgname;
761 sh = sctp_hdr(skb);
762
763 if (ip_hdr(skb)->version == 4) {
764 addr->v4.sin_family = AF_INET;
765 addr->v4.sin_port = sh->source;
766 addr->v4.sin_addr.s_addr = ip_hdr(skb)->saddr;
767 } else {
768 addr->v6.sin6_family = AF_INET6;
769 addr->v6.sin6_flowinfo = 0;
770 addr->v6.sin6_port = sh->source;
771 addr->v6.sin6_addr = ipv6_hdr(skb)->saddr;
772 if (ipv6_addr_type(&addr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) {
781 struct sctp_ulpevent *ev = sctp_skb2event(skb); 773 struct sctp_ulpevent *ev = sctp_skb2event(skb);
782 sin6->sin6_scope_id = ev->iif; 774 addr->v6.sin6_scope_id = ev->iif;
783 } 775 }
784 } 776 }
777
778 *addr_len = sctp_v6_addr_to_user(sctp_sk(skb->sk), addr);
785} 779}
786 780
787/* Do we support this AF? */ 781/* Do we support this AF? */
@@ -857,9 +851,6 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
857 return 0; 851 return 0;
858 } 852 }
859 rcu_read_unlock(); 853 rcu_read_unlock();
860 } else if (type == IPV6_ADDR_MAPPED) {
861 if (!opt->v4mapped)
862 return 0;
863 } 854 }
864 855
865 af = opt->pf->af; 856 af = opt->pf->af;
@@ -914,6 +905,23 @@ static int sctp_inet6_supported_addrs(const struct sctp_sock *opt,
914 return 1; 905 return 1;
915} 906}
916 907
908/* Handle SCTP_I_WANT_MAPPED_V4_ADDR for getpeername() and getsockname() */
909static int sctp_getname(struct socket *sock, struct sockaddr *uaddr,
910 int *uaddr_len, int peer)
911{
912 int rc;
913
914 rc = inet6_getname(sock, uaddr, uaddr_len, peer);
915
916 if (rc != 0)
917 return rc;
918
919 *uaddr_len = sctp_v6_addr_to_user(sctp_sk(sock->sk),
920 (union sctp_addr *)uaddr);
921
922 return rc;
923}
924
917static const struct proto_ops inet6_seqpacket_ops = { 925static const struct proto_ops inet6_seqpacket_ops = {
918 .family = PF_INET6, 926 .family = PF_INET6,
919 .owner = THIS_MODULE, 927 .owner = THIS_MODULE,
@@ -922,7 +930,7 @@ static const struct proto_ops inet6_seqpacket_ops = {
922 .connect = inet_dgram_connect, 930 .connect = inet_dgram_connect,
923 .socketpair = sock_no_socketpair, 931 .socketpair = sock_no_socketpair,
924 .accept = inet_accept, 932 .accept = inet_accept,
925 .getname = inet6_getname, 933 .getname = sctp_getname,
926 .poll = sctp_poll, 934 .poll = sctp_poll,
927 .ioctl = inet6_ioctl, 935 .ioctl = inet6_ioctl,
928 .listen = sctp_inet_listen, 936 .listen = sctp_inet_listen,
@@ -974,8 +982,6 @@ static struct sctp_af sctp_af_inet6 = {
974 .copy_addrlist = sctp_v6_copy_addrlist, 982 .copy_addrlist = sctp_v6_copy_addrlist,
975 .from_skb = sctp_v6_from_skb, 983 .from_skb = sctp_v6_from_skb,
976 .from_sk = sctp_v6_from_sk, 984 .from_sk = sctp_v6_from_sk,
977 .to_sk_saddr = sctp_v6_to_sk_saddr,
978 .to_sk_daddr = sctp_v6_to_sk_daddr,
979 .from_addr_param = sctp_v6_from_addr_param, 985 .from_addr_param = sctp_v6_from_addr_param,
980 .to_addr_param = sctp_v6_to_addr_param, 986 .to_addr_param = sctp_v6_to_addr_param,
981 .cmp_addr = sctp_v6_cmp_addr, 987 .cmp_addr = sctp_v6_cmp_addr,
@@ -1005,7 +1011,9 @@ static struct sctp_pf sctp_pf_inet6 = {
1005 .send_verify = sctp_inet6_send_verify, 1011 .send_verify = sctp_inet6_send_verify,
1006 .supported_addrs = sctp_inet6_supported_addrs, 1012 .supported_addrs = sctp_inet6_supported_addrs,
1007 .create_accept_sk = sctp_v6_create_accept_sk, 1013 .create_accept_sk = sctp_v6_create_accept_sk,
1008 .addr_v4map = sctp_v6_addr_v4map, 1014 .addr_to_user = sctp_v6_addr_to_user,
1015 .to_sk_saddr = sctp_v6_to_sk_saddr,
1016 .to_sk_daddr = sctp_v6_to_sk_daddr,
1009 .af = &sctp_af_inet6, 1017 .af = &sctp_af_inet6,
1010}; 1018};
1011 1019
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 6789d785e698..6240834f4b95 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -576,10 +576,10 @@ out:
576 return newsk; 576 return newsk;
577} 577}
578 578
579/* Map address, empty for v4 family */ 579static int sctp_v4_addr_to_user(struct sctp_sock *sp, union sctp_addr *addr)
580static void sctp_v4_addr_v4map(struct sctp_sock *sp, union sctp_addr *addr)
581{ 580{
582 /* Empty */ 581 /* No address mapping for V4 sockets */
582 return sizeof(struct sockaddr_in);
583} 583}
584 584
585/* Dump the v4 addr to the seq file. */ 585/* Dump the v4 addr to the seq file. */
@@ -976,7 +976,9 @@ static struct sctp_pf sctp_pf_inet = {
976 .send_verify = sctp_inet_send_verify, 976 .send_verify = sctp_inet_send_verify,
977 .supported_addrs = sctp_inet_supported_addrs, 977 .supported_addrs = sctp_inet_supported_addrs,
978 .create_accept_sk = sctp_v4_create_accept_sk, 978 .create_accept_sk = sctp_v4_create_accept_sk,
979 .addr_v4map = sctp_v4_addr_v4map, 979 .addr_to_user = sctp_v4_addr_to_user,
980 .to_sk_saddr = sctp_v4_to_sk_saddr,
981 .to_sk_daddr = sctp_v4_to_sk_daddr,
980 .af = &sctp_af_inet 982 .af = &sctp_af_inet
981}; 983};
982 984
@@ -1047,8 +1049,6 @@ static struct sctp_af sctp_af_inet = {
1047 .copy_addrlist = sctp_v4_copy_addrlist, 1049 .copy_addrlist = sctp_v4_copy_addrlist,
1048 .from_skb = sctp_v4_from_skb, 1050 .from_skb = sctp_v4_from_skb,
1049 .from_sk = sctp_v4_from_sk, 1051 .from_sk = sctp_v4_from_sk,
1050 .to_sk_saddr = sctp_v4_to_sk_saddr,
1051 .to_sk_daddr = sctp_v4_to_sk_daddr,
1052 .from_addr_param = sctp_v4_from_addr_param, 1052 .from_addr_param = sctp_v4_from_addr_param,
1053 .to_addr_param = sctp_v4_to_addr_param, 1053 .to_addr_param = sctp_v4_to_addr_param,
1054 .cmp_addr = sctp_v4_cmp_addr, 1054 .cmp_addr = sctp_v4_cmp_addr,
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 743308f40544..eb71d49e7653 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -254,7 +254,7 @@ static struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
254 if (id_asoc && (id_asoc != addr_asoc)) 254 if (id_asoc && (id_asoc != addr_asoc))
255 return NULL; 255 return NULL;
256 256
257 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), 257 sctp_get_pf_specific(sk->sk_family)->addr_to_user(sctp_sk(sk),
258 (union sctp_addr *)addr); 258 (union sctp_addr *)addr);
259 259
260 return transport; 260 return transport;
@@ -396,7 +396,7 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
396 /* Copy back into socket for getsockname() use. */ 396 /* Copy back into socket for getsockname() use. */
397 if (!ret) { 397 if (!ret) {
398 inet_sk(sk)->inet_sport = htons(inet_sk(sk)->inet_num); 398 inet_sk(sk)->inet_sport = htons(inet_sk(sk)->inet_num);
399 af->to_sk_saddr(addr, sk); 399 sp->pf->to_sk_saddr(addr, sk);
400 } 400 }
401 401
402 return ret; 402 return ret;
@@ -1053,7 +1053,6 @@ static int __sctp_connect(struct sock *sk,
1053 struct sctp_association *asoc2; 1053 struct sctp_association *asoc2;
1054 struct sctp_transport *transport; 1054 struct sctp_transport *transport;
1055 union sctp_addr to; 1055 union sctp_addr to;
1056 struct sctp_af *af;
1057 sctp_scope_t scope; 1056 sctp_scope_t scope;
1058 long timeo; 1057 long timeo;
1059 int err = 0; 1058 int err = 0;
@@ -1081,6 +1080,8 @@ static int __sctp_connect(struct sock *sk,
1081 /* Walk through the addrs buffer and count the number of addresses. */ 1080 /* Walk through the addrs buffer and count the number of addresses. */
1082 addr_buf = kaddrs; 1081 addr_buf = kaddrs;
1083 while (walk_size < addrs_size) { 1082 while (walk_size < addrs_size) {
1083 struct sctp_af *af;
1084
1084 if (walk_size + sizeof(sa_family_t) > addrs_size) { 1085 if (walk_size + sizeof(sa_family_t) > addrs_size) {
1085 err = -EINVAL; 1086 err = -EINVAL;
1086 goto out_free; 1087 goto out_free;
@@ -1205,8 +1206,7 @@ static int __sctp_connect(struct sock *sk,
1205 1206
1206 /* Initialize sk's dport and daddr for getpeername() */ 1207 /* Initialize sk's dport and daddr for getpeername() */
1207 inet_sk(sk)->inet_dport = htons(asoc->peer.port); 1208 inet_sk(sk)->inet_dport = htons(asoc->peer.port);
1208 af = sctp_get_af_specific(sa_addr->sa.sa_family); 1209 sp->pf->to_sk_daddr(sa_addr, sk);
1209 af->to_sk_daddr(sa_addr, sk);
1210 sk->sk_err = 0; 1210 sk->sk_err = 0;
1211 1211
1212 /* in-kernel sockets don't generally have a file allocated to them 1212 /* in-kernel sockets don't generally have a file allocated to them
@@ -4255,7 +4255,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len,
4255 memcpy(&status.sstat_primary.spinfo_address, &transport->ipaddr, 4255 memcpy(&status.sstat_primary.spinfo_address, &transport->ipaddr,
4256 transport->af_specific->sockaddr_len); 4256 transport->af_specific->sockaddr_len);
4257 /* Map ipv4 address into v4-mapped-on-v6 address. */ 4257 /* Map ipv4 address into v4-mapped-on-v6 address. */
4258 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), 4258 sctp_get_pf_specific(sk->sk_family)->addr_to_user(sctp_sk(sk),
4259 (union sctp_addr *)&status.sstat_primary.spinfo_address); 4259 (union sctp_addr *)&status.sstat_primary.spinfo_address);
4260 status.sstat_primary.spinfo_state = transport->state; 4260 status.sstat_primary.spinfo_state = transport->state;
4261 status.sstat_primary.spinfo_cwnd = transport->cwnd; 4261 status.sstat_primary.spinfo_cwnd = transport->cwnd;
@@ -4413,8 +4413,8 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv
4413int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) 4413int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp)
4414{ 4414{
4415 struct sctp_association *asoc = sctp_id2assoc(sk, id); 4415 struct sctp_association *asoc = sctp_id2assoc(sk, id);
4416 struct sctp_sock *sp = sctp_sk(sk);
4416 struct socket *sock; 4417 struct socket *sock;
4417 struct sctp_af *af;
4418 int err = 0; 4418 int err = 0;
4419 4419
4420 if (!asoc) 4420 if (!asoc)
@@ -4436,8 +4436,7 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp)
4436 /* Make peeled-off sockets more like 1-1 accepted sockets. 4436 /* Make peeled-off sockets more like 1-1 accepted sockets.
4437 * Set the daddr and initialize id to something more random 4437 * Set the daddr and initialize id to something more random
4438 */ 4438 */
4439 af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family); 4439 sp->pf->to_sk_daddr(&asoc->peer.primary_addr, sk);
4440 af->to_sk_daddr(&asoc->peer.primary_addr, sk);
4441 4440
4442 /* Populate the fields of the newsk from the oldsk and migrate the 4441 /* Populate the fields of the newsk from the oldsk and migrate the
4443 * asoc to the newsk. 4442 * asoc to the newsk.
@@ -4821,8 +4820,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
4821 list_for_each_entry(from, &asoc->peer.transport_addr_list, 4820 list_for_each_entry(from, &asoc->peer.transport_addr_list,
4822 transports) { 4821 transports) {
4823 memcpy(&temp, &from->ipaddr, sizeof(temp)); 4822 memcpy(&temp, &from->ipaddr, sizeof(temp));
4824 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); 4823 addrlen = sctp_get_pf_specific(sk->sk_family)
4825 addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; 4824 ->addr_to_user(sp, &temp);
4826 if (space_left < addrlen) 4825 if (space_left < addrlen)
4827 return -ENOMEM; 4826 return -ENOMEM;
4828 if (copy_to_user(to, &temp, addrlen)) 4827 if (copy_to_user(to, &temp, addrlen))
@@ -4866,9 +4865,9 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to,
4866 if (!temp.v4.sin_port) 4865 if (!temp.v4.sin_port)
4867 temp.v4.sin_port = htons(port); 4866 temp.v4.sin_port = htons(port);
4868 4867
4869 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), 4868 addrlen = sctp_get_pf_specific(sk->sk_family)
4870 &temp); 4869 ->addr_to_user(sctp_sk(sk), &temp);
4871 addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; 4870
4872 if (space_left < addrlen) { 4871 if (space_left < addrlen) {
4873 cnt = -ENOMEM; 4872 cnt = -ENOMEM;
4874 break; 4873 break;
@@ -4956,8 +4955,8 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
4956 */ 4955 */
4957 list_for_each_entry(addr, &bp->address_list, list) { 4956 list_for_each_entry(addr, &bp->address_list, list) {
4958 memcpy(&temp, &addr->a, sizeof(temp)); 4957 memcpy(&temp, &addr->a, sizeof(temp));
4959 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); 4958 addrlen = sctp_get_pf_specific(sk->sk_family)
4960 addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; 4959 ->addr_to_user(sp, &temp);
4961 if (space_left < addrlen) { 4960 if (space_left < addrlen) {
4962 err = -ENOMEM; /*fixme: right error?*/ 4961 err = -ENOMEM; /*fixme: right error?*/
4963 goto out; 4962 goto out;
@@ -5016,7 +5015,7 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
5016 memcpy(&prim.ssp_addr, &asoc->peer.primary_path->ipaddr, 5015 memcpy(&prim.ssp_addr, &asoc->peer.primary_path->ipaddr,
5017 asoc->peer.primary_path->af_specific->sockaddr_len); 5016 asoc->peer.primary_path->af_specific->sockaddr_len);
5018 5017
5019 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, 5018 sctp_get_pf_specific(sk->sk_family)->addr_to_user(sp,
5020 (union sctp_addr *)&prim.ssp_addr); 5019 (union sctp_addr *)&prim.ssp_addr);
5021 5020
5022 if (put_user(len, optlen)) 5021 if (put_user(len, optlen))
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index b10e047bbd15..a0a431824f63 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -289,8 +289,8 @@ void sctp_transport_route(struct sctp_transport *transport,
289 */ 289 */
290 if (asoc && (!asoc->peer.primary_path || 290 if (asoc && (!asoc->peer.primary_path ||
291 (transport == asoc->peer.active_path))) 291 (transport == asoc->peer.active_path)))
292 opt->pf->af->to_sk_saddr(&transport->saddr, 292 opt->pf->to_sk_saddr(&transport->saddr,
293 asoc->base.sk); 293 asoc->base.sk);
294 } else 294 } else
295 transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; 295 transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
296} 296}
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index e049298ecfa0..d1e38308f615 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -341,7 +341,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
341 memcpy(&spc->spc_aaddr, aaddr, sizeof(struct sockaddr_storage)); 341 memcpy(&spc->spc_aaddr, aaddr, sizeof(struct sockaddr_storage));
342 342
343 /* Map ipv4 address into v4-mapped-on-v6 address. */ 343 /* Map ipv4 address into v4-mapped-on-v6 address. */
344 sctp_get_pf_specific(asoc->base.sk->sk_family)->addr_v4map( 344 sctp_get_pf_specific(asoc->base.sk->sk_family)->addr_to_user(
345 sctp_sk(asoc->base.sk), 345 sctp_sk(asoc->base.sk),
346 (union sctp_addr *)&spc->spc_aaddr); 346 (union sctp_addr *)&spc->spc_aaddr);
347 347