As defined per RFC Draft ndata Section 4.3.3, named as SCTP_STREAM_SCHEDULER_VALUE.
Unified · Split
| @@ -123,6 +123,7 @@ typedef __s32 sctp_assoc_t; · 122 unmodified lines | |||
| 123 | #define SCTP_ADD_STREAMS 121 | 123 | #define SCTP_ADD_STREAMS 121 |
| 124 | #define SCTP_SOCKOPT_PEELOFF_FLAGS 122 | 124 | #define SCTP_SOCKOPT_PEELOFF_FLAGS 122 |
| 125 | #define SCTP_STREAM_SCHEDULER 123 | 125 | #define SCTP_STREAM_SCHEDULER 123 |
| 126 | #define SCTP_STREAM_SCHEDULER_VALUE 124 | ||
| 126 | 127 | ||
| 127 | /* PR-SCTP policies */ | 128 | /* PR-SCTP policies */ |
| 128 | #define SCTP_PR_SCTP_NONE 0x0000 | 129 | #define SCTP_PR_SCTP_NONE 0x0000 |
| @@ -815,6 +816,12 @@ struct sctp_assoc_value { · 686 unmodified lines | |||
| 815 | uint32_t assoc_value; | 816 | uint32_t assoc_value; |
| 816 | }; | 817 | }; |
| 817 | 818 | ||
| 819 | struct sctp_stream_value { | ||
| 820 | sctp_assoc_t assoc_id; | ||
| 821 | uint16_t stream_id; | ||
| 822 | uint16_t stream_value; | ||
| 823 | }; | ||
| 824 | |||
| 818 | /* | 825 | /* |
| 819 | * 7.2.2 Peer Address Information | 826 | * 7.2.2 Peer Address Information |
| 820 | * | 827 | * |
| @@ -3945,6 +3945,34 @@ out: · 3944 unmodified lines | |||
| 3945 | return retval; | 3945 | return retval; |
| 3946 | } | 3946 | } |
| 3947 | 3947 | ||
| 3948 | static int sctp_setsockopt_scheduler_value(struct sock *sk, | ||
| 3949 | char __user *optval, | ||
| 3950 | unsigned int optlen) | ||
| 3951 | { | ||
| 3952 | struct sctp_association *asoc; | ||
| 3953 | struct sctp_stream_value params; | ||
| 3954 | int retval = -EINVAL; | ||
| 3955 | |||
| 3956 | if (optlen < sizeof(params)) | ||
| 3957 | goto out; | ||
| 3958 | |||
| 3959 | optlen = sizeof(params); | ||
| 3960 | if (copy_from_user(¶ms, optval, optlen)) { | ||
| 3961 | retval = -EFAULT; | ||
| 3962 | goto out; | ||
| 3963 | } | ||
| 3964 | |||
| 3965 | asoc = sctp_id2assoc(sk, params.assoc_id); | ||
| 3966 | if (!asoc) | ||
| 3967 | goto out; | ||
| 3968 | |||
| 3969 | retval = sctp_sched_set_value(asoc, params.stream_id, | ||
| 3970 | params.stream_value, GFP_KERNEL); | ||
| 3971 | |||
| 3972 | out: | ||
| 3973 | return retval; | ||
| 3974 | } | ||
| 3975 | |||
| 3948 | /* API 6.2 setsockopt(), getsockopt() | 3976 | /* API 6.2 setsockopt(), getsockopt() |
| 3949 | * | 3977 | * |
| 3950 | * Applications use setsockopt() and getsockopt() to set or retrieve | 3978 | * Applications use setsockopt() and getsockopt() to set or retrieve |
| @@ -4129,6 +4157,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname, · 178 unmodified lines | |||
| 4129 | case SCTP_STREAM_SCHEDULER: | 4157 | case SCTP_STREAM_SCHEDULER: |
| 4130 | retval = sctp_setsockopt_scheduler(sk, optval, optlen); | 4158 | retval = sctp_setsockopt_scheduler(sk, optval, optlen); |
| 4131 | break; | 4159 | break; |
| 4160 | case SCTP_STREAM_SCHEDULER_VALUE: | ||
| 4161 | retval = sctp_setsockopt_scheduler_value(sk, optval, optlen); | ||
| 4162 | break; | ||
| 4132 | default: | 4163 | default: |
| 4133 | retval = -ENOPROTOOPT; | 4164 | retval = -ENOPROTOOPT; |
| 4134 | break; | 4165 | break; |
| @@ -6864,6 +6895,48 @@ out: · 2729 unmodified lines | |||
| 6864 | return retval; | 6895 | return retval; |
| 6865 | } | 6896 | } |
| 6866 | 6897 | ||
| 6898 | static int sctp_getsockopt_scheduler_value(struct sock *sk, int len, | ||
| 6899 | char __user *optval, | ||
| 6900 | int __user *optlen) | ||
| 6901 | { | ||
| 6902 | struct sctp_stream_value params; | ||
| 6903 | struct sctp_association *asoc; | ||
| 6904 | int retval = -EFAULT; | ||
| 6905 | |||
| 6906 | if (len < sizeof(params)) { | ||
| 6907 | retval = -EINVAL; | ||
| 6908 | goto out; | ||
| 6909 | } | ||
| 6910 | |||
| 6911 | len = sizeof(params); | ||
| 6912 | if (copy_from_user(¶ms, optval, len)) | ||
| 6913 | goto out; | ||
| 6914 | |||
| 6915 | asoc = sctp_id2assoc(sk, params.assoc_id); | ||
| 6916 | if (!asoc) { | ||
| 6917 | retval = -EINVAL; | ||
| 6918 | goto out; | ||
| 6919 | } | ||
| 6920 | |||
| 6921 | retval = sctp_sched_get_value(asoc, params.stream_id, | ||
| 6922 | ¶ms.stream_value); | ||
| 6923 | if (retval) | ||
| 6924 | goto out; | ||
| 6925 | |||
| 6926 | if (put_user(len, optlen)) { | ||
| 6927 | retval = -EFAULT; | ||
| 6928 | goto out; | ||
| 6929 | } | ||
| 6930 | |||
| 6931 | if (copy_to_user(optval, ¶ms, len)) { | ||
| 6932 | retval = -EFAULT; | ||
| 6933 | goto out; | ||
| 6934 | } | ||
| 6935 | |||
| 6936 | out: | ||
| 6937 | return retval; | ||
| 6938 | } | ||
| 6939 | |||
| 6867 | static int sctp_getsockopt(struct sock *sk, int level, int optname, | 6940 | static int sctp_getsockopt(struct sock *sk, int level, int optname, |
| 6868 | char __user *optval, int __user *optlen) | 6941 | char __user *optval, int __user *optlen) |
| 6869 | { | 6942 | { |
| @@ -7050,6 +7123,10 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, · 180 unmodified lines | |||
| 7050 | retval = sctp_getsockopt_scheduler(sk, len, optval, | 7123 | retval = sctp_getsockopt_scheduler(sk, len, optval, |
| 7051 | optlen); | 7124 | optlen); |
| 7052 | break; | 7125 | break; |
| 7126 | case SCTP_STREAM_SCHEDULER_VALUE: | ||
| 7127 | retval = sctp_getsockopt_scheduler_value(sk, len, optval, | ||
| 7128 | optlen); | ||
| 7129 | break; | ||
| 7053 | default: | 7130 | default: |
| 7054 | retval = -ENOPROTOOPT; | 7131 | retval = -ENOPROTOOPT; |
| 7055 | break; | 7132 | break; |