sctp: improve the events for sctp stream reset
This patch is to improve sctp stream reset events in 4 places: 1. In sctp_process_strreset_outreq(), the flag should always be set with SCTP_STREAM_RESET_INCOMING_SSN instead of OUTGOING, as receiver's in stream is reset here. 2. In sctp_process_strreset_outreq(), move up SCTP_STRRESET_ERR_WRONG_SSN check, as the reset has to succeed after reconf_timer stops for the in stream reset request retransmission. 3. In sctp_process_strreset_inreq(), no event should be sent, as no in or out stream is reset here. 4. In sctp_process_strreset_resp(), SCTP_STREAM_RESET_INCOMING_SSN or OUTGOING event should always be sent for stream reset requests, no matter it fails or succeeds to process the request. Fixes:8105447645
("sctp: implement receiver-side procedures for the Outgoing SSN Reset Request Parameter") Fixes:16e1a91965
("sctp: implement receiver-side procedures for the Incoming SSN Reset Request Parameter") Fixes:11ae76e67a
("sctp: implement receiver-side procedures for the Reconf Response Parameter") Reported-by: Ying Xu <yinxu@redhat.com> Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d71b57532d
commit
2e6dc4d951
|
@ -585,9 +585,9 @@ struct sctp_chunk *sctp_process_strreset_outreq(
|
|||
struct sctp_strreset_outreq *outreq = param.v;
|
||||
struct sctp_stream *stream = &asoc->stream;
|
||||
__u32 result = SCTP_STRRESET_DENIED;
|
||||
__u16 i, nums, flags = 0;
|
||||
__be16 *str_p = NULL;
|
||||
__u32 request_seq;
|
||||
__u16 i, nums;
|
||||
|
||||
request_seq = ntohl(outreq->request_seq);
|
||||
|
||||
|
@ -615,6 +615,15 @@ struct sctp_chunk *sctp_process_strreset_outreq(
|
|||
if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ))
|
||||
goto out;
|
||||
|
||||
nums = (ntohs(param.p->length) - sizeof(*outreq)) / sizeof(__u16);
|
||||
str_p = outreq->list_of_streams;
|
||||
for (i = 0; i < nums; i++) {
|
||||
if (ntohs(str_p[i]) >= stream->incnt) {
|
||||
result = SCTP_STRRESET_ERR_WRONG_SSN;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (asoc->strreset_chunk) {
|
||||
if (!sctp_chunk_lookup_strreset_param(
|
||||
asoc, outreq->response_seq,
|
||||
|
@ -637,32 +646,19 @@ struct sctp_chunk *sctp_process_strreset_outreq(
|
|||
sctp_chunk_put(asoc->strreset_chunk);
|
||||
asoc->strreset_chunk = NULL;
|
||||
}
|
||||
|
||||
flags = SCTP_STREAM_RESET_INCOMING_SSN;
|
||||
}
|
||||
|
||||
nums = (ntohs(param.p->length) - sizeof(*outreq)) / sizeof(__u16);
|
||||
if (nums) {
|
||||
str_p = outreq->list_of_streams;
|
||||
for (i = 0; i < nums; i++) {
|
||||
if (ntohs(str_p[i]) >= stream->incnt) {
|
||||
result = SCTP_STRRESET_ERR_WRONG_SSN;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (nums)
|
||||
for (i = 0; i < nums; i++)
|
||||
SCTP_SI(stream, ntohs(str_p[i]))->mid = 0;
|
||||
} else {
|
||||
else
|
||||
for (i = 0; i < stream->incnt; i++)
|
||||
SCTP_SI(stream, i)->mid = 0;
|
||||
}
|
||||
|
||||
result = SCTP_STRRESET_PERFORMED;
|
||||
|
||||
*evp = sctp_ulpevent_make_stream_reset_event(asoc,
|
||||
flags | SCTP_STREAM_RESET_OUTGOING_SSN, nums, str_p,
|
||||
GFP_ATOMIC);
|
||||
SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC);
|
||||
|
||||
out:
|
||||
sctp_update_strreset_result(asoc, result);
|
||||
|
@ -738,9 +734,6 @@ struct sctp_chunk *sctp_process_strreset_inreq(
|
|||
|
||||
result = SCTP_STRRESET_PERFORMED;
|
||||
|
||||
*evp = sctp_ulpevent_make_stream_reset_event(asoc,
|
||||
SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC);
|
||||
|
||||
out:
|
||||
sctp_update_strreset_result(asoc, result);
|
||||
err:
|
||||
|
@ -1036,10 +1029,10 @@ struct sctp_chunk *sctp_process_strreset_resp(
|
|||
sout->mid_uo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
flags = SCTP_STREAM_RESET_OUTGOING_SSN;
|
||||
}
|
||||
|
||||
flags |= SCTP_STREAM_RESET_OUTGOING_SSN;
|
||||
|
||||
for (i = 0; i < stream->outcnt; i++)
|
||||
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
|
||||
|
||||
|
@ -1058,6 +1051,8 @@ struct sctp_chunk *sctp_process_strreset_resp(
|
|||
nums = (ntohs(inreq->param_hdr.length) - sizeof(*inreq)) /
|
||||
sizeof(__u16);
|
||||
|
||||
flags |= SCTP_STREAM_RESET_INCOMING_SSN;
|
||||
|
||||
*evp = sctp_ulpevent_make_stream_reset_event(asoc, flags,
|
||||
nums, str_p, GFP_ATOMIC);
|
||||
} else if (req->type == SCTP_PARAM_RESET_TSN_REQUEST) {
|
||||
|
|
Loading…
Reference in New Issue