Skip to contentSkip to conversation

sctp: implement rfc7496 in sctp

PATCH In review Xin Long 3 participants 10 messages Jul 9, 2016 – Jul 11, 2016

Subsystems (3)
lore
Share & tools
lore

Xin Long

author maintainer
#0 lore raw

cover sctp: implement rfc7496 in sctp

This patchset implements "Additional Policies for the Partially Reliable Stream Control Transmission Protocol Extension" described on RFC7496.

The Partially Reliable SCTP (PR-SCTP) extension defined in [RFC3758] provides a generic method for senders to abandon user messages. The decision to abandon a user message is sender side only, and the exact condition is called a "PR-SCTP policy". This patchset implements 3 policies:

1. Timed Reliability: This allows the sender to specify a timeout for a user message after which the SCTP stack abandons the user message.

2. Limited Retransmission Policy: Allows limitation of the number of retransmissions.

3. Priority Policy: Allows removal of lower-priority messages if space for higher-priority messages is needed in the send buffer.

Patch 1-3 add some sockopts in sctp to set/get pr_sctp policy status. Patch 4-6 implement these 3 policies one by one.

Xin Long (6):
sctp: add SCTP_PR_SUPPORTED on sctp sockopt
sctp: add SCTP_DEFAULT_PRINFO into sctp sockopt
sctp: add SCTP_PR_ASSOC_STATUS on sctp sockopt
sctp: implement prsctp TTL policy
sctp: implement prsctp RTX policy
sctp: implement prsctp PRIO policy

 include/net/sctp/structs.h |  23 ++++-
 include/uapi/linux/sctp.h  |  42 ++++++++
 net/sctp/associola.c       |   1 +
 net/sctp/chunk.c           |  25 ++++-
 net/sctp/endpointola.c     |   1 +
 net/sctp/output.c          |   2 +
 net/sctp/outqueue.c        |  99 +++++++++++++++++++
 net/sctp/sm_make_chunk.c   |  27 +++--
 net/sctp/socket.c          | 240 ++++++++++++++++++++++++++++++++++++++++++++-
 9 files changed, 447 insertions(+), 13 deletions(-)
Signature · 1 line
2.1.0
author maintainer
#1 lore raw

PATCH 1/6 sctp: add SCTP_PR_SUPPORTED on sctp sockopt

According to section 4.5 of rfc7496, prsctp_enable should be per asoc. We will add prsctp_enable to both asoc and ep, and replace the places where it used net.sctp->prsctp_enable with asoc->prsctp_enable.

ep->prsctp_enable will be initialized with net.sctp->prsctp_enable, and asoc->prsctp_enable will be initialized with ep->prsctp_enable. We can also modify it's value through sockopt SCTP_PR_SUPPORTED.

---
 include/net/sctp/structs.h |  6 ++--
 include/uapi/linux/sctp.h  |  1 +
 net/sctp/associola.c       |  1 +
 net/sctp/endpointola.c     |  1 +
 net/sctp/sm_make_chunk.c   | 12 +++----
 net/sctp/socket.c          | 80 ++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 93 insertions(+), 8 deletions(-)
include/net/sctp/structs.h +4 -2
index 83c5ec5..07115ca 100644
@@ -1256,7 +1256,8 @@ struct sctp_endpoint {
 	/* SCTP-AUTH: endpoint shared keys */
 	struct list_head endpoint_shared_keys;
 	__u16 active_key_id;
-	__u8  auth_enable;
+	__u8  auth_enable:1,
+	      prsctp_enable:1;
 };
 
 /* Recover the outter endpoint structure. */
@@ -1848,7 +1849,8 @@ struct sctp_association {
 	__u16 active_key_id;
 
 	__u8 need_ecne:1,	/* Need to send an ECNE Chunk? */
-	     temp:1;		/* Is it a temporary association? */
+	     temp:1,		/* Is it a temporary association? */
+	     prsctp_enable:1;
 
 	struct sctp_priv_assoc_stats stats;
 };
include/uapi/linux/sctp.h +1 -0
index ce70fe6..aa08906 100644
@@ -112,6 +112,7 @@ typedef __s32 sctp_assoc_t;
 #define SCTP_SOCKOPT_CONNECTX	110		/* CONNECTX requests. */
 #define SCTP_SOCKOPT_CONNECTX3	111	/* CONNECTX requests (updated) */
 #define SCTP_GET_ASSOC_STATS	112	/* Read only */
+#define SCTP_PR_SUPPORTED	113
 
 /* These are bit fields for msghdr->msg_flags.  See section 5.1.  */
 /* On user space Linux, these live in <bits/socket.h> as an enum.  */
net/sctp/associola.c +1 -0
index e1849f3..1c23060 100644
@@ -268,6 +268,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
 		goto fail_init;
 
 	asoc->active_key_id = ep->active_key_id;
+	asoc->prsctp_enable = ep->prsctp_enable;
 
 	/* Save the hmacs and chunks list into this association */
 	if (ep->auth_hmacs_list)
net/sctp/endpointola.c +1 -0
index 9d494e3..1f03065 100644
@@ -163,6 +163,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
 	 */
 	ep->auth_hmacs_list = auth_hmacs;
 	ep->auth_chunk_list = auth_chunks;
+	ep->prsctp_enable = net->sctp.prsctp_enable;
 
 	return ep;
 
net/sctp/sm_make_chunk.c +6 -6
index 56f364d..0e3045e 100644
@@ -261,7 +261,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
 	chunksize += WORD_ROUND(SCTP_SAT_LEN(num_types));
 	chunksize += sizeof(ecap_param);
 
-	if (net->sctp.prsctp_enable)
+	if (asoc->prsctp_enable)
 		chunksize += sizeof(prsctp_param);
 
 	/* ADDIP: Section 4.2.7:
@@ -355,7 +355,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
 		sctp_addto_param(retval, num_ext, extensions);
 	}
 
-	if (net->sctp.prsctp_enable)
+	if (asoc->prsctp_enable)
 		sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
 
 	if (sp->adaptation_ind) {
@@ -2024,8 +2024,8 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
 	for (i = 0; i < num_ext; i++) {
 		switch (param.ext->chunks[i]) {
 		case SCTP_CID_FWD_TSN:
-			if (net->sctp.prsctp_enable && !asoc->peer.prsctp_capable)
-				    asoc->peer.prsctp_capable = 1;
+			if (asoc->prsctp_enable && !asoc->peer.prsctp_capable)
+				asoc->peer.prsctp_capable = 1;
 			break;
 		case SCTP_CID_AUTH:
 			/* if the peer reports AUTH, assume that he
@@ -2169,7 +2169,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net,
 		break;
 
 	case SCTP_PARAM_FWD_TSN_SUPPORT:
-		if (net->sctp.prsctp_enable)
+		if (ep->prsctp_enable)
 			break;
 		goto fallthrough;
 
@@ -2653,7 +2653,7 @@ do_addr_param:
 		break;
 
 	case SCTP_PARAM_FWD_TSN_SUPPORT:
-		if (net->sctp.prsctp_enable) {
+		if (asoc->prsctp_enable) {
 			asoc->peer.prsctp_capable = 1;
 			break;
 		}
net/sctp/socket.c +80 -0

104 lines not on this page · raw message

Signature · 1 line
2.1.0
author maintainer
#2 lore raw

PATCH 2/6 sctp: add SCTP_DEFAULT_PRINFO into sctp sockopt

This patch adds SCTP_DEFAULT_PRINFO to sctp sockopt. It is used to set/get sctp Partially Reliable Policies' default params, which includes 3 policies (ttl, rtx, prio) and their values.

Still, if we set policy params in sndinfo, we will use the params of sndinfo against chunks, instead of the default params.

In this patch, we will use 5-8bit of sp/asoc->default_flags to store prsctp policies, and reuse asoc->default_timetolive to store their values. It means if we enable and set prsctp policy, prior ttl timeout in sctp will not work any more.

---
 include/uapi/linux/sctp.h | 29 +++++++++++++++
 net/sctp/socket.c         | 91 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+)
include/uapi/linux/sctp.h +29 -0
index aa08906..984cf2e 100644
@@ -113,6 +113,29 @@ typedef __s32 sctp_assoc_t;
 #define SCTP_SOCKOPT_CONNECTX3	111	/* CONNECTX requests (updated) */
 #define SCTP_GET_ASSOC_STATS	112	/* Read only */
 #define SCTP_PR_SUPPORTED	113
+#define SCTP_DEFAULT_PRINFO	114
+
+/* PR-SCTP policies */
+#define SCTP_PR_SCTP_NONE	0x0000
+#define SCTP_PR_SCTP_TTL	0x0010
+#define SCTP_PR_SCTP_RTX	0x0020
+#define SCTP_PR_SCTP_PRIO	0x0030
+#define SCTP_PR_SCTP_MAX	SCTP_PR_SCTP_PRIO
+#define SCTP_PR_SCTP_MASK	0x0030
+
+#define __SCTP_PR_INDEX(x)	((x >> 4) - 1)
+#define SCTP_PR_INDEX(x)	__SCTP_PR_INDEX(SCTP_PR_SCTP_ ## x)
+
+#define SCTP_PR_POLICY(x)	((x) & SCTP_PR_SCTP_MASK)
+#define SCTP_PR_SET_POLICY(flags, x)	\
+	do {				\
+		flags &= ~SCTP_PR_SCTP_MASK;	\
+		flags |= x;		\
+	} while (0)
+
+#define SCTP_PR_TTL_ENABLED(x)	(SCTP_PR_POLICY(x) = SCTP_PR_SCTP_TTL)
+#define SCTP_PR_RTX_ENABLED(x)	(SCTP_PR_POLICY(x) = SCTP_PR_SCTP_RTX)
+#define SCTP_PR_PRIO_ENABLED(x)	(SCTP_PR_POLICY(x) = SCTP_PR_SCTP_PRIO)
 
 /* These are bit fields for msghdr->msg_flags.  See section 5.1.  */
 /* On user space Linux, these live in <bits/socket.h> as an enum.  */
@@ -903,4 +926,10 @@ struct sctp_paddrthlds {
 	__u16 spt_pathpfthld;
 };
 
+struct sctp_default_prinfo {
+	sctp_assoc_t pr_assoc_id;
+	__u32 pr_value;
+	__u16 pr_policy;
+};
+
 #endif /* _UAPI_SCTP_H */
net/sctp/socket.c +91 -0

115 lines not on this page · raw message

Signature · 1 line
2.1.0
author maintainer
#3 lore raw

PATCH 3/6 sctp: add SCTP_PR_ASSOC_STATUS on sctp sockopt

This patch adds SCTP_PR_ASSOC_STATUS to sctp sockopt, which is used to dump the prsctp statistics info from the asoc. The prsctp statistics includes abandoned_sent/unsent from the asoc. abandoned_sent is the count of the packets we drop packets from retransmit/transmited queue, and abandoned_unsent is the count of the packets we drop from out_queue according to the policy.

Note: another option for prsctp statistics dump described in rfc is SCTP_PR_STREAM_STATUS, which is used to dump the prsctp statistics info from each stream. But by now, linux doesn't yet have per stream statistics info, it needs rfc6525 to be implemented. As the prsctp statistics for each stream has to be based on per stream statistics, we will delay it until rfc6525 is done in linux.

---
 include/net/sctp/structs.h |  3 +++
 include/uapi/linux/sctp.h  | 12 +++++++++
 net/sctp/socket.c          | 62 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+)
include/net/sctp/structs.h +3 -0
index 07115ca..d8e464a 100644
@@ -1853,6 +1853,9 @@ struct sctp_association {
 	     prsctp_enable:1;
 
 	struct sctp_priv_assoc_stats stats;
+
+	__u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1];
+	__u64 abandoned_sent[SCTP_PR_INDEX(MAX) + 1];
 };
 
 
include/uapi/linux/sctp.h +12 -0
index 984cf2e..d304f4c 100644
@@ -114,6 +114,7 @@ typedef __s32 sctp_assoc_t;
 #define SCTP_GET_ASSOC_STATS	112	/* Read only */
 #define SCTP_PR_SUPPORTED	113
 #define SCTP_DEFAULT_PRINFO	114
+#define SCTP_PR_ASSOC_STATUS	115
 
 /* PR-SCTP policies */
 #define SCTP_PR_SCTP_NONE	0x0000
@@ -926,6 +927,17 @@ struct sctp_paddrthlds {
 	__u16 spt_pathpfthld;
 };
 
+/*
+ * Socket Option for Getting the Association/Stream-Specific PR-SCTP Status
+ */
+struct sctp_prstatus {
+	sctp_assoc_t sprstat_assoc_id;
+	__u16 sprstat_sid;
+	__u16 sprstat_policy;
+	__u64 sprstat_abandoned_unsent;
+	__u64 sprstat_abandoned_sent;
+};
+
 struct sctp_default_prinfo {
 	sctp_assoc_t pr_assoc_id;
 	__u32 pr_value;
net/sctp/socket.c +58 -0

70 lines not on this page · raw message

Signature · 1 line
2.1.0
author maintainer
#4 lore raw

PATCH 4/6 sctp: implement prsctp TTL policy

prsctp TTL policy is a policy to abandon chunks when they expire at the specific time in local stack. It's similar with expires_at in struct sctp_datamsg.

This patch uses sinfo->sinfo_timetolive to set the specific time for TTL policy. sinfo->sinfo_timetolive is also used for msg->expires_at. So if prsctp_enable or TTL policy is not enabled, msg->expires_at still works as before.

---
 include/net/sctp/structs.h | 10 ++++++++++
 net/sctp/chunk.c           | 20 +++++++++++++++++---
 net/sctp/output.c          |  2 ++
 net/sctp/sm_make_chunk.c   | 12 ++++++++++++
 net/sctp/socket.c          |  4 ++--
 5 files changed, 43 insertions(+), 5 deletions(-)
include/net/sctp/structs.h +10 -0
index d8e464a..6bcda71 100644
@@ -602,6 +602,16 @@ struct sctp_chunk {
 	/* This needs to be recoverable for SCTP_SEND_FAILED events. */
 	struct sctp_sndrcvinfo sinfo;
 
+	/* We use this field to record param for prsctp policies,
+	 * for TTL policy, it is the time_to_drop of this chunk,
+	 * for RTX policy, it is the max_sent_count of this chunk,
+	 * for PRIO policy, it is the priority of this chunk.
+	 */
+	unsigned long prsctp_param;
+
+	/* How many times this chunk have been sent, for prsctp RTX policy */
+	int sent_count;
+
 	/* Which association does this belong to?  */
 	struct sctp_association *asoc;
 
net/sctp/chunk.c +17 -3
index 1eb94bf..2698d12 100644
@@ -335,13 +335,27 @@ errout:
 /* Check whether this message has expired. */
 int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 {
-	struct sctp_datamsg *msg = chunk->msg;
+	if (!chunk->asoc->prsctp_enable ||
+	    !SCTP_PR_POLICY(chunk->sinfo.sinfo_flags)) {
+		struct sctp_datamsg *msg = chunk->msg;
+
+		if (!msg->can_abandon)
+			return 0;
+
+		if (time_after(jiffies, msg->expires_at))
+			return 1;
 
-	if (!msg->can_abandon)
 		return 0;
+	}
 
-	if (time_after(jiffies, msg->expires_at))
+	if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
+	    time_after(jiffies, chunk->prsctp_param)) {
+		if (chunk->sent_count)
+			chunk->asoc->abandoned_sent[SCTP_PR_INDEX(TTL)]++;
+		else
+			chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
 		return 1;
+	}
 
 	return 0;
 }
net/sctp/output.c +2 -0
index 2e9223b..7425f6c 100644
@@ -316,6 +316,8 @@ static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet,
 		packet->has_data = 1;
 		/* timestamp the chunk for rtx purposes */
 		chunk->sent_at = jiffies;
+		/* Mainly used for prsctp RTX policy */
+		chunk->sent_count++;
 		break;
 	case SCTP_CID_COOKIE_ECHO:
 		packet->has_cookie_echo = 1;
net/sctp/sm_make_chunk.c +11 -0
index 0e3045e..2c431ee 100644
@@ -711,6 +711,17 @@ nodata:
 	return retval;
 }
 
+static void sctp_set_prsctp_policy(struct sctp_chunk *chunk,
+				   const struct sctp_sndrcvinfo *sinfo)
+{
+	if (!chunk->asoc->prsctp_enable)
+		return;
+
+	if (SCTP_PR_TTL_ENABLED(sinfo->sinfo_flags))
+		chunk->prsctp_param +			jiffies + msecs_to_jiffies(sinfo->sinfo_timetolive);
+}
+
 /* Make a DATA chunk for the given association from the provided
  * parameters.  However, do not populate the data payload.
  */
@@ -744,6 +755,7 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
 
 	retval->subh.data_hdr = sctp_addto_chunk(retval, sizeof(dp), &dp);
 	memcpy(&retval->sinfo, sinfo, sizeof(struct sctp_sndrcvinfo));
+	sctp_set_prsctp_policy(retval, sinfo);
 
 nodata:
 	return retval;
net/sctp/socket.c +2 -2
index c3167c4..0861429 100644
@@ -7099,7 +7099,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
 
 			if (cmsgs->srinfo->sinfo_flags &
 			    ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
-			      SCTP_SACK_IMMEDIATELY |
+			      SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK |
 			      SCTP_ABORT | SCTP_EOF))
 				return -EINVAL;
 			break;
@@ -7123,7 +7123,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
 
 			if (cmsgs->sinfo->snd_flags &
 			    ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
-			      SCTP_SACK_IMMEDIATELY |
+			      SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK |
 			      SCTP_ABORT | SCTP_EOF))
 				return -EINVAL;
 			break;
Signature · 1 line
2.1.0
author maintainer
#5 lore raw

PATCH 5/6 sctp: implement prsctp RTX policy

prsctp RTX policy is a policy to abandon chunks when they are retransmitted beyond the max count.

This patch uses sent_count to count how many times one chunk has been sent, and prsctp_param is the max rtx count, which is from sinfo->sinfo_timetolive in sctp_set_prsctp_policy(). So similar to TTL policy, if RTX policy is enabled, msg->expire_at won't work.

Then in sctp_chunk_abandoned, this patch checks if chunk->sent_count is bigger than chunk->prsctp_param to abandon this chunk.

---
 net/sctp/chunk.c         | 4 ++++
 net/sctp/sm_make_chunk.c | 2 ++
 2 files changed, 6 insertions(+)
net/sctp/chunk.c +4 -0
index 2698d12..b3692b5 100644
@@ -355,6 +355,10 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 		else
 			chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
 		return 1;
+	} else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) &&
+		   chunk->sent_count > chunk->prsctp_param) {
+		chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
+		return 1;
 	}
 
 	return 0;
net/sctp/sm_make_chunk.c +2 -0
index 2c431ee..cfde934 100644
@@ -720,6 +720,8 @@ static void sctp_set_prsctp_policy(struct sctp_chunk *chunk,
 	if (SCTP_PR_TTL_ENABLED(sinfo->sinfo_flags))
 		chunk->prsctp_param  			jiffies + msecs_to_jiffies(sinfo->sinfo_timetolive);
+	else if (SCTP_PR_RTX_ENABLED(sinfo->sinfo_flags))
+		chunk->prsctp_param = sinfo->sinfo_timetolive;
 }
 
 /* Make a DATA chunk for the given association from the provided
Signature · 1 line
2.1.0
author maintainer
#6 lore raw

PATCH 6/6 sctp: implement prsctp PRIO policy

prsctp PRIO policy is a policy to abandon lower priority chunks when asoc doesn't have enough snd buffer, so that the current chunk with higher priority can be queued successfully.

Similar to TTL/RTX policy, we will set the priority of the chunk to prsctp_param with sinfo->sinfo_timetolive in sctp_set_prsctp_policy(). So if PRIO policy is enabled, msg->expire_at won't work.

asoc->sent_cnt_removable will record how many chunks can be checked to remove. If priority policy is enabled, when the chunk is queued into the out_queue, we will increase sent_cnt_removable. When the chunk is moved to abandon_queue or dequeue and free, we will decrease sent_cnt_removable.

In sctp_sendmsg, we will check if there is enough snd buffer for current msg and if sent_cnt_removable is not 0. Then try to abandon chunks in sctp_prune_prsctp when sendmsg from the retransmit/transmited queue, and free chunks from out_queue in right order until the abandon+free size > msg_len - sctp_wfree. For the abandon size, we have to wait until it sends FORWARD TSN, receives the sack and the chunks are really freed.

---
 include/net/sctp/structs.h |  4 ++
 net/sctp/chunk.c           |  1 +
 net/sctp/outqueue.c        | 99 ++++++++++++++++++++++++++++++++++++++++++++++
 net/sctp/sm_make_chunk.c   |  3 +-
 net/sctp/socket.c          |  3 ++
 5 files changed, 109 insertions(+), 1 deletion(-)
include/net/sctp/structs.h +4 -0
index 6bcda71..8626bdd 100644
@@ -1084,6 +1084,8 @@ void sctp_retransmit(struct sctp_outq *, struct sctp_transport *,
 		     sctp_retransmit_reason_t);
 void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8);
 int sctp_outq_uncork(struct sctp_outq *, gfp_t gfp);
+void sctp_prsctp_prune(struct sctp_association *asoc,
+		       struct sctp_sndrcvinfo *sinfo, int msg_len);
 /* Uncork and flush an outqueue.  */
 static inline void sctp_outq_cork(struct sctp_outq *q)
 {
@@ -1864,6 +1866,8 @@ struct sctp_association {
 
 	struct sctp_priv_assoc_stats stats;
 
+	int sent_cnt_removable;
+
 	__u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1];
 	__u64 abandoned_sent[SCTP_PR_INDEX(MAX) + 1];
 };
net/sctp/chunk.c +1 -0
index b3692b5..a55e547 100644
@@ -360,6 +360,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 		chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
 		return 1;
 	}
+	/* PRIO policy is processed by sendmsg, not here */
 
 	return 0;
 }
net/sctp/outqueue.c +98 -0

122 lines not on this page · raw message

net/sctp/sm_make_chunk.c +2 -1
index cfde934..1c96f47 100644
@@ -720,7 +720,8 @@ static void sctp_set_prsctp_policy(struct sctp_chunk *chunk,
 	if (SCTP_PR_TTL_ENABLED(sinfo->sinfo_flags))
 		chunk->prsctp_param  			jiffies + msecs_to_jiffies(sinfo->sinfo_timetolive);
-	else if (SCTP_PR_RTX_ENABLED(sinfo->sinfo_flags))
+	else if (SCTP_PR_RTX_ENABLED(sinfo->sinfo_flags) ||
+		 SCTP_PR_PRIO_ENABLED(sinfo->sinfo_flags))
 		chunk->prsctp_param = sinfo->sinfo_timetolive;
 }
 
net/sctp/socket.c +3 -0
index 0861429..71c7dc5 100644
@@ -1914,6 +1914,9 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
 		goto out_free;
 	}
 
+	if (sctp_wspace(asoc) < msg_len)
+		sctp_prsctp_prune(asoc, sinfo, msg_len - sctp_wspace(asoc));
+
 	timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
 	if (!sctp_wspace(asoc)) {
 		err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len);
Signature · 1 line
2.1.0
author maintainer
#7 lore raw
In reply to Xin Long
Quoted 12 lines · Xin Long

This patchset implements "Additional Policies for the Partially Reliable Stream Control Transmission Protocol Extension" described on RFC7496.

The Partially Reliable SCTP (PR-SCTP) extension defined in [RFC3758] provides a generic method for senders to abandon user messages. The decision to abandon a user message is sender side only, and the exact condition is called a "PR-SCTP policy". This patchset implements 3 policies:

1. Timed Reliability: This allows the sender to specify a timeout for a user message after which the SCTP stack abandons the user message.

Quoted 9 lines

2. Limited Retransmission Policy: Allows limitation of the number of retransmissions.

3. Priority Policy: Allows removal of lower-priority messages if space for higher-priority messages is needed in the send buffer.

Patch 1-3 add some sockopts in sctp to set/get pr_sctp policy status. Patch 4-6 implement these 3 policies one by one.

Attachment is some tests for this patchset.

maintainer Acked-by on the v1 series
#8 lore raw
In reply to Xin Long
Quoted 21 lines · Xin Long

This patchset implements "Additional Policies for the Partially Reliable Stream Control Transmission Protocol Extension" described on RFC7496.

The Partially Reliable SCTP (PR-SCTP) extension defined in [RFC3758] provides a generic method for senders to abandon user messages. The decision to abandon a user message is sender side only, and the exact condition is called a "PR-SCTP policy". This patchset implements 3 policies:

1. Timed Reliability: This allows the sender to specify a timeout for a user message after which the SCTP stack abandons the user message.

2. Limited Retransmission Policy: Allows limitation of the number of retransmissions.

3. Priority Policy: Allows removal of lower-priority messages if space for higher-priority messages is needed in the send buffer.

Patch 1-3 add some sockopts in sctp to set/get pr_sctp policy status. Patch 4-6 implement these 3 policies one by one.

Quoted 7 lines

Xin Long (6):
sctp: add SCTP_PR_SUPPORTED on sctp sockopt
sctp: add SCTP_DEFAULT_PRINFO into sctp sockopt
sctp: add SCTP_PR_ASSOC_STATUS on sctp sockopt
sctp: implement prsctp TTL policy
sctp: implement prsctp RTX policy
sctp: implement prsctp PRIO policy

Thanks Xin

maintainer
#9 lore raw

From: Marcelo Ricardo Leitner <[email protected]>
Date: Mon, 11 Jul 2016 13:15:29 -0300

Quoted 30 lines · Xin Long
Quoted 21 lines

This patchset implements "Additional Policies for the Partially Reliable Stream Control Transmission Protocol Extension" described on RFC7496.

The Partially Reliable SCTP (PR-SCTP) extension defined in [RFC3758] provides a generic method for senders to abandon user messages. The decision to abandon a user message is sender side only, and the exact condition is called a "PR-SCTP policy". This patchset implements 3 policies:

1. Timed Reliability: This allows the sender to specify a timeout for a user message after which the SCTP stack abandons the user message.

2. Limited Retransmission Policy: Allows limitation of the number of retransmissions.

3. Priority Policy: Allows removal of lower-priority messages if space for higher-priority messages is needed in the send buffer.

Patch 1-3 add some sockopts in sctp to set/get pr_sctp policy status. Patch 4-6 implement these 3 policies one by one.

Quoted 7 lines

Xin Long (6):
sctp: add SCTP_PR_SUPPORTED on sctp sockopt
sctp: add SCTP_DEFAULT_PRINFO into sctp sockopt
sctp: add SCTP_PR_ASSOC_STATUS on sctp sockopt
sctp: implement prsctp TTL policy
sctp: implement prsctp RTX policy
sctp: implement prsctp PRIO policy

Quoted 1 line

Series applied.