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

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

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.

Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 826d253d
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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;

+17 −3
Original line number Diff line number Diff line
@@ -335,6 +335,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
/* Check whether this message has expired. */
int sctp_chunk_abandoned(struct sctp_chunk *chunk)
{
	if (!chunk->asoc->prsctp_enable ||
	    !SCTP_PR_POLICY(chunk->sinfo.sinfo_flags)) {
		struct sctp_datamsg *msg = chunk->msg;

		if (!msg->can_abandon)
@@ -346,6 +348,18 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
		return 0;
	}

	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;
}

/* This chunk (and consequently entire message) has failed in its sending. */
void sctp_chunk_fail(struct sctp_chunk *chunk, int error)
{
+2 −0
Original line number Diff line number Diff line
@@ -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;
+12 −0
Original line number Diff line number Diff line
@@ -711,6 +711,17 @@ struct sctp_chunk *sctp_make_ecne(const struct sctp_association *asoc,
	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;
+2 −2
Original line number Diff line number Diff line
@@ -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;