aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
authorWei Yongjun <yjwei@cn.fujitsu.com>2008-05-09 18:13:26 -0400
committerDavid S. Miller <davem@davemloft.net>2008-05-09 18:13:26 -0400
commitd364d9276b54af16fcb4db83f1315b620daec102 (patch)
tree1554b1e3f951cdbde62500056f3b26630c8e09ab /net/sctp/socket.c
parent5c5e12898af0978a780991950be12d0d73c02f04 (diff)
sctp: Bring SCTP_DELAYED_ACK socket option into API compliance
Brings delayed_ack socket option set/get into line with the latest ietf socket extensions API draft, while maintaining backwards compatibility. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c242
1 files changed, 153 insertions, 89 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index e7e3baf7009e..66985871401b 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2305,74 +2305,98 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
2305 return 0; 2305 return 0;
2306} 2306}
2307 2307
2308/* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) 2308/*
2309 * 2309 * 7.1.23. Get or set delayed ack timer (SCTP_DELAYED_SACK)
2310 * This options will get or set the delayed ack timer. The time is set 2310 *
2311 * in milliseconds. If the assoc_id is 0, then this sets or gets the 2311 * This option will effect the way delayed acks are performed. This
2312 * endpoints default delayed ack timer value. If the assoc_id field is 2312 * option allows you to get or set the delayed ack time, in
2313 * non-zero, then the set or get effects the specified association. 2313 * milliseconds. It also allows changing the delayed ack frequency.
2314 * 2314 * Changing the frequency to 1 disables the delayed sack algorithm. If
2315 * struct sctp_assoc_value { 2315 * the assoc_id is 0, then this sets or gets the endpoints default
2316 * sctp_assoc_t assoc_id; 2316 * values. If the assoc_id field is non-zero, then the set or get
2317 * uint32_t assoc_value; 2317 * effects the specified association for the one to many model (the
2318 * }; 2318 * assoc_id field is ignored by the one to one model). Note that if
2319 * 2319 * sack_delay or sack_freq are 0 when setting this option, then the
2320 * assoc_id - This parameter, indicates which association the 2320 * current values will remain unchanged.
2321 * user is preforming an action upon. Note that if 2321 *
2322 * this field's value is zero then the endpoints 2322 * struct sctp_sack_info {
2323 * default value is changed (effecting future 2323 * sctp_assoc_t sack_assoc_id;
2324 * associations only). 2324 * uint32_t sack_delay;
2325 * 2325 * uint32_t sack_freq;
2326 * assoc_value - This parameter contains the number of milliseconds 2326 * };
2327 * that the user is requesting the delayed ACK timer 2327 *
2328 * be set to. Note that this value is defined in 2328 * sack_assoc_id - This parameter, indicates which association the user
2329 * the standard to be between 200 and 500 milliseconds. 2329 * is performing an action upon. Note that if this field's value is
2330 * 2330 * zero then the endpoints default value is changed (effecting future
2331 * Note: a value of zero will leave the value alone, 2331 * associations only).
2332 * but disable SACK delay. A non-zero value will also 2332 *
2333 * enable SACK delay. 2333 * sack_delay - This parameter contains the number of milliseconds that
2334 * the user is requesting the delayed ACK timer be set to. Note that
2335 * this value is defined in the standard to be between 200 and 500
2336 * milliseconds.
2337 *
2338 * sack_freq - This parameter contains the number of packets that must
2339 * be received before a sack is sent without waiting for the delay
2340 * timer to expire. The default value for this is 2, setting this
2341 * value to 1 will disable the delayed sack algorithm.
2334 */ 2342 */
2335 2343
2336static int sctp_setsockopt_delayed_ack_time(struct sock *sk, 2344static int sctp_setsockopt_delayed_ack(struct sock *sk,
2337 char __user *optval, int optlen) 2345 char __user *optval, int optlen)
2338{ 2346{
2339 struct sctp_assoc_value params; 2347 struct sctp_sack_info params;
2340 struct sctp_transport *trans = NULL; 2348 struct sctp_transport *trans = NULL;
2341 struct sctp_association *asoc = NULL; 2349 struct sctp_association *asoc = NULL;
2342 struct sctp_sock *sp = sctp_sk(sk); 2350 struct sctp_sock *sp = sctp_sk(sk);
2343 2351
2344 if (optlen != sizeof(struct sctp_assoc_value)) 2352 if (optlen == sizeof(struct sctp_sack_info)) {
2345 return - EINVAL; 2353 if (copy_from_user(&params, optval, optlen))
2354 return -EFAULT;
2346 2355
2347 if (copy_from_user(&params, optval, optlen)) 2356 if (params.sack_delay == 0 && params.sack_freq == 0)
2348 return -EFAULT; 2357 return 0;
2358 } else if (optlen == sizeof(struct sctp_assoc_value)) {
2359 printk(KERN_WARNING "SCTP: Use of struct sctp_sack_info "
2360 "in delayed_ack socket option deprecated\n");
2361 printk(KERN_WARNING "SCTP: struct sctp_sack_info instead\n");
2362 if (copy_from_user(&params, optval, optlen))
2363 return -EFAULT;
2364
2365 if (params.sack_delay == 0)
2366 params.sack_freq = 1;
2367 else
2368 params.sack_freq = 0;
2369 } else
2370 return - EINVAL;
2349 2371
2350 /* Validate value parameter. */ 2372 /* Validate value parameter. */
2351 if (params.assoc_value > 500) 2373 if (params.sack_delay > 500)
2352 return -EINVAL; 2374 return -EINVAL;
2353 2375
2354 /* Get association, if assoc_id != 0 and the socket is a one 2376 /* Get association, if sack_assoc_id != 0 and the socket is a one
2355 * to many style socket, and an association was not found, then 2377 * to many style socket, and an association was not found, then
2356 * the id was invalid. 2378 * the id was invalid.
2357 */ 2379 */
2358 asoc = sctp_id2assoc(sk, params.assoc_id); 2380 asoc = sctp_id2assoc(sk, params.sack_assoc_id);
2359 if (!asoc && params.assoc_id && sctp_style(sk, UDP)) 2381 if (!asoc && params.sack_assoc_id && sctp_style(sk, UDP))
2360 return -EINVAL; 2382 return -EINVAL;
2361 2383
2362 if (params.assoc_value) { 2384 if (params.sack_delay) {
2363 if (asoc) { 2385 if (asoc) {
2364 asoc->sackdelay = 2386 asoc->sackdelay =
2365 msecs_to_jiffies(params.assoc_value); 2387 msecs_to_jiffies(params.sack_delay);
2366 asoc->param_flags = 2388 asoc->param_flags =
2367 (asoc->param_flags & ~SPP_SACKDELAY) | 2389 (asoc->param_flags & ~SPP_SACKDELAY) |
2368 SPP_SACKDELAY_ENABLE; 2390 SPP_SACKDELAY_ENABLE;
2369 } else { 2391 } else {
2370 sp->sackdelay = params.assoc_value; 2392 sp->sackdelay = params.sack_delay;
2371 sp->param_flags = 2393 sp->param_flags =
2372 (sp->param_flags & ~SPP_SACKDELAY) | 2394 (sp->param_flags & ~SPP_SACKDELAY) |
2373 SPP_SACKDELAY_ENABLE; 2395 SPP_SACKDELAY_ENABLE;
2374 } 2396 }
2375 } else { 2397 }
2398
2399 if (params.sack_freq == 1) {
2376 if (asoc) { 2400 if (asoc) {
2377 asoc->param_flags = 2401 asoc->param_flags =
2378 (asoc->param_flags & ~SPP_SACKDELAY) | 2402 (asoc->param_flags & ~SPP_SACKDELAY) |
@@ -2382,22 +2406,40 @@ static int sctp_setsockopt_delayed_ack_time(struct sock *sk,
2382 (sp->param_flags & ~SPP_SACKDELAY) | 2406 (sp->param_flags & ~SPP_SACKDELAY) |
2383 SPP_SACKDELAY_DISABLE; 2407 SPP_SACKDELAY_DISABLE;
2384 } 2408 }
2409 } else if (params.sack_freq > 1) {
2410 if (asoc) {
2411 asoc->sackfreq = params.sack_freq;
2412 asoc->param_flags =
2413 (asoc->param_flags & ~SPP_SACKDELAY) |
2414 SPP_SACKDELAY_ENABLE;
2415 } else {
2416 sp->sackfreq = params.sack_freq;
2417 sp->param_flags =
2418 (sp->param_flags & ~SPP_SACKDELAY) |
2419 SPP_SACKDELAY_ENABLE;
2420 }
2385 } 2421 }
2386 2422
2387 /* If change is for association, also apply to each transport. */ 2423 /* If change is for association, also apply to each transport. */
2388 if (asoc) { 2424 if (asoc) {
2389 list_for_each_entry(trans, &asoc->peer.transport_addr_list, 2425 list_for_each_entry(trans, &asoc->peer.transport_addr_list,
2390 transports) { 2426 transports) {
2391 if (params.assoc_value) { 2427 if (params.sack_delay) {
2392 trans->sackdelay = 2428 trans->sackdelay =
2393 msecs_to_jiffies(params.assoc_value); 2429 msecs_to_jiffies(params.sack_delay);
2394 trans->param_flags = 2430 trans->param_flags =
2395 (trans->param_flags & ~SPP_SACKDELAY) | 2431 (trans->param_flags & ~SPP_SACKDELAY) |
2396 SPP_SACKDELAY_ENABLE; 2432 SPP_SACKDELAY_ENABLE;
2397 } else { 2433 }
2434 if (params.sack_delay == 1) {
2398 trans->param_flags = 2435 trans->param_flags =
2399 (trans->param_flags & ~SPP_SACKDELAY) | 2436 (trans->param_flags & ~SPP_SACKDELAY) |
2400 SPP_SACKDELAY_DISABLE; 2437 SPP_SACKDELAY_DISABLE;
2438 } else if (params.sack_freq > 1) {
2439 trans->sackfreq = params.sack_freq;
2440 trans->param_flags =
2441 (trans->param_flags & ~SPP_SACKDELAY) |
2442 SPP_SACKDELAY_ENABLE;
2401 } 2443 }
2402 } 2444 }
2403 } 2445 }
@@ -3186,8 +3228,8 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
3186 retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen); 3228 retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen);
3187 break; 3229 break;
3188 3230
3189 case SCTP_DELAYED_ACK_TIME: 3231 case SCTP_DELAYED_ACK:
3190 retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen); 3232 retval = sctp_setsockopt_delayed_ack(sk, optval, optlen);
3191 break; 3233 break;
3192 case SCTP_PARTIAL_DELIVERY_POINT: 3234 case SCTP_PARTIAL_DELIVERY_POINT:
3193 retval = sctp_setsockopt_partial_delivery_point(sk, optval, optlen); 3235 retval = sctp_setsockopt_partial_delivery_point(sk, optval, optlen);
@@ -3446,6 +3488,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
3446 sp->pathmaxrxt = sctp_max_retrans_path; 3488 sp->pathmaxrxt = sctp_max_retrans_path;
3447 sp->pathmtu = 0; // allow default discovery 3489 sp->pathmtu = 0; // allow default discovery
3448 sp->sackdelay = sctp_sack_timeout; 3490 sp->sackdelay = sctp_sack_timeout;
3491 sp->sackfreq = 3;
3449 sp->param_flags = SPP_HB_ENABLE | 3492 sp->param_flags = SPP_HB_ENABLE |
3450 SPP_PMTUD_ENABLE | 3493 SPP_PMTUD_ENABLE |
3451 SPP_SACKDELAY_ENABLE; 3494 SPP_SACKDELAY_ENABLE;
@@ -3999,70 +4042,91 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
3999 return 0; 4042 return 0;
4000} 4043}
4001 4044
4002/* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) 4045/*
4003 * 4046 * 7.1.23. Get or set delayed ack timer (SCTP_DELAYED_SACK)
4004 * This options will get or set the delayed ack timer. The time is set 4047 *
4005 * in milliseconds. If the assoc_id is 0, then this sets or gets the 4048 * This option will effect the way delayed acks are performed. This
4006 * endpoints default delayed ack timer value. If the assoc_id field is 4049 * option allows you to get or set the delayed ack time, in
4007 * non-zero, then the set or get effects the specified association. 4050 * milliseconds. It also allows changing the delayed ack frequency.
4008 * 4051 * Changing the frequency to 1 disables the delayed sack algorithm. If
4009 * struct sctp_assoc_value { 4052 * the assoc_id is 0, then this sets or gets the endpoints default
4010 * sctp_assoc_t assoc_id; 4053 * values. If the assoc_id field is non-zero, then the set or get
4011 * uint32_t assoc_value; 4054 * effects the specified association for the one to many model (the
4012 * }; 4055 * assoc_id field is ignored by the one to one model). Note that if
4056 * sack_delay or sack_freq are 0 when setting this option, then the
4057 * current values will remain unchanged.
4058 *
4059 * struct sctp_sack_info {
4060 * sctp_assoc_t sack_assoc_id;
4061 * uint32_t sack_delay;
4062 * uint32_t sack_freq;
4063 * };
4013 * 4064 *
4014 * assoc_id - This parameter, indicates which association the 4065 * sack_assoc_id - This parameter, indicates which association the user
4015 * user is preforming an action upon. Note that if 4066 * is performing an action upon. Note that if this field's value is
4016 * this field's value is zero then the endpoints 4067 * zero then the endpoints default value is changed (effecting future
4017 * default value is changed (effecting future 4068 * associations only).
4018 * associations only).
4019 * 4069 *
4020 * assoc_value - This parameter contains the number of milliseconds 4070 * sack_delay - This parameter contains the number of milliseconds that
4021 * that the user is requesting the delayed ACK timer 4071 * the user is requesting the delayed ACK timer be set to. Note that
4022 * be set to. Note that this value is defined in 4072 * this value is defined in the standard to be between 200 and 500
4023 * the standard to be between 200 and 500 milliseconds. 4073 * milliseconds.
4024 * 4074 *
4025 * Note: a value of zero will leave the value alone, 4075 * sack_freq - This parameter contains the number of packets that must
4026 * but disable SACK delay. A non-zero value will also 4076 * be received before a sack is sent without waiting for the delay
4027 * enable SACK delay. 4077 * timer to expire. The default value for this is 2, setting this
4078 * value to 1 will disable the delayed sack algorithm.
4028 */ 4079 */
4029static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len, 4080static int sctp_getsockopt_delayed_ack(struct sock *sk, int len,
4030 char __user *optval, 4081 char __user *optval,
4031 int __user *optlen) 4082 int __user *optlen)
4032{ 4083{
4033 struct sctp_assoc_value params; 4084 struct sctp_sack_info params;
4034 struct sctp_association *asoc = NULL; 4085 struct sctp_association *asoc = NULL;
4035 struct sctp_sock *sp = sctp_sk(sk); 4086 struct sctp_sock *sp = sctp_sk(sk);
4036 4087
4037 if (len < sizeof(struct sctp_assoc_value)) 4088 if (len >= sizeof(struct sctp_sack_info)) {
4038 return - EINVAL; 4089 len = sizeof(struct sctp_sack_info);
4039 4090
4040 len = sizeof(struct sctp_assoc_value); 4091 if (copy_from_user(&params, optval, len))
4041 4092 return -EFAULT;
4042 if (copy_from_user(&params, optval, len)) 4093 } else if (len == sizeof(struct sctp_assoc_value)) {
4043 return -EFAULT; 4094 printk(KERN_WARNING "SCTP: Use of struct sctp_sack_info "
4095 "in delayed_ack socket option deprecated\n");
4096 printk(KERN_WARNING "SCTP: struct sctp_sack_info instead\n");
4097 if (copy_from_user(&params, optval, len))
4098 return -EFAULT;
4099 } else
4100 return - EINVAL;
4044 4101
4045 /* Get association, if assoc_id != 0 and the socket is a one 4102 /* Get association, if sack_assoc_id != 0 and the socket is a one
4046 * to many style socket, and an association was not found, then 4103 * to many style socket, and an association was not found, then
4047 * the id was invalid. 4104 * the id was invalid.
4048 */ 4105 */
4049 asoc = sctp_id2assoc(sk, params.assoc_id); 4106 asoc = sctp_id2assoc(sk, params.sack_assoc_id);
4050 if (!asoc && params.assoc_id && sctp_style(sk, UDP)) 4107 if (!asoc && params.sack_assoc_id && sctp_style(sk, UDP))
4051 return -EINVAL; 4108 return -EINVAL;
4052 4109
4053 if (asoc) { 4110 if (asoc) {
4054 /* Fetch association values. */ 4111 /* Fetch association values. */
4055 if (asoc->param_flags & SPP_SACKDELAY_ENABLE) 4112 if (asoc->param_flags & SPP_SACKDELAY_ENABLE) {
4056 params.assoc_value = jiffies_to_msecs( 4113 params.sack_delay = jiffies_to_msecs(
4057 asoc->sackdelay); 4114 asoc->sackdelay);
4058 else 4115 params.sack_freq = asoc->sackfreq;
4059 params.assoc_value = 0; 4116
4117 } else {
4118 params.sack_delay = 0;
4119 params.sack_freq = 1;
4120 }
4060 } else { 4121 } else {
4061 /* Fetch socket values. */ 4122 /* Fetch socket values. */
4062 if (sp->param_flags & SPP_SACKDELAY_ENABLE) 4123 if (sp->param_flags & SPP_SACKDELAY_ENABLE) {
4063 params.assoc_value = sp->sackdelay; 4124 params.sack_delay = sp->sackdelay;
4064 else 4125 params.sack_freq = sp->sackfreq;
4065 params.assoc_value = 0; 4126 } else {
4127 params.sack_delay = 0;
4128 params.sack_freq = 1;
4129 }
4066 } 4130 }
4067 4131
4068 if (copy_to_user(optval, &params, len)) 4132 if (copy_to_user(optval, &params, len))
@@ -5218,8 +5282,8 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
5218 retval = sctp_getsockopt_peer_addr_params(sk, len, optval, 5282 retval = sctp_getsockopt_peer_addr_params(sk, len, optval,
5219 optlen); 5283 optlen);
5220 break; 5284 break;
5221 case SCTP_DELAYED_ACK_TIME: 5285 case SCTP_DELAYED_ACK:
5222 retval = sctp_getsockopt_delayed_ack_time(sk, len, optval, 5286 retval = sctp_getsockopt_delayed_ack(sk, len, optval,
5223 optlen); 5287 optlen);
5224 break; 5288 break;
5225 case SCTP_INITMSG: 5289 case SCTP_INITMSG: