mptcp: sysctl: set path manager by name
authorGeliang Tang <tanggeliang@kylinos.cn>
Thu, 13 Mar 2025 10:20:57 +0000 (11:20 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 20 Mar 2025 09:14:48 +0000 (10:14 +0100)
Similar to net.mptcp.scheduler, a new net.mptcp.path_manager sysctl knob
is added to determine which path manager will be used by each newly
created MPTCP socket by setting the name of it.

Dealing with an explicit name is easier than with a number, especially
when more PMs will be introduced.

This sysctl knob makes the old one "pm_type" deprecated.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250313-net-next-mptcp-pm-ops-intro-v1-8-f4e4a88efc50@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Documentation/networking/mptcp-sysctl.rst
net/mptcp/ctrl.c
net/mptcp/protocol.h

index 03e1d36..b78a225 100644 (file)
@@ -72,6 +72,23 @@ enabled - BOOLEAN
 
        Default: 1 (enabled)
 
+path_manager - STRING
+       Set the default path manager name 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.
+
+       * "kernel"          - In-kernel path manager
+       * "userspace"       - Userspace path manager
+
+       Default: "kernel"
+
 pm_type - INTEGER
        Set the default path manager type to use for each new MPTCP
        socket. In-kernel path management will control subflow
@@ -84,6 +101,8 @@ pm_type - INTEGER
 
        This is a per-namespace sysctl.
 
+       Deprecated since v6.15, use path_manager instead.
+
        * 0 - In-kernel path manager
        * 1 - Userspace path manager
 
index be6c023..4209dc7 100644 (file)
@@ -39,6 +39,7 @@ struct mptcp_pernet {
        u8 allow_join_initial_addr_port;
        u8 pm_type;
        char scheduler[MPTCP_SCHED_NAME_MAX];
+       char path_manager[MPTCP_PM_NAME_MAX];
 };
 
 static struct mptcp_pernet *mptcp_get_pernet(const struct net *net)
@@ -83,6 +84,11 @@ int mptcp_get_pm_type(const struct net *net)
        return mptcp_get_pernet(net)->pm_type;
 }
 
+const char *mptcp_get_path_manager(const struct net *net)
+{
+       return mptcp_get_pernet(net)->path_manager;
+}
+
 const char *mptcp_get_scheduler(const struct net *net)
 {
        return mptcp_get_pernet(net)->scheduler;
@@ -101,6 +107,7 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
        pernet->stale_loss_cnt = 4;
        pernet->pm_type = MPTCP_PM_TYPE_KERNEL;
        strscpy(pernet->scheduler, "default", sizeof(pernet->scheduler));
+       strscpy(pernet->path_manager, "kernel", sizeof(pernet->path_manager));
 }
 
 #ifdef CONFIG_SYSCTL
@@ -174,6 +181,42 @@ static int proc_blackhole_detect_timeout(const struct ctl_table *table,
        return ret;
 }
 
+static int mptcp_set_path_manager(char *path_manager, const char *name)
+{
+       struct mptcp_pm_ops *pm_ops;
+       int ret = 0;
+
+       rcu_read_lock();
+       pm_ops = mptcp_pm_find(name);
+       if (pm_ops)
+               strscpy(path_manager, name, MPTCP_PM_NAME_MAX);
+       else
+               ret = -ENOENT;
+       rcu_read_unlock();
+
+       return ret;
+}
+
+static int proc_path_manager(const struct ctl_table *ctl, int write,
+                            void *buffer, size_t *lenp, loff_t *ppos)
+{
+       char (*path_manager)[MPTCP_PM_NAME_MAX] = ctl->data;
+       char pm_name[MPTCP_PM_NAME_MAX];
+       const struct ctl_table tbl = {
+               .data = pm_name,
+               .maxlen = MPTCP_PM_NAME_MAX,
+       };
+       int ret;
+
+       strscpy(pm_name, *path_manager, MPTCP_PM_NAME_MAX);
+
+       ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
+       if (write && ret == 0)
+               ret = mptcp_set_path_manager(*path_manager, pm_name);
+
+       return ret;
+}
+
 static struct ctl_table mptcp_sysctl_table[] = {
        {
                .procname = "enabled",
@@ -253,6 +296,12 @@ static struct ctl_table mptcp_sysctl_table[] = {
                .mode = 0644,
                .proc_handler = proc_dou8vec_minmax,
        },
+       {
+               .procname = "path_manager",
+               .maxlen = MPTCP_PM_NAME_MAX,
+               .mode = 0644,
+               .proc_handler = proc_path_manager,
+       },
 };
 
 static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
@@ -278,6 +327,7 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
        table[8].data = &pernet->close_timeout;
        table[9].data = &pernet->blackhole_timeout;
        table[10].data = &pernet->syn_retrans_before_tcp_fallback;
+       table[11].data = &pernet->path_manager;
 
        hdr = register_net_sysctl_sz(net, MPTCP_SYSCTL_PATH, table,
                                     ARRAY_SIZE(mptcp_sysctl_table));
index c9e435a..818c2c6 100644 (file)
@@ -699,6 +699,7 @@ int mptcp_allow_join_id0(const struct net *net);
 unsigned int mptcp_stale_loss_cnt(const struct net *net);
 unsigned int mptcp_close_timeout(const struct sock *sk);
 int mptcp_get_pm_type(const struct net *net);
+const char *mptcp_get_path_manager(const struct net *net);
 const char *mptcp_get_scheduler(const struct net *net);
 
 void mptcp_active_disable(struct sock *sk);