forked from mirrors/linux
		
	sctp: enable udp tunneling socks
This patch is to enable udp tunneling socks by calling
sctp_udp_sock_start() in sctp_ctrlsock_init(), and
sctp_udp_sock_stop() in sctp_ctrlsock_exit().
Also add sysctl udp_port to allow changing the listening
sock's port by users.
Wit this patch, the whole sctp over udp feature can be
enabled and used.
v1->v2:
  - Also update ctl_sock udp_port in proc_sctp_do_udp_port()
    where netns udp_port gets changed.
v2->v3:
  - Call htons() when setting sk udp_port from netns udp_port.
v3->v4:
  - Not call sctp_udp_sock_start() when new_value is 0.
  - Add udp_port entry in ip-sysctl.rst.
v4->v5:
  - Not call sctp_udp_sock_start/stop() in sctp_ctrlsock_init/exit().
  - Improve the description of udp_port in ip-sysctl.rst.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									1c16a18625
								
							
						
					
					
						commit
						046c052b47
					
				
					 2 changed files with 67 additions and 0 deletions
				
			
		|  | @ -2642,6 +2642,21 @@ addr_scope_policy - INTEGER | |||
| 
 | ||||
| 	Default: 1 | ||||
| 
 | ||||
| udp_port - INTEGER | ||||
| 	The listening port for the local UDP tunneling sock. Normally it's | ||||
| 	using the IANA-assigned UDP port number 9899 (sctp-tunneling). | ||||
| 
 | ||||
| 	This UDP sock is used for processing the incoming UDP-encapsulated | ||||
| 	SCTP packets (from RFC6951), and shared by all applications in the | ||||
| 	same net namespace. This UDP sock will be closed when the value is | ||||
| 	set to 0. | ||||
| 
 | ||||
| 	The value will also be used to set the src port of the UDP header | ||||
| 	for the outgoing UDP-encapsulated SCTP packets. For the dest port, | ||||
| 	please refer to 'encap_port' below. | ||||
| 
 | ||||
| 	Default: 0 | ||||
| 
 | ||||
| encap_port - INTEGER | ||||
| 	The default remote UDP encapsulation port. | ||||
| 
 | ||||
|  |  | |||
|  | @ -49,6 +49,8 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | |||
| 				void *buffer, size_t *lenp, loff_t *ppos); | ||||
| static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer, | ||||
| 				size_t *lenp, loff_t *ppos); | ||||
| static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write, void *buffer, | ||||
| 				 size_t *lenp, loff_t *ppos); | ||||
| static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, | ||||
| 				   void *buffer, size_t *lenp, loff_t *ppos); | ||||
| static int proc_sctp_do_auth(struct ctl_table *ctl, int write, | ||||
|  | @ -291,6 +293,15 @@ static struct ctl_table sctp_net_table[] = { | |||
| 		.mode		= 0644, | ||||
| 		.proc_handler	= proc_dointvec, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.procname	= "udp_port", | ||||
| 		.data		= &init_net.sctp.udp_port, | ||||
| 		.maxlen		= sizeof(int), | ||||
| 		.mode		= 0644, | ||||
| 		.proc_handler	= proc_sctp_do_udp_port, | ||||
| 		.extra1		= SYSCTL_ZERO, | ||||
| 		.extra2		= &udp_port_max, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.procname	= "encap_port", | ||||
| 		.data		= &init_net.sctp.encap_port, | ||||
|  | @ -487,6 +498,47 @@ static int proc_sctp_do_auth(struct ctl_table *ctl, int write, | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write, | ||||
| 				 void *buffer, size_t *lenp, loff_t *ppos) | ||||
| { | ||||
| 	struct net *net = current->nsproxy->net_ns; | ||||
| 	unsigned int min = *(unsigned int *)ctl->extra1; | ||||
| 	unsigned int max = *(unsigned int *)ctl->extra2; | ||||
| 	struct ctl_table tbl; | ||||
| 	int ret, new_value; | ||||
| 
 | ||||
| 	memset(&tbl, 0, sizeof(struct ctl_table)); | ||||
| 	tbl.maxlen = sizeof(unsigned int); | ||||
| 
 | ||||
| 	if (write) | ||||
| 		tbl.data = &new_value; | ||||
| 	else | ||||
| 		tbl.data = &net->sctp.udp_port; | ||||
| 
 | ||||
| 	ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||||
| 	if (write && ret == 0) { | ||||
| 		struct sock *sk = net->sctp.ctl_sock; | ||||
| 
 | ||||
| 		if (new_value > max || new_value < min) | ||||
| 			return -EINVAL; | ||||
| 
 | ||||
| 		net->sctp.udp_port = new_value; | ||||
| 		sctp_udp_sock_stop(net); | ||||
| 		if (new_value) { | ||||
| 			ret = sctp_udp_sock_start(net); | ||||
| 			if (ret) | ||||
| 				net->sctp.udp_port = 0; | ||||
| 		} | ||||
| 
 | ||||
| 		/* Update the value in the control socket */ | ||||
| 		lock_sock(sk); | ||||
| 		sctp_sk(sk)->udp_port = htons(net->sctp.udp_port); | ||||
| 		release_sock(sk); | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| int sctp_sysctl_net_register(struct net *net) | ||||
| { | ||||
| 	struct ctl_table *table; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Xin Long
						Xin Long