Skip to content

Commit

Permalink
sctp: implement receiver-side procedures for the Add Incoming Streams…
Browse files Browse the repository at this point in the history
… 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 <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Xin Long authored and David S. Miller committed Mar 13, 2017
1 parent 50a4159 commit c5c4ebb
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 12 deletions.
4 changes: 4 additions & 0 deletions include/net/sctp/sm.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,10 @@ struct sctp_chunk *sctp_process_strreset_addstrm_out(
struct sctp_association *asoc,
union sctp_params param,
struct sctp_ulpevent **evp);
struct sctp_chunk *sctp_process_strreset_addstrm_in(
struct sctp_association *asoc,
union sctp_params param,
struct sctp_ulpevent **evp);

/* Prototypes for statetable processing. */

Expand Down
3 changes: 3 additions & 0 deletions net/sctp/sm_statefuns.c
Original file line number Diff line number Diff line change
Expand Up @@ -3878,6 +3878,9 @@ sctp_disposition_t sctp_sf_do_reconf(struct net *net,
else if (param.p->type == SCTP_PARAM_RESET_ADD_OUT_STREAMS)
reply = sctp_process_strreset_addstrm_out(
(struct sctp_association *)asoc, param, &ev);
else if (param.p->type == SCTP_PARAM_RESET_ADD_IN_STREAMS)
reply = sctp_process_strreset_addstrm_in(
(struct sctp_association *)asoc, param, &ev);
/* More handles for other types will be added here, by now it
* just ignores other types.
*/
Expand Down
74 changes: 62 additions & 12 deletions net/sctp/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,18 +267,6 @@ int sctp_send_add_streams(struct sctp_association *asoc,
stream->out = streamout;
}

if (in) {
struct sctp_stream_in *streamin;

streamin = krealloc(stream->in, incnt * sizeof(*streamin),
GFP_KERNEL);
if (!streamin)
goto out;

memset(streamin + stream->incnt, 0, in * sizeof(*streamin));
stream->in = streamin;
}

chunk = sctp_make_strreset_addstrm(asoc, out, in);
if (!chunk)
goto out;
Expand Down Expand Up @@ -625,3 +613,65 @@ struct sctp_chunk *sctp_process_strreset_addstrm_out(
out:
return sctp_make_strreset_resp(asoc, result, request_seq);
}

struct sctp_chunk *sctp_process_strreset_addstrm_in(
struct sctp_association *asoc,
union sctp_params param,
struct sctp_ulpevent **evp)
{
struct sctp_strreset_addstrm *addstrm = param.v;
struct sctp_stream *stream = asoc->stream;
__u32 result = SCTP_STRRESET_DENIED;
struct sctp_stream_out *streamout;
struct sctp_chunk *chunk = NULL;
__u32 request_seq, outcnt;
__u16 out;

request_seq = ntohl(addstrm->request_seq);
if (request_seq > asoc->strreset_inseq) {
result = SCTP_STRRESET_ERR_BAD_SEQNO;
goto out;
} else if (request_seq == asoc->strreset_inseq) {
asoc->strreset_inseq++;
}

if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ))
goto out;

if (asoc->strreset_outstanding) {
result = SCTP_STRRESET_ERR_IN_PROGRESS;
goto out;
}

out = ntohs(addstrm->number_of_streams);
outcnt = stream->outcnt + out;
if (!out || outcnt > SCTP_MAX_STREAM)
goto out;

streamout = krealloc(stream->out, outcnt * sizeof(*streamout),
GFP_ATOMIC);
if (!streamout)
goto out;

memset(streamout + stream->outcnt, 0, out * sizeof(*streamout));
stream->out = streamout;

chunk = sctp_make_strreset_addstrm(asoc, out, 0);
if (!chunk)
goto out;

asoc->strreset_chunk = chunk;
asoc->strreset_outstanding = 1;
sctp_chunk_hold(asoc->strreset_chunk);

stream->outcnt = outcnt;

*evp = sctp_ulpevent_make_stream_change_event(asoc,
0, 0, ntohs(addstrm->number_of_streams), GFP_ATOMIC);

out:
if (!chunk)
chunk = sctp_make_strreset_resp(asoc, result, request_seq);

return chunk;
}

0 comments on commit c5c4ebb

Please sign in to comment.