Skip to content

Commit

Permalink
sctp: prepare asoc stream for stream reconf
Browse files Browse the repository at this point in the history
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. It defines sctp_stream that includes stream arrays inside
to replace ssnmap.

Note that we use different structures for IN and OUT streams, as
the members in per OUT stream will get more and more different
from per IN stream.

v1->v2:
  - put these patches into a smaller group.
v2->v3:
  - define sctp_stream to contain stream arrays, and create stream.c
    to put stream-related functions.
  - merge 3 patches into 1, as new sctp_stream has the same name
    with before.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Xin Long authored and David S. Miller committed Jan 7, 2017
1 parent df56005 commit a838631
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 206 deletions.
1 change: 0 additions & 1 deletion include/net/sctp/sctp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
76 changes: 31 additions & 45 deletions include/net/sctp/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ struct sctp_outq;
struct sctp_bind_addr;
struct sctp_ulpq;
struct sctp_ep_common;
struct sctp_ssnmap;
struct crypto_shash;


Expand Down Expand Up @@ -377,54 +376,22 @@ 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);
struct sctp_stream *sctp_stream_new(__u16 incnt, __u16 outcnt, gfp_t gfp);
void sctp_stream_free(struct sctp_stream *stream);
void sctp_stream_clear(struct sctp_stream *stream);

/* 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(stream, type, sid) \
((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(stream, type, sid) \
((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(stream, type, sid, ssn) \
((stream)->type[sid].ssn = ssn + 1)

/*
* Pointers to address related SCTP functions.
* (i.e. things that depend on the address family.)
Expand Down Expand Up @@ -1331,6 +1298,25 @@ struct sctp_inithdr_host {
__u32 initial_tsn;
};

struct sctp_stream_out {
__u16 ssn;
__u8 state;
};

struct sctp_stream_in {
__u16 ssn;
};

struct sctp_stream {
struct sctp_stream_out *out;
struct sctp_stream_in *in;
__u16 outcnt;
__u16 incnt;
};

#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
Expand Down Expand Up @@ -1746,8 +1732,8 @@ struct sctp_association {
/* Default receive parameters */
__u32 default_rcv_context;

/* This tracks outbound ssn for a given stream. */
struct sctp_ssnmap *ssnmap;
/* Stream arrays */
struct sctp_stream *stream;

/* All outbound chunks go through this structure. */
struct sctp_outq outqueue;
Expand Down
2 changes: 1 addition & 1 deletion net/sctp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +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 \
output.o input.o debug.o stream.o auth.o \
offload.o

sctp_probe-y := probe.o
Expand Down
13 changes: 6 additions & 7 deletions net/sctp/associola.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ 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. */
sctp_stream_free(asoc->stream);

/* Clean up the bound address list. */
sctp_bind_addr_free(&asoc->base.bind_addr);
Expand Down Expand Up @@ -1137,7 +1137,7 @@ void sctp_assoc_update(struct sctp_association *asoc,
/* Reinitialize SSN for both local streams
* and peer's streams.
*/
sctp_ssnmap_clear(asoc->ssnmap);
sctp_stream_clear(asoc->stream);

/* Flush the ULP reassembly and ordered queue.
* Any data there will now be stale and will
Expand All @@ -1162,10 +1162,9 @@ 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->stream) {
asoc->stream = new->stream;
new->stream = NULL;
}

if (!asoc->assoc_id) {
Expand Down
2 changes: 0 additions & 2 deletions net/sctp/objcnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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),
};
Expand Down
10 changes: 5 additions & 5 deletions net/sctp/sm_make_chunk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1536,7 +1536,7 @@ 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;
stream = chunk->asoc->stream;

/* Now assign the sequence number to the entire message.
* All fragments must have the same stream sequence number.
Expand All @@ -1547,9 +1547,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(stream, out, sid);
else
ssn = sctp_ssn_peek(stream, sid);
ssn = sctp_ssn_peek(stream, out, sid);
}

lchunk->subh.data_hdr->ssn = htons(ssn);
Expand Down Expand Up @@ -2444,9 +2444,9 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
if (!asoc->temp) {
int error;

asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
asoc->stream = sctp_stream_new(asoc->c.sinit_max_instreams,
asoc->c.sinit_num_ostreams, gfp);
if (!asoc->ssnmap)
if (!asoc->stream)
goto clean_up;

error = sctp_assoc_set_id(asoc, gfp);
Expand Down
3 changes: 1 addition & 2 deletions net/sctp/sm_statefuns.c
Original file line number Diff line number Diff line change
Expand Up @@ -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->stream, 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
Expand Down
125 changes: 0 additions & 125 deletions net/sctp/ssnmap.c

This file was deleted.

Loading

0 comments on commit a838631

Please sign in to comment.