Commit 7708610b1bff4a0ba8a73733d3c7c4bda9f94b21
Committed by
David S. Miller
1 parent
52ccb8e90c
Exists in
master
and in
7 other branches
[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 |
net/sctp/socket.c
... | ... | @@ -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(¶ms, 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(¶ms, 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, ¶ms, 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: |