History

sctp: add sockopt to get/set stream scheduler parameters

As defined per RFC Draft ndata Section 4.3.3, named as SCTP_STREAM_SCHEDULER_VALUE.

Marcelo Ricardo Leitner committed 9 years ago

Commit 0ccdf3c1 parent 13aa8772 files · +84 −0Browse files

Unified · Split

2 files
  1. include/uapi/linux/sctp.h +7 −0
  2. net/sctp/socket.c +77 −0
include/uapi/linux/sctp.h+7−0
@@ -123,6 +123,7 @@ typedef __s32 sctp_assoc_t; · 122 unmodified lines
123123 #define SCTP_ADD_STREAMS 121
124124 #define SCTP_SOCKOPT_PEELOFF_FLAGS 122
125125 #define SCTP_STREAM_SCHEDULER 123
126+#define SCTP_STREAM_SCHEDULER_VALUE 124
126127
127128 /* PR-SCTP policies */
128129 #define SCTP_PR_SCTP_NONE 0x0000
@@ -815,6 +816,12 @@ struct sctp_assoc_value { · 686 unmodified lines
815816 uint32_t assoc_value;
816817 };
817818
819+struct sctp_stream_value {
820+ sctp_assoc_t assoc_id;
821+ uint16_t stream_id;
822+ uint16_t stream_value;
823+};
824+
818825 /*
819826 * 7.2.2 Peer Address Information
820827 *
net/sctp/socket.c+77−0
@@ -3945,6 +3945,34 @@ out: · 3944 unmodified lines
39453945 return retval;
39463946 }
39473947
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(&params, 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+
39483976 /* API 6.2 setsockopt(), getsockopt()
39493977 *
39503978 * 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
41294157 case SCTP_STREAM_SCHEDULER:
41304158 retval = sctp_setsockopt_scheduler(sk, optval, optlen);
41314159 break;
4160+ case SCTP_STREAM_SCHEDULER_VALUE:
4161+ retval = sctp_setsockopt_scheduler_value(sk, optval, optlen);
4162+ break;
41324163 default:
41334164 retval = -ENOPROTOOPT;
41344165 break;
@@ -6864,6 +6895,48 @@ out: · 2729 unmodified lines
68646895 return retval;
68656896 }
68666897
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(&params, 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+ &params.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, &params, len)) {
6932+ retval = -EFAULT;
6933+ goto out;
6934+ }
6935+
6936+out:
6937+ return retval;
6938+}
6939+
68676940 static int sctp_getsockopt(struct sock *sk, int level, int optname,
68686941 char __user *optval, int __user *optlen)
68696942 {
@@ -7050,6 +7123,10 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, · 180 unmodified lines
70507123 retval = sctp_getsockopt_scheduler(sk, len, optval,
70517124 optlen);
70527125 break;
7126+ case SCTP_STREAM_SCHEDULER_VALUE:
7127+ retval = sctp_getsockopt_scheduler_value(sk, len, optval,
7128+ optlen);
7129+ break;
70537130 default:
70547131 retval = -ENOPROTOOPT;
70557132 break;