diff options
author | Xin Long <lucien.xin@gmail.com> | 2017-01-17 11:44:47 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-01-18 14:55:11 -0500 |
commit | 7f9d68ac944e24ee5f9ac8d059ca00b1c1d34137 (patch) | |
tree | 08007191a5e6a018f08dd26919305175b5a14b23 /net/sctp/outqueue.c | |
parent | 9fb657aec0e20b4ed4401c44a4140f8d7b7a9ca0 (diff) |
sctp: implement sender-side procedures for SSN Reset Request Parameter
This patch is to implement sender-side procedures for the Outgoing
and Incoming SSN Reset Request Parameter described in rfc6525 section
5.1.2 and 5.1.3.
It is also add sockopt SCTP_RESET_STREAMS in rfc6525 section 6.3.2
for users.
Note that the new asoc member strreset_outstanding is to make sure
only one reconf request chunk on the fly as rfc6525 section 5.1.1
demands.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/outqueue.c')
-rw-r--r-- | net/sctp/outqueue.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 34efaa4ef2f6..65abe22d8691 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -915,22 +915,28 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) | |||
915 | case SCTP_CID_ECN_ECNE: | 915 | case SCTP_CID_ECN_ECNE: |
916 | case SCTP_CID_ASCONF: | 916 | case SCTP_CID_ASCONF: |
917 | case SCTP_CID_FWD_TSN: | 917 | case SCTP_CID_FWD_TSN: |
918 | case SCTP_CID_RECONF: | ||
918 | status = sctp_packet_transmit_chunk(packet, chunk, | 919 | status = sctp_packet_transmit_chunk(packet, chunk, |
919 | one_packet, gfp); | 920 | one_packet, gfp); |
920 | if (status != SCTP_XMIT_OK) { | 921 | if (status != SCTP_XMIT_OK) { |
921 | /* put the chunk back */ | 922 | /* put the chunk back */ |
922 | list_add(&chunk->list, &q->control_chunk_list); | 923 | list_add(&chunk->list, &q->control_chunk_list); |
923 | } else { | 924 | break; |
924 | asoc->stats.octrlchunks++; | 925 | } |
925 | /* PR-SCTP C5) If a FORWARD TSN is sent, the | 926 | |
926 | * sender MUST assure that at least one T3-rtx | 927 | asoc->stats.octrlchunks++; |
927 | * timer is running. | 928 | /* PR-SCTP C5) If a FORWARD TSN is sent, the |
928 | */ | 929 | * sender MUST assure that at least one T3-rtx |
929 | if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) { | 930 | * timer is running. |
930 | sctp_transport_reset_t3_rtx(transport); | 931 | */ |
931 | transport->last_time_sent = jiffies; | 932 | if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) { |
932 | } | 933 | sctp_transport_reset_t3_rtx(transport); |
934 | transport->last_time_sent = jiffies; | ||
933 | } | 935 | } |
936 | |||
937 | if (chunk == asoc->strreset_chunk) | ||
938 | sctp_transport_reset_reconf_timer(transport); | ||
939 | |||
934 | break; | 940 | break; |
935 | 941 | ||
936 | default: | 942 | default: |
@@ -1016,6 +1022,8 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) | |||
1016 | 1022 | ||
1017 | /* Finally, transmit new packets. */ | 1023 | /* Finally, transmit new packets. */ |
1018 | while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { | 1024 | while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { |
1025 | __u32 sid = ntohs(chunk->subh.data_hdr->stream); | ||
1026 | |||
1019 | /* RFC 2960 6.5 Every DATA chunk MUST carry a valid | 1027 | /* RFC 2960 6.5 Every DATA chunk MUST carry a valid |
1020 | * stream identifier. | 1028 | * stream identifier. |
1021 | */ | 1029 | */ |
@@ -1038,6 +1046,11 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) | |||
1038 | continue; | 1046 | continue; |
1039 | } | 1047 | } |
1040 | 1048 | ||
1049 | if (asoc->stream->out[sid].state == SCTP_STREAM_CLOSED) { | ||
1050 | sctp_outq_head_data(q, chunk); | ||
1051 | goto sctp_flush_out; | ||
1052 | } | ||
1053 | |||
1041 | /* If there is a specified transport, use it. | 1054 | /* If there is a specified transport, use it. |
1042 | * Otherwise, we want to use the active path. | 1055 | * Otherwise, we want to use the active path. |
1043 | */ | 1056 | */ |