Skip to contentSkip to conversation

sctp: prepare asoc stream for stream reconf

PATCH Superseded Xin Long 2 participants 6 messages Jan 3, 2017 – Jan 6, 2017

Subsystems (3)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Xin Long

author maintainer
#0 lore raw

v2 cover sctp: prepare asoc stream for stream reconf

sctp stream reconf, described in RFC 6525, needs a structure to save per stream information in assoc, like stream state.

In the future, sctp stream scheduler also needs it to save some stream scheduler params and queues.

This patchset is to prepare the stream array in assoc for stream reconf.

v1->v2:
put these patches into a smaller group.

Xin Long (3):
sctp: add stream arrays in asoc
sctp: replace ssnmap with asoc stream arrays
sctp: remove asoc ssnmap and ssnmap.c

 include/net/sctp/sctp.h    |   1 -
 include/net/sctp/structs.h |  70 +++++++++----------------
 net/sctp/Makefile          |   3 +-
 net/sctp/associola.c       |  23 ++++++---
 net/sctp/objcnt.c          |   2 -
 net/sctp/sm_make_chunk.c   |  24 ++++++---
 net/sctp/sm_statefuns.c    |   3 +-
 net/sctp/ssnmap.c          | 125 ---------------------------------------------
 net/sctp/ulpqueue.c        |  33 ++++--------
 9 files changed, 69 insertions(+), 215 deletions(-)
 delete mode 100644 net/sctp/ssnmap.c
Signature · 1 line
2.1.0
author maintainer
#1 lore raw

PATCH v2 1/3 sctp: add stream arrays in asoc

This patch is to add streamout and streamin arrays in asoc, initialize them in sctp_process_init and free them in sctp_association_free.

Stream arrays are used to replace ssnmap to save more stream things in the next patch.

---
 include/net/sctp/structs.h | 18 ++++++++++++++++++
 net/sctp/associola.c       | 19 +++++++++++++++++++
 net/sctp/sm_make_chunk.c   | 17 ++++++++++++++++-
 3 files changed, 53 insertions(+), 1 deletion(-)
include/net/sctp/structs.h +18 -0
index 87d56cc..549f17d 100644
@@ -1331,6 +1331,18 @@ struct sctp_inithdr_host {
 	__u32 initial_tsn;
 };
 
+struct sctp_stream_out {
+	__u16	ssn;
+	__u8	state;
+};
+
+struct sctp_stream_in {
+	__u16	ssn;
+};
+
+#define SCTP_STREAM_CLOSED		0x00
+#define SCTP_STREAM_OPEN		0x01
+
 /* SCTP_GET_ASSOC_STATS counters */
 struct sctp_priv_assoc_stats {
 	/* Maximum observed rto in the association during subsequent
@@ -1879,6 +1891,12 @@ struct sctp_association {
 	     temp:1,		/* Is it a temporary association? */
 	     prsctp_enable:1;
 
+	/* stream arrays */
+	struct sctp_stream_out *streamout;
+	struct sctp_stream_in *streamin;
+	__u16 streamoutcnt;
+	__u16 streamincnt;
+
 	struct sctp_priv_assoc_stats stats;
 
 	int sent_cnt_removable;
net/sctp/associola.c +19 -0
index d3cc30c..290ec4d 100644
@@ -361,6 +361,10 @@ void sctp_association_free(struct sctp_association *asoc)
 	/* Free ssnmap storage. */
 	sctp_ssnmap_free(asoc->ssnmap);
 
+	/* Free stream information. */
+	kfree(asoc->streamout);
+	kfree(asoc->streamin);
+
 	/* Clean up the bound address list. */
 	sctp_bind_addr_free(&asoc->base.bind_addr);
 
@@ -1130,6 +1134,8 @@ void sctp_assoc_update(struct sctp_association *asoc,
 	 * has been discarded and needs retransmission.
 	 */
 	if (asoc->state >= SCTP_STATE_ESTABLISHED) {
+		int i;
+
 		asoc->next_tsn = new->next_tsn;
 		asoc->ctsn_ack_point = new->ctsn_ack_point;
 		asoc->adv_peer_ack_point = new->adv_peer_ack_point;
@@ -1139,6 +1145,12 @@ void sctp_assoc_update(struct sctp_association *asoc,
 		 */
 		sctp_ssnmap_clear(asoc->ssnmap);
 
+		for (i = 0; i < asoc->streamoutcnt; i++)
+			asoc->streamout[i].ssn = 0;
+
+		for (i = 0; i < asoc->streamincnt; i++)
+			asoc->streamin[i].ssn = 0;
+
 		/* Flush the ULP reassembly and ordered queue.
 		 * Any data there will now be stale and will
 		 * cause problems.
@@ -1168,6 +1180,13 @@ void sctp_assoc_update(struct sctp_association *asoc,
 			new->ssnmap = NULL;
 		}
 
+		if (!asoc->streamin && !asoc->streamout) {
+			asoc->streamout = new->streamout;
+			asoc->streamin = new->streamin;
+			new->streamout = NULL;
+			new->streamin = NULL;
+		}
+
 		if (!asoc->assoc_id) {
 			/* get a new association id since we don't have one
 			 * yet.
net/sctp/sm_make_chunk.c +16 -1
index 9e9690b..eeadeef 100644
@@ -2442,13 +2442,28 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
 	 * association.
 	 */
 	if (!asoc->temp) {
-		int error;
+		int error, i;
+
+		asoc->streamoutcnt = asoc->c.sinit_num_ostreams;
+		asoc->streamincnt = asoc->c.sinit_max_instreams;
 
 		asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
 					       asoc->c.sinit_num_ostreams, gfp);
 		if (!asoc->ssnmap)
 			goto clean_up;
 
+		asoc->streamout = kcalloc(asoc->streamoutcnt,
+					  sizeof(*asoc->streamout), gfp);
+		if (!asoc->streamout)
+			goto clean_up;
+		for (i = 0; i < asoc->streamoutcnt; i++)
+			asoc->streamout[i].state = SCTP_STREAM_OPEN;
+
+		asoc->streamin = kcalloc(asoc->streamincnt,
+					 sizeof(*asoc->streamin), gfp);
+		if (!asoc->streamin)
+			goto clean_up;
+
 		error = sctp_assoc_set_id(asoc, gfp);
 		if (error)
 			goto clean_up;
Signature · 1 line
2.1.0
author maintainer
#2 lore raw

PATCH v2 2/3 sctp: replace ssnmap with asoc stream arrays

Stream arrays are used to save per stream information, which includes ssn for each stream already.

This patch is to replace ssnmap with asoc stream arrays.

---
 include/net/sctp/structs.h | 19 ++++++-------------
 net/sctp/associola.c       | 10 ----------
 net/sctp/sm_make_chunk.c   | 11 ++---------
 net/sctp/sm_statefuns.c    |  3 +--
 net/sctp/ulpqueue.c        | 33 +++++++++++----------------------
 5 files changed, 20 insertions(+), 56 deletions(-)
include/net/sctp/structs.h +6 -13
index 549f17d..f81c321 100644
@@ -407,23 +407,16 @@ void sctp_ssnmap_free(struct sctp_ssnmap *map);
 void sctp_ssnmap_clear(struct sctp_ssnmap *map);
 
 /* What is the current SSN number for this stream? */
-static inline __u16 sctp_ssn_peek(struct sctp_stream *stream, __u16 id)
-{
-	return stream->ssn[id];
-}
+#define sctp_ssn_peek(asoc, type, sid) \
+	((asoc)->stream##type[sid].ssn)
 
 /* Return the next SSN number for this stream.	*/
-static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id)
-{
-	return stream->ssn[id]++;
-}
+#define sctp_ssn_next(asoc, type, sid) \
+	((asoc)->stream##type[sid].ssn++)
 
 /* Skip over this ssn and all below. */
-static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id, 
-				 __u16 ssn)
-{
-	stream->ssn[id] = ssn+1;
-}
+#define sctp_ssn_skip(asoc, type, sid, ssn) \
+	((asoc)->stream##type[sid].ssn = ssn + 1)
               
 /*
  * Pointers to address related SCTP functions.
net/sctp/associola.c +0 -10
index 290ec4d..ea03270 100644
@@ -358,9 +358,6 @@ void sctp_association_free(struct sctp_association *asoc)
 
 	sctp_tsnmap_free(&asoc->peer.tsn_map);
 
-	/* Free ssnmap storage. */
-	sctp_ssnmap_free(asoc->ssnmap);
-
 	/* Free stream information. */
 	kfree(asoc->streamout);
 	kfree(asoc->streamin);
@@ -1143,8 +1140,6 @@ void sctp_assoc_update(struct sctp_association *asoc,
 		/* Reinitialize SSN for both local streams
 		 * and peer's streams.
 		 */
-		sctp_ssnmap_clear(asoc->ssnmap);
-
 		for (i = 0; i < asoc->streamoutcnt; i++)
 			asoc->streamout[i].ssn = 0;
 
@@ -1174,11 +1169,6 @@ void sctp_assoc_update(struct sctp_association *asoc,
 
 		asoc->ctsn_ack_point = asoc->next_tsn - 1;
 		asoc->adv_peer_ack_point = asoc->ctsn_ack_point;
-		if (!asoc->ssnmap) {
-			/* Move the ssnmap. */
-			asoc->ssnmap = new->ssnmap;
-			new->ssnmap = NULL;
-		}
 
 		if (!asoc->streamin && !asoc->streamout) {
 			asoc->streamout = new->streamout;
net/sctp/sm_make_chunk.c +2 -9
index eeadeef..78cbd1b 100644
@@ -1527,7 +1527,6 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
 {
 	struct sctp_datamsg *msg;
 	struct sctp_chunk *lchunk;
-	struct sctp_stream *stream;
 	__u16 ssn;
 	__u16 sid;
 
@@ -1536,7 +1535,6 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
 
 	/* All fragments will be on the same stream */
 	sid = ntohs(chunk->subh.data_hdr->stream);
-	stream = &chunk->asoc->ssnmap->out;
 
 	/* Now assign the sequence number to the entire message.
 	 * All fragments must have the same stream sequence number.
@@ -1547,9 +1545,9 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
 			ssn = 0;
 		} else {
 			if (lchunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG)
-				ssn = sctp_ssn_next(stream, sid);
+				ssn = sctp_ssn_next(chunk->asoc, out, sid);
 			else
-				ssn = sctp_ssn_peek(stream, sid);
+				ssn = sctp_ssn_peek(chunk->asoc, out, sid);
 		}
 
 		lchunk->subh.data_hdr->ssn = htons(ssn);
@@ -2447,11 +2445,6 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
 		asoc->streamoutcnt = asoc->c.sinit_num_ostreams;
 		asoc->streamincnt = asoc->c.sinit_max_instreams;
 
-		asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
-					       asoc->c.sinit_num_ostreams, gfp);
-		if (!asoc->ssnmap)
-			goto clean_up;
-
 		asoc->streamout = kcalloc(asoc->streamoutcnt,
 					  sizeof(*asoc->streamout), gfp);
 		if (!asoc->streamout)
net/sctp/sm_statefuns.c +1 -2
index 3382ef2..8a130a7 100644
@@ -6274,9 +6274,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
 	 * and is invalid.
 	 */
 	ssn = ntohs(data_hdr->ssn);
-	if (ordered && SSN_lt(ssn, sctp_ssn_peek(&asoc->ssnmap->in, sid))) {
+	if (ordered && SSN_lt(ssn, sctp_ssn_peek(asoc, in, sid)))
 		return SCTP_IERROR_PROTO_VIOLATION;
-	}
 
 	/* Send the data up to the user.  Note:  Schedule  the
 	 * SCTP_CMD_CHUNK_ULP cmd before the SCTP_CMD_GEN_SACK, as the SACK
net/sctp/ulpqueue.c +11 -22
index 84d0fda..0d8bf26 100644
@@ -760,11 +760,9 @@ static void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq,
 	struct sk_buff_head *event_list;
 	struct sk_buff *pos, *tmp;
 	struct sctp_ulpevent *cevent;
-	struct sctp_stream *in;
 	__u16 sid, csid, cssn;
 
 	sid = event->stream;
-	in  = &ulpq->asoc->ssnmap->in;
 
 	event_list = (struct sk_buff_head *) sctp_event2skb(event)->prev;
 
@@ -782,11 +780,11 @@ static void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq,
 		if (csid < sid)
 			continue;
 
-		if (cssn != sctp_ssn_peek(in, sid))
+		if (cssn != sctp_ssn_peek(ulpq->asoc, in, sid))
 			break;
 
-		/* Found it, so mark in the ssnmap. */
-		sctp_ssn_next(in, sid);
+		/* Found it, so mark in stream array. */
+		sctp_ssn_next(ulpq->asoc, in, sid);
 
 		__skb_unlink(pos, &ulpq->lobby);
 
@@ -849,7 +847,6 @@ static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
 					     struct sctp_ulpevent *event)
 {
 	__u16 sid, ssn;
-	struct sctp_stream *in;
 
 	/* Check if this message needs ordering.  */
 	if (SCTP_DATA_UNORDERED & event->msg_flags)
@@ -858,10 +855,9 @@ static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
 	/* Note: The stream ID must be verified before this routine.  */
 	sid = event->stream;
 	ssn = event->ssn;
-	in  = &ulpq->asoc->ssnmap->in;
 
 	/* Is this the expected SSN for this stream ID?  */
-	if (ssn != sctp_ssn_peek(in, sid)) {
+	if (ssn != sctp_ssn_peek(ulpq->asoc, in, sid)) {
 		/* We've received something out of order, so find where it
 		 * needs to be placed.  We order by stream and then by SSN.
 		 */
@@ -870,7 +866,7 @@ static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
 	}
 
 	/* Mark that the next chunk has been found.  */
-	sctp_ssn_next(in, sid);
+	sctp_ssn_next(ulpq->asoc, in, sid);
 
 	/* Go find any other chunks that were waiting for
 	 * ordering.
@@ -888,13 +884,10 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
 	struct sk_buff *pos, *tmp;
 	struct sctp_ulpevent *cevent;
 	struct sctp_ulpevent *event;
-	struct sctp_stream *in;
 	struct sk_buff_head temp;
 	struct sk_buff_head *lobby = &ulpq->lobby;
 	__u16 csid, cssn;
 
-	in  = &ulpq->asoc->ssnmap->in;
-
 	/* We are holding the chunks by stream, by SSN.  */
 	skb_queue_head_init(&temp);
 	event = NULL;
@@ -912,7 +905,7 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
 			continue;
 
 		/* see if this ssn has been marked by skipping */
-		if (!SSN_lt(cssn, sctp_ssn_peek(in, csid)))
+		if (!SSN_lt(cssn, sctp_ssn_peek(ulpq->asoc, in, csid)))
 			break;
 
 		__skb_unlink(pos, lobby);
@@ -932,8 +925,9 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
 		csid = cevent->stream;
 		cssn = cevent->ssn;
 
-		if (csid = sid && cssn = sctp_ssn_peek(in, csid)) {
-			sctp_ssn_next(in, csid);
+		if (csid = sid &&
+		    cssn = sctp_ssn_peek(ulpq->asoc, in, csid)) {
+			sctp_ssn_next(ulpq->asoc, in, csid);
 			__skb_unlink(pos, lobby);
 			__skb_queue_tail(&temp, pos);
 			event = sctp_skb2event(pos);
@@ -955,17 +949,12 @@ static void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
  */
 void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn)
 {
-	struct sctp_stream *in;
-
-	/* Note: The stream ID must be verified before this routine.  */
-	in  = &ulpq->asoc->ssnmap->in;
-
 	/* Is this an old SSN?  If so ignore. */
-	if (SSN_lt(ssn, sctp_ssn_peek(in, sid)))
+	if (SSN_lt(ssn, sctp_ssn_peek(ulpq->asoc, in, sid)))
 		return;
 
 	/* Mark that we are no longer expecting this SSN or lower. */
-	sctp_ssn_skip(in, sid, ssn);
+	sctp_ssn_skip(ulpq->asoc, in, sid, ssn);
 
 	/* Go find any other chunks that were waiting for
 	 * ordering and deliver them if needed.
Signature · 1 line
2.1.0
author maintainer
#3 lore raw

PATCH v2 3/3 sctp: remove asoc ssnmap and ssnmap.c

Since asoc stream arrays has replaced ssnmap, ssnmap is not used any more, this patch is to remove asoc ssnmap and ssnmap.c.

---
 include/net/sctp/sctp.h    |   1 -
 include/net/sctp/structs.h |  33 ------------
 net/sctp/Makefile          |   3 +-
 net/sctp/objcnt.c          |   2 -
 net/sctp/ssnmap.c          | 125 ---------------------------------------------
 5 files changed, 1 insertion(+), 163 deletions(-)
 delete mode 100644 net/sctp/ssnmap.c
include/net/sctp/sctp.h +0 -1
index d8833a8..598d938 100644
@@ -283,7 +283,6 @@ extern atomic_t sctp_dbg_objcnt_chunk;
 extern atomic_t sctp_dbg_objcnt_bind_addr;
 extern atomic_t sctp_dbg_objcnt_bind_bucket;
 extern atomic_t sctp_dbg_objcnt_addr;
-extern atomic_t sctp_dbg_objcnt_ssnmap;
 extern atomic_t sctp_dbg_objcnt_datamsg;
 extern atomic_t sctp_dbg_objcnt_keys;
 
include/net/sctp/structs.h +0 -33
index f81c321..9075d61 100644
@@ -82,7 +82,6 @@ struct sctp_outq;
 struct sctp_bind_addr;
 struct sctp_ulpq;
 struct sctp_ep_common;
-struct sctp_ssnmap;
 struct crypto_shash;
 
 
@@ -377,35 +376,6 @@ typedef struct sctp_sender_hb_info {
 	__u64 hb_nonce;
 } __packed sctp_sender_hb_info_t;
 
-/*
- *  RFC 2960 1.3.2 Sequenced Delivery within Streams
- *
- *  The term "stream" is used in SCTP to refer to a sequence of user
- *  messages that are to be delivered to the upper-layer protocol in
- *  order with respect to other messages within the same stream.  This is
- *  in contrast to its usage in TCP, where it refers to a sequence of
- *  bytes (in this document a byte is assumed to be eight bits).
- *  ...
- *
- *  This is the structure we use to track both our outbound and inbound
- *  SSN, or Stream Sequence Numbers.
- */
-
-struct sctp_stream {
-	__u16 *ssn;
-	unsigned int len;
-};
-
-struct sctp_ssnmap {
-	struct sctp_stream in;
-	struct sctp_stream out;
-};
-
-struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
-				    gfp_t gfp);
-void sctp_ssnmap_free(struct sctp_ssnmap *map);
-void sctp_ssnmap_clear(struct sctp_ssnmap *map);
-
 /* What is the current SSN number for this stream? */
 #define sctp_ssn_peek(asoc, type, sid) \
 	((asoc)->stream##type[sid].ssn)
@@ -1751,9 +1721,6 @@ struct sctp_association {
 	/* Default receive parameters */
 	__u32 default_rcv_context;
 
-	/* This tracks outbound ssn for a given stream.	 */
-	struct sctp_ssnmap *ssnmap;
-
 	/* All outbound chunks go through this structure.  */
 	struct sctp_outq outqueue;
 
net/sctp/Makefile +1 -2
index 6c4f749..48bfc74 100644
@@ -11,8 +11,7 @@ sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \
 	  transport.o chunk.o sm_make_chunk.o ulpevent.o \
 	  inqueue.o outqueue.o ulpqueue.o \
 	  tsnmap.o bind_addr.o socket.o primitive.o \
-	  output.o input.o debug.o ssnmap.o auth.o \
-	  offload.o
+	  output.o input.o debug.o auth.o offload.o
 
 sctp_probe-y := probe.o
 
net/sctp/objcnt.c +0 -2
index 40e7fac..105ac33 100644
@@ -51,7 +51,6 @@ SCTP_DBG_OBJCNT(bind_addr);
 SCTP_DBG_OBJCNT(bind_bucket);
 SCTP_DBG_OBJCNT(chunk);
 SCTP_DBG_OBJCNT(addr);
-SCTP_DBG_OBJCNT(ssnmap);
 SCTP_DBG_OBJCNT(datamsg);
 SCTP_DBG_OBJCNT(keys);
 
@@ -67,7 +66,6 @@ static sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
 	SCTP_DBG_OBJCNT_ENTRY(bind_addr),
 	SCTP_DBG_OBJCNT_ENTRY(bind_bucket),
 	SCTP_DBG_OBJCNT_ENTRY(addr),
-	SCTP_DBG_OBJCNT_ENTRY(ssnmap),
 	SCTP_DBG_OBJCNT_ENTRY(datamsg),
 	SCTP_DBG_OBJCNT_ENTRY(keys),
 };
net/sctp/ssnmap.c deleted +0 -125

125 lines not on this page · raw message

Signature · 1 line
2.1.0
#4 lore raw

Re: [PATCHv2 net-next 1/3] sctp: add stream arrays in asoc

In reply to Xin Long
Quoted 121 lines · Xin Long

This patch is to add streamout and streamin arrays in asoc, initialize them in sctp_process_init and free them in sctp_association_free.

Stream arrays are used to replace ssnmap to save more stream things in the next patch.

---
 include/net/sctp/structs.h | 18 ++++++++++++++++++
 net/sctp/associola.c       | 19 +++++++++++++++++++
 net/sctp/sm_make_chunk.c   | 17 ++++++++++++++++-
 3 files changed, 53 insertions(+), 1 deletion(-)
include/net/sctp/structs.h +18 -0
index 87d56cc..549f17d 100644
@@ -1331,6 +1331,18 @@ struct sctp_inithdr_host {
 	__u32 initial_tsn;
 };
 
+struct sctp_stream_out {
+	__u16	ssn;
+	__u8	state;
+};
+
+struct sctp_stream_in {
+	__u16	ssn;
+};
+
+#define SCTP_STREAM_CLOSED		0x00
+#define SCTP_STREAM_OPEN		0x01
+
 /* SCTP_GET_ASSOC_STATS counters */
 struct sctp_priv_assoc_stats {
 	/* Maximum observed rto in the association during subsequent
@@ -1879,6 +1891,12 @@ struct sctp_association {
 	     temp:1,		/* Is it a temporary association? */
 	     prsctp_enable:1;
 
+	/* stream arrays */
+	struct sctp_stream_out *streamout;
+	struct sctp_stream_in *streamin;
+	__u16 streamoutcnt;
+	__u16 streamincnt;
+
 	struct sctp_priv_assoc_stats stats;
 
 	int sent_cnt_removable;
net/sctp/associola.c +19 -0
index d3cc30c..290ec4d 100644
@@ -361,6 +361,10 @@ void sctp_association_free(struct sctp_association *asoc)
 	/* Free ssnmap storage. */
 	sctp_ssnmap_free(asoc->ssnmap);
 
+	/* Free stream information. */
+	kfree(asoc->streamout);
+	kfree(asoc->streamin);
+
 	/* Clean up the bound address list. */
 	sctp_bind_addr_free(&asoc->base.bind_addr);
 
@@ -1130,6 +1134,8 @@ void sctp_assoc_update(struct sctp_association *asoc,
 	 * has been discarded and needs retransmission.
 	 */
 	if (asoc->state >= SCTP_STATE_ESTABLISHED) {
+		int i;
+
 		asoc->next_tsn = new->next_tsn;
 		asoc->ctsn_ack_point = new->ctsn_ack_point;
 		asoc->adv_peer_ack_point = new->adv_peer_ack_point;
@@ -1139,6 +1145,12 @@ void sctp_assoc_update(struct sctp_association *asoc,
 		 */
 		sctp_ssnmap_clear(asoc->ssnmap);
 
+		for (i = 0; i < asoc->streamoutcnt; i++)
+			asoc->streamout[i].ssn = 0;
+
+		for (i = 0; i < asoc->streamincnt; i++)
+			asoc->streamin[i].ssn = 0;
+
 		/* Flush the ULP reassembly and ordered queue.
 		 * Any data there will now be stale and will
 		 * cause problems.
@@ -1168,6 +1180,13 @@ void sctp_assoc_update(struct sctp_association *asoc,
 			new->ssnmap = NULL;
 		}
 
+		if (!asoc->streamin && !asoc->streamout) {
+			asoc->streamout = new->streamout;
+			asoc->streamin = new->streamin;
+			new->streamout = NULL;
+			new->streamin = NULL;
+		}
+
 		if (!asoc->assoc_id) {
 			/* get a new association id since we don't have one
 			 * yet.
net/sctp/sm_make_chunk.c +6 -1
index 9e9690b..eeadeef 100644
@@ -2442,13 +2442,28 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
 	 * association.
 	 */
 	if (!asoc->temp) {
-		int error;
+		int error, i;
+
+		asoc->streamoutcnt = asoc->c.sinit_num_ostreams;
+		asoc->streamincnt = asoc->c.sinit_max_instreams;
 
 		asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
 					       asoc->c.sinit_num_ostreams, gfp);
 		if (!asoc->ssnmap)
 			goto clean_up;
 
+		asoc->streamout = kcalloc(asoc->streamoutcnt,
+					  sizeof(*asoc->streamout), gfp);

net/sctp/sm_make_chunk.c int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk, · line 2466

Quoted 10 lines
net/sctp/sm_make_chunk.c +10 -0
+		if (!asoc->streamout)
+			goto clean_up;
+		for (i = 0; i < asoc->streamoutcnt; i++)
+			asoc->streamout[i].state = SCTP_STREAM_OPEN;
+
+		asoc->streamin = kcalloc(asoc->streamincnt,
+					 sizeof(*asoc->streamin), gfp);
+		if (!asoc->streamin)
+			goto clean_up;
+

Xin, I understand the need to remove the 'ssnmap' term from the charts here as it will be, but lets try to put all the inner details of stream handling in a dedicated file.

On the original patchset you were creating stream.c for RFC 6525 stuff. We probably can create it earlier and concentrate everything stream-related in there, so we keep it more contained. Thanks

Quoted 11 lines
net/sctp/sm_make_chunk.c +0 -0
 		error = sctp_assoc_set_id(asoc, gfp);
 		if (error)
 			goto clean_up;
Signature · 6 lines
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
author maintainer
#5 lore raw

Re: [PATCHv2 net-next 1/3] sctp: add stream arrays in asoc

Quoted 137 lines · Marcelo Ricardo Leitner
Quoted 121 lines · Xin Long

This patch is to add streamout and streamin arrays in asoc, initialize them in sctp_process_init and free them in sctp_association_free.

Stream arrays are used to replace ssnmap to save more stream things in the next patch.

---
 include/net/sctp/structs.h | 18 ++++++++++++++++++
 net/sctp/associola.c       | 19 +++++++++++++++++++
 net/sctp/sm_make_chunk.c   | 17 ++++++++++++++++-
 3 files changed, 53 insertions(+), 1 deletion(-)
include/net/sctp/structs.h +18 -0
index 87d56cc..549f17d 100644
@@ -1331,6 +1331,18 @@ struct sctp_inithdr_host {
      __u32 initial_tsn;
 };
 
+struct sctp_stream_out {
+     __u16   ssn;
+     __u8    state;
+};
+
+struct sctp_stream_in {
+     __u16   ssn;
+};
+
+#define SCTP_STREAM_CLOSED           0x00
+#define SCTP_STREAM_OPEN             0x01
+
 /* SCTP_GET_ASSOC_STATS counters */
 struct sctp_priv_assoc_stats {
      /* Maximum observed rto in the association during subsequent
@@ -1879,6 +1891,12 @@ struct sctp_association {
           temp:1,            /* Is it a temporary association? */
           prsctp_enable:1;
 
+     /* stream arrays */
+     struct sctp_stream_out *streamout;
+     struct sctp_stream_in *streamin;
+     __u16 streamoutcnt;
+     __u16 streamincnt;
+
      struct sctp_priv_assoc_stats stats;
 
      int sent_cnt_removable;
net/sctp/associola.c +19 -0
index d3cc30c..290ec4d 100644
@@ -361,6 +361,10 @@ void sctp_association_free(struct sctp_association *asoc)
      /* Free ssnmap storage. */
      sctp_ssnmap_free(asoc->ssnmap);
 
+     /* Free stream information. */
+     kfree(asoc->streamout);
+     kfree(asoc->streamin);
+
      /* Clean up the bound address list. */
      sctp_bind_addr_free(&asoc->base.bind_addr);
 
@@ -1130,6 +1134,8 @@ void sctp_assoc_update(struct sctp_association *asoc,
       * has been discarded and needs retransmission.
       */
      if (asoc->state >= SCTP_STATE_ESTABLISHED) {
+             int i;
+
              asoc->next_tsn = new->next_tsn;
              asoc->ctsn_ack_point = new->ctsn_ack_point;
              asoc->adv_peer_ack_point = new->adv_peer_ack_point;
@@ -1139,6 +1145,12 @@ void sctp_assoc_update(struct sctp_association *asoc,
               */
              sctp_ssnmap_clear(asoc->ssnmap);
 
+             for (i = 0; i < asoc->streamoutcnt; i++)
+                     asoc->streamout[i].ssn = 0;
+
+             for (i = 0; i < asoc->streamincnt; i++)
+                     asoc->streamin[i].ssn = 0;
+
              /* Flush the ULP reassembly and ordered queue.
               * Any data there will now be stale and will
               * cause problems.
@@ -1168,6 +1180,13 @@ void sctp_assoc_update(struct sctp_association *asoc,
                      new->ssnmap = NULL;
              }
 
+             if (!asoc->streamin && !asoc->streamout) {
+                     asoc->streamout = new->streamout;
+                     asoc->streamin = new->streamin;
+                     new->streamout = NULL;
+                     new->streamin = NULL;
+             }
+
              if (!asoc->assoc_id) {
                      /* get a new association id since we don't have one
                       * yet.
net/sctp/sm_make_chunk.c +6 -1
index 9e9690b..eeadeef 100644
@@ -2442,13 +2442,28 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
       * association.
       */
      if (!asoc->temp) {
-             int error;
+             int error, i;
+
+             asoc->streamoutcnt = asoc->c.sinit_num_ostreams;
+             asoc->streamincnt = asoc->c.sinit_max_instreams;
 
              asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
                                             asoc->c.sinit_num_ostreams, gfp);
              if (!asoc->ssnmap)
                      goto clean_up;
 
+             asoc->streamout = kcalloc(asoc->streamoutcnt,
+                                       sizeof(*asoc->streamout), gfp);

net/sctp/sm_make_chunk.c int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk, · line 2466

Quoted 10 lines
net/sctp/sm_make_chunk.c +10 -0
+             if (!asoc->streamout)
+                     goto clean_up;
+             for (i = 0; i < asoc->streamoutcnt; i++)
+                     asoc->streamout[i].state = SCTP_STREAM_OPEN;
+
+             asoc->streamin = kcalloc(asoc->streamincnt,
+                                      sizeof(*asoc->streamin), gfp);
+             if (!asoc->streamin)
+                     goto clean_up;
+

Xin, I understand the need to remove the 'ssnmap' term from the charts here as it will be, but lets try to put all the inner details of stream handling in a dedicated file.

Quoted 3 lines

On the original patchset you were creating stream.c for RFC 6525 stuff. We probably can create it earlier and concentrate everything stream-related in there, so we keep it more contained. Thanks

will improve and repost.

Quoted 13 lines
Quoted 13 lines
net/sctp/sm_make_chunk.c +0 -1
              error = sctp_assoc_set_id(asoc, gfp);
              if (error)
                      goto clean_up;
--

2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-sctp" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html