Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9622ed4 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'sctp-stream-interleave-part-1'



Xin Long says:

====================
sctp: Implement Stream Interleave: The I-DATA Chunk Supporting User Message Interleaving

Stream Interleave would be Implemented in two Parts:

   1. The I-DATA Chunk Supporting User Message Interleaving
   2. Interaction with Other SCTP Extensions

Overview in section 1.1 of RFC8260 for Part 1:

   This document describes a new chunk carrying payload data called
   I-DATA.  This chunk incorporates the properties of the current SCTP
   DATA chunk, all the flags and fields except the Stream Sequence
   Number (SSN), and also adds two new fields in its chunk header -- the
   Fragment Sequence Number (FSN) and the Message Identifier (MID).  The
   FSN is only used for reassembling all fragments that have the same
   MID and the same ordering property.  The TSN is only used for the
   reliable transfer in combination with Selective Acknowledgment (SACK)
   chunks.

   In addition, the MID is also used for ensuring ordered delivery
   instead of using the stream sequence number (the I-DATA chunk omits
   an SSN).

As the 1st part of Stream Interleave Implementation, this patchset adds
an ops framework named sctp_stream_interleave with a bunch of stuff that
does lots of things needed somewhere.

Then it defines sctp_stream_interleave_0 to work for normal DATA chunks
and sctp_stream_interleave_1 for I-DATA chunks.

With these functions, hundreds of if-else checks for the different process
on I-DATA chunks would be avoided. Besides, very few codes could be shared
in these two function sets.

In this patchset, it adds some basic variables, structures and socket
options firstly, then implement these functions one by one to add the
procedures for ordered idata gradually, at last adjusts some codes to
make them work for unordered idata.

To make it safe to be implemented and also not break the normal data
chunk process, this feature can't be enabled to use until all stream
interleave codes are completely accomplished.

v1 -> v2:
  - fixed a checkpatch warning that a blank line was missed.
  - avoided a kbuild warning reported from gcc-4.9.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 92ff4264 13228238
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -102,6 +102,9 @@ enum sctp_cid {
	/* AUTH Extension Section 4.1 */
	SCTP_CID_AUTH			= 0x0F,

	/* sctp ndata 5.1. I-DATA */
	SCTP_CID_I_DATA			= 0x40,

	/* PR-SCTP Sec 3.2 */
	SCTP_CID_FWD_TSN		= 0xC0,

@@ -240,6 +243,23 @@ struct sctp_data_chunk {
	struct sctp_datahdr data_hdr;
};

struct sctp_idatahdr {
	__be32 tsn;
	__be16 stream;
	__be16 reserved;
	__be32 mid;
	union {
		__u32 ppid;
		__be32 fsn;
	};
	__u8 payload[0];
};

struct sctp_idata_chunk {
	struct sctp_chunkhdr chunk_hdr;
	struct sctp_idatahdr data_hdr;
};

/* DATA Chuck Specific Flags */
enum {
	SCTP_DATA_MIDDLE_FRAG	= 0x00,
+4 −1
Original line number Diff line number Diff line
@@ -122,9 +122,12 @@ struct netns_sctp {
	/* Flag to indicate if PR-CONFIG is enabled. */
	int reconf_enable;

	/* Flag to idicate if SCTP-AUTH is enabled */
	/* Flag to indicate if SCTP-AUTH is enabled */
	int auth_enable;

	/* Flag to indicate if stream interleave is enabled */
	int intl_enable;

	/*
	 * Policy to control SCTP IPv4 address scoping
	 * 0   - Disable IPv4 address scoping
+5 −4
Original line number Diff line number Diff line
@@ -145,12 +145,13 @@ SCTP_SUBTYPE_CONSTRUCTOR(OTHER, enum sctp_event_other, other)
SCTP_SUBTYPE_CONSTRUCTOR(PRIMITIVE,	enum sctp_event_primitive, primitive)


#define sctp_chunk_is_data(a) (a->chunk_hdr->type == SCTP_CID_DATA)
#define sctp_chunk_is_data(a) (a->chunk_hdr->type == SCTP_CID_DATA || \
			       a->chunk_hdr->type == SCTP_CID_I_DATA)

/* Calculate the actual data size in a data chunk */
#define SCTP_DATA_SNDSIZE(c) ((int)((unsigned long)(c->chunk_end)\
		       		- (unsigned long)(c->chunk_hdr)\
				- sizeof(struct sctp_data_chunk)))
#define SCTP_DATA_SNDSIZE(c) ((int)((unsigned long)(c->chunk_end) - \
				    (unsigned long)(c->chunk_hdr) - \
				    sctp_datachk_len(&c->asoc->stream)))

/* Internal error codes */
enum sctp_ierror {
+2 −2
Original line number Diff line number Diff line
@@ -444,13 +444,13 @@ static inline int sctp_frag_point(const struct sctp_association *asoc, int pmtu)
	int frag = pmtu;

	frag -= sp->pf->af->net_header_len;
	frag -= sizeof(struct sctphdr) + sizeof(struct sctp_data_chunk);
	frag -= sizeof(struct sctphdr) + sctp_datachk_len(&asoc->stream);

	if (asoc->user_frag)
		frag = min_t(int, frag, asoc->user_frag);

	frag = SCTP_TRUNC4(min_t(int, frag, SCTP_MAX_CHUNK_LEN -
					    sizeof(struct sctp_data_chunk)));
					    sctp_datachk_len(&asoc->stream)));

	return frag;
}
+11 −4
Original line number Diff line number Diff line
@@ -197,10 +197,11 @@ struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc,
struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc,
				 const __u32 lowest_tsn,
				 const struct sctp_chunk *chunk);
struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
struct sctp_chunk *sctp_make_idata(const struct sctp_association *asoc,
				   __u8 flags, int paylen, gfp_t gfp);
struct sctp_chunk *sctp_make_datafrag_empty(const struct sctp_association *asoc,
					    const struct sctp_sndrcvinfo *sinfo,
					    int len, const __u8 flags,
					    __u16 ssn, gfp_t gfp);
					    int len, __u8 flags, gfp_t gfp);
struct sctp_chunk *sctp_make_ecne(const struct sctp_association *asoc,
				  const __u32 lowest_tsn);
struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc);
@@ -342,7 +343,7 @@ static inline __u16 sctp_data_size(struct sctp_chunk *chunk)
	__u16 size;

	size = ntohs(chunk->chunk_hdr->length);
	size -= sizeof(struct sctp_data_chunk);
	size -= sctp_datahdr_len(&chunk->asoc->stream);

	return size;
}
@@ -358,6 +359,12 @@ static inline __u16 sctp_data_size(struct sctp_chunk *chunk)
	 typecheck(__u32, b) && \
	 ((__s32)((a) - (b)) <= 0))

/* Compare two MIDs */
#define MID_lt(a, b)	\
	(typecheck(__u32, a) && \
	 typecheck(__u32, b) && \
	 ((__s32)((a) - (b)) < 0))

/* Compare two SSNs */
#define SSN_lt(a,b)		\
	(typecheck(__u16, a) && \
Loading