summaryrefslogtreecommitdiff
path: root/wireless.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2021-06-19 08:36:06 +0200
committerFelix Fietkau <nbd@nbd.name>2021-06-19 09:16:51 +0200
commitf037b082923abc2dad0d14c8401ebe0afd816b5c (patch)
treeafa32955b66f3ef38243045c81b56495c1bfe705 /wireless.c
parent013a1171e9b0df4f458fb87bbfb3bf8c9602ce6b (diff)
downloadnetifd-f037b082923abc2dad0d14c8401ebe0afd816b5c.tar.gz
wireless: handle WDS per-sta devices
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'wireless.c')
-rw-r--r--wireless.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/wireless.c b/wireless.c
index 2339f94..0c4930c 100644
--- a/wireless.c
+++ b/wireless.c
@@ -313,7 +313,7 @@ wireless_device_free_state(struct wireless_device *wdev)
}
}
-static void wireless_interface_handle_link(struct wireless_interface *vif, bool up)
+static void wireless_interface_handle_link(struct wireless_interface *vif, const char *ifname, bool up)
{
struct interface *iface;
struct blob_attr *cur;
@@ -323,8 +323,11 @@ static void wireless_interface_handle_link(struct wireless_interface *vif, bool
if (!vif->network || !vif->ifname)
return;
+ if (!ifname)
+ ifname = vif->ifname;
+
if (up) {
- struct device *dev = device_get(vif->ifname, 2);
+ struct device *dev = device_get(ifname, 2);
if (dev) {
dev->wireless_isolate = vif->isolate;
dev->wireless = true;
@@ -339,7 +342,7 @@ static void wireless_interface_handle_link(struct wireless_interface *vif, bool
if (!iface)
continue;
- interface_handle_link(iface, vif->ifname, NULL, up, true);
+ interface_handle_link(iface, ifname, NULL, up, true);
}
}
@@ -515,7 +518,7 @@ wireless_device_mark_down(struct wireless_device *wdev)
wireless_vlan_handle_link(vlan, false);
vlist_for_each_element(&wdev->interfaces, vif, node)
- wireless_interface_handle_link(vif, false);
+ wireless_interface_handle_link(vif, NULL, false);
wireless_process_kill_all(wdev, SIGTERM, true);
@@ -587,7 +590,7 @@ wireless_device_mark_up(struct wireless_device *wdev)
D(WIRELESS, "Wireless device '%s' is now up\n", wdev->name);
wdev->state = IFS_UP;
vlist_for_each_element(&wdev->interfaces, vif, node)
- wireless_interface_handle_link(vif, true);
+ wireless_interface_handle_link(vif, NULL, true);
vlist_for_each_element(&wdev->vlans, vlan, node)
wireless_vlan_handle_link(vlan, true);
}
@@ -817,7 +820,7 @@ vif_update(struct vlist_tree *tree, struct vlist_node *node_new,
}
D(WIRELESS, "Update wireless interface %s on device %s\n", vif_new->name, wdev->name);
- wireless_interface_handle_link(vif_old, false);
+ wireless_interface_handle_link(vif_old, NULL, false);
free(vif_old->config);
vif_old->config = blob_memdup(vif_new->config);
vif_old->isolate = vif_new->isolate;
@@ -831,7 +834,7 @@ vif_update(struct vlist_tree *tree, struct vlist_node *node_new,
wireless_interface_init_config(vif_new);
} else if (vif_old) {
D(WIRELESS, "Delete wireless interface %s on device %s\n", vif_old->name, wdev->name);
- wireless_interface_handle_link(vif_old, false);
+ wireless_interface_handle_link(vif_old, NULL, false);
free((void *) vif_old->section);
free(vif_old->config);
free(vif_old);
@@ -1494,3 +1497,33 @@ wireless_start_pending(void)
vlist_for_each_element(&wireless_devices, wdev, node)
__wireless_device_set_up(wdev, 0);
}
+
+void wireless_device_hotplug_event(const char *name, bool add)
+{
+ struct wireless_interface *vif;
+ struct wireless_device *wdev;
+ const char *s;
+ int len;
+
+ s = strstr(name, ".sta");
+ if (!s)
+ return;
+
+ if (strchr(s + 4, '.'))
+ return;
+
+ len = s - name;
+
+ vlist_for_each_element(&wireless_devices, wdev, node) {
+ vlist_for_each_element(&wdev->interfaces, vif, node) {
+ if (!vif->ifname)
+ continue;
+
+ if (strlen(vif->ifname) != len ||
+ strncmp(vif->ifname, name, len) != 0)
+ continue;
+
+ wireless_interface_handle_link(vif, name, add);
+ }
+ }
+}