diff options
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r-- | net/sctp/sm_statefuns.c | 92 |
1 files changed, 58 insertions, 34 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 8848d329aa2c..d4c3fbc4671e 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -119,7 +119,7 @@ static sctp_disposition_t sctp_sf_violation_paramlen( | |||
119 | const struct sctp_endpoint *ep, | 119 | const struct sctp_endpoint *ep, |
120 | const struct sctp_association *asoc, | 120 | const struct sctp_association *asoc, |
121 | const sctp_subtype_t type, | 121 | const sctp_subtype_t type, |
122 | void *arg, | 122 | void *arg, void *ext, |
123 | sctp_cmd_seq_t *commands); | 123 | sctp_cmd_seq_t *commands); |
124 | 124 | ||
125 | static sctp_disposition_t sctp_sf_violation_ctsn( | 125 | static sctp_disposition_t sctp_sf_violation_ctsn( |
@@ -315,8 +315,10 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
315 | /* If the packet is an OOTB packet which is temporarily on the | 315 | /* If the packet is an OOTB packet which is temporarily on the |
316 | * control endpoint, respond with an ABORT. | 316 | * control endpoint, respond with an ABORT. |
317 | */ | 317 | */ |
318 | if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) | 318 | if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) { |
319 | SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES); | ||
319 | return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); | 320 | return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); |
321 | } | ||
320 | 322 | ||
321 | /* 3.1 A packet containing an INIT chunk MUST have a zero Verification | 323 | /* 3.1 A packet containing an INIT chunk MUST have a zero Verification |
322 | * Tag. | 324 | * Tag. |
@@ -635,8 +637,10 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, | |||
635 | /* If the packet is an OOTB packet which is temporarily on the | 637 | /* If the packet is an OOTB packet which is temporarily on the |
636 | * control endpoint, respond with an ABORT. | 638 | * control endpoint, respond with an ABORT. |
637 | */ | 639 | */ |
638 | if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) | 640 | if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) { |
641 | SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES); | ||
639 | return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); | 642 | return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); |
643 | } | ||
640 | 644 | ||
641 | /* Make sure that the COOKIE_ECHO chunk has a valid length. | 645 | /* Make sure that the COOKIE_ECHO chunk has a valid length. |
642 | * In this case, we check that we have enough for at least a | 646 | * In this case, we check that we have enough for at least a |
@@ -2076,10 +2080,6 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort( | |||
2076 | sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) | 2080 | sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) |
2077 | return sctp_sf_discard_chunk(ep, asoc, type, arg, commands); | 2081 | return sctp_sf_discard_chunk(ep, asoc, type, arg, commands); |
2078 | 2082 | ||
2079 | /* Stop the T5-shutdown guard timer. */ | ||
2080 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | ||
2081 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | ||
2082 | |||
2083 | return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands); | 2083 | return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands); |
2084 | } | 2084 | } |
2085 | 2085 | ||
@@ -3382,6 +3382,8 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep, | |||
3382 | * packet and the state function that handles OOTB SHUTDOWN_ACK is | 3382 | * packet and the state function that handles OOTB SHUTDOWN_ACK is |
3383 | * called with a NULL association. | 3383 | * called with a NULL association. |
3384 | */ | 3384 | */ |
3385 | SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES); | ||
3386 | |||
3385 | return sctp_sf_shut_8_4_5(ep, NULL, type, arg, commands); | 3387 | return sctp_sf_shut_8_4_5(ep, NULL, type, arg, commands); |
3386 | } | 3388 | } |
3387 | 3389 | ||
@@ -3425,7 +3427,7 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep, | |||
3425 | addr_param = (union sctp_addr_param *)hdr->params; | 3427 | addr_param = (union sctp_addr_param *)hdr->params; |
3426 | length = ntohs(addr_param->p.length); | 3428 | length = ntohs(addr_param->p.length); |
3427 | if (length < sizeof(sctp_paramhdr_t)) | 3429 | if (length < sizeof(sctp_paramhdr_t)) |
3428 | return sctp_sf_violation_paramlen(ep, asoc, type, | 3430 | return sctp_sf_violation_paramlen(ep, asoc, type, arg, |
3429 | (void *)addr_param, commands); | 3431 | (void *)addr_param, commands); |
3430 | 3432 | ||
3431 | /* Verify the ASCONF chunk before processing it. */ | 3433 | /* Verify the ASCONF chunk before processing it. */ |
@@ -3433,8 +3435,8 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep, | |||
3433 | (sctp_paramhdr_t *)((void *)addr_param + length), | 3435 | (sctp_paramhdr_t *)((void *)addr_param + length), |
3434 | (void *)chunk->chunk_end, | 3436 | (void *)chunk->chunk_end, |
3435 | &err_param)) | 3437 | &err_param)) |
3436 | return sctp_sf_violation_paramlen(ep, asoc, type, | 3438 | return sctp_sf_violation_paramlen(ep, asoc, type, arg, |
3437 | (void *)&err_param, commands); | 3439 | (void *)err_param, commands); |
3438 | 3440 | ||
3439 | /* ADDIP 5.2 E1) Compare the value of the serial number to the value | 3441 | /* ADDIP 5.2 E1) Compare the value of the serial number to the value |
3440 | * the endpoint stored in a new association variable | 3442 | * the endpoint stored in a new association variable |
@@ -3542,8 +3544,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, | |||
3542 | (sctp_paramhdr_t *)addip_hdr->params, | 3544 | (sctp_paramhdr_t *)addip_hdr->params, |
3543 | (void *)asconf_ack->chunk_end, | 3545 | (void *)asconf_ack->chunk_end, |
3544 | &err_param)) | 3546 | &err_param)) |
3545 | return sctp_sf_violation_paramlen(ep, asoc, type, | 3547 | return sctp_sf_violation_paramlen(ep, asoc, type, arg, |
3546 | (void *)&err_param, commands); | 3548 | (void *)err_param, commands); |
3547 | 3549 | ||
3548 | if (last_asconf) { | 3550 | if (last_asconf) { |
3549 | addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr; | 3551 | addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr; |
@@ -4186,11 +4188,10 @@ static sctp_disposition_t sctp_sf_abort_violation( | |||
4186 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); | 4188 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); |
4187 | } | 4189 | } |
4188 | 4190 | ||
4189 | discard: | ||
4190 | sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands); | ||
4191 | |||
4192 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 4191 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); |
4193 | 4192 | ||
4193 | discard: | ||
4194 | sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands); | ||
4194 | return SCTP_DISPOSITION_ABORT; | 4195 | return SCTP_DISPOSITION_ABORT; |
4195 | 4196 | ||
4196 | nomem_pkt: | 4197 | nomem_pkt: |
@@ -4240,12 +4241,36 @@ static sctp_disposition_t sctp_sf_violation_paramlen( | |||
4240 | const struct sctp_endpoint *ep, | 4241 | const struct sctp_endpoint *ep, |
4241 | const struct sctp_association *asoc, | 4242 | const struct sctp_association *asoc, |
4242 | const sctp_subtype_t type, | 4243 | const sctp_subtype_t type, |
4243 | void *arg, | 4244 | void *arg, void *ext, |
4244 | sctp_cmd_seq_t *commands) { | 4245 | sctp_cmd_seq_t *commands) |
4245 | static const char err_str[] = "The following parameter had invalid length:"; | 4246 | { |
4247 | struct sctp_chunk *chunk = arg; | ||
4248 | struct sctp_paramhdr *param = ext; | ||
4249 | struct sctp_chunk *abort = NULL; | ||
4246 | 4250 | ||
4247 | return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str, | 4251 | if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc)) |
4248 | sizeof(err_str)); | 4252 | goto discard; |
4253 | |||
4254 | /* Make the abort chunk. */ | ||
4255 | abort = sctp_make_violation_paramlen(asoc, chunk, param); | ||
4256 | if (!abort) | ||
4257 | goto nomem; | ||
4258 | |||
4259 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); | ||
4260 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); | ||
4261 | |||
4262 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
4263 | SCTP_ERROR(ECONNABORTED)); | ||
4264 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | ||
4265 | SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION)); | ||
4266 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); | ||
4267 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | ||
4268 | |||
4269 | discard: | ||
4270 | sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands); | ||
4271 | return SCTP_DISPOSITION_ABORT; | ||
4272 | nomem: | ||
4273 | return SCTP_DISPOSITION_NOMEM; | ||
4249 | } | 4274 | } |
4250 | 4275 | ||
4251 | /* Handle a protocol violation when the peer trying to advance the | 4276 | /* Handle a protocol violation when the peer trying to advance the |
@@ -4517,13 +4542,6 @@ sctp_disposition_t sctp_sf_do_9_2_prm_shutdown( | |||
4517 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | 4542 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, |
4518 | SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING)); | 4543 | SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING)); |
4519 | 4544 | ||
4520 | /* sctpimpguide-05 Section 2.12.2 | ||
4521 | * The sender of the SHUTDOWN MAY also start an overall guard timer | ||
4522 | * 'T5-shutdown-guard' to bound the overall time for shutdown sequence. | ||
4523 | */ | ||
4524 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | ||
4525 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | ||
4526 | |||
4527 | disposition = SCTP_DISPOSITION_CONSUME; | 4545 | disposition = SCTP_DISPOSITION_CONSUME; |
4528 | if (sctp_outq_is_empty(&asoc->outqueue)) { | 4546 | if (sctp_outq_is_empty(&asoc->outqueue)) { |
4529 | disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type, | 4547 | disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type, |
@@ -4968,6 +4986,13 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown( | |||
4968 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 4986 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, |
4969 | SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); | 4987 | SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); |
4970 | 4988 | ||
4989 | /* RFC 4960 Section 9.2 | ||
4990 | * The sender of the SHUTDOWN MAY also start an overall guard timer | ||
4991 | * 'T5-shutdown-guard' to bound the overall time for shutdown sequence. | ||
4992 | */ | ||
4993 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | ||
4994 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | ||
4995 | |||
4971 | if (asoc->autoclose) | 4996 | if (asoc->autoclose) |
4972 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 4997 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
4973 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 4998 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
@@ -5279,6 +5304,8 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep | |||
5279 | if (!repl) | 5304 | if (!repl) |
5280 | return SCTP_DISPOSITION_NOMEM; | 5305 | return SCTP_DISPOSITION_NOMEM; |
5281 | 5306 | ||
5307 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT, | ||
5308 | SCTP_CHUNK(repl)); | ||
5282 | /* Issue a sideeffect to do the needed accounting. */ | 5309 | /* Issue a sideeffect to do the needed accounting. */ |
5283 | sctp_add_cmd_sf(commands, SCTP_CMD_COOKIEECHO_RESTART, | 5310 | sctp_add_cmd_sf(commands, SCTP_CMD_COOKIEECHO_RESTART, |
5284 | SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE)); | 5311 | SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE)); |
@@ -5406,7 +5433,7 @@ sctp_disposition_t sctp_sf_t4_timer_expire( | |||
5406 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 5433 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, |
5407 | SCTP_PERR(SCTP_ERROR_NO_ERROR)); | 5434 | SCTP_PERR(SCTP_ERROR_NO_ERROR)); |
5408 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 5435 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); |
5409 | SCTP_INC_STATS(SCTP_MIB_CURRESTAB); | 5436 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); |
5410 | return SCTP_DISPOSITION_ABORT; | 5437 | return SCTP_DISPOSITION_ABORT; |
5411 | } | 5438 | } |
5412 | 5439 | ||
@@ -5462,6 +5489,9 @@ sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep, | |||
5462 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 5489 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, |
5463 | SCTP_PERR(SCTP_ERROR_NO_ERROR)); | 5490 | SCTP_PERR(SCTP_ERROR_NO_ERROR)); |
5464 | 5491 | ||
5492 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | ||
5493 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); | ||
5494 | |||
5465 | return SCTP_DISPOSITION_DELETE_TCB; | 5495 | return SCTP_DISPOSITION_DELETE_TCB; |
5466 | nomem: | 5496 | nomem: |
5467 | return SCTP_DISPOSITION_NOMEM; | 5497 | return SCTP_DISPOSITION_NOMEM; |
@@ -5494,12 +5524,6 @@ sctp_disposition_t sctp_sf_autoclose_timer_expire( | |||
5494 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | 5524 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, |
5495 | SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING)); | 5525 | SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING)); |
5496 | 5526 | ||
5497 | /* sctpimpguide-05 Section 2.12.2 | ||
5498 | * The sender of the SHUTDOWN MAY also start an overall guard timer | ||
5499 | * 'T5-shutdown-guard' to bound the overall time for shutdown sequence. | ||
5500 | */ | ||
5501 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | ||
5502 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | ||
5503 | disposition = SCTP_DISPOSITION_CONSUME; | 5527 | disposition = SCTP_DISPOSITION_CONSUME; |
5504 | if (sctp_outq_is_empty(&asoc->outqueue)) { | 5528 | if (sctp_outq_is_empty(&asoc->outqueue)) { |
5505 | disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type, | 5529 | disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type, |