Commit 046c052b authored by Xin Long's avatar Xin Long Committed by Jakub Kicinski

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: default avatarXin Long <lucien.xin@gmail.com>
Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 1c16a186
...@@ -2642,6 +2642,21 @@ addr_scope_policy - INTEGER ...@@ -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, ...@@ -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[] = { ...@@ -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, ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment