Commit 2d07a49a authored by Xin Long's avatar Xin Long Committed by David S. Miller
Browse files

sctp: add basic structures and make chunk function for ifwdtsn



sctp_ifwdtsn_skip, sctp_ifwdtsn_hdr and sctp_ifwdtsn_chunk are used to
define and parse I-FWD TSN chunk format, and sctp_make_ifwdtsn is a
function to build the chunk.

The I-FORWARD-TSN Chunk Format is defined in section 2.3.1 of RFC8260.

Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Acked-by: default avatarMarcelo R. Leitner <marcelo.leitner@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 02477809
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ enum sctp_cid {

	/* Use hex, as defined in ADDIP sec. 3.1 */
	SCTP_CID_ASCONF			= 0xC1,
	SCTP_CID_I_FWD_TSN		= 0xC2,
	SCTP_CID_ASCONF_ACK		= 0x80,
	SCTP_CID_RECONF			= 0x82,
}; /* enum */
@@ -616,6 +617,22 @@ struct sctp_fwdtsn_chunk {
	struct sctp_fwdtsn_hdr fwdtsn_hdr;
};

struct sctp_ifwdtsn_skip {
	__be16 stream;
	__u8 reserved;
	__u8 flags;
	__be32 mid;
};

struct sctp_ifwdtsn_hdr {
	__be32 new_cum_tsn;
	struct sctp_ifwdtsn_skip skip[0];
};

struct sctp_ifwdtsn_chunk {
	struct sctp_chunkhdr chunk_hdr;
	struct sctp_ifwdtsn_hdr fwdtsn_hdr;
};

/* ADDIP
 * Section 3.1.1 Address Configuration Change Chunk (ASCONF)
+3 −0
Original line number Diff line number Diff line
@@ -199,6 +199,9 @@ struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc,
				 const struct sctp_chunk *chunk);
struct sctp_chunk *sctp_make_idata(const struct sctp_association *asoc,
				   __u8 flags, int paylen, gfp_t gfp);
struct sctp_chunk *sctp_make_ifwdtsn(const struct sctp_association *asoc,
				     __u32 new_cum_tsn, size_t nstreams,
				     struct sctp_ifwdtsn_skip *skiplist);
struct sctp_chunk *sctp_make_datafrag_empty(const struct sctp_association *asoc,
					    const struct sctp_sndrcvinfo *sinfo,
					    int len, __u8 flags, gfp_t gfp);
+1 −0
Original line number Diff line number Diff line
@@ -599,6 +599,7 @@ struct sctp_chunk {
		struct sctp_fwdtsn_hdr *fwdtsn_hdr;
		struct sctp_authhdr *auth_hdr;
		struct sctp_idatahdr *idata_hdr;
		struct sctp_ifwdtsn_hdr *ifwdtsn_hdr;
	} subh;

	__u8 *chunk_end;
+24 −0
Original line number Diff line number Diff line
@@ -3536,6 +3536,30 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
	return retval;
}

struct sctp_chunk *sctp_make_ifwdtsn(const struct sctp_association *asoc,
				     __u32 new_cum_tsn, size_t nstreams,
				     struct sctp_ifwdtsn_skip *skiplist)
{
	struct sctp_chunk *retval = NULL;
	struct sctp_ifwdtsn_hdr ftsn_hdr;
	size_t hint;

	hint = (nstreams + 1) * sizeof(__u32);

	retval = sctp_make_control(asoc, SCTP_CID_I_FWD_TSN, 0, hint,
				   GFP_ATOMIC);
	if (!retval)
		return NULL;

	ftsn_hdr.new_cum_tsn = htonl(new_cum_tsn);
	retval->subh.ifwdtsn_hdr =
		sctp_addto_chunk(retval, sizeof(ftsn_hdr), &ftsn_hdr);

	sctp_addto_chunk(retval, nstreams * sizeof(skiplist[0]), skiplist);

	return retval;
}

/* RE-CONFIG 3.1 (RE-CONFIG chunk)
 *   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