mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-21 22:47:51 -04:00
ipv4: handle devconf post-set actions on netlink updates
When IPv4 device configuration parameters are updated via netlink, the kernel currently only updates the value. This bypasses several post-modification actions that occur when these same parameters are updated via sysctl, such as flushing the routing cache or emitting RTM_NEWNETCONF notifications. This patch addresses the inconsistency by calling the devinet_conf_post_set() helper inside inet_set_link_af(). If a flush is required, we defer it until the netlink attribute parsing loop completes. This ensures consistent behavior and side-effects for devconf changes, regardless of whether they are initiated via sysctl or netlink. Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de> Link: https://patch.msgid.link/20260609204520.4670-2-fmancera@suse.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
3a29b55505
commit
489730ec2a
@@ -2161,6 +2161,20 @@ static bool devinet_conf_post_set(struct net *net, struct ipv4_devconf *cnf,
|
||||
NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN,
|
||||
ifindex, cnf);
|
||||
break;
|
||||
case IPV4_DEVCONF_FORWARDING:
|
||||
if (new == 1) {
|
||||
/* it is safe to use container_of() because forwarding case
|
||||
* is only used by the netlink path
|
||||
*/
|
||||
struct in_device *idev = container_of(cnf, struct in_device, cnf);
|
||||
|
||||
netif_disable_lro(idev->dev);
|
||||
}
|
||||
|
||||
inet_netconf_notify_devconf(net, RTM_NEWNETCONF,
|
||||
NETCONFA_FORWARDING,
|
||||
ifindex, cnf);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2173,6 +2187,8 @@ static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla,
|
||||
{
|
||||
struct in_device *in_dev = __in_dev_get_rtnl(dev);
|
||||
struct nlattr *a, *tb[IFLA_INET_MAX+1];
|
||||
struct net *net = dev_net(dev);
|
||||
bool flush_cache = false;
|
||||
int rem;
|
||||
|
||||
if (!in_dev)
|
||||
@@ -2182,8 +2198,17 @@ static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla,
|
||||
return -EINVAL;
|
||||
|
||||
if (tb[IFLA_INET_CONF]) {
|
||||
nla_for_each_nested(a, tb[IFLA_INET_CONF], rem)
|
||||
ipv4_devconf_set(in_dev, nla_type(a), nla_get_u32(a));
|
||||
nla_for_each_nested(a, tb[IFLA_INET_CONF], rem) {
|
||||
int old_value = ipv4_devconf_get(in_dev, nla_type(a));
|
||||
int new_value = nla_get_u32(a);
|
||||
|
||||
ipv4_devconf_set(in_dev, nla_type(a), new_value);
|
||||
if (devinet_conf_post_set(net, &in_dev->cnf, nla_type(a), new_value,
|
||||
old_value, dev->ifindex))
|
||||
flush_cache = true;
|
||||
}
|
||||
if (flush_cache)
|
||||
rt_cache_flush(net);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user