From: Fernando Fernandez Mancera <fmancera@suse.de>
To: netdev@vger.kernel.org
Cc: horms@kernel.org, pabeni@redhat.com, kuba@kernel.org,
edumazet@google.com, dsahern@kernel.org, davem@davemloft.net,
Fernando Fernandez Mancera <fmancera@suse.de>
Subject: [PATCH 1/2 net-next v2] ipv4: centralize devconf sysctl handling
Date: Fri, 27 Mar 2026 13:02:01 +0100 [thread overview]
Message-ID: <20260327120202.4761-1-fmancera@suse.de> (raw)
The logic for handling IPv4 devconf sysctls is scattered. Notification
and cache flushes are managed in devinet_conf_proc(), while a separate
ipv4_doint_and_flush() function and DEVINET_SYSCTL_FLUSHING_ENTRY macro
is used for properties that solely require a cache flush.
This patch refactors the sysctl handling by introducing a centralized
helper, devinet_conf_post_set(). This new function evaluates the changed
attribute and handles all necessary operations like triggering netlink
notifications. It returns a boolean indicating whether a routing cache
flush is required.
Note that the boolean is necessary as this function will be re-used for
netlink IPv4 devconf handling where the cache flushing must wait until
all the attributes have been processed.
Finally, this is introducing a small change in behavior for
IPV4_DEVCONF_ROUTE_LOCALNET. As commit d0daebc3d622 ("ipv4: Add
interface option to enable routing of 127.0.0.0/8") intended, the cache
flush should only be performed when ROUTE_LOCALNET changes from 1 to 0.
Unfortunately, this was not true because while implementing it the
DEVINET_SYSCTL_FLUSHING_ENTRY was used for the attribute, making the
code related to it on devinet_conf_proc() dead.
IPV4_DEVCONF_FORWARDING is still being handled separately as it requires
more operations.
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
---
v2: no changes
---
net/ipv4/devinet.c | 127 ++++++++++++++++++++++++---------------------
1 file changed, 68 insertions(+), 59 deletions(-)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 58fe7cb69545..8300516fb38f 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -2128,6 +2128,46 @@ static int inet_validate_link_af(const struct net_device *dev,
return 0;
}
+static bool devinet_conf_post_set(struct net *net, struct ipv4_devconf *cnf,
+ int attr, int new, int old, int ifindex)
+{
+ if (new == old)
+ return false;
+
+ switch (attr) {
+ case IPV4_DEVCONF_ROUTE_LOCALNET:
+ case IPV4_DEVCONF_ACCEPT_LOCAL:
+ if (new == 0)
+ return true;
+ break;
+ case IPV4_DEVCONF_NOXFRM:
+ case IPV4_DEVCONF_NOPOLICY:
+ case IPV4_DEVCONF_PROMOTE_SECONDARIES:
+ case IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST:
+ case IPV4_DEVCONF_BC_FORWARDING:
+ return true;
+ case IPV4_DEVCONF_RP_FILTER:
+ inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
+ NETCONFA_RP_FILTER,
+ ifindex, cnf);
+ break;
+ case IPV4_DEVCONF_PROXY_ARP:
+ inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
+ NETCONFA_PROXY_NEIGH,
+ ifindex, cnf);
+ break;
+ case IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN:
+ inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
+ NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
+ ifindex, cnf);
+ break;
+ default:
+ break;
+ }
+
+ return false;
+}
+
static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla,
struct netlink_ext_ack *extack)
{
@@ -2509,44 +2549,31 @@ static int devinet_conf_proc(const struct ctl_table *ctl, int write,
if (write) {
struct ipv4_devconf *cnf = ctl->extra1;
- struct net *net = ctl->extra2;
int i = (int *)ctl->data - cnf->data;
+ struct net *net = ctl->extra2;
int ifindex;
- set_bit(i, cnf->state);
-
- if (cnf == net->ipv4.devconf_dflt)
- devinet_copy_dflt_conf(net, i);
- if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1 ||
- i == IPV4_DEVCONF_ROUTE_LOCALNET - 1)
- if ((new_value == 0) && (old_value != 0))
- rt_cache_flush(net);
+ /* These attributes are bypassing the tracking state,
+ * for the rest track the state and propagate the changes
+ * to default config
+ */
+ switch (i + 1) {
+ case IPV4_DEVCONF_NOXFRM:
+ case IPV4_DEVCONF_NOPOLICY:
+ case IPV4_DEVCONF_PROMOTE_SECONDARIES:
+ case IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST:
+ break;
+ default:
+ set_bit(i, cnf->state);
+ if (cnf == net->ipv4.devconf_dflt)
+ devinet_copy_dflt_conf(net, i);
+ break;
+ }
- if (i == IPV4_DEVCONF_BC_FORWARDING - 1 &&
- new_value != old_value)
+ ifindex = devinet_conf_ifindex(net, cnf);
+ if (devinet_conf_post_set(net, cnf, i + 1, new_value,
+ old_value, ifindex))
rt_cache_flush(net);
-
- if (i == IPV4_DEVCONF_RP_FILTER - 1 &&
- new_value != old_value) {
- ifindex = devinet_conf_ifindex(net, cnf);
- inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
- NETCONFA_RP_FILTER,
- ifindex, cnf);
- }
- if (i == IPV4_DEVCONF_PROXY_ARP - 1 &&
- new_value != old_value) {
- ifindex = devinet_conf_ifindex(net, cnf);
- inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
- NETCONFA_PROXY_NEIGH,
- ifindex, cnf);
- }
- if (i == IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN - 1 &&
- new_value != old_value) {
- ifindex = devinet_conf_ifindex(net, cnf);
- inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
- NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
- ifindex, cnf);
- }
}
return ret;
@@ -2599,20 +2626,6 @@ static int devinet_sysctl_forward(const struct ctl_table *ctl, int write,
return ret;
}
-static int ipv4_doint_and_flush(const struct ctl_table *ctl, int write,
- void *buffer, size_t *lenp, loff_t *ppos)
-{
- int *valp = ctl->data;
- int val = *valp;
- int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
- struct net *net = ctl->extra2;
-
- if (write && *valp != val)
- rt_cache_flush(net);
-
- return ret;
-}
-
#define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc) \
{ \
.procname = name, \
@@ -2633,9 +2646,6 @@ static int ipv4_doint_and_flush(const struct ctl_table *ctl, int write,
#define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc) \
DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc)
-#define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \
- DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush)
-
static struct devinet_sysctl_table {
struct ctl_table_header *sysctl_header;
struct ctl_table devinet_vars[IPV4_DEVCONF_MAX];
@@ -2678,15 +2688,14 @@ static struct devinet_sysctl_table {
"ignore_routes_with_linkdown"),
DEVINET_SYSCTL_RW_ENTRY(DROP_GRATUITOUS_ARP,
"drop_gratuitous_arp"),
-
- DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
- DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
- DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES,
- "promote_secondaries"),
- DEVINET_SYSCTL_FLUSHING_ENTRY(ROUTE_LOCALNET,
- "route_localnet"),
- DEVINET_SYSCTL_FLUSHING_ENTRY(DROP_UNICAST_IN_L2_MULTICAST,
- "drop_unicast_in_l2_multicast"),
+ DEVINET_SYSCTL_RW_ENTRY(NOXFRM, "disable_xfrm"),
+ DEVINET_SYSCTL_RW_ENTRY(NOPOLICY, "disable_policy"),
+ DEVINET_SYSCTL_RW_ENTRY(PROMOTE_SECONDARIES,
+ "promote_secondaries"),
+ DEVINET_SYSCTL_RW_ENTRY(ROUTE_LOCALNET,
+ "route_localnet"),
+ DEVINET_SYSCTL_RW_ENTRY(DROP_UNICAST_IN_L2_MULTICAST,
+ "drop_unicast_in_l2_multicast"),
},
};
--
2.53.0
next reply other threads:[~2026-03-27 12:02 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-27 12:02 Fernando Fernandez Mancera [this message]
2026-03-27 12:02 ` [PATCH 2/2 net-next v2] ipv4: handle devconf post-set actions on netlink updates Fernando Fernandez Mancera
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=20260327120202.4761-1-fmancera@suse.de \
--to=fmancera@suse.de \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/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