diff options
| author | Wei Yongjun <yjwei@cn.fujitsu.com> | 2008-10-23 04:01:18 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2008-10-23 04:01:18 -0400 |
| commit | 2e3f92dad6bdbee796274bae5c1c50a6ddd31cbb (patch) | |
| tree | e4a08c8d2c43d8fc45937fe9db85f616d2f7c7a1 /net | |
| parent | cf896d514a4564027929a6d284872c74987085ef (diff) | |
sctp: Fix to handle SHUTDOWN in SHUTDOWN_RECEIVED state
Once an endpoint has reached the SHUTDOWN-RECEIVED state,
it MUST NOT send a SHUTDOWN in response to a ULP request.
The Cumulative TSN Ack of the received SHUTDOWN chunk
MUST be processed.
This patch fix to process Cumulative TSN Ack of the received
SHUTDOWN chunk in SHUTDOWN_RECEIVED state.
Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
| -rw-r--r-- | net/sctp/sm_statefuns.c | 45 | ||||
| -rw-r--r-- | net/sctp/sm_statetable.c | 2 |
2 files changed, 46 insertions, 1 deletions
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 */ |
