From: wen.yang@linux.dev
To: Joel Granados <joel.granados@kernel.org>
Cc: Wen Yang <wen.yang@linux.dev>,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH 31/39] ipvs: derive sysctl ownership from numeric storage
Date: Thu, 29 Oct 2026 00:35:10 +0800 [thread overview]
Message-ID: <36ed716eb067114083b25e360443624ad2a63261.1793204511.git.wen.yang@linux.dev> (raw)
In-Reply-To: <cover.1793204511.git.wen.yang@linux.dev>
From: Wen Yang <wen.yang@linux.dev>
Derive IPVS ownership from each sysctl field instead of extra pointers.
Suggested-by: Joel Granados <joel.granados@kernel.org>
Signed-off-by: Wen Yang <wen.yang@linux.dev>
---
net/netfilter/ipvs/ip_vs_ctl.c | 156 +++++++++++++++++++--------------
1 file changed, 88 insertions(+), 68 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 6c29a901d139..ed8e641da2ae 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -16,7 +16,6 @@
#define pr_fmt(fmt) "IPVS: " fmt
#include <linux/module.h>
-#include <linux/limits.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/capability.h>
@@ -2375,6 +2374,8 @@ proc_do_conn_max(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
int *valp = table->data;
+ struct netns_ipvs *ipvs = container_of(valp, struct netns_ipvs,
+ sysctl_conn_max);
/* We can not use *valp to check if new value is provided, use INT_MIN
* for this because different admins change different limits.
*/
@@ -2382,14 +2383,13 @@ proc_do_conn_max(const struct ctl_table *table, int write,
int val = write ? unset : READ_ONCE(*valp);
int rc;
- const struct ctl_table tmp = {
- .data = &val,
- .maxlen = sizeof(int),
- };
+ struct ctl_table tmp = *table;
+
+ tmp.data = &val;
+ tmp.maxlen = sizeof(val);
rc = proc_dointvec(&tmp, write, buffer, lenp, ppos);
if (write && !rc && val != unset) {
- struct netns_ipvs *ipvs = table->extra2;
bool priv = capable(CAP_NET_ADMIN);
int max;
@@ -2410,19 +2410,17 @@ proc_do_conn_max(const struct ctl_table *table, int write,
}
static int
-proc_do_defense_mode(const struct ctl_table *table, int write,
- void *buffer, size_t *lenp, loff_t *ppos)
+proc_do_defense_mode(struct netns_ipvs *ipvs, const struct ctl_table *table,
+ int write, void *buffer, size_t *lenp, loff_t *ppos)
{
- struct netns_ipvs *ipvs = table->extra2;
int *valp = table->data;
int val = *valp;
int rc;
- struct ctl_table tmp = {
- .data = &val,
- .maxlen = sizeof(int),
- .mode = table->mode,
- };
+ struct ctl_table tmp = *table;
+
+ tmp.data = &val;
+ tmp.maxlen = sizeof(val);
rc = proc_dointvec(&tmp, write, buffer, lenp, ppos);
if (write && (*valp != val)) {
@@ -2436,19 +2434,49 @@ proc_do_defense_mode(const struct ctl_table *table, int write,
return rc;
}
+static int proc_do_drop_entry(const struct ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ int *valp = table->data;
+ struct netns_ipvs *ipvs = container_of(valp, struct netns_ipvs,
+ sysctl_drop_entry);
+
+ return proc_do_defense_mode(ipvs, table, write, buffer, lenp, ppos);
+}
+
+static int proc_do_drop_packet(const struct ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ int *valp = table->data;
+ struct netns_ipvs *ipvs = container_of(valp, struct netns_ipvs,
+ sysctl_drop_packet);
+
+ return proc_do_defense_mode(ipvs, table, write, buffer, lenp, ppos);
+}
+
+static int proc_do_secure_tcp(const struct ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ int *valp = table->data;
+ struct netns_ipvs *ipvs = container_of(valp, struct netns_ipvs,
+ sysctl_secure_tcp);
+
+ return proc_do_defense_mode(ipvs, table, write, buffer, lenp, ppos);
+}
+
static int
proc_do_sync_threshold(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
- struct netns_ipvs *ipvs = table->extra2;
- int *valp = table->data;
+ int (*valp)[2] = table->data;
+ struct netns_ipvs *ipvs = container_of(valp, struct netns_ipvs,
+ sysctl_sync_threshold);
int val[2];
int rc;
- struct ctl_table tmp = {
- .data = &val,
- .maxlen = table->maxlen,
- .mode = table->mode,
- };
+ struct ctl_table tmp = *table;
+
+ tmp.data = val;
+ tmp.maxlen = sizeof(val);
mutex_lock(&ipvs->sync_mutex);
memcpy(val, valp, sizeof(val));
@@ -2475,11 +2503,10 @@ proc_do_sync_ports(const struct ctl_table *table, int write,
int val = *valp;
int rc;
- struct ctl_table tmp = {
- .data = &val,
- .maxlen = sizeof(int),
- .mode = table->mode,
- };
+ struct ctl_table tmp = *table;
+
+ tmp.data = &val;
+ tmp.maxlen = sizeof(val);
rc = proc_dointvec(&tmp, write, buffer, lenp, ppos);
if (write && (*valp != val)) {
@@ -2494,8 +2521,9 @@ proc_do_sync_ports(const struct ctl_table *table, int write,
static int ipvs_proc_est_cpumask_set(const struct ctl_table *table,
void *buffer)
{
- struct netns_ipvs *ipvs = table->extra2;
cpumask_var_t *valp = table->data;
+ struct netns_ipvs *ipvs = container_of(valp, struct netns_ipvs,
+ sysctl_est_cpulist);
cpumask_var_t newmask;
int ret;
@@ -2533,8 +2561,9 @@ static int ipvs_proc_est_cpumask_set(const struct ctl_table *table,
static int ipvs_proc_est_cpumask_get(const struct ctl_table *table,
void *buffer, size_t size)
{
- struct netns_ipvs *ipvs = table->extra2;
cpumask_var_t *valp = table->data;
+ struct netns_ipvs *ipvs = container_of(valp, struct netns_ipvs,
+ sysctl_est_cpulist);
struct cpumask *mask;
int ret;
@@ -2584,16 +2613,16 @@ static int ipvs_proc_est_cpulist(const struct ctl_table *table, int write,
static int ipvs_proc_est_nice(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
- struct netns_ipvs *ipvs = table->extra2;
int *valp = table->data;
+ struct netns_ipvs *ipvs = container_of(valp, struct netns_ipvs,
+ sysctl_est_nice);
int val = *valp;
int ret;
- struct ctl_table tmp_table = {
- .data = &val,
- .maxlen = sizeof(int),
- .mode = table->mode,
- };
+ struct ctl_table tmp_table = *table;
+
+ tmp_table.data = &val;
+ tmp_table.maxlen = sizeof(val);
ret = proc_dointvec(&tmp_table, write, buffer, lenp, ppos);
if (write && ret >= 0) {
@@ -2614,16 +2643,16 @@ static int ipvs_proc_est_nice(const struct ctl_table *table, int write,
static int ipvs_proc_run_estimation(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
- struct netns_ipvs *ipvs = table->extra2;
int *valp = table->data;
+ struct netns_ipvs *ipvs = container_of(valp, struct netns_ipvs,
+ sysctl_run_estimation);
int val = *valp;
int ret;
- struct ctl_table tmp_table = {
- .data = &val,
- .maxlen = sizeof(int),
- .mode = table->mode,
- };
+ struct ctl_table tmp_table = *table;
+
+ tmp_table.data = &val;
+ tmp_table.maxlen = sizeof(val);
ret = proc_dointvec(&tmp_table, write, buffer, lenp, ppos);
if (write && ret >= 0) {
@@ -2640,15 +2669,16 @@ static int ipvs_proc_run_estimation(const struct ctl_table *table, int write,
static int ipvs_proc_conn_lfactor(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
- struct netns_ipvs *ipvs = table->extra2;
int *valp = table->data;
+ struct netns_ipvs *ipvs = container_of(valp, struct netns_ipvs,
+ sysctl_conn_lfactor);
int val = *valp;
int ret;
- struct ctl_table tmp_table = {
- .data = &val,
- .maxlen = sizeof(int),
- };
+ struct ctl_table tmp_table = *table;
+
+ tmp_table.data = &val;
+ tmp_table.maxlen = sizeof(val);
ret = proc_dointvec(&tmp_table, write, buffer, lenp, ppos);
if (write && ret >= 0) {
@@ -2667,15 +2697,16 @@ static int ipvs_proc_conn_lfactor(const struct ctl_table *table, int write,
static int ipvs_proc_svc_lfactor(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
- struct netns_ipvs *ipvs = table->extra2;
int *valp = table->data;
+ struct netns_ipvs *ipvs = container_of(valp, struct netns_ipvs,
+ sysctl_svc_lfactor);
int val = *valp;
int ret;
- struct ctl_table tmp_table = {
- .data = &val,
- .maxlen = sizeof(int),
- };
+ struct ctl_table tmp_table = *table;
+
+ tmp_table.data = &val;
+ tmp_table.maxlen = sizeof(val);
ret = proc_dointvec(&tmp_table, write, buffer, lenp, ppos);
if (write && ret >= 0) {
@@ -2726,13 +2757,13 @@ static struct ctl_table vs_vars[] = {
.procname = "drop_entry",
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_do_defense_mode,
+ .proc_handler = proc_do_drop_entry,
},
{
.procname = "drop_packet",
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_do_defense_mode,
+ .proc_handler = proc_do_drop_packet,
},
#ifdef CONFIG_IP_VS_NFCT
{
@@ -2746,7 +2777,7 @@ static struct ctl_table vs_vars[] = {
.procname = "secure_tcp",
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_do_defense_mode,
+ .proc_handler = proc_do_secure_tcp,
},
{
.procname = "snat_reroute",
@@ -2759,8 +2790,8 @@ static struct ctl_table vs_vars[] = {
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
- .extra1 = SYSCTL_ZERO,
- .extra2 = SYSCTL_ONE,
+ .min = 0,
+ .max = 1,
},
{
.procname = "sync_ports",
@@ -2836,8 +2867,8 @@ static struct ctl_table vs_vars[] = {
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
- .extra1 = SYSCTL_ZERO,
- .extra2 = SYSCTL_THREE,
+ .min = 0,
+ .max = 3,
},
{
.procname = "nat_icmp_send",
@@ -5071,10 +5102,6 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs)
} else
tbl = vs_vars;
/* Initialize sysctl defaults */
- for (idx = 0; idx < ARRAY_SIZE(vs_vars); idx++) {
- if (tbl[idx].proc_handler == proc_do_defense_mode)
- tbl[idx].extra2 = ipvs;
- }
idx = 0;
ipvs->sysctl_amemthresh = 1024;
tbl[idx++].data = &ipvs->sysctl_amemthresh;
@@ -5085,7 +5112,6 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs)
ipvs->conn_max_limit = net_eq(net, &init_net) ? IP_VS_CONN_MAX :
READ_ONCE(*(int *)vs_vars[idx].data);
ipvs->sysctl_conn_max = ipvs->conn_max_limit;
- tbl[idx].extra2 = ipvs;
tbl[idx++].data = &ipvs->sysctl_conn_max;
tbl[idx++].data = &ipvs->sysctl_drop_entry;
@@ -5120,7 +5146,6 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs)
ipvs->sysctl_sync_threshold[0] = DEFAULT_SYNC_THRESHOLD;
ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD;
tbl[idx].data = &ipvs->sysctl_sync_threshold;
- tbl[idx].extra2 = ipvs;
tbl[idx++].maxlen = sizeof(ipvs->sysctl_sync_threshold);
ipvs->sysctl_sync_refresh_period = DEFAULT_SYNC_REFRESH_PERIOD;
tbl[idx++].data = &ipvs->sysctl_sync_refresh_period;
@@ -5138,29 +5163,24 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs)
ipvs->sysctl_run_estimation = 1;
if (unpriv)
tbl[idx].mode = 0444;
- tbl[idx].extra2 = ipvs;
tbl[idx++].data = &ipvs->sysctl_run_estimation;
ipvs->est_cpulist_valid = 0;
if (unpriv)
tbl[idx].mode = 0444;
- tbl[idx].extra2 = ipvs;
tbl[idx++].data = &ipvs->sysctl_est_cpulist;
ipvs->sysctl_est_nice = IPVS_EST_NICE;
if (unpriv)
tbl[idx].mode = 0444;
- tbl[idx].extra2 = ipvs;
tbl[idx++].data = &ipvs->sysctl_est_nice;
if (unpriv)
tbl[idx].mode = 0444;
- tbl[idx].extra2 = ipvs;
tbl[idx++].data = &ipvs->sysctl_conn_lfactor;
if (unpriv)
tbl[idx].mode = 0444;
- tbl[idx].extra2 = ipvs;
tbl[idx++].data = &ipvs->sysctl_svc_lfactor;
#ifdef CONFIG_IP_VS_DEBUG
--
2.25.1
next prev parent reply other threads:[~2026-10-28 16:38 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 16:34 [RFC PATCH 00/39] sysctl: replace overloaded extra pointers with typed bounds and context wen.yang
2026-10-28 16:34 ` [RFC PATCH 01/39] " wen.yang
2026-10-28 21:09 ` David Laight
2026-10-28 16:34 ` [RFC PATCH 02/39] test_sysctl: convert bounds to numeric values wen.yang
2026-10-28 16:34 ` [RFC PATCH 03/39] sysctl: add KUnit coverage for numeric bounds and handlers wen.yang
2026-10-28 16:34 ` [RFC PATCH 04/39] sysctl: cover runtime ranges and context lifecycles in KUnit wen.yang
2026-10-28 16:34 ` [RFC PATCH 05/39] sysctl: cover priv in KUnit and the debug test module wen.yang
2026-10-28 16:34 ` [RFC PATCH 06/39] sysctl: convert core table bounds to numeric values wen.yang
2026-10-28 16:34 ` [RFC PATCH 07/39] sysctl: store architecture sysctl bounds by value wen.yang
2026-10-28 16:34 ` [RFC PATCH 08/39] sysctl: store crypto " wen.yang
2026-10-28 16:34 ` [RFC PATCH 09/39] sysctl: store device " wen.yang
2026-10-28 16:34 ` [RFC PATCH 10/39] sysctl: store filesystem " wen.yang
2026-10-28 16:34 ` [RFC PATCH 11/39] sysctl: store message-queue " wen.yang
2026-10-28 16:34 ` [RFC PATCH 12/39] sysctl: store kernel " wen.yang
2026-10-28 16:34 ` [RFC PATCH 13/39] sysctl: store memory-management " wen.yang
2026-10-28 16:34 ` [RFC PATCH 14/39] sysctl: store IPv6 scalar " wen.yang
2026-10-28 16:34 ` [RFC PATCH 15/39] sysctl: store netfilter " wen.yang
2026-10-28 16:34 ` [RFC PATCH 16/39] sysctl: store RPC " wen.yang
2026-10-28 16:34 ` [RFC PATCH 17/39] sysctl: store remaining network " wen.yang
2026-10-28 16:34 ` [RFC PATCH 18/39] sysctl: store security " wen.yang
2026-10-28 16:34 ` [RFC PATCH 19/39] io_uring: store its " wen.yang
2026-10-28 16:34 ` [RFC PATCH 20/39] sysctl: refresh dynamic scheduler and PID bounds per call wen.yang
2026-10-28 16:35 ` [RFC PATCH 21/39] sysctl: refresh device-dependent " wen.yang
2026-10-28 16:35 ` [RFC PATCH 22/39] sysctl: refresh namespace IPC " wen.yang
2026-10-28 16:35 ` [RFC PATCH 23/39] yama: preserve scope locking with numeric sysctl bounds wen.yang
2026-10-28 16:35 ` [RFC PATCH 24/39] net: refresh core sysctl limits without bound pointers wen.yang
2026-10-28 16:35 ` [RFC PATCH 25/39] sctp: resolve numeric ranges from the current namespace wen.yang
2026-10-28 16:35 ` [RFC PATCH 26/39] rds: preserve live reconnect limits with numeric bounds wen.yang
2026-10-28 16:35 ` [RFC PATCH 27/39] ipv4: preserve live and vector bounds with numeric sysctls wen.yang
2026-10-28 16:35 ` [RFC PATCH 28/39] net: refresh fragment and remaining dynamic sysctl bounds wen.yang
2026-10-28 16:35 ` [RFC PATCH 29/39] neighbour: derive sysctl ownership independently of bounds wen.yang
2026-10-28 16:35 ` [RFC PATCH 30/39] net: resolve sysctl owners from their backing data wen.yang
2026-10-28 16:35 ` wen.yang [this message]
2026-10-28 16:35 ` [RFC PATCH 32/39] sysctl: remove obsolete nr_open bound variables wen.yang
2026-10-28 16:35 ` [RFC PATCH 33/39] ipv6: move address sysctl context to priv wen.yang
2026-10-28 16:35 ` [RFC PATCH 34/39] ipv4: move device " wen.yang
2026-10-28 16:35 ` [RFC PATCH 35/39] netfilter: move logger " wen.yang
2026-10-28 16:35 ` [RFC PATCH 36/39] parport: move device " wen.yang
2026-10-28 16:35 ` [RFC PATCH 37/39] net: move namespace " wen.yang
2026-10-28 16:35 ` [RFC PATCH 38/39] arm64: move vector-length " wen.yang
2026-10-28 16:35 ` [RFC PATCH 39/39] sysctl: remove the extra pointers and the compatibility bounds read wen.yang
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=36ed716eb067114083b25e360443624ad2a63261.1793204511.git.wen.yang@linux.dev \
--to=wen.yang@linux.dev \
--cc=joel.granados@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/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
all inboxes | Powered by JetHome®