mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-26 06:04:14 +08:00
mptcp: new sysctl to control the activation per NS
New MPTCP sockets will return -ENOPROTOOPT if MPTCP support is disabled for the current net namespace. We are providing here a way to control access to the feature for those that need to turn it on or off. The value of this new sysctl can be different per namespace. We can then restrict the usage of MPTCP to the selected NS. In case of serious issues with MPTCP, administrators can now easily turn MPTCP off. Co-developed-by: Peter Krystad <peter.krystad@linux.intel.com> Signed-off-by: Peter Krystad <peter.krystad@linux.intel.com> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Christoph Paasch <cpaasch@apple.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
57040755a3
commit
784325e9f0
@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_MPTCP) += mptcp.o
|
||||
|
||||
mptcp-y := protocol.o subflow.o options.o token.o crypto.o
|
||||
mptcp-y := protocol.o subflow.o options.o token.o crypto.o ctrl.o
|
||||
|
130
net/mptcp/ctrl.c
Normal file
130
net/mptcp/ctrl.c
Normal file
@ -0,0 +1,130 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Multipath TCP
|
||||
*
|
||||
* Copyright (c) 2019, Tessares SA.
|
||||
*/
|
||||
|
||||
#include <linux/sysctl.h>
|
||||
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/netns/generic.h>
|
||||
|
||||
#include "protocol.h"
|
||||
|
||||
#define MPTCP_SYSCTL_PATH "net/mptcp"
|
||||
|
||||
static int mptcp_pernet_id;
|
||||
struct mptcp_pernet {
|
||||
struct ctl_table_header *ctl_table_hdr;
|
||||
|
||||
int mptcp_enabled;
|
||||
};
|
||||
|
||||
static struct mptcp_pernet *mptcp_get_pernet(struct net *net)
|
||||
{
|
||||
return net_generic(net, mptcp_pernet_id);
|
||||
}
|
||||
|
||||
int mptcp_is_enabled(struct net *net)
|
||||
{
|
||||
return mptcp_get_pernet(net)->mptcp_enabled;
|
||||
}
|
||||
|
||||
static struct ctl_table mptcp_sysctl_table[] = {
|
||||
{
|
||||
.procname = "enabled",
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
/* users with CAP_NET_ADMIN or root (not and) can change this
|
||||
* value, same as other sysctl or the 'net' tree.
|
||||
*/
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
|
||||
{
|
||||
pernet->mptcp_enabled = 1;
|
||||
}
|
||||
|
||||
static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
|
||||
{
|
||||
struct ctl_table_header *hdr;
|
||||
struct ctl_table *table;
|
||||
|
||||
table = mptcp_sysctl_table;
|
||||
if (!net_eq(net, &init_net)) {
|
||||
table = kmemdup(table, sizeof(mptcp_sysctl_table), GFP_KERNEL);
|
||||
if (!table)
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
table[0].data = &pernet->mptcp_enabled;
|
||||
|
||||
hdr = register_net_sysctl(net, MPTCP_SYSCTL_PATH, table);
|
||||
if (!hdr)
|
||||
goto err_reg;
|
||||
|
||||
pernet->ctl_table_hdr = hdr;
|
||||
|
||||
return 0;
|
||||
|
||||
err_reg:
|
||||
if (!net_eq(net, &init_net))
|
||||
kfree(table);
|
||||
err_alloc:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void mptcp_pernet_del_table(struct mptcp_pernet *pernet)
|
||||
{
|
||||
struct ctl_table *table = pernet->ctl_table_hdr->ctl_table_arg;
|
||||
|
||||
unregister_net_sysctl_table(pernet->ctl_table_hdr);
|
||||
|
||||
kfree(table);
|
||||
}
|
||||
|
||||
static int __net_init mptcp_net_init(struct net *net)
|
||||
{
|
||||
struct mptcp_pernet *pernet = mptcp_get_pernet(net);
|
||||
|
||||
mptcp_pernet_set_defaults(pernet);
|
||||
|
||||
return mptcp_pernet_new_table(net, pernet);
|
||||
}
|
||||
|
||||
/* Note: the callback will only be called per extra netns */
|
||||
static void __net_exit mptcp_net_exit(struct net *net)
|
||||
{
|
||||
struct mptcp_pernet *pernet = mptcp_get_pernet(net);
|
||||
|
||||
mptcp_pernet_del_table(pernet);
|
||||
}
|
||||
|
||||
static struct pernet_operations mptcp_pernet_ops = {
|
||||
.init = mptcp_net_init,
|
||||
.exit = mptcp_net_exit,
|
||||
.id = &mptcp_pernet_id,
|
||||
.size = sizeof(struct mptcp_pernet),
|
||||
};
|
||||
|
||||
void __init mptcp_init(void)
|
||||
{
|
||||
mptcp_proto_init();
|
||||
|
||||
if (register_pernet_subsys(&mptcp_pernet_ops) < 0)
|
||||
panic("Failed to register MPTCP pernet subsystem.\n");
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
|
||||
int __init mptcpv6_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = mptcp_proto_v6_init();
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
@ -522,7 +522,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
|
||||
}
|
||||
}
|
||||
|
||||
static int mptcp_init_sock(struct sock *sk)
|
||||
static int __mptcp_init_sock(struct sock *sk)
|
||||
{
|
||||
struct mptcp_sock *msk = mptcp_sk(sk);
|
||||
|
||||
@ -532,6 +532,14 @@ static int mptcp_init_sock(struct sock *sk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mptcp_init_sock(struct sock *sk)
|
||||
{
|
||||
if (!mptcp_is_enabled(sock_net(sk)))
|
||||
return -ENOPROTOOPT;
|
||||
|
||||
return __mptcp_init_sock(sk);
|
||||
}
|
||||
|
||||
static void mptcp_subflow_shutdown(struct sock *ssk, int how)
|
||||
{
|
||||
lock_sock(ssk);
|
||||
@ -640,7 +648,7 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mptcp_init_sock(new_mptcp_sock);
|
||||
__mptcp_init_sock(new_mptcp_sock);
|
||||
|
||||
msk = mptcp_sk(new_mptcp_sock);
|
||||
msk->remote_key = subflow->remote_key;
|
||||
@ -1078,7 +1086,7 @@ static struct inet_protosw mptcp_protosw = {
|
||||
.flags = INET_PROTOSW_ICSK,
|
||||
};
|
||||
|
||||
void __init mptcp_init(void)
|
||||
void mptcp_proto_init(void)
|
||||
{
|
||||
mptcp_prot.h.hashinfo = tcp_prot.h.hashinfo;
|
||||
mptcp_stream_ops = inet_stream_ops;
|
||||
@ -1116,7 +1124,7 @@ static struct inet_protosw mptcp_v6_protosw = {
|
||||
.flags = INET_PROTOSW_ICSK,
|
||||
};
|
||||
|
||||
int mptcpv6_init(void)
|
||||
int mptcp_proto_v6_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -179,6 +179,9 @@ extern const struct inet_connection_sock_af_ops ipv6_specific;
|
||||
#endif
|
||||
|
||||
void mptcp_proto_init(void);
|
||||
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
|
||||
int mptcp_proto_v6_init(void);
|
||||
#endif
|
||||
|
||||
struct mptcp_read_arg {
|
||||
struct msghdr *msg;
|
||||
|
Loading…
Reference in New Issue
Block a user