diff options
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/input.c | 10 | ||||
-rw-r--r-- | net/sctp/inqueue.c | 4 | ||||
-rw-r--r-- | net/sctp/ipv6.c | 7 | ||||
-rw-r--r-- | net/sctp/outqueue.c | 6 | ||||
-rw-r--r-- | net/sctp/proc.c | 17 | ||||
-rw-r--r-- | net/sctp/protocol.c | 11 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 174 | ||||
-rw-r--r-- | net/sctp/socket.c | 33 | ||||
-rw-r--r-- | net/sctp/sysctl.c | 140 | ||||
-rw-r--r-- | net/sctp/transport.c | 2 |
10 files changed, 217 insertions, 187 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index 42b66e74bbb5..03f65de75d88 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -228,7 +228,7 @@ int sctp_rcv(struct sk_buff *skb) | |||
228 | goto discard_release; | 228 | goto discard_release; |
229 | nf_reset(skb); | 229 | nf_reset(skb); |
230 | 230 | ||
231 | if (sk_filter(sk, skb, 1)) | 231 | if (sk_filter(sk, skb)) |
232 | goto discard_release; | 232 | goto discard_release; |
233 | 233 | ||
234 | /* Create an SCTP packet structure. */ | 234 | /* Create an SCTP packet structure. */ |
@@ -255,10 +255,13 @@ int sctp_rcv(struct sk_buff *skb) | |||
255 | */ | 255 | */ |
256 | sctp_bh_lock_sock(sk); | 256 | sctp_bh_lock_sock(sk); |
257 | 257 | ||
258 | if (sock_owned_by_user(sk)) | 258 | if (sock_owned_by_user(sk)) { |
259 | SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG); | ||
259 | sctp_add_backlog(sk, skb); | 260 | sctp_add_backlog(sk, skb); |
260 | else | 261 | } else { |
262 | SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_SOFTIRQ); | ||
261 | sctp_inq_push(&chunk->rcvr->inqueue, chunk); | 263 | sctp_inq_push(&chunk->rcvr->inqueue, chunk); |
264 | } | ||
262 | 265 | ||
263 | sctp_bh_unlock_sock(sk); | 266 | sctp_bh_unlock_sock(sk); |
264 | 267 | ||
@@ -271,6 +274,7 @@ int sctp_rcv(struct sk_buff *skb) | |||
271 | return 0; | 274 | return 0; |
272 | 275 | ||
273 | discard_it: | 276 | discard_it: |
277 | SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_DISCARDS); | ||
274 | kfree_skb(skb); | 278 | kfree_skb(skb); |
275 | return 0; | 279 | return 0; |
276 | 280 | ||
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index cf0c767d43ae..cf6deed7e849 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
@@ -87,7 +87,7 @@ void sctp_inq_free(struct sctp_inq *queue) | |||
87 | /* Put a new packet in an SCTP inqueue. | 87 | /* Put a new packet in an SCTP inqueue. |
88 | * We assume that packet->sctp_hdr is set and in host byte order. | 88 | * We assume that packet->sctp_hdr is set and in host byte order. |
89 | */ | 89 | */ |
90 | void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *packet) | 90 | void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *chunk) |
91 | { | 91 | { |
92 | /* Directly call the packet handling routine. */ | 92 | /* Directly call the packet handling routine. */ |
93 | 93 | ||
@@ -96,7 +96,7 @@ void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *packet) | |||
96 | * Eventually, we should clean up inqueue to not rely | 96 | * Eventually, we should clean up inqueue to not rely |
97 | * on the BH related data structures. | 97 | * on the BH related data structures. |
98 | */ | 98 | */ |
99 | list_add_tail(&packet->list, &q->in_chunk_list); | 99 | list_add_tail(&chunk->list, &q->in_chunk_list); |
100 | q->immediate.func(q->immediate.data); | 100 | q->immediate.func(q->immediate.data); |
101 | } | 101 | } |
102 | 102 | ||
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 99c0cefc04e0..249e5033c1a8 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -78,7 +78,6 @@ | |||
78 | 78 | ||
79 | #include <asm/uaccess.h> | 79 | #include <asm/uaccess.h> |
80 | 80 | ||
81 | extern int sctp_inetaddr_event(struct notifier_block *, unsigned long, void *); | ||
82 | static struct notifier_block sctp_inet6addr_notifier = { | 81 | static struct notifier_block sctp_inet6addr_notifier = { |
83 | .notifier_call = sctp_inetaddr_event, | 82 | .notifier_call = sctp_inetaddr_event, |
84 | }; | 83 | }; |
@@ -322,9 +321,9 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist, | |||
322 | struct inet6_ifaddr *ifp; | 321 | struct inet6_ifaddr *ifp; |
323 | struct sctp_sockaddr_entry *addr; | 322 | struct sctp_sockaddr_entry *addr; |
324 | 323 | ||
325 | read_lock(&addrconf_lock); | 324 | rcu_read_lock(); |
326 | if ((in6_dev = __in6_dev_get(dev)) == NULL) { | 325 | if ((in6_dev = __in6_dev_get(dev)) == NULL) { |
327 | read_unlock(&addrconf_lock); | 326 | rcu_read_unlock(); |
328 | return; | 327 | return; |
329 | } | 328 | } |
330 | 329 | ||
@@ -343,7 +342,7 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist, | |||
343 | } | 342 | } |
344 | 343 | ||
345 | read_unlock(&in6_dev->lock); | 344 | read_unlock(&in6_dev->lock); |
346 | read_unlock(&addrconf_lock); | 345 | rcu_read_unlock(); |
347 | } | 346 | } |
348 | 347 | ||
349 | /* Initialize a sockaddr_storage from in incoming skb. */ | 348 | /* Initialize a sockaddr_storage from in incoming skb. */ |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 30b710c54e64..37074a39ecbb 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -467,6 +467,7 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, | |||
467 | 467 | ||
468 | switch(reason) { | 468 | switch(reason) { |
469 | case SCTP_RTXR_T3_RTX: | 469 | case SCTP_RTXR_T3_RTX: |
470 | SCTP_INC_STATS(SCTP_MIB_T3_RETRANSMITS); | ||
470 | sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX); | 471 | sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX); |
471 | /* Update the retran path if the T3-rtx timer has expired for | 472 | /* Update the retran path if the T3-rtx timer has expired for |
472 | * the current retran path. | 473 | * the current retran path. |
@@ -475,12 +476,15 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, | |||
475 | sctp_assoc_update_retran_path(transport->asoc); | 476 | sctp_assoc_update_retran_path(transport->asoc); |
476 | break; | 477 | break; |
477 | case SCTP_RTXR_FAST_RTX: | 478 | case SCTP_RTXR_FAST_RTX: |
479 | SCTP_INC_STATS(SCTP_MIB_FAST_RETRANSMITS); | ||
478 | sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX); | 480 | sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX); |
479 | fast_retransmit = 1; | 481 | fast_retransmit = 1; |
480 | break; | 482 | break; |
481 | case SCTP_RTXR_PMTUD: | 483 | case SCTP_RTXR_PMTUD: |
482 | default: | 484 | SCTP_INC_STATS(SCTP_MIB_PMTUD_RETRANSMITS); |
483 | break; | 485 | break; |
486 | default: | ||
487 | BUG(); | ||
484 | } | 488 | } |
485 | 489 | ||
486 | sctp_retransmit_mark(q, transport, fast_retransmit); | 490 | sctp_retransmit_mark(q, transport, fast_retransmit); |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 5b3b0e0ae7e5..a356d8d310a9 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
@@ -57,6 +57,21 @@ static struct snmp_mib sctp_snmp_list[] = { | |||
57 | SNMP_MIB_ITEM("SctpReasmUsrMsgs", SCTP_MIB_REASMUSRMSGS), | 57 | SNMP_MIB_ITEM("SctpReasmUsrMsgs", SCTP_MIB_REASMUSRMSGS), |
58 | SNMP_MIB_ITEM("SctpOutSCTPPacks", SCTP_MIB_OUTSCTPPACKS), | 58 | SNMP_MIB_ITEM("SctpOutSCTPPacks", SCTP_MIB_OUTSCTPPACKS), |
59 | SNMP_MIB_ITEM("SctpInSCTPPacks", SCTP_MIB_INSCTPPACKS), | 59 | SNMP_MIB_ITEM("SctpInSCTPPacks", SCTP_MIB_INSCTPPACKS), |
60 | SNMP_MIB_ITEM("SctpT1InitExpireds", SCTP_MIB_T1_INIT_EXPIREDS), | ||
61 | SNMP_MIB_ITEM("SctpT1CookieExpireds", SCTP_MIB_T1_COOKIE_EXPIREDS), | ||
62 | SNMP_MIB_ITEM("SctpT2ShutdownExpireds", SCTP_MIB_T2_SHUTDOWN_EXPIREDS), | ||
63 | SNMP_MIB_ITEM("SctpT3RtxExpireds", SCTP_MIB_T3_RTX_EXPIREDS), | ||
64 | SNMP_MIB_ITEM("SctpT4RtoExpireds", SCTP_MIB_T4_RTO_EXPIREDS), | ||
65 | SNMP_MIB_ITEM("SctpT5ShutdownGuardExpireds", SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS), | ||
66 | SNMP_MIB_ITEM("SctpDelaySackExpireds", SCTP_MIB_DELAY_SACK_EXPIREDS), | ||
67 | SNMP_MIB_ITEM("SctpAutocloseExpireds", SCTP_MIB_AUTOCLOSE_EXPIREDS), | ||
68 | SNMP_MIB_ITEM("SctpT3Retransmits", SCTP_MIB_T3_RETRANSMITS), | ||
69 | SNMP_MIB_ITEM("SctpPmtudRetransmits", SCTP_MIB_PMTUD_RETRANSMITS), | ||
70 | SNMP_MIB_ITEM("SctpFastRetransmits", SCTP_MIB_FAST_RETRANSMITS), | ||
71 | SNMP_MIB_ITEM("SctpInPktSoftirq", SCTP_MIB_IN_PKT_SOFTIRQ), | ||
72 | SNMP_MIB_ITEM("SctpInPktBacklog", SCTP_MIB_IN_PKT_BACKLOG), | ||
73 | SNMP_MIB_ITEM("SctpInPktDiscards", SCTP_MIB_IN_PKT_DISCARDS), | ||
74 | SNMP_MIB_ITEM("SctpInDataChunkDiscards", SCTP_MIB_IN_DATA_CHUNK_DISCARDS), | ||
60 | SNMP_MIB_SENTINEL | 75 | SNMP_MIB_SENTINEL |
61 | }; | 76 | }; |
62 | 77 | ||
@@ -328,8 +343,8 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | |||
328 | "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ", | 343 | "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ", |
329 | assoc, sk, sctp_sk(sk)->type, sk->sk_state, | 344 | assoc, sk, sctp_sk(sk)->type, sk->sk_state, |
330 | assoc->state, hash, assoc->assoc_id, | 345 | assoc->state, hash, assoc->assoc_id, |
331 | (sk->sk_rcvbuf - assoc->rwnd), | ||
332 | assoc->sndbuf_used, | 346 | assoc->sndbuf_used, |
347 | (sk->sk_rcvbuf - assoc->rwnd), | ||
333 | sock_i_uid(sk), sock_i_ino(sk), | 348 | sock_i_uid(sk), sock_i_ino(sk), |
334 | epb->bind_addr.port, | 349 | epb->bind_addr.port, |
335 | assoc->peer.port); | 350 | assoc->peer.port); |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 1ab03a27a76e..fac7674438a4 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -61,7 +61,7 @@ | |||
61 | #include <net/inet_ecn.h> | 61 | #include <net/inet_ecn.h> |
62 | 62 | ||
63 | /* Global data structures. */ | 63 | /* Global data structures. */ |
64 | struct sctp_globals sctp_globals; | 64 | struct sctp_globals sctp_globals __read_mostly; |
65 | struct proc_dir_entry *proc_net_sctp; | 65 | struct proc_dir_entry *proc_net_sctp; |
66 | DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics) __read_mostly; | 66 | DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics) __read_mostly; |
67 | 67 | ||
@@ -82,13 +82,6 @@ static struct sctp_af *sctp_af_v6_specific; | |||
82 | kmem_cache_t *sctp_chunk_cachep __read_mostly; | 82 | kmem_cache_t *sctp_chunk_cachep __read_mostly; |
83 | kmem_cache_t *sctp_bucket_cachep __read_mostly; | 83 | kmem_cache_t *sctp_bucket_cachep __read_mostly; |
84 | 84 | ||
85 | extern int sctp_snmp_proc_init(void); | ||
86 | extern int sctp_snmp_proc_exit(void); | ||
87 | extern int sctp_eps_proc_init(void); | ||
88 | extern int sctp_eps_proc_exit(void); | ||
89 | extern int sctp_assocs_proc_init(void); | ||
90 | extern int sctp_assocs_proc_exit(void); | ||
91 | |||
92 | /* Return the address of the control sock. */ | 85 | /* Return the address of the control sock. */ |
93 | struct sock *sctp_get_ctl_sock(void) | 86 | struct sock *sctp_get_ctl_sock(void) |
94 | { | 87 | { |
@@ -1049,7 +1042,7 @@ SCTP_STATIC __init int sctp_init(void) | |||
1049 | sctp_rto_beta = SCTP_RTO_BETA; | 1042 | sctp_rto_beta = SCTP_RTO_BETA; |
1050 | 1043 | ||
1051 | /* Valid.Cookie.Life - 60 seconds */ | 1044 | /* Valid.Cookie.Life - 60 seconds */ |
1052 | sctp_valid_cookie_life = 60 * HZ; | 1045 | sctp_valid_cookie_life = SCTP_DEFAULT_COOKIE_LIFE; |
1053 | 1046 | ||
1054 | /* Whether Cookie Preservative is enabled(1) or not(0) */ | 1047 | /* Whether Cookie Preservative is enabled(1) or not(0) */ |
1055 | sctp_cookie_preserve_enable = 1; | 1048 | sctp_cookie_preserve_enable = 1; |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 5b5ae7958322..1c42fe983a5b 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -187,10 +187,9 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep, | |||
187 | */ | 187 | */ |
188 | ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_SHUTDOWN_COMP, | 188 | ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_SHUTDOWN_COMP, |
189 | 0, 0, 0, GFP_ATOMIC); | 189 | 0, 0, 0, GFP_ATOMIC); |
190 | if (!ev) | 190 | if (ev) |
191 | goto nomem; | 191 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, |
192 | 192 | SCTP_ULPEVENT(ev)); | |
193 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); | ||
194 | 193 | ||
195 | /* Upon reception of the SHUTDOWN COMPLETE chunk the endpoint | 194 | /* Upon reception of the SHUTDOWN COMPLETE chunk the endpoint |
196 | * will verify that it is in SHUTDOWN-ACK-SENT state, if it is | 195 | * will verify that it is in SHUTDOWN-ACK-SENT state, if it is |
@@ -215,9 +214,6 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep, | |||
215 | sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); | 214 | sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); |
216 | 215 | ||
217 | return SCTP_DISPOSITION_DELETE_TCB; | 216 | return SCTP_DISPOSITION_DELETE_TCB; |
218 | |||
219 | nomem: | ||
220 | return SCTP_DISPOSITION_NOMEM; | ||
221 | } | 217 | } |
222 | 218 | ||
223 | /* | 219 | /* |
@@ -347,8 +343,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
347 | GFP_ATOMIC)) | 343 | GFP_ATOMIC)) |
348 | goto nomem_init; | 344 | goto nomem_init; |
349 | 345 | ||
350 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc)); | ||
351 | |||
352 | /* B) "Z" shall respond immediately with an INIT ACK chunk. */ | 346 | /* B) "Z" shall respond immediately with an INIT ACK chunk. */ |
353 | 347 | ||
354 | /* If there are errors need to be reported for unknown parameters, | 348 | /* If there are errors need to be reported for unknown parameters, |
@@ -360,11 +354,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
360 | sizeof(sctp_chunkhdr_t); | 354 | sizeof(sctp_chunkhdr_t); |
361 | 355 | ||
362 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) | 356 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) |
363 | goto nomem_ack; | 357 | goto nomem_init; |
364 | 358 | ||
365 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); | 359 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); |
366 | if (!repl) | 360 | if (!repl) |
367 | goto nomem_ack; | 361 | goto nomem_init; |
368 | 362 | ||
369 | /* If there are errors need to be reported for unknown parameters, | 363 | /* If there are errors need to be reported for unknown parameters, |
370 | * include them in the outgoing INIT ACK as "Unrecognized parameter" | 364 | * include them in the outgoing INIT ACK as "Unrecognized parameter" |
@@ -388,6 +382,8 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
388 | sctp_chunk_free(err_chunk); | 382 | sctp_chunk_free(err_chunk); |
389 | } | 383 | } |
390 | 384 | ||
385 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc)); | ||
386 | |||
391 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | 387 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); |
392 | 388 | ||
393 | /* | 389 | /* |
@@ -400,12 +396,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
400 | 396 | ||
401 | return SCTP_DISPOSITION_DELETE_TCB; | 397 | return SCTP_DISPOSITION_DELETE_TCB; |
402 | 398 | ||
403 | nomem_ack: | ||
404 | if (err_chunk) | ||
405 | sctp_chunk_free(err_chunk); | ||
406 | nomem_init: | 399 | nomem_init: |
407 | sctp_association_free(new_asoc); | 400 | sctp_association_free(new_asoc); |
408 | nomem: | 401 | nomem: |
402 | if (err_chunk) | ||
403 | sctp_chunk_free(err_chunk); | ||
409 | return SCTP_DISPOSITION_NOMEM; | 404 | return SCTP_DISPOSITION_NOMEM; |
410 | } | 405 | } |
411 | 406 | ||
@@ -600,7 +595,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, | |||
600 | struct sctp_association *new_asoc; | 595 | struct sctp_association *new_asoc; |
601 | sctp_init_chunk_t *peer_init; | 596 | sctp_init_chunk_t *peer_init; |
602 | struct sctp_chunk *repl; | 597 | struct sctp_chunk *repl; |
603 | struct sctp_ulpevent *ev; | 598 | struct sctp_ulpevent *ev, *ai_ev = NULL; |
604 | int error = 0; | 599 | int error = 0; |
605 | struct sctp_chunk *err_chk_p; | 600 | struct sctp_chunk *err_chk_p; |
606 | 601 | ||
@@ -659,20 +654,10 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, | |||
659 | }; | 654 | }; |
660 | } | 655 | } |
661 | 656 | ||
662 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc)); | ||
663 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | ||
664 | SCTP_STATE(SCTP_STATE_ESTABLISHED)); | ||
665 | SCTP_INC_STATS(SCTP_MIB_CURRESTAB); | ||
666 | SCTP_INC_STATS(SCTP_MIB_PASSIVEESTABS); | ||
667 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); | ||
668 | 657 | ||
669 | if (new_asoc->autoclose) | 658 | /* Delay state machine commands until later. |
670 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 659 | * |
671 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 660 | * Re-build the bind address for the association is done in |
672 | |||
673 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); | ||
674 | |||
675 | /* Re-build the bind address for the association is done in | ||
676 | * the sctp_unpack_cookie() already. | 661 | * the sctp_unpack_cookie() already. |
677 | */ | 662 | */ |
678 | /* This is a brand-new association, so these are not yet side | 663 | /* This is a brand-new association, so these are not yet side |
@@ -687,9 +672,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, | |||
687 | 672 | ||
688 | repl = sctp_make_cookie_ack(new_asoc, chunk); | 673 | repl = sctp_make_cookie_ack(new_asoc, chunk); |
689 | if (!repl) | 674 | if (!repl) |
690 | goto nomem_repl; | 675 | goto nomem_init; |
691 | |||
692 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | ||
693 | 676 | ||
694 | /* RFC 2960 5.1 Normal Establishment of an Association | 677 | /* RFC 2960 5.1 Normal Establishment of an Association |
695 | * | 678 | * |
@@ -704,28 +687,53 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, | |||
704 | if (!ev) | 687 | if (!ev) |
705 | goto nomem_ev; | 688 | goto nomem_ev; |
706 | 689 | ||
707 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); | ||
708 | |||
709 | /* Sockets API Draft Section 5.3.1.6 | 690 | /* Sockets API Draft Section 5.3.1.6 |
710 | * When a peer sends a Adaption Layer Indication parameter , SCTP | 691 | * When a peer sends a Adaption Layer Indication parameter , SCTP |
711 | * delivers this notification to inform the application that of the | 692 | * delivers this notification to inform the application that of the |
712 | * peers requested adaption layer. | 693 | * peers requested adaption layer. |
713 | */ | 694 | */ |
714 | if (new_asoc->peer.adaption_ind) { | 695 | if (new_asoc->peer.adaption_ind) { |
715 | ev = sctp_ulpevent_make_adaption_indication(new_asoc, | 696 | ai_ev = sctp_ulpevent_make_adaption_indication(new_asoc, |
716 | GFP_ATOMIC); | 697 | GFP_ATOMIC); |
717 | if (!ev) | 698 | if (!ai_ev) |
718 | goto nomem_ev; | 699 | goto nomem_aiev; |
700 | } | ||
701 | |||
702 | /* Add all the state machine commands now since we've created | ||
703 | * everything. This way we don't introduce memory corruptions | ||
704 | * during side-effect processing and correclty count established | ||
705 | * associations. | ||
706 | */ | ||
707 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc)); | ||
708 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | ||
709 | SCTP_STATE(SCTP_STATE_ESTABLISHED)); | ||
710 | SCTP_INC_STATS(SCTP_MIB_CURRESTAB); | ||
711 | SCTP_INC_STATS(SCTP_MIB_PASSIVEESTABS); | ||
712 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); | ||
713 | |||
714 | if (new_asoc->autoclose) | ||
715 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | ||
716 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | ||
719 | 717 | ||
718 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); | ||
719 | |||
720 | /* This will send the COOKIE ACK */ | ||
721 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | ||
722 | |||
723 | /* Queue the ASSOC_CHANGE event */ | ||
724 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); | ||
725 | |||
726 | /* Send up the Adaptation Layer Indication event */ | ||
727 | if (ai_ev) | ||
720 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | 728 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, |
721 | SCTP_ULPEVENT(ev)); | 729 | SCTP_ULPEVENT(ai_ev)); |
722 | } | ||
723 | 730 | ||
724 | return SCTP_DISPOSITION_CONSUME; | 731 | return SCTP_DISPOSITION_CONSUME; |
725 | 732 | ||
733 | nomem_aiev: | ||
734 | sctp_ulpevent_free(ev); | ||
726 | nomem_ev: | 735 | nomem_ev: |
727 | sctp_chunk_free(repl); | 736 | sctp_chunk_free(repl); |
728 | nomem_repl: | ||
729 | nomem_init: | 737 | nomem_init: |
730 | sctp_association_free(new_asoc); | 738 | sctp_association_free(new_asoc); |
731 | nomem: | 739 | nomem: |
@@ -1360,10 +1368,8 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
1360 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 1368 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, |
1361 | sctp_source(chunk), | 1369 | sctp_source(chunk), |
1362 | (sctp_init_chunk_t *)chunk->chunk_hdr, | 1370 | (sctp_init_chunk_t *)chunk->chunk_hdr, |
1363 | GFP_ATOMIC)) { | 1371 | GFP_ATOMIC)) |
1364 | retval = SCTP_DISPOSITION_NOMEM; | 1372 | goto nomem; |
1365 | goto nomem_init; | ||
1366 | } | ||
1367 | 1373 | ||
1368 | /* Make sure no new addresses are being added during the | 1374 | /* Make sure no new addresses are being added during the |
1369 | * restart. Do not do this check for COOKIE-WAIT state, | 1375 | * restart. Do not do this check for COOKIE-WAIT state, |
@@ -1374,7 +1380,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
1374 | if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, | 1380 | if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, |
1375 | commands)) { | 1381 | commands)) { |
1376 | retval = SCTP_DISPOSITION_CONSUME; | 1382 | retval = SCTP_DISPOSITION_CONSUME; |
1377 | goto cleanup_asoc; | 1383 | goto nomem_retval; |
1378 | } | 1384 | } |
1379 | } | 1385 | } |
1380 | 1386 | ||
@@ -1430,17 +1436,17 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
1430 | sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); | 1436 | sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); |
1431 | retval = SCTP_DISPOSITION_CONSUME; | 1437 | retval = SCTP_DISPOSITION_CONSUME; |
1432 | 1438 | ||
1439 | return retval; | ||
1440 | |||
1441 | nomem: | ||
1442 | retval = SCTP_DISPOSITION_NOMEM; | ||
1443 | nomem_retval: | ||
1444 | if (new_asoc) | ||
1445 | sctp_association_free(new_asoc); | ||
1433 | cleanup: | 1446 | cleanup: |
1434 | if (err_chunk) | 1447 | if (err_chunk) |
1435 | sctp_chunk_free(err_chunk); | 1448 | sctp_chunk_free(err_chunk); |
1436 | return retval; | 1449 | return retval; |
1437 | nomem: | ||
1438 | retval = SCTP_DISPOSITION_NOMEM; | ||
1439 | goto cleanup; | ||
1440 | nomem_init: | ||
1441 | cleanup_asoc: | ||
1442 | sctp_association_free(new_asoc); | ||
1443 | goto cleanup; | ||
1444 | } | 1450 | } |
1445 | 1451 | ||
1446 | /* | 1452 | /* |
@@ -1611,15 +1617,10 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep, | |||
1611 | */ | 1617 | */ |
1612 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); | 1618 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); |
1613 | 1619 | ||
1614 | /* Update the content of current association. */ | ||
1615 | sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); | ||
1616 | |||
1617 | repl = sctp_make_cookie_ack(new_asoc, chunk); | 1620 | repl = sctp_make_cookie_ack(new_asoc, chunk); |
1618 | if (!repl) | 1621 | if (!repl) |
1619 | goto nomem; | 1622 | goto nomem; |
1620 | 1623 | ||
1621 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | ||
1622 | |||
1623 | /* Report association restart to upper layer. */ | 1624 | /* Report association restart to upper layer. */ |
1624 | ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_RESTART, 0, | 1625 | ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_RESTART, 0, |
1625 | new_asoc->c.sinit_num_ostreams, | 1626 | new_asoc->c.sinit_num_ostreams, |
@@ -1628,6 +1629,9 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep, | |||
1628 | if (!ev) | 1629 | if (!ev) |
1629 | goto nomem_ev; | 1630 | goto nomem_ev; |
1630 | 1631 | ||
1632 | /* Update the content of current association. */ | ||
1633 | sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); | ||
1634 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | ||
1631 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); | 1635 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); |
1632 | return SCTP_DISPOSITION_CONSUME; | 1636 | return SCTP_DISPOSITION_CONSUME; |
1633 | 1637 | ||
@@ -1751,7 +1755,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep, | |||
1751 | sctp_cmd_seq_t *commands, | 1755 | sctp_cmd_seq_t *commands, |
1752 | struct sctp_association *new_asoc) | 1756 | struct sctp_association *new_asoc) |
1753 | { | 1757 | { |
1754 | struct sctp_ulpevent *ev = NULL; | 1758 | struct sctp_ulpevent *ev = NULL, *ai_ev = NULL; |
1755 | struct sctp_chunk *repl; | 1759 | struct sctp_chunk *repl; |
1756 | 1760 | ||
1757 | /* Clarification from Implementor's Guide: | 1761 | /* Clarification from Implementor's Guide: |
@@ -1778,29 +1782,25 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep, | |||
1778 | * SCTP user upon reception of a valid COOKIE | 1782 | * SCTP user upon reception of a valid COOKIE |
1779 | * ECHO chunk. | 1783 | * ECHO chunk. |
1780 | */ | 1784 | */ |
1781 | ev = sctp_ulpevent_make_assoc_change(new_asoc, 0, | 1785 | ev = sctp_ulpevent_make_assoc_change(asoc, 0, |
1782 | SCTP_COMM_UP, 0, | 1786 | SCTP_COMM_UP, 0, |
1783 | new_asoc->c.sinit_num_ostreams, | 1787 | asoc->c.sinit_num_ostreams, |
1784 | new_asoc->c.sinit_max_instreams, | 1788 | asoc->c.sinit_max_instreams, |
1785 | GFP_ATOMIC); | 1789 | GFP_ATOMIC); |
1786 | if (!ev) | 1790 | if (!ev) |
1787 | goto nomem; | 1791 | goto nomem; |
1788 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | ||
1789 | SCTP_ULPEVENT(ev)); | ||
1790 | 1792 | ||
1791 | /* Sockets API Draft Section 5.3.1.6 | 1793 | /* Sockets API Draft Section 5.3.1.6 |
1792 | * When a peer sends a Adaption Layer Indication parameter, | 1794 | * When a peer sends a Adaption Layer Indication parameter, |
1793 | * SCTP delivers this notification to inform the application | 1795 | * SCTP delivers this notification to inform the application |
1794 | * that of the peers requested adaption layer. | 1796 | * that of the peers requested adaption layer. |
1795 | */ | 1797 | */ |
1796 | if (new_asoc->peer.adaption_ind) { | 1798 | if (asoc->peer.adaption_ind) { |
1797 | ev = sctp_ulpevent_make_adaption_indication(new_asoc, | 1799 | ai_ev = sctp_ulpevent_make_adaption_indication(asoc, |
1798 | GFP_ATOMIC); | 1800 | GFP_ATOMIC); |
1799 | if (!ev) | 1801 | if (!ai_ev) |
1800 | goto nomem; | 1802 | goto nomem; |
1801 | 1803 | ||
1802 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | ||
1803 | SCTP_ULPEVENT(ev)); | ||
1804 | } | 1804 | } |
1805 | } | 1805 | } |
1806 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); | 1806 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); |
@@ -1809,12 +1809,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep, | |||
1809 | if (!repl) | 1809 | if (!repl) |
1810 | goto nomem; | 1810 | goto nomem; |
1811 | 1811 | ||
1812 | if (ev) | ||
1813 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | ||
1814 | SCTP_ULPEVENT(ev)); | ||
1815 | if (ai_ev) | ||
1816 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | ||
1817 | SCTP_ULPEVENT(ai_ev)); | ||
1818 | |||
1812 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | 1819 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); |
1813 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); | 1820 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL()); |
1814 | 1821 | ||
1815 | return SCTP_DISPOSITION_CONSUME; | 1822 | return SCTP_DISPOSITION_CONSUME; |
1816 | 1823 | ||
1817 | nomem: | 1824 | nomem: |
1825 | if (ai_ev) | ||
1826 | sctp_ulpevent_free(ai_ev); | ||
1818 | if (ev) | 1827 | if (ev) |
1819 | sctp_ulpevent_free(ev); | 1828 | sctp_ulpevent_free(ev); |
1820 | return SCTP_DISPOSITION_NOMEM; | 1829 | return SCTP_DISPOSITION_NOMEM; |
@@ -2663,9 +2672,11 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep, | |||
2663 | break; | 2672 | break; |
2664 | case SCTP_IERROR_HIGH_TSN: | 2673 | case SCTP_IERROR_HIGH_TSN: |
2665 | case SCTP_IERROR_BAD_STREAM: | 2674 | case SCTP_IERROR_BAD_STREAM: |
2675 | SCTP_INC_STATS(SCTP_MIB_IN_DATA_CHUNK_DISCARDS); | ||
2666 | goto discard_noforce; | 2676 | goto discard_noforce; |
2667 | case SCTP_IERROR_DUP_TSN: | 2677 | case SCTP_IERROR_DUP_TSN: |
2668 | case SCTP_IERROR_IGNORE_TSN: | 2678 | case SCTP_IERROR_IGNORE_TSN: |
2679 | SCTP_INC_STATS(SCTP_MIB_IN_DATA_CHUNK_DISCARDS); | ||
2669 | goto discard_force; | 2680 | goto discard_force; |
2670 | case SCTP_IERROR_NO_DATA: | 2681 | case SCTP_IERROR_NO_DATA: |
2671 | goto consume; | 2682 | goto consume; |
@@ -3017,7 +3028,6 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep, | |||
3017 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) | 3028 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) |
3018 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | 3029 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, |
3019 | commands); | 3030 | commands); |
3020 | |||
3021 | /* 10.2 H) SHUTDOWN COMPLETE notification | 3031 | /* 10.2 H) SHUTDOWN COMPLETE notification |
3022 | * | 3032 | * |
3023 | * When SCTP completes the shutdown procedures (section 9.2) this | 3033 | * When SCTP completes the shutdown procedures (section 9.2) this |
@@ -3028,6 +3038,14 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep, | |||
3028 | if (!ev) | 3038 | if (!ev) |
3029 | goto nomem; | 3039 | goto nomem; |
3030 | 3040 | ||
3041 | /* ...send a SHUTDOWN COMPLETE chunk to its peer, */ | ||
3042 | reply = sctp_make_shutdown_complete(asoc, chunk); | ||
3043 | if (!reply) | ||
3044 | goto nomem_chunk; | ||
3045 | |||
3046 | /* Do all the commands now (after allocation), so that we | ||
3047 | * have consistent state if memory allocation failes | ||
3048 | */ | ||
3031 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); | 3049 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); |
3032 | 3050 | ||
3033 | /* Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall | 3051 | /* Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall |
@@ -3039,11 +3057,6 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep, | |||
3039 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 3057 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
3040 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | 3058 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); |
3041 | 3059 | ||
3042 | /* ...send a SHUTDOWN COMPLETE chunk to its peer, */ | ||
3043 | reply = sctp_make_shutdown_complete(asoc, chunk); | ||
3044 | if (!reply) | ||
3045 | goto nomem; | ||
3046 | |||
3047 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | 3060 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, |
3048 | SCTP_STATE(SCTP_STATE_CLOSED)); | 3061 | SCTP_STATE(SCTP_STATE_CLOSED)); |
3049 | SCTP_INC_STATS(SCTP_MIB_SHUTDOWNS); | 3062 | SCTP_INC_STATS(SCTP_MIB_SHUTDOWNS); |
@@ -3054,6 +3067,8 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep, | |||
3054 | sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); | 3067 | sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL()); |
3055 | return SCTP_DISPOSITION_DELETE_TCB; | 3068 | return SCTP_DISPOSITION_DELETE_TCB; |
3056 | 3069 | ||
3070 | nomem_chunk: | ||
3071 | sctp_ulpevent_free(ev); | ||
3057 | nomem: | 3072 | nomem: |
3058 | return SCTP_DISPOSITION_NOMEM; | 3073 | return SCTP_DISPOSITION_NOMEM; |
3059 | } | 3074 | } |
@@ -3652,6 +3667,7 @@ sctp_disposition_t sctp_sf_pdiscard(const struct sctp_endpoint *ep, | |||
3652 | void *arg, | 3667 | void *arg, |
3653 | sctp_cmd_seq_t *commands) | 3668 | sctp_cmd_seq_t *commands) |
3654 | { | 3669 | { |
3670 | SCTP_INC_STATS(SCTP_MIB_IN_PKT_DISCARDS); | ||
3655 | sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL()); | 3671 | sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL()); |
3656 | 3672 | ||
3657 | return SCTP_DISPOSITION_CONSUME; | 3673 | return SCTP_DISPOSITION_CONSUME; |
@@ -4548,6 +4564,8 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep, | |||
4548 | { | 4564 | { |
4549 | struct sctp_transport *transport = arg; | 4565 | struct sctp_transport *transport = arg; |
4550 | 4566 | ||
4567 | SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS); | ||
4568 | |||
4551 | if (asoc->overall_error_count >= asoc->max_retrans) { | 4569 | if (asoc->overall_error_count >= asoc->max_retrans) { |
4552 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | 4570 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, |
4553 | SCTP_ERROR(ETIMEDOUT)); | 4571 | SCTP_ERROR(ETIMEDOUT)); |
@@ -4616,6 +4634,7 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep, | |||
4616 | void *arg, | 4634 | void *arg, |
4617 | sctp_cmd_seq_t *commands) | 4635 | sctp_cmd_seq_t *commands) |
4618 | { | 4636 | { |
4637 | SCTP_INC_STATS(SCTP_MIB_DELAY_SACK_EXPIREDS); | ||
4619 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE()); | 4638 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE()); |
4620 | return SCTP_DISPOSITION_CONSUME; | 4639 | return SCTP_DISPOSITION_CONSUME; |
4621 | } | 4640 | } |
@@ -4650,6 +4669,7 @@ sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep, | |||
4650 | int attempts = asoc->init_err_counter + 1; | 4669 | int attempts = asoc->init_err_counter + 1; |
4651 | 4670 | ||
4652 | SCTP_DEBUG_PRINTK("Timer T1 expired (INIT).\n"); | 4671 | SCTP_DEBUG_PRINTK("Timer T1 expired (INIT).\n"); |
4672 | SCTP_INC_STATS(SCTP_MIB_T1_INIT_EXPIREDS); | ||
4653 | 4673 | ||
4654 | if (attempts <= asoc->max_init_attempts) { | 4674 | if (attempts <= asoc->max_init_attempts) { |
4655 | bp = (struct sctp_bind_addr *) &asoc->base.bind_addr; | 4675 | bp = (struct sctp_bind_addr *) &asoc->base.bind_addr; |
@@ -4709,6 +4729,7 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep | |||
4709 | int attempts = asoc->init_err_counter + 1; | 4729 | int attempts = asoc->init_err_counter + 1; |
4710 | 4730 | ||
4711 | SCTP_DEBUG_PRINTK("Timer T1 expired (COOKIE-ECHO).\n"); | 4731 | SCTP_DEBUG_PRINTK("Timer T1 expired (COOKIE-ECHO).\n"); |
4732 | SCTP_INC_STATS(SCTP_MIB_T1_COOKIE_EXPIREDS); | ||
4712 | 4733 | ||
4713 | if (attempts <= asoc->max_init_attempts) { | 4734 | if (attempts <= asoc->max_init_attempts) { |
4714 | repl = sctp_make_cookie_echo(asoc, NULL); | 4735 | repl = sctp_make_cookie_echo(asoc, NULL); |
@@ -4753,6 +4774,8 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep, | |||
4753 | struct sctp_chunk *reply = NULL; | 4774 | struct sctp_chunk *reply = NULL; |
4754 | 4775 | ||
4755 | SCTP_DEBUG_PRINTK("Timer T2 expired.\n"); | 4776 | SCTP_DEBUG_PRINTK("Timer T2 expired.\n"); |
4777 | SCTP_INC_STATS(SCTP_MIB_T2_SHUTDOWN_EXPIREDS); | ||
4778 | |||
4756 | if (asoc->overall_error_count >= asoc->max_retrans) { | 4779 | if (asoc->overall_error_count >= asoc->max_retrans) { |
4757 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | 4780 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, |
4758 | SCTP_ERROR(ETIMEDOUT)); | 4781 | SCTP_ERROR(ETIMEDOUT)); |
@@ -4814,6 +4837,8 @@ sctp_disposition_t sctp_sf_t4_timer_expire( | |||
4814 | struct sctp_chunk *chunk = asoc->addip_last_asconf; | 4837 | struct sctp_chunk *chunk = asoc->addip_last_asconf; |
4815 | struct sctp_transport *transport = chunk->transport; | 4838 | struct sctp_transport *transport = chunk->transport; |
4816 | 4839 | ||
4840 | SCTP_INC_STATS(SCTP_MIB_T4_RTO_EXPIREDS); | ||
4841 | |||
4817 | /* ADDIP 4.1 B1) Increment the error counters and perform path failure | 4842 | /* ADDIP 4.1 B1) Increment the error counters and perform path failure |
4818 | * detection on the appropriate destination address as defined in | 4843 | * detection on the appropriate destination address as defined in |
4819 | * RFC2960 [5] section 8.1 and 8.2. | 4844 | * RFC2960 [5] section 8.1 and 8.2. |
@@ -4880,6 +4905,7 @@ sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep, | |||
4880 | struct sctp_chunk *reply = NULL; | 4905 | struct sctp_chunk *reply = NULL; |
4881 | 4906 | ||
4882 | SCTP_DEBUG_PRINTK("Timer T5 expired.\n"); | 4907 | SCTP_DEBUG_PRINTK("Timer T5 expired.\n"); |
4908 | SCTP_INC_STATS(SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS); | ||
4883 | 4909 | ||
4884 | reply = sctp_make_abort(asoc, NULL, 0); | 4910 | reply = sctp_make_abort(asoc, NULL, 0); |
4885 | if (!reply) | 4911 | if (!reply) |
@@ -4910,6 +4936,8 @@ sctp_disposition_t sctp_sf_autoclose_timer_expire( | |||
4910 | { | 4936 | { |
4911 | int disposition; | 4937 | int disposition; |
4912 | 4938 | ||
4939 | SCTP_INC_STATS(SCTP_MIB_AUTOCLOSE_EXPIREDS); | ||
4940 | |||
4913 | /* From 9.2 Shutdown of an Association | 4941 | /* From 9.2 Shutdown of an Association |
4914 | * Upon receipt of the SHUTDOWN primitive from its upper | 4942 | * Upon receipt of the SHUTDOWN primitive from its upper |
4915 | * layer, the endpoint enters SHUTDOWN-PENDING state and | 4943 | * layer, the endpoint enters SHUTDOWN-PENDING state and |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 85caf7963886..79c3e072cf28 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -2081,13 +2081,13 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
2081 | * SPP_SACKDELAY_ENABLE, setting both will have undefined | 2081 | * SPP_SACKDELAY_ENABLE, setting both will have undefined |
2082 | * results. | 2082 | * results. |
2083 | */ | 2083 | */ |
2084 | int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | 2084 | static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, |
2085 | struct sctp_transport *trans, | 2085 | struct sctp_transport *trans, |
2086 | struct sctp_association *asoc, | 2086 | struct sctp_association *asoc, |
2087 | struct sctp_sock *sp, | 2087 | struct sctp_sock *sp, |
2088 | int hb_change, | 2088 | int hb_change, |
2089 | int pmtud_change, | 2089 | int pmtud_change, |
2090 | int sackdelay_change) | 2090 | int sackdelay_change) |
2091 | { | 2091 | { |
2092 | int error; | 2092 | int error; |
2093 | 2093 | ||
@@ -2970,7 +2970,7 @@ SCTP_STATIC struct sock *sctp_accept(struct sock *sk, int flags, int *err) | |||
2970 | goto out; | 2970 | goto out; |
2971 | } | 2971 | } |
2972 | 2972 | ||
2973 | timeo = sock_rcvtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK); | 2973 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); |
2974 | 2974 | ||
2975 | error = sctp_wait_for_accept(sk, timeo); | 2975 | error = sctp_wait_for_accept(sk, timeo); |
2976 | if (error) | 2976 | if (error) |
@@ -3045,14 +3045,14 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3045 | sp->initmsg.sinit_num_ostreams = sctp_max_outstreams; | 3045 | sp->initmsg.sinit_num_ostreams = sctp_max_outstreams; |
3046 | sp->initmsg.sinit_max_instreams = sctp_max_instreams; | 3046 | sp->initmsg.sinit_max_instreams = sctp_max_instreams; |
3047 | sp->initmsg.sinit_max_attempts = sctp_max_retrans_init; | 3047 | sp->initmsg.sinit_max_attempts = sctp_max_retrans_init; |
3048 | sp->initmsg.sinit_max_init_timeo = jiffies_to_msecs(sctp_rto_max); | 3048 | sp->initmsg.sinit_max_init_timeo = sctp_rto_max; |
3049 | 3049 | ||
3050 | /* Initialize default RTO related parameters. These parameters can | 3050 | /* Initialize default RTO related parameters. These parameters can |
3051 | * be modified for with the SCTP_RTOINFO socket option. | 3051 | * be modified for with the SCTP_RTOINFO socket option. |
3052 | */ | 3052 | */ |
3053 | sp->rtoinfo.srto_initial = jiffies_to_msecs(sctp_rto_initial); | 3053 | sp->rtoinfo.srto_initial = sctp_rto_initial; |
3054 | sp->rtoinfo.srto_max = jiffies_to_msecs(sctp_rto_max); | 3054 | sp->rtoinfo.srto_max = sctp_rto_max; |
3055 | sp->rtoinfo.srto_min = jiffies_to_msecs(sctp_rto_min); | 3055 | sp->rtoinfo.srto_min = sctp_rto_min; |
3056 | 3056 | ||
3057 | /* Initialize default association related parameters. These parameters | 3057 | /* Initialize default association related parameters. These parameters |
3058 | * can be modified with the SCTP_ASSOCINFO socket option. | 3058 | * can be modified with the SCTP_ASSOCINFO socket option. |
@@ -3061,8 +3061,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3061 | sp->assocparams.sasoc_number_peer_destinations = 0; | 3061 | sp->assocparams.sasoc_number_peer_destinations = 0; |
3062 | sp->assocparams.sasoc_peer_rwnd = 0; | 3062 | sp->assocparams.sasoc_peer_rwnd = 0; |
3063 | sp->assocparams.sasoc_local_rwnd = 0; | 3063 | sp->assocparams.sasoc_local_rwnd = 0; |
3064 | sp->assocparams.sasoc_cookie_life = | 3064 | sp->assocparams.sasoc_cookie_life = sctp_valid_cookie_life; |
3065 | jiffies_to_msecs(sctp_valid_cookie_life); | ||
3066 | 3065 | ||
3067 | /* Initialize default event subscriptions. By default, all the | 3066 | /* Initialize default event subscriptions. By default, all the |
3068 | * options are off. | 3067 | * options are off. |
@@ -3072,10 +3071,10 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3072 | /* Default Peer Address Parameters. These defaults can | 3071 | /* Default Peer Address Parameters. These defaults can |
3073 | * be modified via SCTP_PEER_ADDR_PARAMS | 3072 | * be modified via SCTP_PEER_ADDR_PARAMS |
3074 | */ | 3073 | */ |
3075 | sp->hbinterval = jiffies_to_msecs(sctp_hb_interval); | 3074 | sp->hbinterval = sctp_hb_interval; |
3076 | sp->pathmaxrxt = sctp_max_retrans_path; | 3075 | sp->pathmaxrxt = sctp_max_retrans_path; |
3077 | sp->pathmtu = 0; // allow default discovery | 3076 | sp->pathmtu = 0; // allow default discovery |
3078 | sp->sackdelay = jiffies_to_msecs(sctp_sack_timeout); | 3077 | sp->sackdelay = sctp_sack_timeout; |
3079 | sp->param_flags = SPP_HB_ENABLE | | 3078 | sp->param_flags = SPP_HB_ENABLE | |
3080 | SPP_PMTUD_ENABLE | | 3079 | SPP_PMTUD_ENABLE | |
3081 | SPP_SACKDELAY_ENABLE; | 3080 | SPP_SACKDELAY_ENABLE; |
@@ -5619,6 +5618,8 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5619 | /* Copy the bind_addr list from the original endpoint to the new | 5618 | /* Copy the bind_addr list from the original endpoint to the new |
5620 | * endpoint so that we can handle restarts properly | 5619 | * endpoint so that we can handle restarts properly |
5621 | */ | 5620 | */ |
5621 | if (PF_INET6 == assoc->base.sk->sk_family) | ||
5622 | flags = SCTP_ADDR6_ALLOWED; | ||
5622 | if (assoc->peer.ipv4_address) | 5623 | if (assoc->peer.ipv4_address) |
5623 | flags |= SCTP_ADDR4_PEERSUPP; | 5624 | flags |= SCTP_ADDR4_PEERSUPP; |
5624 | if (assoc->peer.ipv6_address) | 5625 | if (assoc->peer.ipv6_address) |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index dc6f3ff32358..633cd178654b 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -45,9 +45,10 @@ | |||
45 | #include <net/sctp/sctp.h> | 45 | #include <net/sctp/sctp.h> |
46 | #include <linux/sysctl.h> | 46 | #include <linux/sysctl.h> |
47 | 47 | ||
48 | static ctl_handler sctp_sysctl_jiffies_ms; | 48 | static int zero = 0; |
49 | static long rto_timer_min = 1; | 49 | static int one = 1; |
50 | static long rto_timer_max = 86400000; /* One day */ | 50 | static int timer_max = 86400000; /* ms in one day */ |
51 | static int int_max = INT_MAX; | ||
51 | static long sack_timer_min = 1; | 52 | static long sack_timer_min = 1; |
52 | static long sack_timer_max = 500; | 53 | static long sack_timer_max = 500; |
53 | 54 | ||
@@ -56,45 +57,45 @@ static ctl_table sctp_table[] = { | |||
56 | .ctl_name = NET_SCTP_RTO_INITIAL, | 57 | .ctl_name = NET_SCTP_RTO_INITIAL, |
57 | .procname = "rto_initial", | 58 | .procname = "rto_initial", |
58 | .data = &sctp_rto_initial, | 59 | .data = &sctp_rto_initial, |
59 | .maxlen = sizeof(long), | 60 | .maxlen = sizeof(unsigned int), |
60 | .mode = 0644, | 61 | .mode = 0644, |
61 | .proc_handler = &proc_doulongvec_ms_jiffies_minmax, | 62 | .proc_handler = &proc_dointvec_minmax, |
62 | .strategy = &sctp_sysctl_jiffies_ms, | 63 | .strategy = &sysctl_intvec, |
63 | .extra1 = &rto_timer_min, | 64 | .extra1 = &one, |
64 | .extra2 = &rto_timer_max | 65 | .extra2 = &timer_max |
65 | }, | 66 | }, |
66 | { | 67 | { |
67 | .ctl_name = NET_SCTP_RTO_MIN, | 68 | .ctl_name = NET_SCTP_RTO_MIN, |
68 | .procname = "rto_min", | 69 | .procname = "rto_min", |
69 | .data = &sctp_rto_min, | 70 | .data = &sctp_rto_min, |
70 | .maxlen = sizeof(long), | 71 | .maxlen = sizeof(unsigned int), |
71 | .mode = 0644, | 72 | .mode = 0644, |
72 | .proc_handler = &proc_doulongvec_ms_jiffies_minmax, | 73 | .proc_handler = &proc_dointvec_minmax, |
73 | .strategy = &sctp_sysctl_jiffies_ms, | 74 | .strategy = &sysctl_intvec, |
74 | .extra1 = &rto_timer_min, | 75 | .extra1 = &one, |
75 | .extra2 = &rto_timer_max | 76 | .extra2 = &timer_max |
76 | }, | 77 | }, |
77 | { | 78 | { |
78 | .ctl_name = NET_SCTP_RTO_MAX, | 79 | .ctl_name = NET_SCTP_RTO_MAX, |
79 | .procname = "rto_max", | 80 | .procname = "rto_max", |
80 | .data = &sctp_rto_max, | 81 | .data = &sctp_rto_max, |
81 | .maxlen = sizeof(long), | 82 | .maxlen = sizeof(unsigned int), |
82 | .mode = 0644, | 83 | .mode = 0644, |
83 | .proc_handler = &proc_doulongvec_ms_jiffies_minmax, | 84 | .proc_handler = &proc_dointvec_minmax, |
84 | .strategy = &sctp_sysctl_jiffies_ms, | 85 | .strategy = &sysctl_intvec, |
85 | .extra1 = &rto_timer_min, | 86 | .extra1 = &one, |
86 | .extra2 = &rto_timer_max | 87 | .extra2 = &timer_max |
87 | }, | 88 | }, |
88 | { | 89 | { |
89 | .ctl_name = NET_SCTP_VALID_COOKIE_LIFE, | 90 | .ctl_name = NET_SCTP_VALID_COOKIE_LIFE, |
90 | .procname = "valid_cookie_life", | 91 | .procname = "valid_cookie_life", |
91 | .data = &sctp_valid_cookie_life, | 92 | .data = &sctp_valid_cookie_life, |
92 | .maxlen = sizeof(long), | 93 | .maxlen = sizeof(unsigned int), |
93 | .mode = 0644, | 94 | .mode = 0644, |
94 | .proc_handler = &proc_doulongvec_ms_jiffies_minmax, | 95 | .proc_handler = &proc_dointvec_minmax, |
95 | .strategy = &sctp_sysctl_jiffies_ms, | 96 | .strategy = &sysctl_intvec, |
96 | .extra1 = &rto_timer_min, | 97 | .extra1 = &one, |
97 | .extra2 = &rto_timer_max | 98 | .extra2 = &timer_max |
98 | }, | 99 | }, |
99 | { | 100 | { |
100 | .ctl_name = NET_SCTP_MAX_BURST, | 101 | .ctl_name = NET_SCTP_MAX_BURST, |
@@ -102,7 +103,10 @@ static ctl_table sctp_table[] = { | |||
102 | .data = &sctp_max_burst, | 103 | .data = &sctp_max_burst, |
103 | .maxlen = sizeof(int), | 104 | .maxlen = sizeof(int), |
104 | .mode = 0644, | 105 | .mode = 0644, |
105 | .proc_handler = &proc_dointvec | 106 | .proc_handler = &proc_dointvec_minmax, |
107 | .strategy = &sysctl_intvec, | ||
108 | .extra1 = &zero, | ||
109 | .extra2 = &int_max | ||
106 | }, | 110 | }, |
107 | { | 111 | { |
108 | .ctl_name = NET_SCTP_ASSOCIATION_MAX_RETRANS, | 112 | .ctl_name = NET_SCTP_ASSOCIATION_MAX_RETRANS, |
@@ -110,7 +114,10 @@ static ctl_table sctp_table[] = { | |||
110 | .data = &sctp_max_retrans_association, | 114 | .data = &sctp_max_retrans_association, |
111 | .maxlen = sizeof(int), | 115 | .maxlen = sizeof(int), |
112 | .mode = 0644, | 116 | .mode = 0644, |
113 | .proc_handler = &proc_dointvec | 117 | .proc_handler = &proc_dointvec_minmax, |
118 | .strategy = &sysctl_intvec, | ||
119 | .extra1 = &one, | ||
120 | .extra2 = &int_max | ||
114 | }, | 121 | }, |
115 | { | 122 | { |
116 | .ctl_name = NET_SCTP_SNDBUF_POLICY, | 123 | .ctl_name = NET_SCTP_SNDBUF_POLICY, |
@@ -118,7 +125,8 @@ static ctl_table sctp_table[] = { | |||
118 | .data = &sctp_sndbuf_policy, | 125 | .data = &sctp_sndbuf_policy, |
119 | .maxlen = sizeof(int), | 126 | .maxlen = sizeof(int), |
120 | .mode = 0644, | 127 | .mode = 0644, |
121 | .proc_handler = &proc_dointvec | 128 | .proc_handler = &proc_dointvec, |
129 | .strategy = &sysctl_intvec | ||
122 | }, | 130 | }, |
123 | { | 131 | { |
124 | .ctl_name = NET_SCTP_RCVBUF_POLICY, | 132 | .ctl_name = NET_SCTP_RCVBUF_POLICY, |
@@ -126,7 +134,8 @@ static ctl_table sctp_table[] = { | |||
126 | .data = &sctp_rcvbuf_policy, | 134 | .data = &sctp_rcvbuf_policy, |
127 | .maxlen = sizeof(int), | 135 | .maxlen = sizeof(int), |
128 | .mode = 0644, | 136 | .mode = 0644, |
129 | .proc_handler = &proc_dointvec | 137 | .proc_handler = &proc_dointvec, |
138 | .strategy = &sysctl_intvec | ||
130 | }, | 139 | }, |
131 | { | 140 | { |
132 | .ctl_name = NET_SCTP_PATH_MAX_RETRANS, | 141 | .ctl_name = NET_SCTP_PATH_MAX_RETRANS, |
@@ -134,7 +143,10 @@ static ctl_table sctp_table[] = { | |||
134 | .data = &sctp_max_retrans_path, | 143 | .data = &sctp_max_retrans_path, |
135 | .maxlen = sizeof(int), | 144 | .maxlen = sizeof(int), |
136 | .mode = 0644, | 145 | .mode = 0644, |
137 | .proc_handler = &proc_dointvec | 146 | .proc_handler = &proc_dointvec_minmax, |
147 | .strategy = &sysctl_intvec, | ||
148 | .extra1 = &one, | ||
149 | .extra2 = &int_max | ||
138 | }, | 150 | }, |
139 | { | 151 | { |
140 | .ctl_name = NET_SCTP_MAX_INIT_RETRANSMITS, | 152 | .ctl_name = NET_SCTP_MAX_INIT_RETRANSMITS, |
@@ -142,18 +154,21 @@ static ctl_table sctp_table[] = { | |||
142 | .data = &sctp_max_retrans_init, | 154 | .data = &sctp_max_retrans_init, |
143 | .maxlen = sizeof(int), | 155 | .maxlen = sizeof(int), |
144 | .mode = 0644, | 156 | .mode = 0644, |
145 | .proc_handler = &proc_dointvec | 157 | .proc_handler = &proc_dointvec_minmax, |
158 | .strategy = &sysctl_intvec, | ||
159 | .extra1 = &one, | ||
160 | .extra2 = &int_max | ||
146 | }, | 161 | }, |
147 | { | 162 | { |
148 | .ctl_name = NET_SCTP_HB_INTERVAL, | 163 | .ctl_name = NET_SCTP_HB_INTERVAL, |
149 | .procname = "hb_interval", | 164 | .procname = "hb_interval", |
150 | .data = &sctp_hb_interval, | 165 | .data = &sctp_hb_interval, |
151 | .maxlen = sizeof(long), | 166 | .maxlen = sizeof(unsigned int), |
152 | .mode = 0644, | 167 | .mode = 0644, |
153 | .proc_handler = &proc_doulongvec_ms_jiffies_minmax, | 168 | .proc_handler = &proc_dointvec_minmax, |
154 | .strategy = &sctp_sysctl_jiffies_ms, | 169 | .strategy = &sysctl_intvec, |
155 | .extra1 = &rto_timer_min, | 170 | .extra1 = &one, |
156 | .extra2 = &rto_timer_max | 171 | .extra2 = &timer_max |
157 | }, | 172 | }, |
158 | { | 173 | { |
159 | .ctl_name = NET_SCTP_PRESERVE_ENABLE, | 174 | .ctl_name = NET_SCTP_PRESERVE_ENABLE, |
@@ -161,23 +176,26 @@ static ctl_table sctp_table[] = { | |||
161 | .data = &sctp_cookie_preserve_enable, | 176 | .data = &sctp_cookie_preserve_enable, |
162 | .maxlen = sizeof(int), | 177 | .maxlen = sizeof(int), |
163 | .mode = 0644, | 178 | .mode = 0644, |
164 | .proc_handler = &proc_dointvec | 179 | .proc_handler = &proc_dointvec, |
180 | .strategy = &sysctl_intvec | ||
165 | }, | 181 | }, |
166 | { | 182 | { |
167 | .ctl_name = NET_SCTP_RTO_ALPHA, | 183 | .ctl_name = NET_SCTP_RTO_ALPHA, |
168 | .procname = "rto_alpha_exp_divisor", | 184 | .procname = "rto_alpha_exp_divisor", |
169 | .data = &sctp_rto_alpha, | 185 | .data = &sctp_rto_alpha, |
170 | .maxlen = sizeof(int), | 186 | .maxlen = sizeof(int), |
171 | .mode = 0644, | 187 | .mode = 0444, |
172 | .proc_handler = &proc_dointvec | 188 | .proc_handler = &proc_dointvec, |
189 | .strategy = &sysctl_intvec | ||
173 | }, | 190 | }, |
174 | { | 191 | { |
175 | .ctl_name = NET_SCTP_RTO_BETA, | 192 | .ctl_name = NET_SCTP_RTO_BETA, |
176 | .procname = "rto_beta_exp_divisor", | 193 | .procname = "rto_beta_exp_divisor", |
177 | .data = &sctp_rto_beta, | 194 | .data = &sctp_rto_beta, |
178 | .maxlen = sizeof(int), | 195 | .maxlen = sizeof(int), |
179 | .mode = 0644, | 196 | .mode = 0444, |
180 | .proc_handler = &proc_dointvec | 197 | .proc_handler = &proc_dointvec, |
198 | .strategy = &sysctl_intvec | ||
181 | }, | 199 | }, |
182 | { | 200 | { |
183 | .ctl_name = NET_SCTP_ADDIP_ENABLE, | 201 | .ctl_name = NET_SCTP_ADDIP_ENABLE, |
@@ -185,7 +203,8 @@ static ctl_table sctp_table[] = { | |||
185 | .data = &sctp_addip_enable, | 203 | .data = &sctp_addip_enable, |
186 | .maxlen = sizeof(int), | 204 | .maxlen = sizeof(int), |
187 | .mode = 0644, | 205 | .mode = 0644, |
188 | .proc_handler = &proc_dointvec | 206 | .proc_handler = &proc_dointvec, |
207 | .strategy = &sysctl_intvec | ||
189 | }, | 208 | }, |
190 | { | 209 | { |
191 | .ctl_name = NET_SCTP_PRSCTP_ENABLE, | 210 | .ctl_name = NET_SCTP_PRSCTP_ENABLE, |
@@ -193,7 +212,8 @@ static ctl_table sctp_table[] = { | |||
193 | .data = &sctp_prsctp_enable, | 212 | .data = &sctp_prsctp_enable, |
194 | .maxlen = sizeof(int), | 213 | .maxlen = sizeof(int), |
195 | .mode = 0644, | 214 | .mode = 0644, |
196 | .proc_handler = &proc_dointvec | 215 | .proc_handler = &proc_dointvec, |
216 | .strategy = &sysctl_intvec | ||
197 | }, | 217 | }, |
198 | { | 218 | { |
199 | .ctl_name = NET_SCTP_SACK_TIMEOUT, | 219 | .ctl_name = NET_SCTP_SACK_TIMEOUT, |
@@ -201,8 +221,8 @@ static ctl_table sctp_table[] = { | |||
201 | .data = &sctp_sack_timeout, | 221 | .data = &sctp_sack_timeout, |
202 | .maxlen = sizeof(long), | 222 | .maxlen = sizeof(long), |
203 | .mode = 0644, | 223 | .mode = 0644, |
204 | .proc_handler = &proc_doulongvec_ms_jiffies_minmax, | 224 | .proc_handler = &proc_dointvec_minmax, |
205 | .strategy = &sctp_sysctl_jiffies_ms, | 225 | .strategy = &sysctl_intvec, |
206 | .extra1 = &sack_timer_min, | 226 | .extra1 = &sack_timer_min, |
207 | .extra2 = &sack_timer_max, | 227 | .extra2 = &sack_timer_max, |
208 | }, | 228 | }, |
@@ -242,37 +262,3 @@ void sctp_sysctl_unregister(void) | |||
242 | { | 262 | { |
243 | unregister_sysctl_table(sctp_sysctl_header); | 263 | unregister_sysctl_table(sctp_sysctl_header); |
244 | } | 264 | } |
245 | |||
246 | /* Strategy function to convert jiffies to milliseconds. */ | ||
247 | static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen, | ||
248 | void __user *oldval, size_t __user *oldlenp, | ||
249 | void __user *newval, size_t newlen, void **context) { | ||
250 | |||
251 | if (oldval) { | ||
252 | size_t olen; | ||
253 | |||
254 | if (oldlenp) { | ||
255 | if (get_user(olen, oldlenp)) | ||
256 | return -EFAULT; | ||
257 | |||
258 | if (olen != sizeof (int)) | ||
259 | return -EINVAL; | ||
260 | } | ||
261 | if (put_user((*(int *)(table->data) * 1000) / HZ, | ||
262 | (int __user *)oldval) || | ||
263 | (oldlenp && put_user(sizeof (int), oldlenp))) | ||
264 | return -EFAULT; | ||
265 | } | ||
266 | if (newval && newlen) { | ||
267 | int new; | ||
268 | |||
269 | if (newlen != sizeof (int)) | ||
270 | return -EINVAL; | ||
271 | |||
272 | if (get_user(new, (int __user *)newval)) | ||
273 | return -EFAULT; | ||
274 | |||
275 | *(int *)(table->data) = (new * HZ) / 1000; | ||
276 | } | ||
277 | return 1; | ||
278 | } | ||
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 2763aa93de1a..3e5936a5f671 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -75,7 +75,7 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
75 | * parameter 'RTO.Initial'. | 75 | * parameter 'RTO.Initial'. |
76 | */ | 76 | */ |
77 | peer->rtt = 0; | 77 | peer->rtt = 0; |
78 | peer->rto = sctp_rto_initial; | 78 | peer->rto = msecs_to_jiffies(sctp_rto_initial); |
79 | peer->rttvar = 0; | 79 | peer->rttvar = 0; |
80 | peer->srtt = 0; | 80 | peer->srtt = 0; |
81 | peer->rto_pending = 0; | 81 | peer->rto_pending = 0; |