diff options
| author | Frank Filz <ffilz@us.ibm.com> | 2005-12-22 14:37:30 -0500 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2006-01-03 16:11:13 -0500 |
| commit | 7708610b1bff4a0ba8a73733d3c7c4bda9f94b21 (patch) | |
| tree | 5594f507d721be8de0ec17a7a2c3b473e1e45c15 | |
| parent | 52ccb8e90c0ace233b8b740f2fc5de0dbd706b27 (diff) | |
[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>
| -rw-r--r-- | include/net/sctp/user.h | 14 | ||||
| -rw-r--r-- | net/sctp/socket.c | 184 |
2 files changed, 198 insertions, 0 deletions
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h index b9052864fa5a..8a6bef6f91eb 100644 --- a/include/net/sctp/user.h +++ b/include/net/sctp/user.h | |||
| @@ -93,6 +93,8 @@ enum sctp_optname { | |||
| 93 | #define SCTP_STATUS SCTP_STATUS | 93 | #define SCTP_STATUS SCTP_STATUS |
| 94 | SCTP_GET_PEER_ADDR_INFO, | 94 | SCTP_GET_PEER_ADDR_INFO, |
| 95 | #define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO | 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 | /* Internal Socket Options. Some of the sctp library functions are | 99 | /* Internal Socket Options. Some of the sctp library functions are |
| 98 | * implemented using these socket options. | 100 | * implemented using these socket options. |
| @@ -526,6 +528,18 @@ struct sctp_paddrparams { | |||
| 526 | __u32 spp_flags; | 528 | __u32 spp_flags; |
| 527 | } __attribute__((packed, aligned(4))); | 529 | } __attribute__((packed, aligned(4))); |
| 528 | 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 | }; | ||
| 542 | |||
| 529 | /* | 543 | /* |
| 530 | * 7.2.2 Peer Address Information | 544 | * 7.2.2 Peer Address Information |
| 531 | * | 545 | * |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index adb5ee62c2a6..fc04d185fa33 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -2214,6 +2214,109 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk, | |||
| 2214 | return 0; | 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 | /* 7.1.3 Initialization Parameters (SCTP_INITMSG) | 2320 | /* 7.1.3 Initialization Parameters (SCTP_INITMSG) |
| 2218 | * | 2321 | * |
| 2219 | * Applications can specify protocol parameters for the default association | 2322 | * Applications can specify protocol parameters for the default association |
| @@ -2660,6 +2763,10 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
| 2660 | retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen); | 2763 | retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen); |
| 2661 | break; | 2764 | break; |
| 2662 | 2765 | ||
| 2766 | case SCTP_DELAYED_ACK_TIME: | ||
| 2767 | retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen); | ||
| 2768 | break; | ||
| 2769 | |||
| 2663 | case SCTP_INITMSG: | 2770 | case SCTP_INITMSG: |
| 2664 | retval = sctp_setsockopt_initmsg(sk, optval, optlen); | 2771 | retval = sctp_setsockopt_initmsg(sk, optval, optlen); |
| 2665 | break; | 2772 | break; |
| @@ -3417,6 +3524,79 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, | |||
| 3417 | return 0; | 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 | /* 7.1.3 Initialization Parameters (SCTP_INITMSG) | 3600 | /* 7.1.3 Initialization Parameters (SCTP_INITMSG) |
| 3421 | * | 3601 | * |
| 3422 | * Applications can specify protocol parameters for the default association | 3602 | * Applications can specify protocol parameters for the default association |
| @@ -4274,6 +4454,10 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
| 4274 | retval = sctp_getsockopt_peer_addr_params(sk, len, optval, | 4454 | retval = sctp_getsockopt_peer_addr_params(sk, len, optval, |
| 4275 | optlen); | 4455 | optlen); |
| 4276 | break; | 4456 | break; |
| 4457 | case SCTP_DELAYED_ACK_TIME: | ||
| 4458 | retval = sctp_getsockopt_delayed_ack_time(sk, len, optval, | ||
| 4459 | optlen); | ||
| 4460 | break; | ||
| 4277 | case SCTP_INITMSG: | 4461 | case SCTP_INITMSG: |
| 4278 | retval = sctp_getsockopt_initmsg(sk, len, optval, optlen); | 4462 | retval = sctp_getsockopt_initmsg(sk, len, optval, optlen); |
| 4279 | break; | 4463 | break; |
