diff options
author | Felix Fietkau <nbd@nbd.name> | 2022-12-30 16:38:41 +0100 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2022-12-30 16:38:42 +0100 |
commit | 81c1fbcba2f27f687c2a471f341502d47679f401 (patch) | |
tree | e048b6f94bcaa4f16ffe53b9cf9549c7ae50885c /device.c | |
parent | 7ce73fc167652146631967294ef4b358bf8ff152 (diff) | |
download | netifd-81c1fbcba2f27f687c2a471f341502d47679f401.tar.gz |
device: fix vlan device issues with disappearing lower devices
In some cases, if a VLAN is created on top of a bridge, a config reload
can lead to the bridge being torn down while netifd still considers the
VLAN device to be up.
In that case even a setup retry of an interface on top of the vlan does
not recreate the vlan device, because it is still claimed.
Fix this by releasing all device claims whenever a device goes away.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'device.c')
-rw-r--r-- | device.c | 13 |
1 files changed, 13 insertions, 0 deletions
@@ -472,6 +472,17 @@ static void __init dev_init(void) avl_init(&devices, avl_strcmp, true, NULL); } +static int device_release_cb(void *ctx, struct safe_list *list) +{ + struct device_user *dep = container_of(list, struct device_user, list); + + if (!dep->dev || !dep->claimed) + return 0; + + device_release(dep); + return 0; +} + static int device_broadcast_cb(void *ctx, struct safe_list *list) { struct device_user *dep = container_of(list, struct device_user, list); @@ -771,6 +782,8 @@ void device_set_present(struct device *dev, bool state) D(DEVICE, "%s '%s' %s present\n", dev->type->name, dev->ifname, state ? "is now" : "is no longer" ); dev->sys_present = state; device_refresh_present(dev); + if (!state) + safe_list_for_each(&dev->users, device_release_cb, NULL); } void device_set_link(struct device *dev, bool state) |