summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/sctp.h7
-rw-r--r--include/net/sctp/sm.h3
-rw-r--r--net/sctp/sm_make_chunk.c46
3 files changed, 56 insertions, 0 deletions
diff --git a/include/linux/sctp.h b/include/linux/sctp.h
index 71c0d41d9a59..b055788de0cf 100644
--- a/include/linux/sctp.h
+++ b/include/linux/sctp.h
@@ -742,4 +742,11 @@ struct sctp_strreset_tsnreq {
__u32 request_seq;
};
+struct sctp_strreset_addstrm {
+ sctp_paramhdr_t param_hdr;
+ __u32 request_seq;
+ __u16 number_of_streams;
+ __u16 reserved;
+};
+
#endif /* __LINUX_SCTP_H__ */
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index ac37c1782e23..3675fde3a26e 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -267,6 +267,9 @@ struct sctp_chunk *sctp_make_strreset_req(
bool out, bool in);
struct sctp_chunk *sctp_make_strreset_tsnreq(
const struct sctp_association *asoc);
+struct sctp_chunk *sctp_make_strreset_addstrm(
+ const struct sctp_association *asoc,
+ __u16 out, __u16 in);
void sctp_chunk_assign_tsn(struct sctp_chunk *);
void sctp_chunk_assign_ssn(struct sctp_chunk *);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 749842aead33..7f8dbf2c6cee 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3687,3 +3687,49 @@ struct sctp_chunk *sctp_make_strreset_tsnreq(
return retval;
}
+
+/* RE-CONFIG 4.5/4.6 (ADD STREAM)
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Parameter Type = 17 | Parameter Length = 12 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Re-configuration Request Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of new streams | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct sctp_chunk *sctp_make_strreset_addstrm(
+ const struct sctp_association *asoc,
+ __u16 out, __u16 in)
+{
+ struct sctp_strreset_addstrm addstrm;
+ __u16 size = sizeof(addstrm);
+ struct sctp_chunk *retval;
+
+ retval = sctp_make_reconf(asoc, (!!out + !!in) * size);
+ if (!retval)
+ return NULL;
+
+ if (out) {
+ addstrm.param_hdr.type = SCTP_PARAM_RESET_ADD_OUT_STREAMS;
+ addstrm.param_hdr.length = htons(size);
+ addstrm.number_of_streams = htons(out);
+ addstrm.request_seq = htonl(asoc->strreset_outseq);
+ addstrm.reserved = 0;
+
+ sctp_addto_chunk(retval, size, &addstrm);
+ }
+
+ if (in) {
+ addstrm.param_hdr.type = SCTP_PARAM_RESET_ADD_IN_STREAMS;
+ addstrm.param_hdr.length = htons(size);
+ addstrm.number_of_streams = htons(in);
+ addstrm.request_seq = htonl(asoc->strreset_outseq + !!out);
+ addstrm.reserved = 0;
+
+ sctp_addto_chunk(retval, size, &addstrm);
+ }
+
+ return retval;
+}