mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									826d253d57
								
							
						
					
					
						commit
						a6c2f79287
					
				
					 5 changed files with 43 additions and 5 deletions
				
			
		| 
						 | 
					@ -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,6 +335,8 @@ 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)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (!chunk->asoc->prsctp_enable ||
 | 
				
			||||||
 | 
						    !SCTP_PR_POLICY(chunk->sinfo.sinfo_flags)) {
 | 
				
			||||||
		struct sctp_datamsg *msg = chunk->msg;
 | 
							struct sctp_datamsg *msg = chunk->msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!msg->can_abandon)
 | 
							if (!msg->can_abandon)
 | 
				
			||||||
| 
						 | 
					@ -343,6 +345,18 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 | 
				
			||||||
		if (time_after(jiffies, msg->expires_at))
 | 
							if (time_after(jiffies, msg->expires_at))
 | 
				
			||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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,
 | 
				
			||||||
	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,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue