Skip to content

Commit c5c4ebb

Browse files
lxindavem330
authored andcommitted
sctp: implement receiver-side procedures for the Add Incoming Streams Request Parameter
This patch is to implement Receiver-Side Procedures for the Add Incoming Streams Request Parameter described in rfc6525 section 5.2.6. It is also to fix that it shouldn't have add streams when sending addstrm in request, as the process in peer will handle it by sending a addstrm out request back. Signed-off-by: Xin Long <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 50a4159 commit c5c4ebb

File tree

3 files changed

+69
-12
lines changed

3 files changed

+69
-12
lines changed

include/net/sctp/sm.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,10 @@ struct sctp_chunk *sctp_process_strreset_addstrm_out(
301301
struct sctp_association *asoc,
302302
union sctp_params param,
303303
struct sctp_ulpevent **evp);
304+
struct sctp_chunk *sctp_process_strreset_addstrm_in(
305+
struct sctp_association *asoc,
306+
union sctp_params param,
307+
struct sctp_ulpevent **evp);
304308

305309
/* Prototypes for statetable processing. */
306310

net/sctp/sm_statefuns.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3878,6 +3878,9 @@ sctp_disposition_t sctp_sf_do_reconf(struct net *net,
38783878
else if (param.p->type == SCTP_PARAM_RESET_ADD_OUT_STREAMS)
38793879
reply = sctp_process_strreset_addstrm_out(
38803880
(struct sctp_association *)asoc, param, &ev);
3881+
else if (param.p->type == SCTP_PARAM_RESET_ADD_IN_STREAMS)
3882+
reply = sctp_process_strreset_addstrm_in(
3883+
(struct sctp_association *)asoc, param, &ev);
38813884
/* More handles for other types will be added here, by now it
38823885
* just ignores other types.
38833886
*/

net/sctp/stream.c

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -267,18 +267,6 @@ int sctp_send_add_streams(struct sctp_association *asoc,
267267
stream->out = streamout;
268268
}
269269

270-
if (in) {
271-
struct sctp_stream_in *streamin;
272-
273-
streamin = krealloc(stream->in, incnt * sizeof(*streamin),
274-
GFP_KERNEL);
275-
if (!streamin)
276-
goto out;
277-
278-
memset(streamin + stream->incnt, 0, in * sizeof(*streamin));
279-
stream->in = streamin;
280-
}
281-
282270
chunk = sctp_make_strreset_addstrm(asoc, out, in);
283271
if (!chunk)
284272
goto out;
@@ -625,3 +613,65 @@ struct sctp_chunk *sctp_process_strreset_addstrm_out(
625613
out:
626614
return sctp_make_strreset_resp(asoc, result, request_seq);
627615
}
616+
617+
struct sctp_chunk *sctp_process_strreset_addstrm_in(
618+
struct sctp_association *asoc,
619+
union sctp_params param,
620+
struct sctp_ulpevent **evp)
621+
{
622+
struct sctp_strreset_addstrm *addstrm = param.v;
623+
struct sctp_stream *stream = asoc->stream;
624+
__u32 result = SCTP_STRRESET_DENIED;
625+
struct sctp_stream_out *streamout;
626+
struct sctp_chunk *chunk = NULL;
627+
__u32 request_seq, outcnt;
628+
__u16 out;
629+
630+
request_seq = ntohl(addstrm->request_seq);
631+
if (request_seq > asoc->strreset_inseq) {
632+
result = SCTP_STRRESET_ERR_BAD_SEQNO;
633+
goto out;
634+
} else if (request_seq == asoc->strreset_inseq) {
635+
asoc->strreset_inseq++;
636+
}
637+
638+
if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ))
639+
goto out;
640+
641+
if (asoc->strreset_outstanding) {
642+
result = SCTP_STRRESET_ERR_IN_PROGRESS;
643+
goto out;
644+
}
645+
646+
out = ntohs(addstrm->number_of_streams);
647+
outcnt = stream->outcnt + out;
648+
if (!out || outcnt > SCTP_MAX_STREAM)
649+
goto out;
650+
651+
streamout = krealloc(stream->out, outcnt * sizeof(*streamout),
652+
GFP_ATOMIC);
653+
if (!streamout)
654+
goto out;
655+
656+
memset(streamout + stream->outcnt, 0, out * sizeof(*streamout));
657+
stream->out = streamout;
658+
659+
chunk = sctp_make_strreset_addstrm(asoc, out, 0);
660+
if (!chunk)
661+
goto out;
662+
663+
asoc->strreset_chunk = chunk;
664+
asoc->strreset_outstanding = 1;
665+
sctp_chunk_hold(asoc->strreset_chunk);
666+
667+
stream->outcnt = outcnt;
668+
669+
*evp = sctp_ulpevent_make_stream_change_event(asoc,
670+
0, 0, ntohs(addstrm->number_of_streams), GFP_ATOMIC);
671+
672+
out:
673+
if (!chunk)
674+
chunk = sctp_make_strreset_resp(asoc, result, request_seq);
675+
676+
return chunk;
677+
}

0 commit comments

Comments
 (0)