Browse Source

system-linux: add retry for adding member devices to a bridge

When netifd tries to add bridge members brought up by hostapd asynchronously
(e.g. after an autochannel run), the first try often fails with EBUSY or
EAGAIN, since it's racing against hostapd's own setup.
Add retry logic, which includes checking if the device was added to the
bridge in the meantime to deal with this issue

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Felix Fietkau 3 years ago
parent
commit
3abe1fc871
1 changed files with 11 additions and 2 deletions
  1. 11 2
      system-linux.c

+ 11 - 2
system-linux.c

@@ -813,11 +813,20 @@ int system_bridge_addif(struct device *bridge, struct device *dev)
 {
 	char buf[64];
 	char *oldbr;
-	int ret = 0;
+	int tries = 0;
+	int ret;
 
+retry:
+	ret = 0;
 	oldbr = system_get_bridge(dev->ifname, dev_buf, sizeof(dev_buf));
-	if (!oldbr || strcmp(oldbr, bridge->ifname) != 0)
+	if (!oldbr || strcmp(oldbr, bridge->ifname) != 0) {
 		ret = system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL);
+		tries++;
+		D(SYSTEM, "Failed to add device '%s' to bridge '%s' (tries=%d): %s\n",
+		  dev->ifname, bridge->ifname, tries, strerror(errno));
+		if (tries <= 3)
+			goto retry;
+	}
 
 	if (dev->wireless)
 		system_bridge_set_wireless(bridge, dev);