summaryrefslogtreecommitdiffstats
path: root/net/sctp/stream.c
diff options
context:
space:
mode:
authorXin Long2017-02-08 18:18:18 +0100
committerDavid S. Miller2017-02-09 22:57:38 +0100
commita92ce1a42dde1caaee4afae67531e3e7acecf6e4 (patch)
tree986627557298741d54a71074fd9d31ce1bfae810 /net/sctp/stream.c
parentsctp: add support for generating stream reconf ssn/tsn reset request chunk (diff)
downloadkernel-qcow2-linux-a92ce1a42dde1caaee4afae67531e3e7acecf6e4.tar.gz
kernel-qcow2-linux-a92ce1a42dde1caaee4afae67531e3e7acecf6e4.tar.xz
kernel-qcow2-linux-a92ce1a42dde1caaee4afae67531e3e7acecf6e4.zip
sctp: implement sender-side procedures for SSN/TSN Reset Request Parameter
This patch is to implement Sender-Side Procedures for the SSN/TSN Reset Request Parameter descibed in rfc6525 section 5.1.4. It is also to add sockopt SCTP_RESET_ASSOC in rfc6525 section 6.3.3 for users. Signed-off-by: Xin Long <lucien.xin@gmail.com> Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/stream.c')
-rw-r--r--net/sctp/stream.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index 6a686e330c57..53e49fc2f0a3 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -177,3 +177,43 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
out:
return retval;
}
+
+int sctp_send_reset_assoc(struct sctp_association *asoc)
+{
+ struct sctp_chunk *chunk = NULL;
+ int retval;
+ __u16 i;
+
+ if (!asoc->peer.reconf_capable ||
+ !(asoc->strreset_enable & SCTP_ENABLE_RESET_ASSOC_REQ))
+ return -ENOPROTOOPT;
+
+ if (asoc->strreset_outstanding)
+ return -EINPROGRESS;
+
+ chunk = sctp_make_strreset_tsnreq(asoc);
+ if (!chunk)
+ return -ENOMEM;
+
+ /* Block further xmit of data until this request is completed */
+ for (i = 0; i < asoc->stream->outcnt; i++)
+ asoc->stream->out[i].state = SCTP_STREAM_CLOSED;
+
+ asoc->strreset_chunk = chunk;
+ sctp_chunk_hold(asoc->strreset_chunk);
+
+ retval = sctp_send_reconf(asoc, chunk);
+ if (retval) {
+ sctp_chunk_put(asoc->strreset_chunk);
+ asoc->strreset_chunk = NULL;
+
+ for (i = 0; i < asoc->stream->outcnt; i++)
+ asoc->stream->out[i].state = SCTP_STREAM_OPEN;
+
+ return retval;
+ }
+
+ asoc->strreset_outstanding = 1;
+
+ return 0;
+}