Fixes corner cases related to AP WDS station interfaces
Signed-off-by: Felix Fietkau <nbd@nbd.name>
-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);
{
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] == '@')
return get_vlan_device_chain(name, create);
if (name[0] == '@')
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);
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);
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);
void device_free_unused(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);
void alias_notify_device(const char *name, struct device *dev);
struct device *device_alias_get(const char *name);
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "netifd.h"
#include "system.h"
#include "netifd.h"
#include "system.h"
static char *split_vlan(char *s)
{
static char *split_vlan(char *s)
{
s = strchr(s, '.');
if (!s)
s = strchr(s, '.');
if (!s)
+ return NULL;
+
+ if (!isdigit(s[1])) {
+ s++;
+ goto retry;
+ }
-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;
{
struct device *dev = NULL;
char *buf, *s, *next;
return NULL;
s = split_vlan(buf);
return NULL;
s = split_vlan(buf);
- dev = device_get(buf, create);
+ dev = __device_get(buf, create, false);
next = split_vlan(s);
dev = get_vlan_device(dev, s, create);
if (!dev)
next = split_vlan(s);
dev = get_vlan_device(dev, s, create);
if (!dev)
- if (!s)
- goto out;
- } while (1);
out:
free(buf);
return dev;
out:
free(buf);
return dev;