aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_statefuns.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r--net/sctp/sm_statefuns.c92
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
125static sctp_disposition_t sctp_sf_violation_ctsn( 125static 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
4189discard:
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
4193discard:
4194 sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
4194 return SCTP_DISPOSITION_ABORT; 4195 return SCTP_DISPOSITION_ABORT;
4195 4196
4196nomem_pkt: 4197nomem_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
4269discard:
4270 sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
4271 return SCTP_DISPOSITION_ABORT;
4272nomem:
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;
5466nomem: 5496nomem:
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,