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

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
...@@ -602,6 +602,16 @@ struct sctp_chunk { ...@@ -602,6 +602,16 @@ struct sctp_chunk {
/* This needs to be recoverable for SCTP_SEND_FAILED events. */ /* This needs to be recoverable for SCTP_SEND_FAILED events. */
struct sctp_sndrcvinfo sinfo; 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? */ /* Which association does this belong to? */
struct sctp_association *asoc; struct sctp_association *asoc;
......
...@@ -335,13 +335,27 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, ...@@ -335,13 +335,27 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
/* Check whether this message has expired. */ /* Check whether this message has expired. */
int sctp_chunk_abandoned(struct sctp_chunk *chunk) 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; 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 1;
}
return 0; return 0;
} }
......
...@@ -316,6 +316,8 @@ static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet, ...@@ -316,6 +316,8 @@ static sctp_xmit_t __sctp_packet_append_chunk(struct sctp_packet *packet,
packet->has_data = 1; packet->has_data = 1;
/* timestamp the chunk for rtx purposes */ /* timestamp the chunk for rtx purposes */
chunk->sent_at = jiffies; chunk->sent_at = jiffies;
/* Mainly used for prsctp RTX policy */
chunk->sent_count++;
break; break;
case SCTP_CID_COOKIE_ECHO: case SCTP_CID_COOKIE_ECHO:
packet->has_cookie_echo = 1; packet->has_cookie_echo = 1;
......
...@@ -711,6 +711,17 @@ struct sctp_chunk *sctp_make_ecne(const struct sctp_association *asoc, ...@@ -711,6 +711,17 @@ struct sctp_chunk *sctp_make_ecne(const struct sctp_association *asoc,
return retval; 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 /* Make a DATA chunk for the given association from the provided
* parameters. However, do not populate the data payload. * parameters. However, do not populate the data payload.
*/ */
...@@ -744,6 +755,7 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc, ...@@ -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); retval->subh.data_hdr = sctp_addto_chunk(retval, sizeof(dp), &dp);
memcpy(&retval->sinfo, sinfo, sizeof(struct sctp_sndrcvinfo)); memcpy(&retval->sinfo, sinfo, sizeof(struct sctp_sndrcvinfo));
sctp_set_prsctp_policy(retval, sinfo);
nodata: nodata:
return retval; return retval;
......
...@@ -7099,7 +7099,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) ...@@ -7099,7 +7099,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
if (cmsgs->srinfo->sinfo_flags & if (cmsgs->srinfo->sinfo_flags &
~(SCTP_UNORDERED | SCTP_ADDR_OVER | ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
SCTP_SACK_IMMEDIATELY | SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK |
SCTP_ABORT | SCTP_EOF)) SCTP_ABORT | SCTP_EOF))
return -EINVAL; return -EINVAL;
break; break;
...@@ -7123,7 +7123,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) ...@@ -7123,7 +7123,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
if (cmsgs->sinfo->snd_flags & if (cmsgs->sinfo->snd_flags &
~(SCTP_UNORDERED | SCTP_ADDR_OVER | ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
SCTP_SACK_IMMEDIATELY | SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK |
SCTP_ABORT | SCTP_EOF)) SCTP_ABORT | SCTP_EOF))
return -EINVAL; return -EINVAL;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment