Browse Source

vlan: fix device vlan alias handling

A recent commit changed the vlan chain handling to not treat devices with
non-digit characters after "." as vlan devices. This broke aliases, which
rely on names after the "." component.
Fix dealing with both cases by first trying to set up a vlan regardless
of the non-digit characters, but for the first component allow falling back
to treating the first two parts as a full device name

Fixes: 013a1171e9b0 ("device: do not treat devices with non-digit characters after . as vlan devices")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Felix Fietkau 2 years ago
parent
commit
7f24a06347
1 changed files with 23 additions and 8 deletions
  1. 23 8
      vlan.c

+ 23 - 8
vlan.c

@@ -239,16 +239,10 @@ error:
 
 static char *split_vlan(char *s)
 {
-retry:
 	s = strchr(s, '.');
 	if (!s)
 		return NULL;
 
-	if (!isdigit(s[1])) {
-		s++;
-		goto retry;
-	}
-
 	*s = 0;
 	s++;
 
@@ -257,7 +251,7 @@ retry:
 
 struct device *get_vlan_device_chain(const char *ifname, int create)
 {
-	struct device *dev = NULL;
+	struct device *dev = NULL, *vldev;
 	char *buf, *s, *next;
 
 	buf = strdup(ifname);
@@ -266,9 +260,30 @@ struct device *get_vlan_device_chain(const char *ifname, int create)
 
 	s = split_vlan(buf);
 	dev = __device_get(buf, create, false);
-	if (!dev)
+	if (!dev || !s)
 		goto out;
 
+	/* for the first split, we need to check if we're using an alias or
+	 * if the . separator isn't being used as a vlan separator (e.g. for
+	 * AP WDS VLANs */
+	if (!isdigit(s[0])) {
+		next = split_vlan(s);
+		vldev = get_vlan_device(dev, s, create);
+		if (!vldev) {
+			s[-1] = '.';
+			dev = __device_get(buf, create, false);
+			if (!dev)
+				goto out;
+
+			if (next)
+				next[-1] = '.';
+		} else {
+			dev = vldev;
+			s = next;
+		}
+	}
+
+
 	while (s) {
 		next = split_vlan(s);
 		dev = get_vlan_device(dev, s, create);