Commit 7708610b1bff4a0ba8a73733d3c7c4bda9f94b21

Authored by Frank Filz
Committed by David S. Miller
1 parent 52ccb8e90c

[SCTP]: Add support for SCTP_DELAYED_ACK_TIME socket option.

Signed-off-by: Frank Filz <ffilz@us.ibm.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 2 changed files with 198 additions and 0 deletions Side-by-side Diff

include/net/sctp/user.h
... ... @@ -93,6 +93,8 @@
93 93 #define SCTP_STATUS SCTP_STATUS
94 94 SCTP_GET_PEER_ADDR_INFO,
95 95 #define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO
  96 + SCTP_DELAYED_ACK_TIME,
  97 +#define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK_TIME
96 98  
97 99 /* Internal Socket Options. Some of the sctp library functions are
98 100 * implemented using these socket options.
... ... @@ -525,6 +527,18 @@
525 527 __u32 spp_sackdelay;
526 528 __u32 spp_flags;
527 529 } __attribute__((packed, aligned(4)));
  530 +
  531 +/* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
  532 + *
  533 + * This options will get or set the delayed ack timer. The time is set
  534 + * in milliseconds. If the assoc_id is 0, then this sets or gets the
  535 + * endpoints default delayed ack timer value. If the assoc_id field is
  536 + * non-zero, then the set or get effects the specified association.
  537 + */
  538 +struct sctp_assoc_value {
  539 + sctp_assoc_t assoc_id;
  540 + uint32_t assoc_value;
  541 +};
528 542  
529 543 /*
530 544 * 7.2.2 Peer Address Information
... ... @@ -2214,6 +2214,109 @@
2214 2214 return 0;
2215 2215 }
2216 2216  
  2217 +/* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
  2218 + *
  2219 + * This options will get or set the delayed ack timer. The time is set
  2220 + * in milliseconds. If the assoc_id is 0, then this sets or gets the
  2221 + * endpoints default delayed ack timer value. If the assoc_id field is
  2222 + * non-zero, then the set or get effects the specified association.
  2223 + *
  2224 + * struct sctp_assoc_value {
  2225 + * sctp_assoc_t assoc_id;
  2226 + * uint32_t assoc_value;
  2227 + * };
  2228 + *
  2229 + * assoc_id - This parameter, indicates which association the
  2230 + * user is preforming an action upon. Note that if
  2231 + * this field's value is zero then the endpoints
  2232 + * default value is changed (effecting future
  2233 + * associations only).
  2234 + *
  2235 + * assoc_value - This parameter contains the number of milliseconds
  2236 + * that the user is requesting the delayed ACK timer
  2237 + * be set to. Note that this value is defined in
  2238 + * the standard to be between 200 and 500 milliseconds.
  2239 + *
  2240 + * Note: a value of zero will leave the value alone,
  2241 + * but disable SACK delay. A non-zero value will also
  2242 + * enable SACK delay.
  2243 + */
  2244 +
  2245 +static int sctp_setsockopt_delayed_ack_time(struct sock *sk,
  2246 + char __user *optval, int optlen)
  2247 +{
  2248 + struct sctp_assoc_value params;
  2249 + struct sctp_transport *trans = NULL;
  2250 + struct sctp_association *asoc = NULL;
  2251 + struct sctp_sock *sp = sctp_sk(sk);
  2252 +
  2253 + if (optlen != sizeof(struct sctp_assoc_value))
  2254 + return - EINVAL;
  2255 +
  2256 + if (copy_from_user(&params, optval, optlen))
  2257 + return -EFAULT;
  2258 +
  2259 + /* Validate value parameter. */
  2260 + if (params.assoc_value > 500)
  2261 + return -EINVAL;
  2262 +
  2263 + /* Get association, if assoc_id != 0 and the socket is a one
  2264 + * to many style socket, and an association was not found, then
  2265 + * the id was invalid.
  2266 + */
  2267 + asoc = sctp_id2assoc(sk, params.assoc_id);
  2268 + if (!asoc && params.assoc_id && sctp_style(sk, UDP))
  2269 + return -EINVAL;
  2270 +
  2271 + if (params.assoc_value) {
  2272 + if (asoc) {
  2273 + asoc->sackdelay =
  2274 + msecs_to_jiffies(params.assoc_value);
  2275 + asoc->param_flags =
  2276 + (asoc->param_flags & ~SPP_SACKDELAY) |
  2277 + SPP_SACKDELAY_ENABLE;
  2278 + } else {
  2279 + sp->sackdelay = params.assoc_value;
  2280 + sp->param_flags =
  2281 + (sp->param_flags & ~SPP_SACKDELAY) |
  2282 + SPP_SACKDELAY_ENABLE;
  2283 + }
  2284 + } else {
  2285 + if (asoc) {
  2286 + asoc->param_flags =
  2287 + (asoc->param_flags & ~SPP_SACKDELAY) |
  2288 + SPP_SACKDELAY_DISABLE;
  2289 + } else {
  2290 + sp->param_flags =
  2291 + (sp->param_flags & ~SPP_SACKDELAY) |
  2292 + SPP_SACKDELAY_DISABLE;
  2293 + }
  2294 + }
  2295 +
  2296 + /* If change is for association, also apply to each transport. */
  2297 + if (asoc) {
  2298 + struct list_head *pos;
  2299 +
  2300 + list_for_each(pos, &asoc->peer.transport_addr_list) {
  2301 + trans = list_entry(pos, struct sctp_transport,
  2302 + transports);
  2303 + if (params.assoc_value) {
  2304 + trans->sackdelay =
  2305 + msecs_to_jiffies(params.assoc_value);
  2306 + trans->param_flags =
  2307 + (trans->param_flags & ~SPP_SACKDELAY) |
  2308 + SPP_SACKDELAY_ENABLE;
  2309 + } else {
  2310 + trans->param_flags =
  2311 + (trans->param_flags & ~SPP_SACKDELAY) |
  2312 + SPP_SACKDELAY_DISABLE;
  2313 + }
  2314 + }
  2315 + }
  2316 +
  2317 + return 0;
  2318 +}
  2319 +
2217 2320 /* 7.1.3 Initialization Parameters (SCTP_INITMSG)
2218 2321 *
2219 2322 * Applications can specify protocol parameters for the default association
... ... @@ -2660,6 +2763,10 @@
2660 2763 retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen);
2661 2764 break;
2662 2765  
  2766 + case SCTP_DELAYED_ACK_TIME:
  2767 + retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen);
  2768 + break;
  2769 +
2663 2770 case SCTP_INITMSG:
2664 2771 retval = sctp_setsockopt_initmsg(sk, optval, optlen);
2665 2772 break;
... ... @@ -3417,6 +3524,79 @@
3417 3524 return 0;
3418 3525 }
3419 3526  
  3527 +/* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
  3528 + *
  3529 + * This options will get or set the delayed ack timer. The time is set
  3530 + * in milliseconds. If the assoc_id is 0, then this sets or gets the
  3531 + * endpoints default delayed ack timer value. If the assoc_id field is
  3532 + * non-zero, then the set or get effects the specified association.
  3533 + *
  3534 + * struct sctp_assoc_value {
  3535 + * sctp_assoc_t assoc_id;
  3536 + * uint32_t assoc_value;
  3537 + * };
  3538 + *
  3539 + * assoc_id - This parameter, indicates which association the
  3540 + * user is preforming an action upon. Note that if
  3541 + * this field's value is zero then the endpoints
  3542 + * default value is changed (effecting future
  3543 + * associations only).
  3544 + *
  3545 + * assoc_value - This parameter contains the number of milliseconds
  3546 + * that the user is requesting the delayed ACK timer
  3547 + * be set to. Note that this value is defined in
  3548 + * the standard to be between 200 and 500 milliseconds.
  3549 + *
  3550 + * Note: a value of zero will leave the value alone,
  3551 + * but disable SACK delay. A non-zero value will also
  3552 + * enable SACK delay.
  3553 + */
  3554 +static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len,
  3555 + char __user *optval,
  3556 + int __user *optlen)
  3557 +{
  3558 + struct sctp_assoc_value params;
  3559 + struct sctp_association *asoc = NULL;
  3560 + struct sctp_sock *sp = sctp_sk(sk);
  3561 +
  3562 + if (len != sizeof(struct sctp_assoc_value))
  3563 + return - EINVAL;
  3564 +
  3565 + if (copy_from_user(&params, optval, len))
  3566 + return -EFAULT;
  3567 +
  3568 + /* Get association, if assoc_id != 0 and the socket is a one
  3569 + * to many style socket, and an association was not found, then
  3570 + * the id was invalid.
  3571 + */
  3572 + asoc = sctp_id2assoc(sk, params.assoc_id);
  3573 + if (!asoc && params.assoc_id && sctp_style(sk, UDP))
  3574 + return -EINVAL;
  3575 +
  3576 + if (asoc) {
  3577 + /* Fetch association values. */
  3578 + if (asoc->param_flags & SPP_SACKDELAY_ENABLE)
  3579 + params.assoc_value = jiffies_to_msecs(
  3580 + asoc->sackdelay);
  3581 + else
  3582 + params.assoc_value = 0;
  3583 + } else {
  3584 + /* Fetch socket values. */
  3585 + if (sp->param_flags & SPP_SACKDELAY_ENABLE)
  3586 + params.assoc_value = sp->sackdelay;
  3587 + else
  3588 + params.assoc_value = 0;
  3589 + }
  3590 +
  3591 + if (copy_to_user(optval, &params, len))
  3592 + return -EFAULT;
  3593 +
  3594 + if (put_user(len, optlen))
  3595 + return -EFAULT;
  3596 +
  3597 + return 0;
  3598 +}
  3599 +
3420 3600 /* 7.1.3 Initialization Parameters (SCTP_INITMSG)
3421 3601 *
3422 3602 * Applications can specify protocol parameters for the default association
... ... @@ -4272,6 +4452,10 @@
4272 4452 break;
4273 4453 case SCTP_PEER_ADDR_PARAMS:
4274 4454 retval = sctp_getsockopt_peer_addr_params(sk, len, optval,
  4455 + optlen);
  4456 + break;
  4457 + case SCTP_DELAYED_ACK_TIME:
  4458 + retval = sctp_getsockopt_delayed_ack_time(sk, len, optval,
4275 4459 optlen);
4276 4460 break;
4277 4461 case SCTP_INITMSG: