devlink: fix reload error on netns teardown

During network namespace teardown, devlink_pernet_pre_exit() reloads
devlink instances into init_net. If reload_down() fails, devlink_reload()
returns before changing the namespace, leaving the registered devlink with
a pointer to the namespace being destroyed.

Move the fallback transition to devlink_pernet_pre_exit(), where the
teardown context is explicit. Do it only when the devlink still belongs to
the exiting namespace, since reload_up() can fail after the regular reload
path has already moved the instance. Keep the original reload error.

Cc: stable+noautosel@kernel.org # unlikely driver error paths
Fixes: 070c63f20f ("net: devlink: allow to change namespaces during reload")
Reported-by: Vega <vega@nebusec.ai>
Closes: https://bugtracker.nebusec.ai/f/11365
Signed-off-by: Zixuan Chai <petalzu987@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Link: https://patch.msgid.link/c43794aa549424b79a0da624e73bbb5215c0e9f5.1791555658.git.petalzu987@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Zixuan Chai 2026-10-10 14:25:31 +08:00 committed by Jakub Kicinski
parent ac1f6e58cb
commit 6b3e737748
3 changed files with 8 additions and 3 deletions

View File

@ -585,6 +585,8 @@ static void __net_exit devlink_pernet_pre_exit(struct net *net)
DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
DEVLINK_RELOAD_LIMIT_UNSPEC,
&actions_performed, NULL);
if (err && net_eq(devlink_net(devlink), net))
devlink_reload_netns_change(devlink, net, &init_net);
devl_dev_unlock(devlink, true);
devlink_put(devlink);
if (err && err != -EOPNOTSUPP)

View File

@ -412,9 +412,9 @@ static struct net *devlink_netns_get(struct sk_buff *skb,
return net;
}
static void devlink_reload_netns_change(struct devlink *devlink,
struct net *curr_net,
struct net *dest_net)
void devlink_reload_netns_change(struct devlink *devlink,
struct net *curr_net,
struct net *dest_net)
{
/* Userspace needs to be notified about devlink objects
* removed from original and entering new network namespace.

View File

@ -324,6 +324,9 @@ struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
/* Reload */
bool devlink_reload_actions_valid(const struct devlink_ops *ops);
void devlink_reload_netns_change(struct devlink *devlink,
struct net *curr_net,
struct net *dest_net);
int devlink_reload(struct devlink *devlink, struct net *dest_net,
enum devlink_reload_action action,
enum devlink_reload_limit limit,