diff options
| -rw-r--r-- | include/net/sctp/sm.h | 1 | ||||
| -rw-r--r-- | net/sctp/sm_statefuns.c | 45 | ||||
| -rw-r--r-- | net/sctp/sm_statetable.c | 2 |
3 files changed, 47 insertions, 1 deletions
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 029a54a02396..c1dd89365833 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h | |||
| @@ -125,6 +125,7 @@ sctp_state_fn_t sctp_sf_beat_8_3; | |||
| 125 | sctp_state_fn_t sctp_sf_backbeat_8_3; | 125 | sctp_state_fn_t sctp_sf_backbeat_8_3; |
| 126 | sctp_state_fn_t sctp_sf_do_9_2_final; | 126 | sctp_state_fn_t sctp_sf_do_9_2_final; |
| 127 | sctp_state_fn_t sctp_sf_do_9_2_shutdown; | 127 | sctp_state_fn_t sctp_sf_do_9_2_shutdown; |
| 128 | sctp_state_fn_t sctp_sf_do_9_2_shut_ctsn; | ||
| 128 | sctp_state_fn_t sctp_sf_do_ecn_cwr; | 129 | sctp_state_fn_t sctp_sf_do_ecn_cwr; |
| 129 | sctp_state_fn_t sctp_sf_do_ecne; | 130 | sctp_state_fn_t sctp_sf_do_ecne; |
| 130 | sctp_state_fn_t sctp_sf_ootb; | 131 | sctp_state_fn_t sctp_sf_ootb; |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 12f62174f4a1..a6a0ea71ae93 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -2608,6 +2608,51 @@ out: | |||
| 2608 | return disposition; | 2608 | return disposition; |
| 2609 | } | 2609 | } |
| 2610 | 2610 | ||
| 2611 | /* | ||
| 2612 | * sctp_sf_do_9_2_shut_ctsn | ||
| 2613 | * | ||
| 2614 | * Once an endpoint has reached the SHUTDOWN-RECEIVED state, | ||
| 2615 | * it MUST NOT send a SHUTDOWN in response to a ULP request. | ||
| 2616 | * The Cumulative TSN Ack of the received SHUTDOWN chunk | ||
| 2617 | * MUST be processed. | ||
| 2618 | */ | ||
| 2619 | sctp_disposition_t sctp_sf_do_9_2_shut_ctsn(const struct sctp_endpoint *ep, | ||
| 2620 | const struct sctp_association *asoc, | ||
| 2621 | const sctp_subtype_t type, | ||
| 2622 | void *arg, | ||
| 2623 | sctp_cmd_seq_t *commands) | ||
| 2624 | { | ||
| 2625 | struct sctp_chunk *chunk = arg; | ||
| 2626 | sctp_shutdownhdr_t *sdh; | ||
| 2627 | |||
| 2628 | if (!sctp_vtag_verify(chunk, asoc)) | ||
| 2629 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | ||
| 2630 | |||
| 2631 | /* Make sure that the SHUTDOWN chunk has a valid length. */ | ||
| 2632 | if (!sctp_chunk_length_valid(chunk, | ||
| 2633 | sizeof(struct sctp_shutdown_chunk_t))) | ||
| 2634 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | ||
| 2635 | commands); | ||
| 2636 | |||
| 2637 | sdh = (sctp_shutdownhdr_t *)chunk->skb->data; | ||
| 2638 | |||
| 2639 | /* If Cumulative TSN Ack beyond the max tsn currently | ||
| 2640 | * send, terminating the association and respond to the | ||
| 2641 | * sender with an ABORT. | ||
| 2642 | */ | ||
| 2643 | if (!TSN_lt(ntohl(sdh->cum_tsn_ack), asoc->next_tsn)) | ||
| 2644 | return sctp_sf_violation_ctsn(ep, asoc, type, arg, commands); | ||
| 2645 | |||
| 2646 | /* verify, by checking the Cumulative TSN Ack field of the | ||
| 2647 | * chunk, that all its outstanding DATA chunks have been | ||
| 2648 | * received by the SHUTDOWN sender. | ||
| 2649 | */ | ||
| 2650 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_CTSN, | ||
| 2651 | SCTP_BE32(sdh->cum_tsn_ack)); | ||
| 2652 | |||
| 2653 | return SCTP_DISPOSITION_CONSUME; | ||
| 2654 | } | ||
| 2655 | |||
| 2611 | /* RFC 2960 9.2 | 2656 | /* RFC 2960 9.2 |
| 2612 | * If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk | 2657 | * If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk |
| 2613 | * (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination | 2658 | * (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination |
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index a5b5590dc1a6..5c8186d88c61 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c | |||
| @@ -270,7 +270,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
| 270 | /* SCTP_STATE_SHUTDOWN_SENT */ \ | 270 | /* SCTP_STATE_SHUTDOWN_SENT */ \ |
| 271 | TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown_ack), \ | 271 | TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown_ack), \ |
| 272 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ | 272 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ |
| 273 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 273 | TYPE_SCTP_FUNC(sctp_sf_do_9_2_shut_ctsn), \ |
| 274 | /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ | 274 | /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ |
| 275 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 275 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
| 276 | } /* TYPE_SCTP_SHUTDOWN */ | 276 | } /* TYPE_SCTP_SHUTDOWN */ |
