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 | 	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 | encap_port - INTEGER | ||||||
| 	The default remote UDP encapsulation port. | 	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); | 				void *buffer, size_t *lenp, loff_t *ppos); | ||||||
| static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer, | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void *buffer, | ||||||
| 				size_t *lenp, loff_t *ppos); | 				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, | static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write, | ||||||
| 				   void *buffer, size_t *lenp, loff_t *ppos); | 				   void *buffer, size_t *lenp, loff_t *ppos); | ||||||
| static int proc_sctp_do_auth(struct ctl_table *ctl, int write, | 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, | 		.mode		= 0644, | ||||||
| 		.proc_handler	= proc_dointvec, | 		.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", | 		.procname	= "encap_port", | ||||||
| 		.data		= &init_net.sctp.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; | 	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) | int sctp_sysctl_net_register(struct net *net) | ||||||
| { | { | ||||||
| 	struct ctl_table *table; | 	struct ctl_table *table; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Xin Long
						Xin Long