[PATCHv2 net-next 1/3] sctp: add stream arrays in asoc
From: Xin Long <lucien.xin@gmail.com>
Date: 2017-01-03 06:00:04
Also in:
linux-sctp
Subsystem:
networking [general], sctp protocol, the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Marcelo Ricardo Leitner, Xin Long, Linus Torvalds
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. Signed-off-by: Xin Long <lucien.xin@gmail.com> --- 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(-)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 87d56cc..549f17d 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h@@ -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;
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index d3cc30c..290ec4d 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c@@ -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.
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 9e9690b..eeadeef 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c@@ -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;
--
2.1.0