summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2022-12-30 16:38:41 +0100
committerFelix Fietkau <nbd@nbd.name>2022-12-30 16:38:42 +0100
commit81c1fbcba2f27f687c2a471f341502d47679f401 (patch)
treee048b6f94bcaa4f16ffe53b9cf9549c7ae50885c
parent7ce73fc167652146631967294ef4b358bf8ff152 (diff)
downloadnetifd-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>
-rw-r--r--device.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/device.c b/device.c
index b3d0e85..d6610c7 100644
--- a/device.c
+++ b/device.c
@@ -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)