* [PATCHv2 net-next 0/7] sctp: add receiver-side procedures for stream reconf ssn reset request chunk
@ 2017-02-17 4:45 Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 1/7] sctp: add support for generating stream reconf resp chunk Xin Long
2017-02-19 23:18 ` [PATCHv2 net-next 0/7] sctp: add receiver-side procedures for stream reconf ssn reset request chunk David Miller
0 siblings, 2 replies; 9+ messages in thread
From: Xin Long @ 2017-02-17 4:45 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
Patch 3/7 and 4/7 are to implement receiver-side procedures for the
Outgoing and Incoming SSN Reset Request Parameter described in rfc6525
section 5.2.2 and 5.2.3
Patch 1/7 and 2/7 are ahead of them to define some apis.
Patch 5/7-7/7 are to add the process of reconf chunk event in rx path.
Note that with this patchset, asoc->reconf_enable has no chance yet to
be set, until the patch "sctp: add get and set sockopt for reconf_enable"
is applied in the future. As we can not just enable it when sctp is not
capable of processing reconf chunk yet.
v1->v2:
- re-split the patchset and make sure it has no dead codes for review.
- rename the titles of the commits and improve some changelogs.
- drop __packed from some structures in patch 1/7.
- fix some kbuild warnings in patch 3/7 by initializing str_p = NULL.
- sctp_chunk_lookup_strreset_param changes to return sctp_paramhdr_t *
and uses sctp_strreset_tsnreq to access request_seq in patch 3/7.
- use __u<size> in uapi sctp.h in patch 1/7.
- do str_list endian conversion when generating stream_reset_event in patch
2/7.
- remove str_list endian conversion, pass resp_seq param with network endian
to lookup_strreset_param in 3/7.
- move str_list endian conversion out of sctp_make_strreset_req, so that
sctp_make_strreset_req can be used more conveniently to process inreq in
patch 4/7.
- remove sctp_merge_reconf_chunk and not support response with multiparam
in patch 6/7.
Xin Long (7):
sctp: add support for generating stream reconf resp chunk
sctp: add support for generating stream ssn reset event notification
sctp: implement receiver-side procedures for the Outgoing SSN Reset
Request Parameter
sctp: implement receiver-side procedures for the Incoming SSN Reset
Request Parameter
sctp: add a function to verify the sctp reconf chunk
sctp: add reconf chunk process
sctp: add reconf chunk event
include/linux/sctp.h | 24 ++++++
include/net/sctp/constants.h | 3 +
include/net/sctp/sm.h | 21 +++++
include/net/sctp/ulpevent.h | 4 +
include/uapi/linux/sctp.h | 16 ++++
net/sctp/sm_make_chunk.c | 141 +++++++++++++++++++++++++++++++--
net/sctp/sm_statefuns.c | 54 +++++++++++++
net/sctp/sm_statetable.c | 30 +++++++
net/sctp/stream.c | 183 +++++++++++++++++++++++++++++++++++++++++++
net/sctp/ulpevent.c | 29 +++++++
10 files changed, 498 insertions(+), 7 deletions(-)
--
2.1.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCHv2 net-next 1/7] sctp: add support for generating stream reconf resp chunk
2017-02-17 4:45 [PATCHv2 net-next 0/7] sctp: add receiver-side procedures for stream reconf ssn reset request chunk Xin Long
@ 2017-02-17 4:45 ` Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 2/7] sctp: add support for generating stream ssn reset event notification Xin Long
2017-02-19 23:18 ` [PATCHv2 net-next 0/7] sctp: add receiver-side procedures for stream reconf ssn reset request chunk David Miller
1 sibling, 1 reply; 9+ messages in thread
From: Xin Long @ 2017-02-17 4:45 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
This patch is to define Re-configuration Response Parameter described
in rfc6525 section 4.4. As optional fields are only for SSN/TSN Reset
Request Parameter, it uses another function to make that.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/linux/sctp.h | 24 ++++++++++++++++
include/net/sctp/sm.h | 7 +++++
net/sctp/sm_make_chunk.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 105 insertions(+)
diff --git a/include/linux/sctp.h b/include/linux/sctp.h
index b055788..7a4804c 100644
--- a/include/linux/sctp.h
+++ b/include/linux/sctp.h
@@ -749,4 +749,28 @@ struct sctp_strreset_addstrm {
__u16 reserved;
};
+enum {
+ SCTP_STRRESET_NOTHING_TO_DO = 0x00,
+ SCTP_STRRESET_PERFORMED = 0x01,
+ SCTP_STRRESET_DENIED = 0x02,
+ SCTP_STRRESET_ERR_WRONG_SSN = 0x03,
+ SCTP_STRRESET_ERR_IN_PROGRESS = 0x04,
+ SCTP_STRRESET_ERR_BAD_SEQNO = 0x05,
+ SCTP_STRRESET_IN_PROGRESS = 0x06,
+};
+
+struct sctp_strreset_resp {
+ sctp_paramhdr_t param_hdr;
+ __u32 response_seq;
+ __u32 result;
+};
+
+struct sctp_strreset_resptsn {
+ sctp_paramhdr_t param_hdr;
+ __u32 response_seq;
+ __u32 result;
+ __u32 senders_next_tsn;
+ __u32 receivers_next_tsn;
+};
+
#endif /* __LINUX_SCTP_H__ */
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 3675fde..8a85dd7 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -270,6 +270,13 @@ struct sctp_chunk *sctp_make_strreset_tsnreq(
struct sctp_chunk *sctp_make_strreset_addstrm(
const struct sctp_association *asoc,
__u16 out, __u16 in);
+struct sctp_chunk *sctp_make_strreset_resp(
+ const struct sctp_association *asoc,
+ __u32 result, __u32 sn);
+struct sctp_chunk *sctp_make_strreset_tsnresp(
+ struct sctp_association *asoc,
+ __u32 result, __u32 sn,
+ __u32 sender_tsn, __u32 receiver_tsn);
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 7f8dbf2..9680c58 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3733,3 +3733,77 @@ struct sctp_chunk *sctp_make_strreset_addstrm(
return retval;
}
+
+/* RE-CONFIG 4.4 (RESP)
+ * 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 = 16 | Parameter Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Re-configuration Response Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Result |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct sctp_chunk *sctp_make_strreset_resp(
+ const struct sctp_association *asoc,
+ __u32 result, __u32 sn)
+{
+ struct sctp_strreset_resp resp;
+ __u16 length = sizeof(resp);
+ struct sctp_chunk *retval;
+
+ retval = sctp_make_reconf(asoc, length);
+ if (!retval)
+ return NULL;
+
+ resp.param_hdr.type = SCTP_PARAM_RESET_RESPONSE;
+ resp.param_hdr.length = htons(length);
+ resp.response_seq = htonl(sn);
+ resp.result = htonl(result);
+
+ sctp_addto_chunk(retval, sizeof(resp), &resp);
+
+ return retval;
+}
+
+/* RE-CONFIG 4.4 OPTIONAL (TSNRESP)
+ * 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 = 16 | Parameter Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Re-configuration Response Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Result |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sender's Next TSN (optional) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Receiver's Next TSN (optional) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct sctp_chunk *sctp_make_strreset_tsnresp(
+ struct sctp_association *asoc,
+ __u32 result, __u32 sn,
+ __u32 sender_tsn, __u32 receiver_tsn)
+{
+ struct sctp_strreset_resptsn tsnresp;
+ __u16 length = sizeof(tsnresp);
+ struct sctp_chunk *retval;
+
+ retval = sctp_make_reconf(asoc, length);
+ if (!retval)
+ return NULL;
+
+ tsnresp.param_hdr.type = SCTP_PARAM_RESET_RESPONSE;
+ tsnresp.param_hdr.length = htons(length);
+
+ tsnresp.response_seq = htonl(sn);
+ tsnresp.result = htonl(result);
+ tsnresp.senders_next_tsn = htonl(sender_tsn);
+ tsnresp.receivers_next_tsn = htonl(receiver_tsn);
+
+ sctp_addto_chunk(retval, sizeof(tsnresp), &tsnresp);
+
+ return retval;
+}
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2 net-next 2/7] sctp: add support for generating stream ssn reset event notification
2017-02-17 4:45 ` [PATCHv2 net-next 1/7] sctp: add support for generating stream reconf resp chunk Xin Long
@ 2017-02-17 4:45 ` Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 3/7] sctp: implement receiver-side procedures for the Outgoing SSN Reset Request Parameter Xin Long
0 siblings, 1 reply; 9+ messages in thread
From: Xin Long @ 2017-02-17 4:45 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
This patch is to add Stream Reset Event described in rfc6525
section 6.1.1.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/ulpevent.h | 4 ++++
include/uapi/linux/sctp.h | 16 ++++++++++++++++
net/sctp/ulpevent.c | 29 +++++++++++++++++++++++++++++
3 files changed, 49 insertions(+)
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
index 2c098cd..324b596 100644
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -128,6 +128,10 @@ struct sctp_ulpevent *sctp_ulpevent_make_authkey(
struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event(
const struct sctp_association *asoc, gfp_t gfp);
+struct sctp_ulpevent *sctp_ulpevent_make_stream_reset_event(
+ const struct sctp_association *asoc, __u16 flags,
+ __u16 stream_num, __u16 *stream_list, gfp_t gfp);
+
void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
struct msghdr *);
void sctp_ulpevent_read_rcvinfo(const struct sctp_ulpevent *event,
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index a91a9cc..d3ae381 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -490,6 +490,18 @@ struct sctp_sender_dry_event {
sctp_assoc_t sender_dry_assoc_id;
};
+#define SCTP_STREAM_RESET_INCOMING_SSN 0x0001
+#define SCTP_STREAM_RESET_OUTGOING_SSN 0x0002
+#define SCTP_STREAM_RESET_DENIED 0x0004
+#define SCTP_STREAM_RESET_FAILED 0x0008
+struct sctp_stream_reset_event {
+ __u16 strreset_type;
+ __u16 strreset_flags;
+ __u32 strreset_length;
+ sctp_assoc_t strreset_assoc_id;
+ __u16 strreset_stream_list[];
+};
+
/*
* Described in Section 7.3
* Ancillary Data and Notification Interest Options
@@ -505,6 +517,7 @@ struct sctp_event_subscribe {
__u8 sctp_adaptation_layer_event;
__u8 sctp_authentication_event;
__u8 sctp_sender_dry_event;
+ __u8 sctp_stream_reset_event;
};
/*
@@ -529,6 +542,7 @@ union sctp_notification {
struct sctp_pdapi_event sn_pdapi_event;
struct sctp_authkey_event sn_authkey_event;
struct sctp_sender_dry_event sn_sender_dry_event;
+ struct sctp_stream_reset_event sn_strreset_event;
};
/* Section 5.3.1
@@ -556,6 +570,8 @@ enum sctp_sn_type {
#define SCTP_AUTHENTICATION_INDICATION SCTP_AUTHENTICATION_EVENT
SCTP_SENDER_DRY_EVENT,
#define SCTP_SENDER_DRY_EVENT SCTP_SENDER_DRY_EVENT
+ SCTP_STREAM_RESET_EVENT,
+#define SCTP_STREAM_RESET_EVENT SCTP_STREAM_RESET_EVENT
};
/* Notification error codes used to fill up the error fields in some
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index bea0005..c8881bc5 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -854,6 +854,35 @@ struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event(
return event;
}
+struct sctp_ulpevent *sctp_ulpevent_make_stream_reset_event(
+ const struct sctp_association *asoc, __u16 flags, __u16 stream_num,
+ __u16 *stream_list, gfp_t gfp)
+{
+ struct sctp_stream_reset_event *sreset;
+ struct sctp_ulpevent *event;
+ struct sk_buff *skb;
+ int length, i;
+
+ length = sizeof(struct sctp_stream_reset_event) + 2 * stream_num;
+ event = sctp_ulpevent_new(length, MSG_NOTIFICATION, gfp);
+ if (!event)
+ return NULL;
+
+ skb = sctp_event2skb(event);
+ sreset = (struct sctp_stream_reset_event *)skb_put(skb, length);
+
+ sreset->strreset_type = SCTP_STREAM_RESET_EVENT;
+ sreset->strreset_flags = flags;
+ sreset->strreset_length = length;
+ sctp_ulpevent_set_owner(event, asoc);
+ sreset->strreset_assoc_id = sctp_assoc2id(asoc);
+
+ for (i = 0; i < stream_num; i++)
+ sreset->strreset_stream_list[i] = ntohs(stream_list[i]);
+
+ return event;
+}
+
/* Return the notification type, assuming this is a notification
* event.
*/
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2 net-next 3/7] sctp: implement receiver-side procedures for the Outgoing SSN Reset Request Parameter
2017-02-17 4:45 ` [PATCHv2 net-next 2/7] sctp: add support for generating stream ssn reset event notification Xin Long
@ 2017-02-17 4:45 ` Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 4/7] sctp: implement receiver-side procedures for the Incoming " Xin Long
0 siblings, 1 reply; 9+ messages in thread
From: Xin Long @ 2017-02-17 4:45 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
This patch is to implement Receiver-Side Procedures for the Outgoing
SSN Reset Request Parameter described in rfc6525 section 5.2.2.
Note that some checks must be after request_seq check, as even those
checks fail, strreset_inseq still has to be increase by 1.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/sm.h | 6 +++
net/sctp/stream.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 119 insertions(+)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 8a85dd7..c0f9bea 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -280,6 +280,12 @@ struct sctp_chunk *sctp_make_strreset_tsnresp(
void sctp_chunk_assign_tsn(struct sctp_chunk *);
void sctp_chunk_assign_ssn(struct sctp_chunk *);
+/* Prototypes for stream-processing functions. */
+struct sctp_chunk *sctp_process_strreset_outreq(
+ struct sctp_association *asoc,
+ union sctp_params param,
+ struct sctp_ulpevent **evp);
+
/* Prototypes for statetable processing. */
int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype,
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index eb02490..531fcc4 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -294,3 +294,116 @@ int sctp_send_add_streams(struct sctp_association *asoc,
out:
return retval;
}
+
+static sctp_paramhdr_t *sctp_chunk_lookup_strreset_param(
+ struct sctp_association *asoc, __u32 resp_seq)
+{
+ struct sctp_chunk *chunk = asoc->strreset_chunk;
+ struct sctp_reconf_chunk *hdr;
+ union sctp_params param;
+
+ if (ntohl(resp_seq) != asoc->strreset_outseq || !chunk)
+ return NULL;
+
+ hdr = (struct sctp_reconf_chunk *)chunk->chunk_hdr;
+ sctp_walk_params(param, hdr, params) {
+ /* sctp_strreset_tsnreq is actually the basic structure
+ * of all stream reconf params, so it's safe to use it
+ * to access request_seq.
+ */
+ struct sctp_strreset_tsnreq *req = param.v;
+
+ if (req->request_seq == resp_seq)
+ return param.v;
+ }
+
+ return NULL;
+}
+
+struct sctp_chunk *sctp_process_strreset_outreq(
+ struct sctp_association *asoc,
+ union sctp_params param,
+ struct sctp_ulpevent **evp)
+{
+ struct sctp_strreset_outreq *outreq = param.v;
+ struct sctp_stream *stream = asoc->stream;
+ __u16 i, nums, flags = 0, *str_p = NULL;
+ __u32 result = SCTP_STRRESET_DENIED;
+ __u32 request_seq;
+
+ request_seq = ntohl(outreq->request_seq);
+
+ if (ntohl(outreq->send_reset_at_tsn) >
+ sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map)) {
+ result = SCTP_STRRESET_IN_PROGRESS;
+ goto out;
+ }
+
+ if (request_seq > asoc->strreset_inseq) {
+ result = SCTP_STRRESET_ERR_BAD_SEQNO;
+ goto out;
+ } else if (request_seq == asoc->strreset_inseq) {
+ asoc->strreset_inseq++;
+ }
+
+ /* Check strreset_enable after inseq inc, as sender cannot tell
+ * the peer doesn't enable strreset after receiving response with
+ * result denied, as well as to keep consistent with bsd.
+ */
+ if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ))
+ goto out;
+
+ if (asoc->strreset_chunk) {
+ sctp_paramhdr_t *param_hdr;
+ struct sctp_transport *t;
+
+ param_hdr = sctp_chunk_lookup_strreset_param(
+ asoc, outreq->response_seq);
+ if (!param_hdr || param_hdr->type !=
+ SCTP_PARAM_RESET_IN_REQUEST) {
+ /* same process with outstanding isn't 0 */
+ result = SCTP_STRRESET_ERR_IN_PROGRESS;
+ goto out;
+ }
+
+ asoc->strreset_outstanding--;
+ asoc->strreset_outseq++;
+
+ if (!asoc->strreset_outstanding) {
+ t = asoc->strreset_chunk->transport;
+ if (del_timer(&t->reconf_timer))
+ sctp_transport_put(t);
+
+ sctp_chunk_put(asoc->strreset_chunk);
+ asoc->strreset_chunk = NULL;
+ }
+
+ flags = SCTP_STREAM_RESET_INCOMING_SSN;
+ }
+
+ nums = (ntohs(param.p->length) - sizeof(*outreq)) / 2;
+ 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;
+ }
+ }
+
+ for (i = 0; i < nums; i++)
+ stream->in[ntohs(str_p[i])].ssn = 0;
+ } else {
+ for (i = 0; i < stream->incnt; i++)
+ stream->in[i].ssn = 0;
+ }
+
+ result = SCTP_STRRESET_PERFORMED;
+
+ *evp = sctp_ulpevent_make_stream_reset_event(asoc,
+ flags | SCTP_STREAM_RESET_OUTGOING_SSN, nums, str_p,
+ GFP_ATOMIC);
+
+out:
+ return sctp_make_strreset_resp(asoc, result, request_seq);
+}
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2 net-next 4/7] sctp: implement receiver-side procedures for the Incoming SSN Reset Request Parameter
2017-02-17 4:45 ` [PATCHv2 net-next 3/7] sctp: implement receiver-side procedures for the Outgoing SSN Reset Request Parameter Xin Long
@ 2017-02-17 4:45 ` Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 5/7] sctp: add a function to verify the sctp reconf chunk Xin Long
0 siblings, 1 reply; 9+ messages in thread
From: Xin Long @ 2017-02-17 4:45 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
This patch is to implement Receiver-Side Procedures for the Incoming
SSN Reset Request Parameter described in rfc6525 section 5.2.3.
It's also to move str_list endian conversion out of sctp_make_strreset_req,
so that sctp_make_strreset_req can be used more conveniently to process
inreq.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/sm.h | 4 +++
net/sctp/sm_make_chunk.c | 8 +-----
net/sctp/stream.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+), 7 deletions(-)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index c0f9bea..f6a828d 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -285,6 +285,10 @@ struct sctp_chunk *sctp_process_strreset_outreq(
struct sctp_association *asoc,
union sctp_params param,
struct sctp_ulpevent **evp);
+struct sctp_chunk *sctp_process_strreset_inreq(
+ struct sctp_association *asoc,
+ union sctp_params param,
+ struct sctp_ulpevent **evp);
/* Prototypes for statetable processing. */
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 9680c58..60d9fdc 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3617,7 +3617,7 @@ struct sctp_chunk *sctp_make_strreset_req(
__u16 stream_len = stream_num * 2;
struct sctp_strreset_inreq inreq;
struct sctp_chunk *retval;
- __u16 outlen, inlen, i;
+ __u16 outlen, inlen;
outlen = (sizeof(outreq) + stream_len) * out;
inlen = (sizeof(inreq) + stream_len) * in;
@@ -3626,9 +3626,6 @@ struct sctp_chunk *sctp_make_strreset_req(
if (!retval)
return NULL;
- for (i = 0; i < stream_num; i++)
- stream_list[i] = htons(stream_list[i]);
-
if (outlen) {
outreq.param_hdr.type = SCTP_PARAM_RESET_OUT_REQUEST;
outreq.param_hdr.length = htons(outlen);
@@ -3653,9 +3650,6 @@ struct sctp_chunk *sctp_make_strreset_req(
sctp_addto_chunk(retval, stream_len, stream_list);
}
- for (i = 0; i < stream_num; i++)
- stream_list[i] = ntohs(stream_list[i]);
-
return retval;
}
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index 531fcc4..1c6cc04 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -135,7 +135,14 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
if (str_list[i] >= stream->incnt)
goto out;
+ for (i = 0; i < str_nums; i++)
+ str_list[i] = htons(str_list[i]);
+
chunk = sctp_make_strreset_req(asoc, str_nums, str_list, out, in);
+
+ for (i = 0; i < str_nums; i++)
+ str_list[i] = ntohs(str_list[i]);
+
if (!chunk) {
retval = -ENOMEM;
goto out;
@@ -407,3 +414,66 @@ struct sctp_chunk *sctp_process_strreset_outreq(
out:
return sctp_make_strreset_resp(asoc, result, request_seq);
}
+
+struct sctp_chunk *sctp_process_strreset_inreq(
+ struct sctp_association *asoc,
+ union sctp_params param,
+ struct sctp_ulpevent **evp)
+{
+ struct sctp_strreset_inreq *inreq = param.v;
+ struct sctp_stream *stream = asoc->stream;
+ __u32 result = SCTP_STRRESET_DENIED;
+ struct sctp_chunk *chunk = NULL;
+ __u16 i, nums, *str_p;
+ __u32 request_seq;
+
+ request_seq = ntohl(inreq->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_RESET_STREAM_REQ))
+ goto out;
+
+ if (asoc->strreset_outstanding) {
+ result = SCTP_STRRESET_ERR_IN_PROGRESS;
+ goto out;
+ }
+
+ nums = (ntohs(param.p->length) - sizeof(*inreq)) / 2;
+ str_p = inreq->list_of_streams;
+ for (i = 0; i < nums; i++) {
+ if (ntohs(str_p[i]) >= stream->outcnt) {
+ result = SCTP_STRRESET_ERR_WRONG_SSN;
+ goto out;
+ }
+ }
+
+ chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
+ if (!chunk)
+ goto out;
+
+ if (nums)
+ for (i = 0; i < nums; i++)
+ stream->out[ntohs(str_p[i])].state =
+ SCTP_STREAM_CLOSED;
+ else
+ for (i = 0; i < stream->outcnt; i++)
+ stream->out[i].state = SCTP_STREAM_CLOSED;
+
+ asoc->strreset_chunk = chunk;
+ asoc->strreset_outstanding = 1;
+ sctp_chunk_hold(asoc->strreset_chunk);
+
+ *evp = sctp_ulpevent_make_stream_reset_event(asoc,
+ SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC);
+
+out:
+ if (!chunk)
+ chunk = sctp_make_strreset_resp(asoc, result, request_seq);
+
+ return chunk;
+}
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2 net-next 5/7] sctp: add a function to verify the sctp reconf chunk
2017-02-17 4:45 ` [PATCHv2 net-next 4/7] sctp: implement receiver-side procedures for the Incoming " Xin Long
@ 2017-02-17 4:45 ` Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 6/7] sctp: add reconf chunk process Xin Long
0 siblings, 1 reply; 9+ messages in thread
From: Xin Long @ 2017-02-17 4:45 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
This patch is to add a function sctp_verify_reconf to do some length
check and multi-params check for sctp stream reconf according to rfc6525
section 3.1.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/sm.h | 3 +++
net/sctp/sm_make_chunk.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index f6a828d..ca9fbfb 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -277,6 +277,9 @@ struct sctp_chunk *sctp_make_strreset_tsnresp(
struct sctp_association *asoc,
__u32 result, __u32 sn,
__u32 sender_tsn, __u32 receiver_tsn);
+bool sctp_verify_reconf(const struct sctp_association *asoc,
+ struct sctp_chunk *chunk,
+ struct sctp_paramhdr **errp);
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 60d9fdc..969a30c 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3801,3 +3801,62 @@ struct sctp_chunk *sctp_make_strreset_tsnresp(
return retval;
}
+
+bool sctp_verify_reconf(const struct sctp_association *asoc,
+ struct sctp_chunk *chunk,
+ struct sctp_paramhdr **errp)
+{
+ struct sctp_reconf_chunk *hdr;
+ union sctp_params param;
+ __u16 last = 0, cnt = 0;
+
+ hdr = (struct sctp_reconf_chunk *)chunk->chunk_hdr;
+ sctp_walk_params(param, hdr, params) {
+ __u16 length = ntohs(param.p->length);
+
+ *errp = param.p;
+ if (cnt++ > 2)
+ return false;
+ switch (param.p->type) {
+ case SCTP_PARAM_RESET_OUT_REQUEST:
+ if (length < sizeof(struct sctp_strreset_outreq) ||
+ (last && last != SCTP_PARAM_RESET_RESPONSE &&
+ last != SCTP_PARAM_RESET_IN_REQUEST))
+ return false;
+ break;
+ case SCTP_PARAM_RESET_IN_REQUEST:
+ if (length < sizeof(struct sctp_strreset_inreq) ||
+ (last && last != SCTP_PARAM_RESET_OUT_REQUEST))
+ return false;
+ break;
+ case SCTP_PARAM_RESET_RESPONSE:
+ if ((length != sizeof(struct sctp_strreset_resp) &&
+ length != sizeof(struct sctp_strreset_resptsn)) ||
+ (last && last != SCTP_PARAM_RESET_RESPONSE &&
+ last != SCTP_PARAM_RESET_OUT_REQUEST))
+ return false;
+ break;
+ case SCTP_PARAM_RESET_TSN_REQUEST:
+ if (length !=
+ sizeof(struct sctp_strreset_tsnreq) || last)
+ return false;
+ break;
+ case SCTP_PARAM_RESET_ADD_IN_STREAMS:
+ if (length != sizeof(struct sctp_strreset_addstrm) ||
+ (last && last != SCTP_PARAM_RESET_ADD_OUT_STREAMS))
+ return false;
+ break;
+ case SCTP_PARAM_RESET_ADD_OUT_STREAMS:
+ if (length != sizeof(struct sctp_strreset_addstrm) ||
+ (last && last != SCTP_PARAM_RESET_ADD_IN_STREAMS))
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ last = param.p->type;
+ }
+
+ return true;
+}
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2 net-next 6/7] sctp: add reconf chunk process
2017-02-17 4:45 ` [PATCHv2 net-next 5/7] sctp: add a function to verify the sctp reconf chunk Xin Long
@ 2017-02-17 4:45 ` Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 7/7] sctp: add reconf chunk event Xin Long
0 siblings, 1 reply; 9+ messages in thread
From: Xin Long @ 2017-02-17 4:45 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
This patch is to add a function to process the incoming reconf chunk,
in which it verifies the chunk, and traverses the param and process
it with the right function one by one.
sctp_sf_do_reconf would be the process function of reconf chunk event.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/sm.h | 1 +
net/sctp/sm_statefuns.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index ca9fbfb..b6f682e 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -135,6 +135,7 @@ sctp_state_fn_t sctp_sf_do_8_5_1_E_sa;
sctp_state_fn_t sctp_sf_cookie_echoed_err;
sctp_state_fn_t sctp_sf_do_asconf;
sctp_state_fn_t sctp_sf_do_asconf_ack;
+sctp_state_fn_t sctp_sf_do_reconf;
sctp_state_fn_t sctp_sf_do_9_2_reshutack;
sctp_state_fn_t sctp_sf_eat_fwd_tsn;
sctp_state_fn_t sctp_sf_eat_fwd_tsn_fast;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index d8798dd..e03bb1a 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3834,6 +3834,60 @@ sctp_disposition_t sctp_sf_do_asconf_ack(struct net *net,
return SCTP_DISPOSITION_DISCARD;
}
+/* RE-CONFIG Section 5.2 Upon reception of an RECONF Chunk. */
+sctp_disposition_t sctp_sf_do_reconf(struct net *net,
+ const struct sctp_endpoint *ep,
+ const struct sctp_association *asoc,
+ const sctp_subtype_t type, void *arg,
+ sctp_cmd_seq_t *commands)
+{
+ struct sctp_paramhdr *err_param = NULL;
+ struct sctp_chunk *chunk = arg;
+ struct sctp_reconf_chunk *hdr;
+ union sctp_params param;
+
+ if (!sctp_vtag_verify(chunk, asoc)) {
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
+ SCTP_NULL());
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+ }
+
+ /* Make sure that the RECONF chunk has a valid length. */
+ if (!sctp_chunk_length_valid(chunk, sizeof(*hdr)))
+ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
+ commands);
+
+ if (!sctp_verify_reconf(asoc, chunk, &err_param))
+ return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
+ (void *)err_param, commands);
+
+ hdr = (struct sctp_reconf_chunk *)chunk->chunk_hdr;
+ sctp_walk_params(param, hdr, params) {
+ struct sctp_chunk *reply = NULL;
+ struct sctp_ulpevent *ev = NULL;
+
+ if (param.p->type == SCTP_PARAM_RESET_OUT_REQUEST)
+ reply = sctp_process_strreset_outreq(
+ (struct sctp_association *)asoc, param, &ev);
+ else if (param.p->type == SCTP_PARAM_RESET_IN_REQUEST)
+ reply = sctp_process_strreset_inreq(
+ (struct sctp_association *)asoc, param, &ev);
+ /* More handles for other types will be added here, by now it
+ * just ignores other types.
+ */
+
+ if (ev)
+ sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
+ SCTP_ULPEVENT(ev));
+
+ if (reply)
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
+ SCTP_CHUNK(reply));
+ }
+
+ return SCTP_DISPOSITION_CONSUME;
+}
+
/*
* PR-SCTP Section 3.6 Receiver Side Implementation of PR-SCTP
*
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCHv2 net-next 7/7] sctp: add reconf chunk event
2017-02-17 4:45 ` [PATCHv2 net-next 6/7] sctp: add reconf chunk process Xin Long
@ 2017-02-17 4:45 ` Xin Long
0 siblings, 0 replies; 9+ messages in thread
From: Xin Long @ 2017-02-17 4:45 UTC (permalink / raw)
To: network dev, linux-sctp
Cc: Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, davem
This patch is to add reconf chunk event based on the sctp event
frame in rx path, it will call sctp_sf_do_reconf to process the
reconf chunk.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/constants.h | 3 +++
net/sctp/sm_statetable.c | 30 ++++++++++++++++++++++++++++++
2 files changed, 33 insertions(+)
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index 3567c97..b07a745 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -60,11 +60,14 @@ enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM };
#define SCTP_NUM_PRSCTP_CHUNK_TYPES 1
+#define SCTP_NUM_RECONF_CHUNK_TYPES 1
+
#define SCTP_NUM_AUTH_CHUNK_TYPES 1
#define SCTP_NUM_CHUNK_TYPES (SCTP_NUM_BASE_CHUNK_TYPES + \
SCTP_NUM_ADDIP_CHUNK_TYPES +\
SCTP_NUM_PRSCTP_CHUNK_TYPES +\
+ SCTP_NUM_RECONF_CHUNK_TYPES +\
SCTP_NUM_AUTH_CHUNK_TYPES)
/* These are the different flavours of event. */
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index b5438b4..419b18e 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -482,6 +482,32 @@ static const sctp_sm_table_entry_t prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUN
TYPE_SCTP_FWD_TSN,
}; /*state_fn_t prsctp_chunk_event_table[][] */
+#define TYPE_SCTP_RECONF { \
+ /* SCTP_STATE_CLOSED */ \
+ TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
+ /* SCTP_STATE_COOKIE_WAIT */ \
+ TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
+ /* SCTP_STATE_COOKIE_ECHOED */ \
+ TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
+ /* SCTP_STATE_ESTABLISHED */ \
+ TYPE_SCTP_FUNC(sctp_sf_do_reconf), \
+ /* SCTP_STATE_SHUTDOWN_PENDING */ \
+ TYPE_SCTP_FUNC(sctp_sf_do_reconf), \
+ /* SCTP_STATE_SHUTDOWN_SENT */ \
+ TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
+ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
+ TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
+ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
+ TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
+} /* TYPE_SCTP_RECONF */
+
+/* The primary index for this table is the chunk type.
+ * The secondary index for this table is the state.
+ */
+static const sctp_sm_table_entry_t reconf_chunk_event_table[SCTP_NUM_RECONF_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
+ TYPE_SCTP_RECONF,
+}; /*state_fn_t reconf_chunk_event_table[][] */
+
#define TYPE_SCTP_AUTH { \
/* SCTP_STATE_CLOSED */ \
TYPE_SCTP_FUNC(sctp_sf_ootb), \
@@ -964,6 +990,10 @@ static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(struct net *net,
return &addip_chunk_event_table[1][state];
}
+ if (net->sctp.reconf_enable)
+ if (cid == SCTP_CID_RECONF)
+ return &reconf_chunk_event_table[0][state];
+
if (net->sctp.auth_enable) {
if (cid == SCTP_CID_AUTH)
return &auth_chunk_event_table[0][state];
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCHv2 net-next 0/7] sctp: add receiver-side procedures for stream reconf ssn reset request chunk
2017-02-17 4:45 [PATCHv2 net-next 0/7] sctp: add receiver-side procedures for stream reconf ssn reset request chunk Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 1/7] sctp: add support for generating stream reconf resp chunk Xin Long
@ 2017-02-19 23:18 ` David Miller
1 sibling, 0 replies; 9+ messages in thread
From: David Miller @ 2017-02-19 23:18 UTC (permalink / raw)
To: lucien.xin; +Cc: netdev, linux-sctp, marcelo.leitner, nhorman, vyasevich
From: Xin Long <lucien.xin@gmail.com>
Date: Fri, 17 Feb 2017 12:45:36 +0800
> Patch 3/7 and 4/7 are to implement receiver-side procedures for the
> Outgoing and Incoming SSN Reset Request Parameter described in rfc6525
> section 5.2.2 and 5.2.3
>
> Patch 1/7 and 2/7 are ahead of them to define some apis.
>
> Patch 5/7-7/7 are to add the process of reconf chunk event in rx path.
>
> Note that with this patchset, asoc->reconf_enable has no chance yet to
> be set, until the patch "sctp: add get and set sockopt for reconf_enable"
> is applied in the future. As we can not just enable it when sctp is not
> capable of processing reconf chunk yet.
...
Series applied, thanks.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2017-02-19 23:18 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-17 4:45 [PATCHv2 net-next 0/7] sctp: add receiver-side procedures for stream reconf ssn reset request chunk Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 1/7] sctp: add support for generating stream reconf resp chunk Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 2/7] sctp: add support for generating stream ssn reset event notification Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 3/7] sctp: implement receiver-side procedures for the Outgoing SSN Reset Request Parameter Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 4/7] sctp: implement receiver-side procedures for the Incoming " Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 5/7] sctp: add a function to verify the sctp reconf chunk Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 6/7] sctp: add reconf chunk process Xin Long
2017-02-17 4:45 ` [PATCHv2 net-next 7/7] sctp: add reconf chunk event Xin Long
2017-02-19 23:18 ` [PATCHv2 net-next 0/7] sctp: add receiver-side procedures for stream reconf ssn reset request chunk David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).