aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Filz <ffilz@us.ibm.com>2005-12-22 14:37:30 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-01-03 16:11:13 -0500
commit7708610b1bff4a0ba8a73733d3c7c4bda9f94b21 (patch)
tree5594f507d721be8de0ec17a7a2c3b473e1e45c15
parent52ccb8e90c0ace233b8b740f2fc5de0dbd706b27 (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.h14
-rw-r--r--net/sctp/socket.c184
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 */
538struct 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
2245static 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/* 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 */
3554static 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/* 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;