adfd671676
Long ago we set out to remove the kitchen sink on kernel/sysctl.c arrays and placings sysctls to their own sybsystem or file to help avoid merge conflicts. Matthew Wilcox pointed out though that if we're going to do that we might as well also *save* space while at it and try to remove the extra last sysctl entry added at the end of each array, a sentintel, instead of bloating the kernel by adding a new sentinel with each array moved. Doing that was not so trivial, and has required slowing down the moves of kernel/sysctl.c arrays and measuring the impact on size by each new move. The complex part of the effort to help reduce the size of each sysctl is being done by the patient work of el señor Don Joel Granados. A lot of this is truly painful code refactoring and testing and then trying to measure the savings of each move and removing the sentinels. Although Joel already has code which does most of this work, experience with sysctl moves in the past shows is we need to be careful due to the slew of odd build failures that are possible due to the amount of random Kconfig options sysctls use. To that end Joel's work is split by first addressing the major housekeeping needed to remove the sentinels, which is part of this merge request. The rest of the work to actually remove the sentinels will be done later in future kernel releases. At first I was only going to send his first 7 patches of his patch series, posted 1 month ago, but in retrospect due to the testing the changes have received in linux-next and the minor changes they make this goes with the entire set of patches Joel had planned: just sysctl house keeping. There are networking changes but these are part of the house keeping too. The preliminary math is showing this will all help reduce the overall build time size of the kernel and run time memory consumed by the kernel by about ~64 bytes per array where we are able to remove each sentinel in the future. That also means there is no more bloating the kernel with the extra ~64 bytes per array moved as no new sentinels are created. Most of this has been in linux-next for about a month, the last 7 patches took a minor refresh 2 week ago based on feedback. -----BEGIN PGP SIGNATURE----- iQJGBAABCgAwFiEENnNq2KuOejlQLZofziMdCjCSiKcFAmTuVnMSHG1jZ3JvZkBr ZXJuZWwub3JnAAoJEM4jHQowkoinIckP/imvRlfkO6L0IP7MmJBRPtwY01rsTAKO Q14dZ//bG4DVQeGl1FdzrF6hhuLgekU0qW1YDFIWiCXO7CbaxaNBPSUkeW6ReVoC R/VHNUPxSR1PWQy1OTJV2t4XKri2sB7ijmUsfsATtISwhei9bggTHEysShtP4tv+ U87DzhoqMnbYIsfMo49KCqOa1Qm7TmjC1a7WAp6Fph3GJuXAzZR5pXpsd0NtOZ9x Ud5RT22icnQpMl7K+yPsqY6XcS5JkgBe/WbSzMAUkYZvBZFBq9t2D+OW5h9TZMhw piJWQ9X0Rm7qI2D15mJfXwaOhhyDhWci391hzdJmS6DI0prf6Ma2NFdAWOt/zomI uiRujS4bGeBUaK5F4TX2WQ1+jdMtAZ+0FncFnzt4U8q7dzUc91uVCm6iHW3gcfAb N7OEg2ZL0gkkgCZHqKxN8wpNQiC2KwnNk+HLAbnL2a/oJYfBtdopQmlxWfrN2hpF xxROiENqk483BRdMXDq6DR/gyDZmZWCobXIglSzlqCOjCOcLbDziIJ7pJk83ok09 h/QnXTYHf9protBq9OIQesgh2pwNzBBLifK84KZLKcb7IbdIKjpQrW5STp04oNGf wcGJzEz8tXUe0UKyMM47AcHQGzIy6cdXNLjyF8a+m7rnZzr1ndnMqZyRStZzuQin AUg2VWHKPmW9 =sq2p -----END PGP SIGNATURE----- Merge tag 'sysctl-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux Pull sysctl updates from Luis Chamberlain: "Long ago we set out to remove the kitchen sink on kernel/sysctl.c arrays and placings sysctls to their own sybsystem or file to help avoid merge conflicts. Matthew Wilcox pointed out though that if we're going to do that we might as well also *save* space while at it and try to remove the extra last sysctl entry added at the end of each array, a sentintel, instead of bloating the kernel by adding a new sentinel with each array moved. Doing that was not so trivial, and has required slowing down the moves of kernel/sysctl.c arrays and measuring the impact on size by each new move. The complex part of the effort to help reduce the size of each sysctl is being done by the patient work of el señor Don Joel Granados. A lot of this is truly painful code refactoring and testing and then trying to measure the savings of each move and removing the sentinels. Although Joel already has code which does most of this work, experience with sysctl moves in the past shows is we need to be careful due to the slew of odd build failures that are possible due to the amount of random Kconfig options sysctls use. To that end Joel's work is split by first addressing the major housekeeping needed to remove the sentinels, which is part of this merge request. The rest of the work to actually remove the sentinels will be done later in future kernel releases. The preliminary math is showing this will all help reduce the overall build time size of the kernel and run time memory consumed by the kernel by about ~64 bytes per array where we are able to remove each sentinel in the future. That also means there is no more bloating the kernel with the extra ~64 bytes per array moved as no new sentinels are created" * tag 'sysctl-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux: sysctl: Use ctl_table_size as stopping criteria for list macro sysctl: SIZE_MAX->ARRAY_SIZE in register_net_sysctl vrf: Update to register_net_sysctl_sz networking: Update to register_net_sysctl_sz netfilter: Update to register_net_sysctl_sz ax.25: Update to register_net_sysctl_sz sysctl: Add size to register_net_sysctl function sysctl: Add size arg to __register_sysctl_init sysctl: Add size to register_sysctl sysctl: Add a size arg to __register_sysctl_table sysctl: Add size argument to init_header sysctl: Add ctl_table_size to ctl_table_header sysctl: Use ctl_table_header in list_for_each_table_entry sysctl: Prefer ctl_table_header in proc_sysctl
246 lines
5.2 KiB
C
246 lines
5.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/* Multipath TCP
|
|
*
|
|
* Copyright (c) 2019, Tessares SA.
|
|
*/
|
|
|
|
#ifdef CONFIG_SYSCTL
|
|
#include <linux/sysctl.h>
|
|
#endif
|
|
|
|
#include <net/net_namespace.h>
|
|
#include <net/netns/generic.h>
|
|
|
|
#include "protocol.h"
|
|
|
|
#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;
|
|
#endif
|
|
|
|
unsigned int add_addr_timeout;
|
|
unsigned int stale_loss_cnt;
|
|
u8 mptcp_enabled;
|
|
u8 checksum_enabled;
|
|
u8 allow_join_initial_addr_port;
|
|
u8 pm_type;
|
|
char scheduler[MPTCP_SCHED_NAME_MAX];
|
|
};
|
|
|
|
static struct mptcp_pernet *mptcp_get_pernet(const struct net *net)
|
|
{
|
|
return net_generic(net, mptcp_pernet_id);
|
|
}
|
|
|
|
int mptcp_is_enabled(const struct net *net)
|
|
{
|
|
return mptcp_get_pernet(net)->mptcp_enabled;
|
|
}
|
|
|
|
unsigned int mptcp_get_add_addr_timeout(const struct net *net)
|
|
{
|
|
return mptcp_get_pernet(net)->add_addr_timeout;
|
|
}
|
|
|
|
int mptcp_is_checksum_enabled(const struct net *net)
|
|
{
|
|
return mptcp_get_pernet(net)->checksum_enabled;
|
|
}
|
|
|
|
int mptcp_allow_join_id0(const struct net *net)
|
|
{
|
|
return mptcp_get_pernet(net)->allow_join_initial_addr_port;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
const char *mptcp_get_scheduler(const struct net *net)
|
|
{
|
|
return mptcp_get_pernet(net)->scheduler;
|
|
}
|
|
|
|
static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
|
|
{
|
|
pernet->mptcp_enabled = 1;
|
|
pernet->add_addr_timeout = TCP_RTO_MAX;
|
|
pernet->checksum_enabled = 0;
|
|
pernet->allow_join_initial_addr_port = 1;
|
|
pernet->stale_loss_cnt = 4;
|
|
pernet->pm_type = MPTCP_PM_TYPE_KERNEL;
|
|
strcpy(pernet->scheduler, "default");
|
|
}
|
|
|
|
#ifdef CONFIG_SYSCTL
|
|
static struct ctl_table mptcp_sysctl_table[] = {
|
|
{
|
|
.procname = "enabled",
|
|
.maxlen = sizeof(u8),
|
|
.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_dou8vec_minmax,
|
|
.extra1 = SYSCTL_ZERO,
|
|
.extra2 = SYSCTL_ONE
|
|
},
|
|
{
|
|
.procname = "add_addr_timeout",
|
|
.maxlen = sizeof(unsigned int),
|
|
.mode = 0644,
|
|
.proc_handler = proc_dointvec_jiffies,
|
|
},
|
|
{
|
|
.procname = "checksum_enabled",
|
|
.maxlen = sizeof(u8),
|
|
.mode = 0644,
|
|
.proc_handler = proc_dou8vec_minmax,
|
|
.extra1 = SYSCTL_ZERO,
|
|
.extra2 = SYSCTL_ONE
|
|
},
|
|
{
|
|
.procname = "allow_join_initial_addr_port",
|
|
.maxlen = sizeof(u8),
|
|
.mode = 0644,
|
|
.proc_handler = proc_dou8vec_minmax,
|
|
.extra1 = SYSCTL_ZERO,
|
|
.extra2 = SYSCTL_ONE
|
|
},
|
|
{
|
|
.procname = "stale_loss_cnt",
|
|
.maxlen = sizeof(unsigned int),
|
|
.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
|
|
},
|
|
{
|
|
.procname = "scheduler",
|
|
.maxlen = MPTCP_SCHED_NAME_MAX,
|
|
.mode = 0644,
|
|
.proc_handler = proc_dostring,
|
|
},
|
|
{}
|
|
};
|
|
|
|
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;
|
|
table[1].data = &pernet->add_addr_timeout;
|
|
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;
|
|
table[6].data = &pernet->scheduler;
|
|
|
|
hdr = register_net_sysctl_sz(net, MPTCP_SYSCTL_PATH, table,
|
|
ARRAY_SIZE(mptcp_sysctl_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);
|
|
}
|
|
|
|
#else
|
|
|
|
static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static void mptcp_pernet_del_table(struct mptcp_pernet *pernet) {}
|
|
|
|
#endif /* CONFIG_SYSCTL */
|
|
|
|
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_join_cookie_init();
|
|
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
|