mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-31 18:38:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			503 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			503 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From d5484e69a2476ff3bea5d402d06ed3c68d2ef24d Mon Sep 17 00:00:00 2001
 | |
| From: John Crispin <john@phrozen.org>
 | |
| Date: Wed, 6 Nov 2024 12:28:41 +0100
 | |
| Subject: [PATCH] netifd: add various backports
 | |
| 
 | |
| Signed-off-by: John Crispin <john@phrozen.org>
 | |
| ---
 | |
|  .../netifd/patches/100-backport_fixes.patch   | 482 ++++++++++++++++++
 | |
|  1 file changed, 482 insertions(+)
 | |
|  create mode 100644 package/network/config/netifd/patches/100-backport_fixes.patch
 | |
| 
 | |
| diff --git a/package/network/config/netifd/patches/100-backport_fixes.patch b/package/network/config/netifd/patches/100-backport_fixes.patch
 | |
| new file mode 100644
 | |
| index 0000000000..0442beb053
 | |
| --- /dev/null
 | |
| +++ b/package/network/config/netifd/patches/100-backport_fixes.patch
 | |
| @@ -0,0 +1,482 @@
 | |
| +--- a/device.c
 | |
| ++++ b/device.c
 | |
| +@@ -166,12 +166,19 @@ static int set_device_state(struct devic
 | |
| + 		dev->orig_settings.flags &= dev->settings.flags;
 | |
| + 		system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
 | |
| + 
 | |
| +-		system_if_up(dev);
 | |
| ++		if (!dev->external)
 | |
| ++			system_if_up(dev);
 | |
| + 
 | |
| + 		system_if_apply_settings_after_up(dev, &dev->settings);
 | |
| + 	} else {
 | |
| +-		system_if_down(dev);
 | |
| ++		if (!dev->external)
 | |
| ++			system_if_down(dev);
 | |
| + 		system_if_apply_settings(dev, &dev->orig_settings, dev->orig_settings.flags);
 | |
| ++
 | |
| ++		/* Restore any settings present in UCI which may have
 | |
| ++		 * failed to apply so that they will be re-attempted
 | |
| ++		 * the next time the device is brought up */
 | |
| ++		dev->settings.flags |= dev->settings.valid_flags;
 | |
| + 	}
 | |
| + 
 | |
| + 	return 0;
 | |
| +@@ -571,6 +578,9 @@ device_init_settings(struct device *dev,
 | |
| + 		s->flags |= DEV_OPT_EEE;
 | |
| + 	}
 | |
| + 
 | |
| ++	/* Remember the settings present in UCI */
 | |
| ++	s->valid_flags = s->flags;
 | |
| ++
 | |
| + 	cur = tb[DEV_ATTR_AUTH_VLAN];
 | |
| + 	free(dev->config_auth_vlans);
 | |
| + 	dev->config_auth_vlans = cur ? blob_memdup(cur) : NULL;
 | |
| +@@ -609,11 +619,15 @@ static int device_broadcast_cb(void *ctx
 | |
| + 	return 0;
 | |
| + }
 | |
| + 
 | |
| +-void device_broadcast_event(struct device *dev, enum device_event ev)
 | |
| ++static const char *device_event_name(enum device_event ev)
 | |
| + {
 | |
| + 	static const char * const event_names[] = {
 | |
| + 		[DEV_EVENT_ADD] = "add",
 | |
| + 		[DEV_EVENT_REMOVE] = "remove",
 | |
| ++		[DEV_EVENT_UPDATE_IFNAME] = "update_ifname",
 | |
| ++		[DEV_EVENT_UPDATE_IFINDEX] = "update_ifindex",
 | |
| ++		[DEV_EVENT_SETUP] = "setup",
 | |
| ++		[DEV_EVENT_TEARDOWN] = "teardown",
 | |
| + 		[DEV_EVENT_UP] = "up",
 | |
| + 		[DEV_EVENT_DOWN] = "down",
 | |
| + 		[DEV_EVENT_AUTH_UP] = "auth_up",
 | |
| +@@ -621,12 +635,37 @@ void device_broadcast_event(struct devic
 | |
| + 		[DEV_EVENT_LINK_DOWN] = "link_down",
 | |
| + 		[DEV_EVENT_TOPO_CHANGE] = "topo_change",
 | |
| + 	};
 | |
| ++
 | |
| ++	if (ev >= ARRAY_SIZE(event_names) || !event_names[ev])
 | |
| ++		return "unknown";
 | |
| ++
 | |
| ++	return event_names[ev];
 | |
| ++}
 | |
| ++
 | |
| ++void device_broadcast_event(struct device *dev, enum device_event ev)
 | |
| ++{
 | |
| ++	const char *ev_name;
 | |
| + 	int dev_ev = ev;
 | |
| + 
 | |
| + 	safe_list_for_each(&dev->aliases, device_broadcast_cb, &dev_ev);
 | |
| + 	safe_list_for_each(&dev->users, device_broadcast_cb, &dev_ev);
 | |
| + 
 | |
| +-	if (ev >= ARRAY_SIZE(event_names) || !event_names[ev] || !dev->ifname[0])
 | |
| ++	switch (ev) {
 | |
| ++	case DEV_EVENT_ADD:
 | |
| ++	case DEV_EVENT_REMOVE:
 | |
| ++	case DEV_EVENT_UP:
 | |
| ++	case DEV_EVENT_DOWN:
 | |
| ++	case DEV_EVENT_AUTH_UP:
 | |
| ++	case DEV_EVENT_LINK_UP:
 | |
| ++	case DEV_EVENT_LINK_DOWN:
 | |
| ++	case DEV_EVENT_TOPO_CHANGE:
 | |
| ++		break;
 | |
| ++	default:
 | |
| ++		return;
 | |
| ++	}
 | |
| ++
 | |
| ++	ev_name = device_event_name(ev);
 | |
| ++	if (!dev->ifname[0])
 | |
| + 		return;
 | |
| + 
 | |
| + 	blob_buf_init(&b, 0);
 | |
| +@@ -635,7 +674,7 @@ void device_broadcast_event(struct devic
 | |
| + 	blobmsg_add_u8(&b, "present", dev->present);
 | |
| + 	blobmsg_add_u8(&b, "active", dev->active);
 | |
| + 	blobmsg_add_u8(&b, "link_active", dev->link_active);
 | |
| +-	netifd_ubus_device_notify(event_names[ev], b.head, -1);
 | |
| ++	netifd_ubus_device_notify(ev_name, b.head, -1);
 | |
| + }
 | |
| + 
 | |
| + static void
 | |
| +@@ -689,17 +728,7 @@ int device_claim(struct device_user *dep
 | |
| + 
 | |
| + 	device_broadcast_event(dev, DEV_EVENT_SETUP);
 | |
| + 	device_fill_default_settings(dev);
 | |
| +-	if (dev->external) {
 | |
| +-		/* Get ifindex for external claimed devices so a valid   */
 | |
| +-		/* ifindex is in place avoiding possible race conditions */
 | |
| +-		device_set_ifindex(dev, system_if_resolve(dev));
 | |
| +-		if (!dev->ifindex)
 | |
| +-			ret = -1;
 | |
| +-
 | |
| +-		system_if_get_settings(dev, &dev->orig_settings);
 | |
| +-	} else
 | |
| +-		ret = dev->set_state(dev, true);
 | |
| +-
 | |
| ++	ret = dev->set_state(dev, true);
 | |
| + 	if (ret == 0)
 | |
| + 		device_broadcast_event(dev, DEV_EVENT_UP);
 | |
| + 	else {
 | |
| +@@ -727,8 +756,7 @@ void device_release(struct device_user *
 | |
| + 		return;
 | |
| + 
 | |
| + 	device_broadcast_event(dev, DEV_EVENT_TEARDOWN);
 | |
| +-	if (!dev->external)
 | |
| +-		dev->set_state(dev, false);
 | |
| ++	dev->set_state(dev, false);
 | |
| + 
 | |
| + 	if (dev->active)
 | |
| + 		return;
 | |
| +@@ -810,9 +838,6 @@ device_create_default(const char *name,
 | |
| + 	}
 | |
| + 
 | |
| + 	dev->default_config = true;
 | |
| +-	if (external)
 | |
| +-		system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
 | |
| +-
 | |
| + 	device_check_state(dev);
 | |
| + 
 | |
| + 	return dev;
 | |
| +@@ -841,7 +866,6 @@ __device_get(const char *name, int creat
 | |
| + 
 | |
| + 	if (dev) {
 | |
| + 		if (create > 1 && !dev->external) {
 | |
| +-			system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
 | |
| + 			dev->external = true;
 | |
| + 			device_set_present(dev, true);
 | |
| + 		}
 | |
| +@@ -1164,11 +1188,6 @@ device_apply_config(struct device *dev,
 | |
| + 	enum dev_change_type change;
 | |
| + 
 | |
| + 	change = device_set_config(dev, type, config);
 | |
| +-	if (dev->external) {
 | |
| +-		system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
 | |
| +-		change = DEV_CONFIG_APPLIED;
 | |
| +-	}
 | |
| +-
 | |
| + 	switch (change) {
 | |
| + 		case DEV_CONFIG_RESTART:
 | |
| + 		case DEV_CONFIG_APPLIED:
 | |
| +@@ -1180,7 +1199,7 @@ device_apply_config(struct device *dev,
 | |
| + 				int ret = 0;
 | |
| + 
 | |
| + 				device_set_present(dev, false);
 | |
| +-				if (dev->active && !dev->external) {
 | |
| ++				if (dev->active) {
 | |
| + 					ret = dev->set_state(dev, false);
 | |
| + 					if (!ret)
 | |
| + 						ret = dev->set_state(dev, true);
 | |
| +--- a/interface.c
 | |
| ++++ b/interface.c
 | |
| +@@ -1078,11 +1078,17 @@ interface_add_link(struct interface *ifa
 | |
| + {
 | |
| + 	struct device *mdev = iface->main_dev.dev;
 | |
| + 
 | |
| +-	if (mdev == dev)
 | |
| ++	if (mdev == dev) {
 | |
| ++		if (iface->state != IFS_UP) {
 | |
| ++			interface_set_available(iface, false);
 | |
| ++			if (dev->present)
 | |
| ++				interface_set_available(iface, true);
 | |
| ++		}
 | |
| + 		return 0;
 | |
| ++	}
 | |
| + 
 | |
| + 	if (iface->main_dev.hotplug)
 | |
| +-		device_remove_user(&iface->main_dev);
 | |
| ++		interface_set_main_dev(iface, NULL);
 | |
| + 
 | |
| + 	if (mdev) {
 | |
| + 		if (mdev->hotplug_ops)
 | |
| +--- a/wireless.c
 | |
| ++++ b/wireless.c
 | |
| +@@ -138,7 +138,7 @@ static void
 | |
| + put_container(struct blob_buf *buf, struct blob_attr *attr, const char *name)
 | |
| + {
 | |
| + 	void *c = blobmsg_open_table(buf, name);
 | |
| +-	blob_put_raw(buf, blob_data(attr), blob_len(attr));
 | |
| ++	blob_put_raw(buf, blobmsg_data(attr), blobmsg_len(attr));
 | |
| + 	blobmsg_close_table(buf, c);
 | |
| + }
 | |
| + 
 | |
| +@@ -337,12 +337,39 @@ static void wireless_device_set_mcast_to
 | |
| + 	dev->settings.flags |= DEV_OPT_MULTICAST_TO_UNICAST;
 | |
| + }
 | |
| + 
 | |
| ++static void wireless_check_interface(struct blob_attr *list, int *enabled, int *ifindex)
 | |
| ++{
 | |
| ++	struct interface *iface;
 | |
| ++	struct blob_attr *cur;
 | |
| ++	size_t rem;
 | |
| ++
 | |
| ++	blobmsg_for_each_attr(cur, list, rem) {
 | |
| ++		struct device *mdev;
 | |
| ++
 | |
| ++		iface = vlist_find(&interfaces, blobmsg_get_string(cur), iface, node);
 | |
| ++		if (!iface)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		if (iface->autostart)
 | |
| ++			*enabled = 1;
 | |
| ++		else if (*enabled != 1)
 | |
| ++			*enabled = 0;
 | |
| ++
 | |
| ++		mdev = iface->main_dev.dev;
 | |
| ++		if (!mdev || !mdev->hotplug_ops)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		*ifindex = mdev->ifindex;
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| + static void wireless_interface_handle_link(struct wireless_interface *vif, const char *ifname, bool up)
 | |
| + {
 | |
| + 	struct interface *iface;
 | |
| + 	struct blob_attr *cur;
 | |
| + 	const char *network;
 | |
| + 	struct device *dev;
 | |
| ++	int enabled = -1;
 | |
| + 	size_t rem;
 | |
| + 
 | |
| + 	if (!vif->network || !vif->ifname)
 | |
| +@@ -372,6 +399,7 @@ static void wireless_interface_handle_li
 | |
| + 	dev->bpdu_filter = dev->wireless_ap;
 | |
| + 
 | |
| + out:
 | |
| ++	wireless_check_interface(vif->network, &enabled, &vif->network_ifindex);
 | |
| + 	blobmsg_for_each_attr(cur, vif->network, rem) {
 | |
| + 		network = blobmsg_data(cur);
 | |
| + 
 | |
| +@@ -388,6 +416,7 @@ static void wireless_vlan_handle_link(st
 | |
| + 	struct interface *iface;
 | |
| + 	struct blob_attr *cur;
 | |
| + 	const char *network;
 | |
| ++	int enabled = -1;
 | |
| + 	size_t rem;
 | |
| + 
 | |
| + 	if (!vlan->network || !vlan->ifname)
 | |
| +@@ -406,6 +435,7 @@ static void wireless_vlan_handle_link(st
 | |
| + 		}
 | |
| + 	}
 | |
| + 
 | |
| ++	wireless_check_interface(vlan->network, &enabled, &vlan->network_ifindex);
 | |
| + 	blobmsg_for_each_attr(cur, vlan->network, rem) {
 | |
| + 		network = blobmsg_data(cur);
 | |
| + 
 | |
| +@@ -838,7 +868,7 @@ wireless_interface_init_config(struct wi
 | |
| + 	struct blob_attr *cur;
 | |
| + 
 | |
| + 	vif->network = NULL;
 | |
| +-	blobmsg_parse(vif_policy, __VIF_ATTR_MAX, tb, blob_data(vif->config), blob_len(vif->config));
 | |
| ++	blobmsg_parse_attr(vif_policy, __VIF_ATTR_MAX, tb, vif->config);
 | |
| + 
 | |
| + 	if ((cur = tb[VIF_ATTR_NETWORK]))
 | |
| + 		vif->network = cur;
 | |
| +@@ -922,7 +952,7 @@ wireless_vlan_init_config(struct wireles
 | |
| + 	struct blob_attr *cur;
 | |
| + 
 | |
| + 	vlan->network = NULL;
 | |
| +-	blobmsg_parse(vlan_policy, __VLAN_ATTR_MAX, tb, blob_data(vlan->config), blob_len(vlan->config));
 | |
| ++	blobmsg_parse_attr(vlan_policy, __VLAN_ATTR_MAX, tb, vlan->config);
 | |
| + 
 | |
| + 	if ((cur = tb[VLAN_ATTR_NETWORK]))
 | |
| + 		vlan->network = cur;
 | |
| +@@ -1079,7 +1109,7 @@ wireless_device_create(struct wireless_d
 | |
| + 	struct blob_attr *tb[__WDEV_ATTR_MAX];
 | |
| + 	struct blob_attr *cur;
 | |
| + 
 | |
| +-	blobmsg_parse(wdev_policy, __WDEV_ATTR_MAX, tb, blob_data(data), blob_len(data));
 | |
| ++	blobmsg_parse_attr(wdev_policy, __WDEV_ATTR_MAX, tb, data);
 | |
| + 
 | |
| + 	wdev = calloc_a(sizeof(*wdev), &name_buf, strlen(name) + 1);
 | |
| + 
 | |
| +@@ -1128,7 +1158,7 @@ wireless_station_create(struct wireless_
 | |
| + 	char *name_buf;
 | |
| + 	char name[8];
 | |
| + 
 | |
| +-	blobmsg_parse(sta_policy, __STA_ATTR_MAX, tb, blob_data(data), blob_len(data));
 | |
| ++	blobmsg_parse_attr(sta_policy, __STA_ATTR_MAX, tb, data);
 | |
| + 
 | |
| + 	cur = tb[STA_ATTR_DISABLED];
 | |
| + 	if (cur && blobmsg_get_bool(cur))
 | |
| +@@ -1168,7 +1198,7 @@ wireless_vlan_create(struct wireless_int
 | |
| + 	char *name_buf;
 | |
| + 	char name[8];
 | |
| + 
 | |
| +-	blobmsg_parse(vlan_policy, __VLAN_ATTR_MAX, tb, blob_data(data), blob_len(data));
 | |
| ++	blobmsg_parse_attr(vlan_policy, __VLAN_ATTR_MAX, tb, data);
 | |
| + 
 | |
| + 	cur = tb[VLAN_ATTR_DISABLED];
 | |
| + 	if (cur && blobmsg_get_bool(cur))
 | |
| +@@ -1208,7 +1238,7 @@ struct wireless_interface* wireless_inte
 | |
| + 	char *name_buf;
 | |
| + 	char name[8];
 | |
| + 
 | |
| +-	blobmsg_parse(vif_policy, __VIF_ATTR_MAX, tb, blob_data(data), blob_len(data));
 | |
| ++	blobmsg_parse_attr(vif_policy, __VIF_ATTR_MAX, tb, data);
 | |
| + 
 | |
| + 	cur = tb[VIF_ATTR_DISABLED];
 | |
| + 	if (cur && blobmsg_get_bool(cur))
 | |
| +@@ -1232,7 +1262,15 @@ struct wireless_interface* wireless_inte
 | |
| + 
 | |
| + 	vlist_add(&wdev->interfaces, &vif->node, vif->name);
 | |
| + 
 | |
| +-	return vlist_find(&wdev->interfaces, name, vif, node);
 | |
| ++	vif = vlist_find(&wdev->interfaces, name, vif, node);
 | |
| ++	if (!vif)
 | |
| ++		return NULL;
 | |
| ++
 | |
| ++	vif->vlan_idx = vif->sta_idx = 0;
 | |
| ++	vlist_update(&vif->vlans);
 | |
| ++	vlist_update(&vif->stations);
 | |
| ++
 | |
| ++	return vif;
 | |
| + }
 | |
| + 
 | |
| + /* ubus callback network.wireless.status, runs for every interface */
 | |
| +@@ -1321,8 +1359,7 @@ wireless_interface_set_data(struct wirel
 | |
| + 	struct blob_attr *tb[__VIF_DATA_MAX];
 | |
| + 	struct blob_attr *cur;
 | |
| + 
 | |
| +-	blobmsg_parse(data_policy, __VIF_DATA_MAX, tb,
 | |
| +-		      blobmsg_data(vif->data), blobmsg_data_len(vif->data));
 | |
| ++	blobmsg_parse_attr(data_policy, __VIF_DATA_MAX, tb, vif->data);
 | |
| + 
 | |
| + 	if ((cur = tb[VIF_DATA_IFNAME]))
 | |
| + 		vif->ifname = blobmsg_data(cur);
 | |
| +@@ -1342,8 +1379,7 @@ wireless_vlan_set_data(struct wireless_v
 | |
| + 	struct blob_attr *tb[__VLAN_DATA_MAX];
 | |
| + 	struct blob_attr *cur;
 | |
| + 
 | |
| +-	blobmsg_parse(data_policy, __VLAN_DATA_MAX, tb,
 | |
| +-		      blobmsg_data(vlan->data), blobmsg_data_len(vlan->data));
 | |
| ++	blobmsg_parse_attr(data_policy, __VLAN_DATA_MAX, tb, vlan->data);
 | |
| + 
 | |
| + 	if ((cur = tb[VLAN_DATA_IFNAME]))
 | |
| + 		vlan->ifname = blobmsg_data(cur);
 | |
| +@@ -1374,7 +1410,7 @@ wireless_device_add_process(struct wirel
 | |
| + 	if (!data)
 | |
| + 		return UBUS_STATUS_INVALID_ARGUMENT;
 | |
| + 
 | |
| +-	blobmsg_parse(proc_policy, __PROC_ATTR_MAX, tb, blobmsg_data(data), blobmsg_data_len(data));
 | |
| ++	blobmsg_parse_attr(proc_policy, __PROC_ATTR_MAX, tb, data);
 | |
| + 	if (!tb[PROC_ATTR_PID] || !tb[PROC_ATTR_EXE])
 | |
| + 		return UBUS_STATUS_INVALID_ARGUMENT;
 | |
| + 
 | |
| +@@ -1420,7 +1456,7 @@ wireless_device_process_kill_all(struct
 | |
| + 	bool immediate = false;
 | |
| + 	int signal = SIGTERM;
 | |
| + 
 | |
| +-	blobmsg_parse(kill_policy, __KILL_ATTR_MAX, tb, blobmsg_data(data), blobmsg_data_len(data));
 | |
| ++	blobmsg_parse_attr(kill_policy, __KILL_ATTR_MAX, tb, data);
 | |
| + 
 | |
| + 	if ((cur = tb[KILL_ATTR_SIGNAL]))
 | |
| + 		signal = blobmsg_get_u32(cur);
 | |
| +@@ -1451,7 +1487,7 @@ wireless_device_set_retry(struct wireles
 | |
| + 	};
 | |
| + 	struct blob_attr *val;
 | |
| + 
 | |
| +-	blobmsg_parse(&retry_policy, 1, &val, blobmsg_data(data), blobmsg_data_len(data));
 | |
| ++	blobmsg_parse_attr(&retry_policy, 1, &val, data);
 | |
| + 	if (val)
 | |
| + 		wdev->retry = blobmsg_get_u32(val);
 | |
| + 	else
 | |
| +@@ -1492,7 +1528,7 @@ wireless_device_notify(struct wireless_d
 | |
| + 	struct blob_attr *tb[__NOTIFY_MAX];
 | |
| + 	struct blob_attr *cur, **pdata;
 | |
| + 
 | |
| +-	blobmsg_parse(notify_policy, __NOTIFY_MAX, tb, blob_data(data), blob_len(data));
 | |
| ++	blobmsg_parse_attr(notify_policy, __NOTIFY_MAX, tb, data);
 | |
| + 
 | |
| + 	if (!tb[NOTIFY_ATTR_COMMAND])
 | |
| + 		return UBUS_STATUS_INVALID_ARGUMENT;
 | |
| +@@ -1555,33 +1591,41 @@ wireless_device_notify(struct wireless_d
 | |
| + }
 | |
| + 
 | |
| + static void
 | |
| ++wdev_vlan_check_network_enabled(struct wireless_device *wdev,
 | |
| ++				struct wireless_interface *vif)
 | |
| ++{
 | |
| ++	struct wireless_vlan *vlan;
 | |
| ++
 | |
| ++	vlist_for_each_element(&vif->vlans, vlan, node) {
 | |
| ++		int enabled = -1, ifindex = -1;
 | |
| ++
 | |
| ++		wireless_check_interface(vlan->network, &enabled, &ifindex);
 | |
| ++
 | |
| ++		if (wdev->state != IFS_UP || vlan->network_ifindex == ifindex)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		vlan->network_ifindex = ifindex;
 | |
| ++		wdev->config_update = true;
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| ++static void
 | |
| + wdev_check_network_enabled(struct wireless_device *wdev)
 | |
| + {
 | |
| + 	struct wireless_interface *vif;
 | |
| +-	struct interface *iface;
 | |
| +-	struct blob_attr *cur;
 | |
| +-	size_t rem;
 | |
| + 
 | |
| + 	vlist_for_each_element(&wdev->interfaces, vif, node) {
 | |
| +-		int enabled = -1;
 | |
| ++		int enabled = -1, ifindex = -1;
 | |
| + 
 | |
| +-		blobmsg_for_each_attr(cur, vif->network, rem) {
 | |
| +-			iface = vlist_find(&interfaces, blobmsg_get_string(cur), iface, node);
 | |
| +-			if (!iface)
 | |
| +-				continue;
 | |
| ++		wireless_check_interface(vif->network, &enabled, &ifindex);
 | |
| ++		wdev_vlan_check_network_enabled(wdev, vif);
 | |
| + 
 | |
| +-			if (iface->autostart) {
 | |
| +-				enabled = 1;
 | |
| +-				break;
 | |
| +-			}
 | |
| +-			if (enabled != 1)
 | |
| +-				enabled = 0;
 | |
| +-		}
 | |
| +-
 | |
| +-		if (vif->disabled == !enabled)
 | |
| ++		if (vif->disabled == !enabled &&
 | |
| ++		    (wdev->state != IFS_UP || vif->network_ifindex == ifindex))
 | |
| + 			continue;
 | |
| + 
 | |
| + 		vif->disabled = !enabled;
 | |
| ++		vif->network_ifindex = ifindex;
 | |
| + 		wdev->config_update = true;
 | |
| + 	}
 | |
| + }
 | |
| +@@ -1639,10 +1683,8 @@ void wireless_device_hotplug_event(const
 | |
| + 			return;
 | |
| + 
 | |
| + 		len = s - name;
 | |
| +-	} else if (!device_find(name)) {
 | |
| +-		len = strlen(name);
 | |
| + 	} else {
 | |
| +-		return;
 | |
| ++		len = strlen(name);
 | |
| + 	}
 | |
| + 
 | |
| + 	vlist_for_each_element(&wireless_devices, wdev, node) {
 | |
| +--- a/wireless.h
 | |
| ++++ b/wireless.h
 | |
| +@@ -96,6 +96,8 @@ struct wireless_interface {
 | |
| + 	int vlan_idx;
 | |
| + 	int sta_idx;
 | |
| + 	bool disabled;
 | |
| ++
 | |
| ++	int network_ifindex;
 | |
| + };
 | |
| + 
 | |
| + struct wireless_vlan {
 | |
| +@@ -112,6 +114,8 @@ struct wireless_vlan {
 | |
| + 	int multicast_to_unicast;
 | |
| + 	bool isolate;
 | |
| + 	bool bridge_isolate;
 | |
| ++
 | |
| ++	int network_ifindex;
 | |
| + };
 | |
| + 
 | |
| + struct wireless_station {
 | |
| -- 
 | |
| 2.34.1
 | |
| 
 | 
