mptcp: Add a per-namespace sysctl to set the default path manager type
authorMat Martineau <mathew.j.martineau@linux.intel.com>
Wed, 27 Apr 2022 22:50:01 +0000 (15:50 -0700)
committerJakub Kicinski <kuba@kernel.org>
Sat, 30 Apr 2022 00:25:14 +0000 (17:25 -0700)
The new net.mptcp.pm_type sysctl determines which path manager will be
used by each newly-created MPTCP socket.

v2: Handle builds without CONFIG_SYSCTL
v3: Clarify logic for type-specific PM init (Geliang Tang and Paolo Abeni)

Acked-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Documentation/networking/mptcp-sysctl.rst
net/mptcp/ctrl.c
net/mptcp/pm.c
net/mptcp/protocol.h

index b0d4da71e68efb62f825e104bb3cde2aefed4a85..e263dfcc4b402f45fc606f24c9b56b8b8c11f84f 100644 (file)
@@ -46,6 +46,24 @@ allow_join_initial_addr_port - BOOLEAN
 
        Default: 1
 
+pm_type - INTEGER
+
+       Set the default path manager type to use for each new MPTCP
+       socket. In-kernel path management will control subflow
+       connections and address advertisements according to
+       per-namespace values configured over the MPTCP netlink
+       API. Userspace path management puts per-MPTCP-connection subflow
+       connection decisions and address advertisements under control of
+       a privileged userspace program, at the cost of more netlink
+       traffic to propagate all of the related events and commands.
+
+       This is a per-namespace sysctl.
+
+       * 0 - In-kernel path manager
+       * 1 - Userspace path manager
+
+       Default: 0
+
 stale_loss_cnt - INTEGER
        The number of MPTCP-level retransmission intervals with no traffic and
        pending outstanding data on a given subflow required to declare it stale.
index 8b235468c88ffa0847465ce20cec22c5338de888..ae20b7d92e288bffae7e4fe4dfa6a45b8f6100e7 100644 (file)
 #define MPTCP_SYSCTL_PATH "net/mptcp"
 
 static int mptcp_pernet_id;
+
+#ifdef CONFIG_SYSCTL
+static int mptcp_pm_type_max = __MPTCP_PM_TYPE_MAX;
+#endif
+
 struct mptcp_pernet {
 #ifdef CONFIG_SYSCTL
        struct ctl_table_header *ctl_table_hdr;
@@ -26,6 +31,7 @@ struct mptcp_pernet {
        u8 mptcp_enabled;
        u8 checksum_enabled;
        u8 allow_join_initial_addr_port;
+       u8 pm_type;
 };
 
 static struct mptcp_pernet *mptcp_get_pernet(const struct net *net)
@@ -58,6 +64,11 @@ unsigned int mptcp_stale_loss_cnt(const struct net *net)
        return mptcp_get_pernet(net)->stale_loss_cnt;
 }
 
+int mptcp_get_pm_type(const struct net *net)
+{
+       return mptcp_get_pernet(net)->pm_type;
+}
+
 static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
 {
        pernet->mptcp_enabled = 1;
@@ -65,6 +76,7 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
        pernet->checksum_enabled = 0;
        pernet->allow_join_initial_addr_port = 1;
        pernet->stale_loss_cnt = 4;
+       pernet->pm_type = MPTCP_PM_TYPE_KERNEL;
 }
 
 #ifdef CONFIG_SYSCTL
@@ -108,6 +120,14 @@ static struct ctl_table mptcp_sysctl_table[] = {
                .mode = 0644,
                .proc_handler = proc_douintvec_minmax,
        },
+       {
+               .procname = "pm_type",
+               .maxlen = sizeof(u8),
+               .mode = 0644,
+               .proc_handler = proc_dou8vec_minmax,
+               .extra1       = SYSCTL_ZERO,
+               .extra2       = &mptcp_pm_type_max
+       },
        {}
 };
 
@@ -128,6 +148,7 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
        table[2].data = &pernet->checksum_enabled;
        table[3].data = &pernet->allow_join_initial_addr_port;
        table[4].data = &pernet->stale_loss_cnt;
+       table[5].data = &pernet->pm_type;
 
        hdr = register_net_sysctl(net, MPTCP_SYSCTL_PATH, table);
        if (!hdr)
index 5320270b3926fa9ebadc3f2b8dc27d846efd428b..57f67578a47fdaffb387b79af6ff4d8a06d24dc3 100644 (file)
@@ -415,7 +415,7 @@ void mptcp_pm_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk)
 
 void mptcp_pm_data_reset(struct mptcp_sock *msk)
 {
-       bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk);
+       u8 pm_type = mptcp_get_pm_type(sock_net((struct sock *)msk));
        struct mptcp_pm_data *pm = &msk->pm;
 
        pm->add_addr_signaled = 0;
@@ -424,17 +424,29 @@ void mptcp_pm_data_reset(struct mptcp_sock *msk)
        pm->subflows = 0;
        pm->rm_list_tx.nr = 0;
        pm->rm_list_rx.nr = 0;
-       WRITE_ONCE(pm->pm_type, MPTCP_PM_TYPE_KERNEL);
-       /* pm->work_pending must be only be set to 'true' when
-        * pm->pm_type is set to MPTCP_PM_TYPE_KERNEL
-        */
-       WRITE_ONCE(pm->work_pending,
-                  (!!mptcp_pm_get_local_addr_max(msk) && subflows_allowed) ||
-                  !!mptcp_pm_get_add_addr_signal_max(msk));
+       WRITE_ONCE(pm->pm_type, pm_type);
+
+       if (pm_type == MPTCP_PM_TYPE_KERNEL) {
+               bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk);
+
+               /* pm->work_pending must be only be set to 'true' when
+                * pm->pm_type is set to MPTCP_PM_TYPE_KERNEL
+                */
+               WRITE_ONCE(pm->work_pending,
+                          (!!mptcp_pm_get_local_addr_max(msk) &&
+                           subflows_allowed) ||
+                          !!mptcp_pm_get_add_addr_signal_max(msk));
+               WRITE_ONCE(pm->accept_addr,
+                          !!mptcp_pm_get_add_addr_accept_max(msk) &&
+                          subflows_allowed);
+               WRITE_ONCE(pm->accept_subflow, subflows_allowed);
+       } else {
+               WRITE_ONCE(pm->work_pending, 0);
+               WRITE_ONCE(pm->accept_addr, 0);
+               WRITE_ONCE(pm->accept_subflow, 0);
+       }
+
        WRITE_ONCE(pm->addr_signal, 0);
-       WRITE_ONCE(pm->accept_addr,
-                  !!mptcp_pm_get_add_addr_accept_max(msk) && subflows_allowed);
-       WRITE_ONCE(pm->accept_subflow, subflows_allowed);
        WRITE_ONCE(pm->remote_deny_join_id0, false);
        pm->status = 0;
        bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
index 79606e9d3f2ad11727cc79857f767a48664d2dc6..54d2b3b2d1001a83daae69c538cd12c87191d6c0 100644 (file)
@@ -585,6 +585,7 @@ unsigned int mptcp_get_add_addr_timeout(const struct net *net);
 int mptcp_is_checksum_enabled(const struct net *net);
 int mptcp_allow_join_id0(const struct net *net);
 unsigned int mptcp_stale_loss_cnt(const struct net *net);
+int mptcp_get_pm_type(const struct net *net);
 void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
                                     struct mptcp_options_received *mp_opt);
 bool __mptcp_retransmit_pending_data(struct sock *sk);