diff options
Diffstat (limited to 'net/sctp/sysctl.c')
| -rw-r--r-- | net/sctp/sysctl.c | 55 | 
1 files changed, 45 insertions, 10 deletions
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 35c8923b5554..7e5eb7554990 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -64,6 +64,9 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,  static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,  				void __user *buffer, size_t *lenp,  				loff_t *ppos); +static int proc_sctp_do_auth(struct ctl_table *ctl, int write, +			     void __user *buffer, size_t *lenp, +			     loff_t *ppos);  static struct ctl_table sctp_table[] = {  	{ @@ -266,7 +269,7 @@ static struct ctl_table sctp_net_table[] = {  		.data		= &init_net.sctp.auth_enable,  		.maxlen		= sizeof(int),  		.mode		= 0644, -		.proc_handler	= proc_dointvec, +		.proc_handler	= proc_sctp_do_auth,  	},  	{  		.procname	= "addr_scope_policy", @@ -400,22 +403,54 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,  	return ret;  } -int sctp_sysctl_net_register(struct net *net) +static int proc_sctp_do_auth(struct ctl_table *ctl, int write, +			     void __user *buffer, size_t *lenp, +			     loff_t *ppos)  { -	struct ctl_table *table = sctp_net_table; +	struct net *net = current->nsproxy->net_ns; +	struct ctl_table tbl; +	int new_value, ret; + +	memset(&tbl, 0, sizeof(struct ctl_table)); +	tbl.maxlen = sizeof(unsigned int); -	if (!net_eq(net, &init_net)) { -		int i; +	if (write) +		tbl.data = &new_value; +	else +		tbl.data = &net->sctp.auth_enable; -		table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); -		if (!table) -			return -ENOMEM; +	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); -		for (i = 0; table[i].data; i++) -			table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; +	if (write) { +		struct sock *sk = net->sctp.ctl_sock; + +		net->sctp.auth_enable = new_value; +		/* Update the value in the control socket */ +		lock_sock(sk); +		sctp_sk(sk)->ep->auth_enable = new_value; +		release_sock(sk);  	} +	return ret; +} + +int sctp_sysctl_net_register(struct net *net) +{ +	struct ctl_table *table; +	int i; + +	table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); +	if (!table) +		return -ENOMEM; + +	for (i = 0; table[i].data; i++) +		table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp; +  	net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table); +	if (net->sctp.sysctl_header == NULL) { +		kfree(table); +		return -ENOMEM; +	}  	return 0;  }  |