mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-30 18:07:52 +00:00 
			
		
		
		
	netifd: various backports from HEAD branch
Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
		
							
								
								
									
										502
									
								
								patches/0078-netifd-add-various-backports.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										502
									
								
								patches/0078-netifd-add-various-backports.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,502 @@ | ||||
| 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 | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 John Crispin
					John Crispin