From 013a1171e9b0df4f458fb87bbfb3bf8c9602ce6b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 19 Jun 2021 08:55:10 +0200 Subject: device: do not treat devices with non-digit characters after . as vlan devices Fixes corner cases related to AP WDS station interfaces Signed-off-by: Felix Fietkau --- device.c | 4 ++-- device.h | 10 ++++++++-- vlan.c | 26 ++++++++++++++------------ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/device.c b/device.c index d8617fc..c6b0b5f 100644 --- a/device.c +++ b/device.c @@ -650,13 +650,13 @@ device_find(const char *name) } struct device * -device_get(const char *name, int create) +__device_get(const char *name, int create, bool check_vlan) { struct device *dev; dev = avl_find_element(&devices, name, dev, avl); - if (!dev && strchr(name, '.')) + if (!dev && check_vlan && strchr(name, '.')) return get_vlan_device_chain(name, create); if (name[0] == '@') diff --git a/device.h b/device.h index 7d6c48b..1da6e3f 100644 --- a/device.h +++ b/device.h @@ -309,7 +309,13 @@ int device_init_virtual(struct device *dev, struct device_type *type, const char int device_init(struct device *dev, struct device_type *type, const char *ifname); void device_cleanup(struct device *dev); struct device *device_find(const char *name); -struct device *device_get(const char *name, int create); + +struct device *__device_get(const char *name, int create, bool check_vlan); +static inline struct device *device_get(const char *name, int create) +{ + return __device_get(name, create, true); +} + void device_add_user(struct device_user *dep, struct device *dev); void device_remove_user(struct device_user *dep); void device_broadcast_event(struct device *dev, enum device_event ev); @@ -326,7 +332,7 @@ void device_dump_status(struct blob_buf *b, struct device *dev); void device_free_unused(struct device *dev); -struct device *get_vlan_device_chain(const char *ifname, bool create); +struct device *get_vlan_device_chain(const char *ifname, int create); void alias_notify_device(const char *name, struct device *dev); struct device *device_alias_get(const char *name); diff --git a/vlan.c b/vlan.c index 459c907..401cc94 100644 --- a/vlan.c +++ b/vlan.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "netifd.h" #include "system.h" @@ -238,18 +239,23 @@ error: static char *split_vlan(char *s) { +retry: s = strchr(s, '.'); if (!s) - goto out; + return NULL; + + if (!isdigit(s[1])) { + s++; + goto retry; + } *s = 0; s++; -out: return s; } -struct device *get_vlan_device_chain(const char *ifname, bool create) +struct device *get_vlan_device_chain(const char *ifname, int create) { struct device *dev = NULL; char *buf, *s, *next; @@ -259,23 +265,19 @@ struct device *get_vlan_device_chain(const char *ifname, bool create) return NULL; s = split_vlan(buf); - dev = device_get(buf, create); + dev = __device_get(buf, create, false); if (!dev) - goto error; + goto out; - do { + while (s) { next = split_vlan(s); dev = get_vlan_device(dev, s, create); if (!dev) - goto error; + break; s = next; - if (!s) - goto out; - } while (1); + } -error: - dev = NULL; out: free(buf); return dev; -- cgit v1.2.1