netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mat Martineau <mathew.j.martineau@linux.intel.com>
To: netdev@vger.kernel.org, edumazet@google.com
Cc: Matthieu Baerts <matthieu.baerts@tessares.net>,
	cpaasch@apple.com, fw@strlen.de, pabeni@redhat.com,
	peter.krystad@linux.intel.com, dcaratti@redhat.com
Subject: [RFC PATCH v2 30/45] mptcp: new sysctl to control the activation per NS
Date: Wed,  2 Oct 2019 16:36:40 -0700	[thread overview]
Message-ID: <20191002233655.24323-31-mathew.j.martineau@linux.intel.com> (raw)
In-Reply-To: <20191002233655.24323-1-mathew.j.martineau@linux.intel.com>

From: Matthieu Baerts <matthieu.baerts@tessares.net>

New MPTCP sockets will return -ENOPROTOOPT if MPTCP support is disabled
for the current net namespace.

For security reasons, it is interesting to have a global switch for
MPTCP. To start, MPTCP will be disabled by default and only privileged
users will be able to modify this. The reason is that because MPTCP is
new, it will not be tested and reviewed by many and security issues can
then take time to be discovered and fixed.

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.

Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
---
 net/mptcp/Makefile   |   2 +-
 net/mptcp/ctrl.c     | 112 +++++++++++++++++++++++++++++++++++++++++++
 net/mptcp/protocol.c |  25 +++++-----
 net/mptcp/protocol.h |   4 ++
 4 files changed, 129 insertions(+), 14 deletions(-)
 create mode 100644 net/mptcp/ctrl.c

diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile
index 7fe7aa64eda0..289fdf4339c1 100644
--- a/net/mptcp/Makefile
+++ b/net/mptcp/Makefile
@@ -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 pm.o
+mptcp-y := protocol.o subflow.o options.o token.o crypto.o pm.o ctrl.o
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c
new file mode 100644
index 000000000000..8d9f15f02369
--- /dev/null
+++ b/net/mptcp/ctrl.c
@@ -0,0 +1,112 @@
+// 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 thi
+		 * value, same as other sysctl or the 'net' tree.
+		 */
+		.proc_handler = proc_dointvec,
+	},
+	{}
+};
+
+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);
+
+	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");
+}
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 8512cf5e0e0f..fa99337ca773 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -562,22 +562,21 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	return copied;
 }
 
-static int mptcp_init_sock(struct sock *sk)
+static int __mptcp_init_sock(struct sock *sk)
 {
 	struct mptcp_sock *msk = mptcp_sk(sk);
-	struct net *net = sock_net(sk);
-	struct socket *sf;
-	int err;
-
-	err = sock_create_kern(net, PF_INET, SOCK_STREAM, IPPROTO_TCP, &sf);
-	if (!err) {
-		pr_debug("subflow=%p", sf->sk);
-		msk->subflow = sf;
-	}
 
 	INIT_LIST_HEAD(&msk->conn_list);
 
-	return err;
+	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_close(struct sock *sk, long timeout)
@@ -646,7 +645,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;
@@ -1067,7 +1066,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;
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 16fe1c766d98..394f2477e6f8 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -204,11 +204,15 @@ mptcp_subflow_tcp_socket(const struct mptcp_subflow_context *subflow)
 	return subflow->tcp_sock;
 }
 
+int mptcp_is_enabled(struct net *net);
+
 void mptcp_subflow_init(void);
 int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock);
 
 extern const struct inet_connection_sock_af_ops ipv4_specific;
 
+void mptcp_proto_init(void);
+
 void mptcp_get_options(const struct sk_buff *skb,
 		       struct tcp_options_received *opt_rx);
 
-- 
2.23.0


  parent reply	other threads:[~2019-10-02 23:38 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-02 23:36 [RFC PATCH v2 00/45] Multipath TCP Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 01/45] tcp: Add MPTCP option number Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 02/45] net: Make sock protocol value checks more specific Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 03/45] sock: Make sk_protocol a 16-bit value Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 04/45] tcp: Define IPPROTO_MPTCP Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 05/45] mptcp: Add MPTCP socket stubs Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 06/45] mptcp: Handle MPTCP TCP options Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 07/45] mptcp: Associate MPTCP context with TCP socket Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 08/45] tcp: Expose tcp struct and routine for MPTCP Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 09/45] mptcp: Handle MP_CAPABLE options for outgoing connections Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 10/45] mptcp: add mptcp_poll Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 11/45] tcp, ulp: Add clone operation to tcp_ulp_ops Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 12/45] mptcp: Create SUBFLOW socket for incoming connections Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 13/45] mptcp: Add key generation and token tree Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 14/45] mptcp: Add shutdown() socket operation Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 15/45] mptcp: Add setsockopt()/getsockopt() socket operations Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 16/45] tcp: clean ext on tx recycle Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 17/45] mptcp: Add MPTCP to skb extensions Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 18/45] tcp: Prevent coalesce/collapse when skb has MPTCP extensions Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 19/45] tcp: Export low-level TCP functions Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 20/45] mptcp: Write MPTCP DSS headers to outgoing data packets Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 21/45] mptcp: Implement MPTCP receive path Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 22/45] mptcp: use sk_page_frag() in sendmsg Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 23/45] mptcp: sendmsg() do spool all the provided data Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 24/45] mptcp: allow collapsing consecutive sendpages on the same substream Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 25/45] tcp: Check for filled TCP option space before SACK Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 26/45] mptcp: Add path manager interface Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 27/45] mptcp: Add ADD_ADDR handling Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 28/45] mptcp: Add handling of incoming MP_JOIN requests Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 29/45] mptcp: harmonize locking on all socket operations Mat Martineau
2019-10-02 23:36 ` Mat Martineau [this message]
2019-10-02 23:36 ` [RFC PATCH v2 31/45] mptcp: add basic kselftest for mptcp Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 32/45] mptcp: Add handling of outgoing MP_JOIN requests Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 33/45] mptcp: Implement path manager interface commands Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 34/45] mptcp: Make MPTCP socket block/wakeup ignore sk_receive_queue Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 35/45] mptcp: update per unacked sequence on pkt reception Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 36/45] mptcp: queue data for mptcp level retransmission Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 37/45] mptcp: introduce MPTCP retransmission timer Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 38/45] mptcp: implement memory accounting for mptcp rtx queue Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 39/45] mptcp: rework mptcp_sendmsg_frag to accept optional dfrag Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 40/45] mptcp: implement and use MPTCP-level retransmission Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 41/45] selftests: mptcp: make tc delays random Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 42/45] selftests: mptcp: extend mptcp_connect tool for ipv6 family Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 43/45] selftests: mptcp: add accept/getpeer checks Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 44/45] selftests: mptcp: add ipv6 connectivity Mat Martineau
2019-10-02 23:36 ` [RFC PATCH v2 45/45] selftests: mptcp: random ethtool tweaking Mat Martineau
2019-10-02 23:53 ` [RFC PATCH v2 00/45] Multipath TCP Mat Martineau
2019-10-03  0:12 ` David Miller
2019-10-03  0:27   ` Mat Martineau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191002233655.24323-31-mathew.j.martineau@linux.intel.com \
    --to=mathew.j.martineau@linux.intel.com \
    --cc=cpaasch@apple.com \
    --cc=dcaratti@redhat.com \
    --cc=edumazet@google.com \
    --cc=fw@strlen.de \
    --cc=matthieu.baerts@tessares.net \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=peter.krystad@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).