Merge branch 'align-ipv4-teardown-with-ipv6-and-fix-driver-regressions'

Yuyang Huang says:

====================
align IPv4 teardown with IPv6 and fix driver regressions

This series aligns the IPv4 address teardown sequence with IPv6 by clearing
dev->ip_ptr early in inetdev_destroy() before freeing the multicast list and
individual IP addresses. This prevents RCU readers from accessing
a partially destroyed in_device structure.

However, clearing dev->ip_ptr early causes __in_dev_get_rtnl() to return
NULL during the notifier loop in inetdev_destroy(). This causes regressions
in some drivers (prestera and mac80211) that use this lookup helper
in their inetaddr notifier callbacks.

To prevent regressions and maintain bisectability, this series first
fixes the affected drivers (Patch 1 and 2) before applying the core
IPv4 change (Patch 3).

An audit was performed on all other registered inetaddr and inet6addr
notifier listeners, and no other drivers were found to be affected.
====================

Link: https://patch.msgid.link/20260711005405.2861680-1-yuyanghuang@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-07-21 12:25:10 -07:00
commit f14a8561f3
3 changed files with 5 additions and 9 deletions

View File

@ -1302,10 +1302,8 @@ static int __prestera_inetaddr_port_event(struct net_device *port_dev,
dev_hold(port_dev);
break;
case NETDEV_DOWN:
if (!re) {
NL_SET_ERR_MSG_MOD(extack, "Can't find RIF");
return -EEXIST;
}
if (!re)
return 0;
prestera_rif_entry_destroy(port->sw, re);
dev_put(port_dev);
break;

View File

@ -322,6 +322,8 @@ static void inetdev_destroy(struct in_device *in_dev)
in_dev->dead = 1;
RCU_INIT_POINTER(dev->ip_ptr, NULL);
ip_mc_destroy_dev(in_dev);
while ((ifa = rtnl_dereference(in_dev->ifa_list)) != NULL) {
@ -329,8 +331,6 @@ static void inetdev_destroy(struct in_device *in_dev)
inet_free_ifa(ifa);
}
RCU_INIT_POINTER(dev->ip_ptr, NULL);
devinet_sysctl_unregister(in_dev);
neigh_parms_release(&arp_tbl, in_dev->arp_parms);
arp_ifdown(dev);

View File

@ -588,9 +588,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
if (sdata->vif.type != NL80211_IFTYPE_STATION)
return NOTIFY_DONE;
idev = __in_dev_get_rtnl(sdata->dev);
if (!idev)
return NOTIFY_DONE;
idev = ifa->ifa_dev;
ifmgd = &sdata->u.mgd;