forked from mirrors/linux
		
	sctp: add SCTP_FUTURE_ASSOC for SCTP_PEER_ADDR_THLDS sockopt
Check with SCTP_FUTURE_ASSOC instead in sctp_set/getsockopt_paddr_thresholds, it's compatible with 0. It also adds pf_retrans in sctp_sock to support SCTP_FUTURE_ASSOC. Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									48c072174d
								
							
						
					
					
						commit
						8add543e36
					
				
					 3 changed files with 43 additions and 19 deletions
				
			
		| 
						 | 
					@ -199,6 +199,8 @@ struct sctp_sock {
 | 
				
			||||||
	__u32 flowlabel;
 | 
						__u32 flowlabel;
 | 
				
			||||||
	__u8  dscp;
 | 
						__u8  dscp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int pf_retrans;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* The initial Path MTU to use for new associations. */
 | 
						/* The initial Path MTU to use for new associations. */
 | 
				
			||||||
	__u32 pathmtu;
 | 
						__u32 pathmtu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,7 +101,7 @@ static struct sctp_association *sctp_association_init(
 | 
				
			||||||
	 * socket values.
 | 
						 * socket values.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt;
 | 
						asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt;
 | 
				
			||||||
	asoc->pf_retrans  = net->sctp.pf_retrans;
 | 
						asoc->pf_retrans  = sp->pf_retrans;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	asoc->rto_initial = msecs_to_jiffies(sp->rtoinfo.srto_initial);
 | 
						asoc->rto_initial = msecs_to_jiffies(sp->rtoinfo.srto_initial);
 | 
				
			||||||
	asoc->rto_max = msecs_to_jiffies(sp->rtoinfo.srto_max);
 | 
						asoc->rto_max = msecs_to_jiffies(sp->rtoinfo.srto_max);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3888,11 +3888,25 @@ static int sctp_setsockopt_paddr_thresholds(struct sock *sk,
 | 
				
			||||||
			   sizeof(struct sctp_paddrthlds)))
 | 
								   sizeof(struct sctp_paddrthlds)))
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) {
 | 
				
			||||||
	if (sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) {
 | 
							trans = sctp_addr_id2transport(sk, &val.spt_address,
 | 
				
			||||||
		asoc = sctp_id2assoc(sk, val.spt_assoc_id);
 | 
										       val.spt_assoc_id);
 | 
				
			||||||
		if (!asoc)
 | 
							if (!trans)
 | 
				
			||||||
			return -ENOENT;
 | 
								return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (val.spt_pathmaxrxt)
 | 
				
			||||||
 | 
								trans->pathmaxrxt = val.spt_pathmaxrxt;
 | 
				
			||||||
 | 
							trans->pf_retrans = val.spt_pathpfthld;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						asoc = sctp_id2assoc(sk, val.spt_assoc_id);
 | 
				
			||||||
 | 
						if (!asoc && val.spt_assoc_id != SCTP_FUTURE_ASSOC &&
 | 
				
			||||||
 | 
						    sctp_style(sk, UDP))
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (asoc) {
 | 
				
			||||||
		list_for_each_entry(trans, &asoc->peer.transport_addr_list,
 | 
							list_for_each_entry(trans, &asoc->peer.transport_addr_list,
 | 
				
			||||||
				    transports) {
 | 
									    transports) {
 | 
				
			||||||
			if (val.spt_pathmaxrxt)
 | 
								if (val.spt_pathmaxrxt)
 | 
				
			||||||
| 
						 | 
					@ -3904,14 +3918,11 @@ static int sctp_setsockopt_paddr_thresholds(struct sock *sk,
 | 
				
			||||||
			asoc->pathmaxrxt = val.spt_pathmaxrxt;
 | 
								asoc->pathmaxrxt = val.spt_pathmaxrxt;
 | 
				
			||||||
		asoc->pf_retrans = val.spt_pathpfthld;
 | 
							asoc->pf_retrans = val.spt_pathpfthld;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		trans = sctp_addr_id2transport(sk, &val.spt_address,
 | 
							struct sctp_sock *sp = sctp_sk(sk);
 | 
				
			||||||
					       val.spt_assoc_id);
 | 
					 | 
				
			||||||
		if (!trans)
 | 
					 | 
				
			||||||
			return -ENOENT;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (val.spt_pathmaxrxt)
 | 
							if (val.spt_pathmaxrxt)
 | 
				
			||||||
			trans->pathmaxrxt = val.spt_pathmaxrxt;
 | 
								sp->pathmaxrxt = val.spt_pathmaxrxt;
 | 
				
			||||||
		trans->pf_retrans = val.spt_pathpfthld;
 | 
							sp->pf_retrans = val.spt_pathpfthld;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -4781,6 +4792,7 @@ static int sctp_init_sock(struct sock *sk)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	sp->hbinterval  = net->sctp.hb_interval;
 | 
						sp->hbinterval  = net->sctp.hb_interval;
 | 
				
			||||||
	sp->pathmaxrxt  = net->sctp.max_retrans_path;
 | 
						sp->pathmaxrxt  = net->sctp.max_retrans_path;
 | 
				
			||||||
 | 
						sp->pf_retrans  = net->sctp.pf_retrans;
 | 
				
			||||||
	sp->pathmtu     = 0; /* allow default discovery */
 | 
						sp->pathmtu     = 0; /* allow default discovery */
 | 
				
			||||||
	sp->sackdelay   = net->sctp.sack_timeout;
 | 
						sp->sackdelay   = net->sctp.sack_timeout;
 | 
				
			||||||
	sp->sackfreq	= 2;
 | 
						sp->sackfreq	= 2;
 | 
				
			||||||
| 
						 | 
					@ -6917,14 +6929,7 @@ static int sctp_getsockopt_paddr_thresholds(struct sock *sk,
 | 
				
			||||||
	if (copy_from_user(&val, (struct sctp_paddrthlds __user *)optval, len))
 | 
						if (copy_from_user(&val, (struct sctp_paddrthlds __user *)optval, len))
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) {
 | 
						if (!sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) {
 | 
				
			||||||
		asoc = sctp_id2assoc(sk, val.spt_assoc_id);
 | 
					 | 
				
			||||||
		if (!asoc)
 | 
					 | 
				
			||||||
			return -ENOENT;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		val.spt_pathpfthld = asoc->pf_retrans;
 | 
					 | 
				
			||||||
		val.spt_pathmaxrxt = asoc->pathmaxrxt;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		trans = sctp_addr_id2transport(sk, &val.spt_address,
 | 
							trans = sctp_addr_id2transport(sk, &val.spt_address,
 | 
				
			||||||
					       val.spt_assoc_id);
 | 
										       val.spt_assoc_id);
 | 
				
			||||||
		if (!trans)
 | 
							if (!trans)
 | 
				
			||||||
| 
						 | 
					@ -6932,6 +6937,23 @@ static int sctp_getsockopt_paddr_thresholds(struct sock *sk,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		val.spt_pathmaxrxt = trans->pathmaxrxt;
 | 
							val.spt_pathmaxrxt = trans->pathmaxrxt;
 | 
				
			||||||
		val.spt_pathpfthld = trans->pf_retrans;
 | 
							val.spt_pathpfthld = trans->pf_retrans;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						asoc = sctp_id2assoc(sk, val.spt_assoc_id);
 | 
				
			||||||
 | 
						if (!asoc && val.spt_assoc_id != SCTP_FUTURE_ASSOC &&
 | 
				
			||||||
 | 
						    sctp_style(sk, UDP))
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (asoc) {
 | 
				
			||||||
 | 
							val.spt_pathpfthld = asoc->pf_retrans;
 | 
				
			||||||
 | 
							val.spt_pathmaxrxt = asoc->pathmaxrxt;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							struct sctp_sock *sp = sctp_sk(sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							val.spt_pathpfthld = sp->pf_retrans;
 | 
				
			||||||
 | 
							val.spt_pathmaxrxt = sp->pathmaxrxt;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (put_user(len, optlen) || copy_to_user(optval, &val, len))
 | 
						if (put_user(len, optlen) || copy_to_user(optval, &val, len))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue