diff options
author | James Morris <james.l.morris@oracle.com> | 2014-11-19 05:32:12 -0500 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2014-11-19 05:32:12 -0500 |
commit | b10778a00d40b3d9fdaaf5891e802794781ff71c (patch) | |
tree | 6ba4cbac86eecedc3f30650e7f764ecf00c83898 /net/sctp/socket.c | |
parent | 594081ee7145cc30a3977cb4e218f81213b63dc5 (diff) | |
parent | bfe01a5ba2490f299e1d2d5508cbbbadd897bbe9 (diff) |
Merge commit 'v3.17' into next
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 329 |
1 files changed, 275 insertions, 54 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 429899689408..634a2abb5f3a 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 |
@@ -1602,12 +1602,13 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1602 | struct sctp_initmsg *sinit; | 1602 | struct sctp_initmsg *sinit; |
1603 | sctp_assoc_t associd = 0; | 1603 | sctp_assoc_t associd = 0; |
1604 | sctp_cmsgs_t cmsgs = { NULL }; | 1604 | sctp_cmsgs_t cmsgs = { NULL }; |
1605 | int err; | ||
1606 | sctp_scope_t scope; | 1605 | sctp_scope_t scope; |
1607 | long timeo; | 1606 | bool fill_sinfo_ttl = false; |
1608 | __u16 sinfo_flags = 0; | ||
1609 | struct sctp_datamsg *datamsg; | 1607 | struct sctp_datamsg *datamsg; |
1610 | int msg_flags = msg->msg_flags; | 1608 | int msg_flags = msg->msg_flags; |
1609 | __u16 sinfo_flags = 0; | ||
1610 | long timeo; | ||
1611 | int err; | ||
1611 | 1612 | ||
1612 | err = 0; | 1613 | err = 0; |
1613 | sp = sctp_sk(sk); | 1614 | sp = sctp_sk(sk); |
@@ -1648,10 +1649,21 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1648 | msg_name = msg->msg_name; | 1649 | msg_name = msg->msg_name; |
1649 | } | 1650 | } |
1650 | 1651 | ||
1651 | sinfo = cmsgs.info; | ||
1652 | sinit = cmsgs.init; | 1652 | sinit = cmsgs.init; |
1653 | if (cmsgs.sinfo != NULL) { | ||
1654 | memset(&default_sinfo, 0, sizeof(default_sinfo)); | ||
1655 | default_sinfo.sinfo_stream = cmsgs.sinfo->snd_sid; | ||
1656 | default_sinfo.sinfo_flags = cmsgs.sinfo->snd_flags; | ||
1657 | default_sinfo.sinfo_ppid = cmsgs.sinfo->snd_ppid; | ||
1658 | default_sinfo.sinfo_context = cmsgs.sinfo->snd_context; | ||
1659 | default_sinfo.sinfo_assoc_id = cmsgs.sinfo->snd_assoc_id; | ||
1653 | 1660 | ||
1654 | /* Did the user specify SNDRCVINFO? */ | 1661 | sinfo = &default_sinfo; |
1662 | fill_sinfo_ttl = true; | ||
1663 | } else { | ||
1664 | sinfo = cmsgs.srinfo; | ||
1665 | } | ||
1666 | /* Did the user specify SNDINFO/SNDRCVINFO? */ | ||
1655 | if (sinfo) { | 1667 | if (sinfo) { |
1656 | sinfo_flags = sinfo->sinfo_flags; | 1668 | sinfo_flags = sinfo->sinfo_flags; |
1657 | associd = sinfo->sinfo_assoc_id; | 1669 | associd = sinfo->sinfo_assoc_id; |
@@ -1858,8 +1870,8 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1858 | pr_debug("%s: we have a valid association\n", __func__); | 1870 | pr_debug("%s: we have a valid association\n", __func__); |
1859 | 1871 | ||
1860 | if (!sinfo) { | 1872 | if (!sinfo) { |
1861 | /* If the user didn't specify SNDRCVINFO, make up one with | 1873 | /* If the user didn't specify SNDINFO/SNDRCVINFO, make up |
1862 | * some defaults. | 1874 | * one with some defaults. |
1863 | */ | 1875 | */ |
1864 | memset(&default_sinfo, 0, sizeof(default_sinfo)); | 1876 | memset(&default_sinfo, 0, sizeof(default_sinfo)); |
1865 | default_sinfo.sinfo_stream = asoc->default_stream; | 1877 | default_sinfo.sinfo_stream = asoc->default_stream; |
@@ -1868,7 +1880,13 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1868 | default_sinfo.sinfo_context = asoc->default_context; | 1880 | default_sinfo.sinfo_context = asoc->default_context; |
1869 | default_sinfo.sinfo_timetolive = asoc->default_timetolive; | 1881 | default_sinfo.sinfo_timetolive = asoc->default_timetolive; |
1870 | default_sinfo.sinfo_assoc_id = sctp_assoc2id(asoc); | 1882 | default_sinfo.sinfo_assoc_id = sctp_assoc2id(asoc); |
1883 | |||
1871 | sinfo = &default_sinfo; | 1884 | sinfo = &default_sinfo; |
1885 | } else if (fill_sinfo_ttl) { | ||
1886 | /* In case SNDINFO was specified, we still need to fill | ||
1887 | * it with a default ttl from the assoc here. | ||
1888 | */ | ||
1889 | sinfo->sinfo_timetolive = asoc->default_timetolive; | ||
1872 | } | 1890 | } |
1873 | 1891 | ||
1874 | /* API 7.1.7, the sndbuf size per association bounds the | 1892 | /* API 7.1.7, the sndbuf size per association bounds the |
@@ -2042,8 +2060,6 @@ static int sctp_skb_pull(struct sk_buff *skb, int len) | |||
2042 | * flags - flags sent or received with the user message, see Section | 2060 | * flags - flags sent or received with the user message, see Section |
2043 | * 5 for complete description of the flags. | 2061 | * 5 for complete description of the flags. |
2044 | */ | 2062 | */ |
2045 | static struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *); | ||
2046 | |||
2047 | static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, | 2063 | static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, |
2048 | struct msghdr *msg, size_t len, int noblock, | 2064 | struct msghdr *msg, size_t len, int noblock, |
2049 | int flags, int *addr_len) | 2065 | int flags, int *addr_len) |
@@ -2094,9 +2110,16 @@ static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
2094 | sp->pf->skb_msgname(skb, msg->msg_name, addr_len); | 2110 | sp->pf->skb_msgname(skb, msg->msg_name, addr_len); |
2095 | } | 2111 | } |
2096 | 2112 | ||
2113 | /* Check if we allow SCTP_NXTINFO. */ | ||
2114 | if (sp->recvnxtinfo) | ||
2115 | sctp_ulpevent_read_nxtinfo(event, msg, sk); | ||
2116 | /* Check if we allow SCTP_RCVINFO. */ | ||
2117 | if (sp->recvrcvinfo) | ||
2118 | sctp_ulpevent_read_rcvinfo(event, msg); | ||
2097 | /* Check if we allow SCTP_SNDRCVINFO. */ | 2119 | /* Check if we allow SCTP_SNDRCVINFO. */ |
2098 | if (sp->subscribe.sctp_data_io_event) | 2120 | if (sp->subscribe.sctp_data_io_event) |
2099 | sctp_ulpevent_read_sndrcvinfo(event, msg); | 2121 | sctp_ulpevent_read_sndrcvinfo(event, msg); |
2122 | |||
2100 | #if 0 | 2123 | #if 0 |
2101 | /* FIXME: we should be calling IP/IPv6 layers. */ | 2124 | /* FIXME: we should be calling IP/IPv6 layers. */ |
2102 | if (sk->sk_protinfo.af_inet.cmsg_flags) | 2125 | if (sk->sk_protinfo.af_inet.cmsg_flags) |
@@ -2182,8 +2205,13 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval, | |||
2182 | if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) | 2205 | if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) |
2183 | return -EFAULT; | 2206 | return -EFAULT; |
2184 | 2207 | ||
2185 | /* | 2208 | if (sctp_sk(sk)->subscribe.sctp_data_io_event) |
2186 | * At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT, | 2209 | pr_warn_ratelimited(DEPRECATED "%s (pid %d) " |
2210 | "Requested SCTP_SNDRCVINFO event.\n" | ||
2211 | "Use SCTP_RCVINFO through SCTP_RECVRCVINFO option instead.\n", | ||
2212 | current->comm, task_pid_nr(current)); | ||
2213 | |||
2214 | /* At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT, | ||
2187 | * if there is no data to be sent or retransmit, the stack will | 2215 | * if there is no data to be sent or retransmit, the stack will |
2188 | * immediately send up this notification. | 2216 | * immediately send up this notification. |
2189 | */ | 2217 | */ |
@@ -2747,19 +2775,22 @@ static int sctp_setsockopt_default_send_param(struct sock *sk, | |||
2747 | char __user *optval, | 2775 | char __user *optval, |
2748 | unsigned int optlen) | 2776 | unsigned int optlen) |
2749 | { | 2777 | { |
2750 | struct sctp_sndrcvinfo info; | ||
2751 | struct sctp_association *asoc; | ||
2752 | struct sctp_sock *sp = sctp_sk(sk); | 2778 | struct sctp_sock *sp = sctp_sk(sk); |
2779 | struct sctp_association *asoc; | ||
2780 | struct sctp_sndrcvinfo info; | ||
2753 | 2781 | ||
2754 | if (optlen != sizeof(struct sctp_sndrcvinfo)) | 2782 | if (optlen != sizeof(info)) |
2755 | return -EINVAL; | 2783 | return -EINVAL; |
2756 | if (copy_from_user(&info, optval, optlen)) | 2784 | if (copy_from_user(&info, optval, optlen)) |
2757 | return -EFAULT; | 2785 | return -EFAULT; |
2786 | if (info.sinfo_flags & | ||
2787 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | | ||
2788 | SCTP_ABORT | SCTP_EOF)) | ||
2789 | return -EINVAL; | ||
2758 | 2790 | ||
2759 | asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); | 2791 | asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); |
2760 | if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP)) | 2792 | if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP)) |
2761 | return -EINVAL; | 2793 | return -EINVAL; |
2762 | |||
2763 | if (asoc) { | 2794 | if (asoc) { |
2764 | asoc->default_stream = info.sinfo_stream; | 2795 | asoc->default_stream = info.sinfo_stream; |
2765 | asoc->default_flags = info.sinfo_flags; | 2796 | asoc->default_flags = info.sinfo_flags; |
@@ -2777,6 +2808,44 @@ static int sctp_setsockopt_default_send_param(struct sock *sk, | |||
2777 | return 0; | 2808 | return 0; |
2778 | } | 2809 | } |
2779 | 2810 | ||
2811 | /* RFC6458, Section 8.1.31. Set/get Default Send Parameters | ||
2812 | * (SCTP_DEFAULT_SNDINFO) | ||
2813 | */ | ||
2814 | static int sctp_setsockopt_default_sndinfo(struct sock *sk, | ||
2815 | char __user *optval, | ||
2816 | unsigned int optlen) | ||
2817 | { | ||
2818 | struct sctp_sock *sp = sctp_sk(sk); | ||
2819 | struct sctp_association *asoc; | ||
2820 | struct sctp_sndinfo info; | ||
2821 | |||
2822 | if (optlen != sizeof(info)) | ||
2823 | return -EINVAL; | ||
2824 | if (copy_from_user(&info, optval, optlen)) | ||
2825 | return -EFAULT; | ||
2826 | if (info.snd_flags & | ||
2827 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | | ||
2828 | SCTP_ABORT | SCTP_EOF)) | ||
2829 | return -EINVAL; | ||
2830 | |||
2831 | asoc = sctp_id2assoc(sk, info.snd_assoc_id); | ||
2832 | if (!asoc && info.snd_assoc_id && sctp_style(sk, UDP)) | ||
2833 | return -EINVAL; | ||
2834 | if (asoc) { | ||
2835 | asoc->default_stream = info.snd_sid; | ||
2836 | asoc->default_flags = info.snd_flags; | ||
2837 | asoc->default_ppid = info.snd_ppid; | ||
2838 | asoc->default_context = info.snd_context; | ||
2839 | } else { | ||
2840 | sp->default_stream = info.snd_sid; | ||
2841 | sp->default_flags = info.snd_flags; | ||
2842 | sp->default_ppid = info.snd_ppid; | ||
2843 | sp->default_context = info.snd_context; | ||
2844 | } | ||
2845 | |||
2846 | return 0; | ||
2847 | } | ||
2848 | |||
2780 | /* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR) | 2849 | /* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR) |
2781 | * | 2850 | * |
2782 | * Requests that the local SCTP stack use the enclosed peer address as | 2851 | * Requests that the local SCTP stack use the enclosed peer address as |
@@ -3523,7 +3592,6 @@ static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval, | |||
3523 | return 0; | 3592 | return 0; |
3524 | } | 3593 | } |
3525 | 3594 | ||
3526 | |||
3527 | /* | 3595 | /* |
3528 | * SCTP_PEER_ADDR_THLDS | 3596 | * SCTP_PEER_ADDR_THLDS |
3529 | * | 3597 | * |
@@ -3574,6 +3642,38 @@ static int sctp_setsockopt_paddr_thresholds(struct sock *sk, | |||
3574 | return 0; | 3642 | return 0; |
3575 | } | 3643 | } |
3576 | 3644 | ||
3645 | static int sctp_setsockopt_recvrcvinfo(struct sock *sk, | ||
3646 | char __user *optval, | ||
3647 | unsigned int optlen) | ||
3648 | { | ||
3649 | int val; | ||
3650 | |||
3651 | if (optlen < sizeof(int)) | ||
3652 | return -EINVAL; | ||
3653 | if (get_user(val, (int __user *) optval)) | ||
3654 | return -EFAULT; | ||
3655 | |||
3656 | sctp_sk(sk)->recvrcvinfo = (val == 0) ? 0 : 1; | ||
3657 | |||
3658 | return 0; | ||
3659 | } | ||
3660 | |||
3661 | static int sctp_setsockopt_recvnxtinfo(struct sock *sk, | ||
3662 | char __user *optval, | ||
3663 | unsigned int optlen) | ||
3664 | { | ||
3665 | int val; | ||
3666 | |||
3667 | if (optlen < sizeof(int)) | ||
3668 | return -EINVAL; | ||
3669 | if (get_user(val, (int __user *) optval)) | ||
3670 | return -EFAULT; | ||
3671 | |||
3672 | sctp_sk(sk)->recvnxtinfo = (val == 0) ? 0 : 1; | ||
3673 | |||
3674 | return 0; | ||
3675 | } | ||
3676 | |||
3577 | /* API 6.2 setsockopt(), getsockopt() | 3677 | /* API 6.2 setsockopt(), getsockopt() |
3578 | * | 3678 | * |
3579 | * Applications use setsockopt() and getsockopt() to set or retrieve | 3679 | * Applications use setsockopt() and getsockopt() to set or retrieve |
@@ -3671,6 +3771,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
3671 | retval = sctp_setsockopt_default_send_param(sk, optval, | 3771 | retval = sctp_setsockopt_default_send_param(sk, optval, |
3672 | optlen); | 3772 | optlen); |
3673 | break; | 3773 | break; |
3774 | case SCTP_DEFAULT_SNDINFO: | ||
3775 | retval = sctp_setsockopt_default_sndinfo(sk, optval, optlen); | ||
3776 | break; | ||
3674 | case SCTP_PRIMARY_ADDR: | 3777 | case SCTP_PRIMARY_ADDR: |
3675 | retval = sctp_setsockopt_primary_addr(sk, optval, optlen); | 3778 | retval = sctp_setsockopt_primary_addr(sk, optval, optlen); |
3676 | break; | 3779 | break; |
@@ -3725,6 +3828,12 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
3725 | case SCTP_PEER_ADDR_THLDS: | 3828 | case SCTP_PEER_ADDR_THLDS: |
3726 | retval = sctp_setsockopt_paddr_thresholds(sk, optval, optlen); | 3829 | retval = sctp_setsockopt_paddr_thresholds(sk, optval, optlen); |
3727 | break; | 3830 | break; |
3831 | case SCTP_RECVRCVINFO: | ||
3832 | retval = sctp_setsockopt_recvrcvinfo(sk, optval, optlen); | ||
3833 | break; | ||
3834 | case SCTP_RECVNXTINFO: | ||
3835 | retval = sctp_setsockopt_recvnxtinfo(sk, optval, optlen); | ||
3836 | break; | ||
3728 | default: | 3837 | default: |
3729 | retval = -ENOPROTOOPT; | 3838 | retval = -ENOPROTOOPT; |
3730 | break; | 3839 | break; |
@@ -3971,6 +4080,9 @@ static int sctp_init_sock(struct sock *sk) | |||
3971 | /* Enable Nagle algorithm by default. */ | 4080 | /* Enable Nagle algorithm by default. */ |
3972 | sp->nodelay = 0; | 4081 | sp->nodelay = 0; |
3973 | 4082 | ||
4083 | sp->recvrcvinfo = 0; | ||
4084 | sp->recvnxtinfo = 0; | ||
4085 | |||
3974 | /* Enable by default. */ | 4086 | /* Enable by default. */ |
3975 | sp->v4mapped = 1; | 4087 | sp->v4mapped = 1; |
3976 | 4088 | ||
@@ -4131,7 +4243,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, | |||
4131 | transport = asoc->peer.primary_path; | 4243 | transport = asoc->peer.primary_path; |
4132 | 4244 | ||
4133 | status.sstat_assoc_id = sctp_assoc2id(asoc); | 4245 | status.sstat_assoc_id = sctp_assoc2id(asoc); |
4134 | status.sstat_state = asoc->state; | 4246 | status.sstat_state = sctp_assoc_to_state(asoc); |
4135 | status.sstat_rwnd = asoc->peer.rwnd; | 4247 | status.sstat_rwnd = asoc->peer.rwnd; |
4136 | status.sstat_unackdata = asoc->unack_data; | 4248 | status.sstat_unackdata = asoc->unack_data; |
4137 | 4249 | ||
@@ -4143,7 +4255,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, | |||
4143 | memcpy(&status.sstat_primary.spinfo_address, &transport->ipaddr, | 4255 | memcpy(&status.sstat_primary.spinfo_address, &transport->ipaddr, |
4144 | transport->af_specific->sockaddr_len); | 4256 | transport->af_specific->sockaddr_len); |
4145 | /* Map ipv4 address into v4-mapped-on-v6 address. */ | 4257 | /* Map ipv4 address into v4-mapped-on-v6 address. */ |
4146 | 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), |
4147 | (union sctp_addr *)&status.sstat_primary.spinfo_address); | 4259 | (union sctp_addr *)&status.sstat_primary.spinfo_address); |
4148 | status.sstat_primary.spinfo_state = transport->state; | 4260 | status.sstat_primary.spinfo_state = transport->state; |
4149 | status.sstat_primary.spinfo_cwnd = transport->cwnd; | 4261 | status.sstat_primary.spinfo_cwnd = transport->cwnd; |
@@ -4301,8 +4413,8 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv | |||
4301 | int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) | 4413 | int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) |
4302 | { | 4414 | { |
4303 | 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); | ||
4304 | struct socket *sock; | 4417 | struct socket *sock; |
4305 | struct sctp_af *af; | ||
4306 | int err = 0; | 4418 | int err = 0; |
4307 | 4419 | ||
4308 | if (!asoc) | 4420 | if (!asoc) |
@@ -4324,8 +4436,7 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) | |||
4324 | /* Make peeled-off sockets more like 1-1 accepted sockets. | 4436 | /* Make peeled-off sockets more like 1-1 accepted sockets. |
4325 | * Set the daddr and initialize id to something more random | 4437 | * Set the daddr and initialize id to something more random |
4326 | */ | 4438 | */ |
4327 | af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family); | 4439 | sp->pf->to_sk_daddr(&asoc->peer.primary_addr, sk); |
4328 | af->to_sk_daddr(&asoc->peer.primary_addr, sk); | ||
4329 | 4440 | ||
4330 | /* 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 |
4331 | * asoc to the newsk. | 4442 | * asoc to the newsk. |
@@ -4709,8 +4820,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, | |||
4709 | list_for_each_entry(from, &asoc->peer.transport_addr_list, | 4820 | list_for_each_entry(from, &asoc->peer.transport_addr_list, |
4710 | transports) { | 4821 | transports) { |
4711 | memcpy(&temp, &from->ipaddr, sizeof(temp)); | 4822 | memcpy(&temp, &from->ipaddr, sizeof(temp)); |
4712 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | 4823 | addrlen = sctp_get_pf_specific(sk->sk_family) |
4713 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4824 | ->addr_to_user(sp, &temp); |
4714 | if (space_left < addrlen) | 4825 | if (space_left < addrlen) |
4715 | return -ENOMEM; | 4826 | return -ENOMEM; |
4716 | if (copy_to_user(to, &temp, addrlen)) | 4827 | if (copy_to_user(to, &temp, addrlen)) |
@@ -4754,9 +4865,9 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, | |||
4754 | if (!temp.v4.sin_port) | 4865 | if (!temp.v4.sin_port) |
4755 | temp.v4.sin_port = htons(port); | 4866 | temp.v4.sin_port = htons(port); |
4756 | 4867 | ||
4757 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), | 4868 | addrlen = sctp_get_pf_specific(sk->sk_family) |
4758 | &temp); | 4869 | ->addr_to_user(sctp_sk(sk), &temp); |
4759 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4870 | |
4760 | if (space_left < addrlen) { | 4871 | if (space_left < addrlen) { |
4761 | cnt = -ENOMEM; | 4872 | cnt = -ENOMEM; |
4762 | break; | 4873 | break; |
@@ -4844,8 +4955,8 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4844 | */ | 4955 | */ |
4845 | list_for_each_entry(addr, &bp->address_list, list) { | 4956 | list_for_each_entry(addr, &bp->address_list, list) { |
4846 | memcpy(&temp, &addr->a, sizeof(temp)); | 4957 | memcpy(&temp, &addr->a, sizeof(temp)); |
4847 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | 4958 | addrlen = sctp_get_pf_specific(sk->sk_family) |
4848 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4959 | ->addr_to_user(sp, &temp); |
4849 | if (space_left < addrlen) { | 4960 | if (space_left < addrlen) { |
4850 | err = -ENOMEM; /*fixme: right error?*/ | 4961 | err = -ENOMEM; /*fixme: right error?*/ |
4851 | goto out; | 4962 | goto out; |
@@ -4904,7 +5015,7 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len, | |||
4904 | memcpy(&prim.ssp_addr, &asoc->peer.primary_path->ipaddr, | 5015 | memcpy(&prim.ssp_addr, &asoc->peer.primary_path->ipaddr, |
4905 | asoc->peer.primary_path->af_specific->sockaddr_len); | 5016 | asoc->peer.primary_path->af_specific->sockaddr_len); |
4906 | 5017 | ||
4907 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, | 5018 | sctp_get_pf_specific(sk->sk_family)->addr_to_user(sp, |
4908 | (union sctp_addr *)&prim.ssp_addr); | 5019 | (union sctp_addr *)&prim.ssp_addr); |
4909 | 5020 | ||
4910 | if (put_user(len, optlen)) | 5021 | if (put_user(len, optlen)) |
@@ -4964,14 +5075,14 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, | |||
4964 | int len, char __user *optval, | 5075 | int len, char __user *optval, |
4965 | int __user *optlen) | 5076 | int __user *optlen) |
4966 | { | 5077 | { |
4967 | struct sctp_sndrcvinfo info; | ||
4968 | struct sctp_association *asoc; | ||
4969 | struct sctp_sock *sp = sctp_sk(sk); | 5078 | struct sctp_sock *sp = sctp_sk(sk); |
5079 | struct sctp_association *asoc; | ||
5080 | struct sctp_sndrcvinfo info; | ||
4970 | 5081 | ||
4971 | if (len < sizeof(struct sctp_sndrcvinfo)) | 5082 | if (len < sizeof(info)) |
4972 | return -EINVAL; | 5083 | return -EINVAL; |
4973 | 5084 | ||
4974 | len = sizeof(struct sctp_sndrcvinfo); | 5085 | len = sizeof(info); |
4975 | 5086 | ||
4976 | if (copy_from_user(&info, optval, len)) | 5087 | if (copy_from_user(&info, optval, len)) |
4977 | return -EFAULT; | 5088 | return -EFAULT; |
@@ -4979,7 +5090,6 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, | |||
4979 | asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); | 5090 | asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); |
4980 | if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP)) | 5091 | if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP)) |
4981 | return -EINVAL; | 5092 | return -EINVAL; |
4982 | |||
4983 | if (asoc) { | 5093 | if (asoc) { |
4984 | info.sinfo_stream = asoc->default_stream; | 5094 | info.sinfo_stream = asoc->default_stream; |
4985 | info.sinfo_flags = asoc->default_flags; | 5095 | info.sinfo_flags = asoc->default_flags; |
@@ -5002,6 +5112,48 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, | |||
5002 | return 0; | 5112 | return 0; |
5003 | } | 5113 | } |
5004 | 5114 | ||
5115 | /* RFC6458, Section 8.1.31. Set/get Default Send Parameters | ||
5116 | * (SCTP_DEFAULT_SNDINFO) | ||
5117 | */ | ||
5118 | static int sctp_getsockopt_default_sndinfo(struct sock *sk, int len, | ||
5119 | char __user *optval, | ||
5120 | int __user *optlen) | ||
5121 | { | ||
5122 | struct sctp_sock *sp = sctp_sk(sk); | ||
5123 | struct sctp_association *asoc; | ||
5124 | struct sctp_sndinfo info; | ||
5125 | |||
5126 | if (len < sizeof(info)) | ||
5127 | return -EINVAL; | ||
5128 | |||
5129 | len = sizeof(info); | ||
5130 | |||
5131 | if (copy_from_user(&info, optval, len)) | ||
5132 | return -EFAULT; | ||
5133 | |||
5134 | asoc = sctp_id2assoc(sk, info.snd_assoc_id); | ||
5135 | if (!asoc && info.snd_assoc_id && sctp_style(sk, UDP)) | ||
5136 | return -EINVAL; | ||
5137 | if (asoc) { | ||
5138 | info.snd_sid = asoc->default_stream; | ||
5139 | info.snd_flags = asoc->default_flags; | ||
5140 | info.snd_ppid = asoc->default_ppid; | ||
5141 | info.snd_context = asoc->default_context; | ||
5142 | } else { | ||
5143 | info.snd_sid = sp->default_stream; | ||
5144 | info.snd_flags = sp->default_flags; | ||
5145 | info.snd_ppid = sp->default_ppid; | ||
5146 | info.snd_context = sp->default_context; | ||
5147 | } | ||
5148 | |||
5149 | if (put_user(len, optlen)) | ||
5150 | return -EFAULT; | ||
5151 | if (copy_to_user(optval, &info, len)) | ||
5152 | return -EFAULT; | ||
5153 | |||
5154 | return 0; | ||
5155 | } | ||
5156 | |||
5005 | /* | 5157 | /* |
5006 | * | 5158 | * |
5007 | * 7.1.5 SCTP_NODELAY | 5159 | * 7.1.5 SCTP_NODELAY |
@@ -5752,6 +5904,46 @@ static int sctp_getsockopt_assoc_stats(struct sock *sk, int len, | |||
5752 | return 0; | 5904 | return 0; |
5753 | } | 5905 | } |
5754 | 5906 | ||
5907 | static int sctp_getsockopt_recvrcvinfo(struct sock *sk, int len, | ||
5908 | char __user *optval, | ||
5909 | int __user *optlen) | ||
5910 | { | ||
5911 | int val = 0; | ||
5912 | |||
5913 | if (len < sizeof(int)) | ||
5914 | return -EINVAL; | ||
5915 | |||
5916 | len = sizeof(int); | ||
5917 | if (sctp_sk(sk)->recvrcvinfo) | ||
5918 | val = 1; | ||
5919 | if (put_user(len, optlen)) | ||
5920 | return -EFAULT; | ||
5921 | if (copy_to_user(optval, &val, len)) | ||
5922 | return -EFAULT; | ||
5923 | |||
5924 | return 0; | ||
5925 | } | ||
5926 | |||
5927 | static int sctp_getsockopt_recvnxtinfo(struct sock *sk, int len, | ||
5928 | char __user *optval, | ||
5929 | int __user *optlen) | ||
5930 | { | ||
5931 | int val = 0; | ||
5932 | |||
5933 | if (len < sizeof(int)) | ||
5934 | return -EINVAL; | ||
5935 | |||
5936 | len = sizeof(int); | ||
5937 | if (sctp_sk(sk)->recvnxtinfo) | ||
5938 | val = 1; | ||
5939 | if (put_user(len, optlen)) | ||
5940 | return -EFAULT; | ||
5941 | if (copy_to_user(optval, &val, len)) | ||
5942 | return -EFAULT; | ||
5943 | |||
5944 | return 0; | ||
5945 | } | ||
5946 | |||
5755 | static int sctp_getsockopt(struct sock *sk, int level, int optname, | 5947 | static int sctp_getsockopt(struct sock *sk, int level, int optname, |
5756 | char __user *optval, int __user *optlen) | 5948 | char __user *optval, int __user *optlen) |
5757 | { | 5949 | { |
@@ -5821,6 +6013,10 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
5821 | retval = sctp_getsockopt_default_send_param(sk, len, | 6013 | retval = sctp_getsockopt_default_send_param(sk, len, |
5822 | optval, optlen); | 6014 | optval, optlen); |
5823 | break; | 6015 | break; |
6016 | case SCTP_DEFAULT_SNDINFO: | ||
6017 | retval = sctp_getsockopt_default_sndinfo(sk, len, | ||
6018 | optval, optlen); | ||
6019 | break; | ||
5824 | case SCTP_PRIMARY_ADDR: | 6020 | case SCTP_PRIMARY_ADDR: |
5825 | retval = sctp_getsockopt_primary_addr(sk, len, optval, optlen); | 6021 | retval = sctp_getsockopt_primary_addr(sk, len, optval, optlen); |
5826 | break; | 6022 | break; |
@@ -5895,6 +6091,12 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
5895 | case SCTP_GET_ASSOC_STATS: | 6091 | case SCTP_GET_ASSOC_STATS: |
5896 | retval = sctp_getsockopt_assoc_stats(sk, len, optval, optlen); | 6092 | retval = sctp_getsockopt_assoc_stats(sk, len, optval, optlen); |
5897 | break; | 6093 | break; |
6094 | case SCTP_RECVRCVINFO: | ||
6095 | retval = sctp_getsockopt_recvrcvinfo(sk, len, optval, optlen); | ||
6096 | break; | ||
6097 | case SCTP_RECVNXTINFO: | ||
6098 | retval = sctp_getsockopt_recvnxtinfo(sk, len, optval, optlen); | ||
6099 | break; | ||
5898 | default: | 6100 | default: |
5899 | retval = -ENOPROTOOPT; | 6101 | retval = -ENOPROTOOPT; |
5900 | break; | 6102 | break; |
@@ -6390,8 +6592,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) | |||
6390 | struct cmsghdr *cmsg; | 6592 | struct cmsghdr *cmsg; |
6391 | struct msghdr *my_msg = (struct msghdr *)msg; | 6593 | struct msghdr *my_msg = (struct msghdr *)msg; |
6392 | 6594 | ||
6393 | for (cmsg = CMSG_FIRSTHDR(msg); | 6595 | for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; |
6394 | cmsg != NULL; | ||
6395 | cmsg = CMSG_NXTHDR(my_msg, cmsg)) { | 6596 | cmsg = CMSG_NXTHDR(my_msg, cmsg)) { |
6396 | if (!CMSG_OK(my_msg, cmsg)) | 6597 | if (!CMSG_OK(my_msg, cmsg)) |
6397 | return -EINVAL; | 6598 | return -EINVAL; |
@@ -6404,7 +6605,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) | |||
6404 | switch (cmsg->cmsg_type) { | 6605 | switch (cmsg->cmsg_type) { |
6405 | case SCTP_INIT: | 6606 | case SCTP_INIT: |
6406 | /* SCTP Socket API Extension | 6607 | /* SCTP Socket API Extension |
6407 | * 5.2.1 SCTP Initiation Structure (SCTP_INIT) | 6608 | * 5.3.1 SCTP Initiation Structure (SCTP_INIT) |
6408 | * | 6609 | * |
6409 | * This cmsghdr structure provides information for | 6610 | * This cmsghdr structure provides information for |
6410 | * initializing new SCTP associations with sendmsg(). | 6611 | * initializing new SCTP associations with sendmsg(). |
@@ -6416,15 +6617,15 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) | |||
6416 | * ------------ ------------ ---------------------- | 6617 | * ------------ ------------ ---------------------- |
6417 | * IPPROTO_SCTP SCTP_INIT struct sctp_initmsg | 6618 | * IPPROTO_SCTP SCTP_INIT struct sctp_initmsg |
6418 | */ | 6619 | */ |
6419 | if (cmsg->cmsg_len != | 6620 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_initmsg))) |
6420 | CMSG_LEN(sizeof(struct sctp_initmsg))) | ||
6421 | return -EINVAL; | 6621 | return -EINVAL; |
6422 | cmsgs->init = (struct sctp_initmsg *)CMSG_DATA(cmsg); | 6622 | |
6623 | cmsgs->init = CMSG_DATA(cmsg); | ||
6423 | break; | 6624 | break; |
6424 | 6625 | ||
6425 | case SCTP_SNDRCV: | 6626 | case SCTP_SNDRCV: |
6426 | /* SCTP Socket API Extension | 6627 | /* SCTP Socket API Extension |
6427 | * 5.2.2 SCTP Header Information Structure(SCTP_SNDRCV) | 6628 | * 5.3.2 SCTP Header Information Structure(SCTP_SNDRCV) |
6428 | * | 6629 | * |
6429 | * This cmsghdr structure specifies SCTP options for | 6630 | * This cmsghdr structure specifies SCTP options for |
6430 | * sendmsg() and describes SCTP header information | 6631 | * sendmsg() and describes SCTP header information |
@@ -6434,24 +6635,44 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) | |||
6434 | * ------------ ------------ ---------------------- | 6635 | * ------------ ------------ ---------------------- |
6435 | * IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo | 6636 | * IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo |
6436 | */ | 6637 | */ |
6437 | if (cmsg->cmsg_len != | 6638 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_sndrcvinfo))) |
6438 | CMSG_LEN(sizeof(struct sctp_sndrcvinfo))) | ||
6439 | return -EINVAL; | 6639 | return -EINVAL; |
6440 | 6640 | ||
6441 | cmsgs->info = | 6641 | cmsgs->srinfo = CMSG_DATA(cmsg); |
6442 | (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | ||
6443 | 6642 | ||
6444 | /* Minimally, validate the sinfo_flags. */ | 6643 | if (cmsgs->srinfo->sinfo_flags & |
6445 | if (cmsgs->info->sinfo_flags & | ||
6446 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | | 6644 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | |
6447 | SCTP_ABORT | SCTP_EOF)) | 6645 | SCTP_ABORT | SCTP_EOF)) |
6448 | return -EINVAL; | 6646 | return -EINVAL; |
6449 | break; | 6647 | break; |
6450 | 6648 | ||
6649 | case SCTP_SNDINFO: | ||
6650 | /* SCTP Socket API Extension | ||
6651 | * 5.3.4 SCTP Send Information Structure (SCTP_SNDINFO) | ||
6652 | * | ||
6653 | * This cmsghdr structure specifies SCTP options for | ||
6654 | * sendmsg(). This structure and SCTP_RCVINFO replaces | ||
6655 | * SCTP_SNDRCV which has been deprecated. | ||
6656 | * | ||
6657 | * cmsg_level cmsg_type cmsg_data[] | ||
6658 | * ------------ ------------ --------------------- | ||
6659 | * IPPROTO_SCTP SCTP_SNDINFO struct sctp_sndinfo | ||
6660 | */ | ||
6661 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_sndinfo))) | ||
6662 | return -EINVAL; | ||
6663 | |||
6664 | cmsgs->sinfo = CMSG_DATA(cmsg); | ||
6665 | |||
6666 | if (cmsgs->sinfo->snd_flags & | ||
6667 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | | ||
6668 | SCTP_ABORT | SCTP_EOF)) | ||
6669 | return -EINVAL; | ||
6670 | break; | ||
6451 | default: | 6671 | default: |
6452 | return -EINVAL; | 6672 | return -EINVAL; |
6453 | } | 6673 | } |
6454 | } | 6674 | } |
6675 | |||
6455 | return 0; | 6676 | return 0; |
6456 | } | 6677 | } |
6457 | 6678 | ||
@@ -6518,8 +6739,8 @@ out: | |||
6518 | * Note: This is pretty much the same routine as in core/datagram.c | 6739 | * Note: This is pretty much the same routine as in core/datagram.c |
6519 | * with a few changes to make lksctp work. | 6740 | * with a few changes to make lksctp work. |
6520 | */ | 6741 | */ |
6521 | static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, | 6742 | struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, |
6522 | int noblock, int *err) | 6743 | int noblock, int *err) |
6523 | { | 6744 | { |
6524 | int error; | 6745 | int error; |
6525 | struct sk_buff *skb; | 6746 | struct sk_buff *skb; |