summaryrefslogtreecommitdiff
path: root/vlan.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2021-07-14 15:22:09 +0200
committerFelix Fietkau <nbd@nbd.name>2021-07-14 15:24:25 +0200
commit7f24a063475e1e2be4e0c516a5b62c3fae5ec542 (patch)
tree5cb7aa818e701c8431bf5add24478494b3591f8f /vlan.c
parent1f283c654aeb1f8983e0a81b7a81cc4784fffe3f (diff)
downloadnetifd-7f24a063475e1e2be4e0c516a5b62c3fae5ec542.tar.gz
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>
Diffstat (limited to 'vlan.c')
-rw-r--r--vlan.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/vlan.c b/vlan.c
index 401cc94..23b20a9 100644
--- a/vlan.c
+++ b/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);