@@ -89,6 +89,10 @@ path_manager - STRING
Default: "in-kernel"
+available_path_managers - STRING
+ Shows the available path managers choices that are registered. More
+ path managers may be available, but not loaded.
+
scheduler - STRING
Select the scheduler of your choice.
@@ -123,6 +123,8 @@ struct mptcp_sched_ops {
} ____cacheline_aligned_in_smp;
#define MPTCP_PM_NAME_MAX 16
+#define MPTCP_PM_MAX 128
+#define MPTCP_PM_BUF_MAX (MPTCP_PM_NAME_MAX * MPTCP_PM_MAX)
struct mptcp_pm_ops {
int (*created)(struct mptcp_sock *msk);
@@ -136,6 +136,24 @@ static int proc_path_manager(const struct ctl_table *ctl, int write,
return ret;
}
+static int proc_available_path_managers(const struct ctl_table *ctl,
+ int write, void *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ struct ctl_table tbl = { .maxlen = MPTCP_PM_BUF_MAX, };
+ int ret;
+
+ tbl.data = kmalloc(tbl.maxlen, GFP_USER);
+ if (!tbl.data)
+ return -ENOMEM;
+
+ mptcp_pm_get_available(tbl.data, MPTCP_PM_BUF_MAX);
+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
+ kfree(tbl.data);
+
+ return ret;
+}
+
static int mptcp_set_scheduler(char *scheduler, const char *name)
{
struct mptcp_sched_ops *sched;
@@ -252,6 +270,12 @@ static struct ctl_table mptcp_sysctl_table[] = {
.mode = 0644,
.proc_handler = proc_path_manager,
},
+ {
+ .procname = "available_path_managers",
+ .maxlen = MPTCP_PM_BUF_MAX,
+ .mode = 0444,
+ .proc_handler = proc_available_path_managers,
+ },
{
.procname = "scheduler",
.maxlen = MPTCP_SCHED_NAME_MAX,
@@ -304,6 +328,7 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
table[i++].data = &pernet->allow_join_initial_addr_port;
table[i++].data = &pernet->stale_loss_cnt;
table[i++].data = &pernet->path_manager;
+ i++; /* table[i] is for available_path_managers which is read-only info */
table[i++].data = &pernet->scheduler;
i++; /* table[i] is for available_schedulers which is read-only info */
table[i++].data = &pernet->close_timeout;
@@ -673,6 +673,26 @@ struct mptcp_pm_ops *mptcp_pm_find(const char *name)
return NULL;
}
+/* Build string with list of available path manager values.
+ * Similar to tcp_get_available_congestion_control()
+ */
+void mptcp_pm_get_available(char *buf, size_t maxlen)
+{
+ struct mptcp_pm_ops *pm;
+ size_t offs = 0;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(pm, &mptcp_pm_list, list) {
+ offs += snprintf(buf + offs, maxlen - offs,
+ "%s%s",
+ offs == 0 ? "" : " ", pm->name);
+
+ if (WARN_ON_ONCE(offs >= maxlen))
+ break;
+ }
+ rcu_read_unlock();
+}
+
int mptcp_pm_validate(struct mptcp_pm_ops *pm)
{
if (!pm->get_local_id || !pm->get_priority) {
@@ -1050,6 +1050,7 @@ void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
extern struct mptcp_pm_ops mptcp_in_kernel_pm;
struct mptcp_pm_ops *mptcp_pm_find(const char *name);
+void mptcp_pm_get_available(char *buf, size_t maxlen);
int mptcp_pm_validate(struct mptcp_pm_ops *pm);
int mptcp_pm_register(struct mptcp_pm_ops *pm);
void mptcp_pm_unregister(struct mptcp_pm_ops *pm);