mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	sctp: add get and set sockopt for reconf_enable
This patchset is to add SCTP_RECONFIG_SUPPORTED sockopt, it would set and get asoc reconf_enable value when asoc_id is set, or it would set and get ep reconf_enalbe value if asoc_id is 0. It is also to add sysctl interface for users to set the default value for reconf_enable. After this patch, stream reconf will work. Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									11ae76e67a
								
							
						
					
					
						commit
						c0d8bab6ae
					
				
					 3 changed files with 89 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -115,6 +115,7 @@ typedef __s32 sctp_assoc_t;
 | 
			
		|||
#define SCTP_PR_SUPPORTED	113
 | 
			
		||||
#define SCTP_DEFAULT_PRINFO	114
 | 
			
		||||
#define SCTP_PR_ASSOC_STATUS	115
 | 
			
		||||
#define SCTP_RECONFIG_SUPPORTED	117
 | 
			
		||||
#define SCTP_ENABLE_STREAM_RESET	118
 | 
			
		||||
#define SCTP_RESET_STREAMS	119
 | 
			
		||||
#define SCTP_RESET_ASSOC	120
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3758,6 +3758,39 @@ static int sctp_setsockopt_default_prinfo(struct sock *sk,
 | 
			
		|||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int sctp_setsockopt_reconfig_supported(struct sock *sk,
 | 
			
		||||
					      char __user *optval,
 | 
			
		||||
					      unsigned int optlen)
 | 
			
		||||
{
 | 
			
		||||
	struct sctp_assoc_value params;
 | 
			
		||||
	struct sctp_association *asoc;
 | 
			
		||||
	int retval = -EINVAL;
 | 
			
		||||
 | 
			
		||||
	if (optlen != sizeof(params))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	if (copy_from_user(¶ms, optval, optlen)) {
 | 
			
		||||
		retval = -EFAULT;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	asoc = sctp_id2assoc(sk, params.assoc_id);
 | 
			
		||||
	if (asoc) {
 | 
			
		||||
		asoc->reconf_enable = !!params.assoc_value;
 | 
			
		||||
	} else if (!params.assoc_id) {
 | 
			
		||||
		struct sctp_sock *sp = sctp_sk(sk);
 | 
			
		||||
 | 
			
		||||
		sp->ep->reconf_enable = !!params.assoc_value;
 | 
			
		||||
	} else {
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	retval = 0;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int sctp_setsockopt_enable_strreset(struct sock *sk,
 | 
			
		||||
					   char __user *optval,
 | 
			
		||||
					   unsigned int optlen)
 | 
			
		||||
| 
						 | 
				
			
			@ -4038,6 +4071,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 | 
			
		|||
	case SCTP_DEFAULT_PRINFO:
 | 
			
		||||
		retval = sctp_setsockopt_default_prinfo(sk, optval, optlen);
 | 
			
		||||
		break;
 | 
			
		||||
	case SCTP_RECONFIG_SUPPORTED:
 | 
			
		||||
		retval = sctp_setsockopt_reconfig_supported(sk, optval, optlen);
 | 
			
		||||
		break;
 | 
			
		||||
	case SCTP_ENABLE_STREAM_RESET:
 | 
			
		||||
		retval = sctp_setsockopt_enable_strreset(sk, optval, optlen);
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -6540,6 +6576,47 @@ static int sctp_getsockopt_pr_assocstatus(struct sock *sk, int len,
 | 
			
		|||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int sctp_getsockopt_reconfig_supported(struct sock *sk, int len,
 | 
			
		||||
					      char __user *optval,
 | 
			
		||||
					      int __user *optlen)
 | 
			
		||||
{
 | 
			
		||||
	struct sctp_assoc_value params;
 | 
			
		||||
	struct sctp_association *asoc;
 | 
			
		||||
	int retval = -EFAULT;
 | 
			
		||||
 | 
			
		||||
	if (len < sizeof(params)) {
 | 
			
		||||
		retval = -EINVAL;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	len = sizeof(params);
 | 
			
		||||
	if (copy_from_user(¶ms, optval, len))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	asoc = sctp_id2assoc(sk, params.assoc_id);
 | 
			
		||||
	if (asoc) {
 | 
			
		||||
		params.assoc_value = asoc->reconf_enable;
 | 
			
		||||
	} else if (!params.assoc_id) {
 | 
			
		||||
		struct sctp_sock *sp = sctp_sk(sk);
 | 
			
		||||
 | 
			
		||||
		params.assoc_value = sp->ep->reconf_enable;
 | 
			
		||||
	} else {
 | 
			
		||||
		retval = -EINVAL;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (put_user(len, optlen))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	if (copy_to_user(optval, ¶ms, len))
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	retval = 0;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int sctp_getsockopt_enable_strreset(struct sock *sk, int len,
 | 
			
		||||
					   char __user *optval,
 | 
			
		||||
					   int __user *optlen)
 | 
			
		||||
| 
						 | 
				
			
			@ -6748,6 +6825,10 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
 | 
			
		|||
		retval = sctp_getsockopt_pr_assocstatus(sk, len, optval,
 | 
			
		||||
							optlen);
 | 
			
		||||
		break;
 | 
			
		||||
	case SCTP_RECONFIG_SUPPORTED:
 | 
			
		||||
		retval = sctp_getsockopt_reconfig_supported(sk, len, optval,
 | 
			
		||||
							    optlen);
 | 
			
		||||
		break;
 | 
			
		||||
	case SCTP_ENABLE_STREAM_RESET:
 | 
			
		||||
		retval = sctp_getsockopt_enable_strreset(sk, len, optval,
 | 
			
		||||
							 optlen);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -274,6 +274,13 @@ static struct ctl_table sctp_net_table[] = {
 | 
			
		|||
		.mode		= 0644,
 | 
			
		||||
		.proc_handler	= proc_dointvec,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		.procname	= "reconf_enable",
 | 
			
		||||
		.data		= &init_net.sctp.reconf_enable,
 | 
			
		||||
		.maxlen		= sizeof(int),
 | 
			
		||||
		.mode		= 0644,
 | 
			
		||||
		.proc_handler	= proc_dointvec,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		.procname	= "auth_enable",
 | 
			
		||||
		.data		= &init_net.sctp.auth_enable,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue