Browse Source

hostapd: do not store data in object prototype

It cannot be properly cloned, since it is attached to the resource type.
Use a separate registry for data. Fixes object confusion issues

Signed-off-by: Felix Fietkau <[email protected]>
Felix Fietkau 2 năm trước cách đây
mục cha
commit
a0a5b97674

+ 9 - 5
package/network/services/hostapd/files/hostapd.uc

@@ -125,13 +125,18 @@ function iface_reload_config(phy, config, old_config)
 	if (config.bss[0].ifname != old_config.bss[0].ifname)
 		return false;
 
-	let iface = hostapd.interfaces[config.bss[0].ifname];
+	let iface_name = config.bss[0].ifname;
+	let iface = hostapd.interfaces[iface_name];
 	if (!iface)
 		return false;
 
+	let first_bss = hostapd.bss[iface_name];
+	if (!first_bss)
+		return false;
+
 	let config_inline = iface_gen_config(phy, config);
 
-	bss_reload_psk(iface.bss[0], config.bss[0], old_config.bss[0]);
+	bss_reload_psk(first_bss, config.bss[0], old_config.bss[0]);
 	if (!is_equal(config.bss[0], old_config.bss[0])) {
 		if (phy_is_fullmac(phy))
 			return false;
@@ -140,18 +145,17 @@ function iface_reload_config(phy, config, old_config)
 			return false;
 
 		hostapd.printf(`Reload config for bss '${config.bss[0].ifname}' on phy '${phy}'`);
-		if (iface.bss[0].set_config(config_inline, 0) < 0) {
+		if (first_bss.set_config(config_inline, 0) < 0) {
 			hostapd.printf(`Failed to set config`);
 			return false;
 		}
 	}
 
-	let bss_list = array_to_obj(iface.bss, "name", 1);
 	let new_cfg = array_to_obj(config.bss, "ifname", 1);
 	let old_cfg = array_to_obj(old_config.bss, "ifname", 1);
 
 	for (let name in old_cfg) {
-		let bss = bss_list[name];
+		let bss = hostapd.bss[name];
 		if (!bss) {
 			hostapd.printf(`bss '${name}' not found`);
 			return false;

+ 12 - 10
package/network/services/hostapd/files/wpa_supplicant.uc

@@ -92,11 +92,16 @@ let main_obj = {
 			if (!phy)
 				return libubus.STATUS_NOT_FOUND;
 
-			if (req.args.stop) {
-				for (let ifname in phy.data)
-					iface_stop(phy.data[ifname]);
-			} else {
-				start_pending(req.args.phy);
+			try {
+				if (req.args.stop) {
+					for (let ifname in phy.data)
+						iface_stop(phy.data[ifname]);
+				} else {
+					start_pending(req.args.phy);
+				}
+			} catch (e) {
+				wpas.printf(`Error chaging state: ${e}\n${e.stacktrace[0].context}`);
+				return libubus.STATUS_INVALID_ARGUMENT;
 			}
 			return 0;
 		}
@@ -221,14 +226,12 @@ return {
 		wpas.ubus.disconnect();
 	},
 	iface_add: function(name, obj) {
-		obj.data.name = name;
 		iface_event("add", name);
 	},
 	iface_remove: function(name, obj) {
 		iface_event("remove", name);
 	},
-	state: function(iface, state) {
-		let ifname = iface.data.name;
+	state: function(ifname, iface, state) {
 		let phy = wpas.data.iface_phy[ifname];
 		if (!phy) {
 			wpas.printf(`no PHY for ifname ${ifname}`);
@@ -237,8 +240,7 @@ return {
 
 		iface_hostapd_notify(phy, ifname, iface, state);
 	},
-	event: function(iface, ev, info) {
-		let ifname = iface.data.name;
+	event: function(ifname, iface, ev, info) {
 		let phy = wpas.data.iface_phy[ifname];
 		if (!phy) {
 			wpas.printf(`no PHY for ifname ${ifname}`);

+ 14 - 14
package/network/services/hostapd/src/src/ap/ucode.c

@@ -23,7 +23,7 @@ hostapd_ucode_bss_get_uval(struct hostapd_data *hapd)
 		return wpa_ucode_registry_get(bss_registry, hapd->ucode.idx);
 
 	val = uc_resource_new(bss_type, hapd);
-	wpa_ucode_registry_add(bss_registry, val, &hapd->ucode.idx);
+	hapd->ucode.idx = wpa_ucode_registry_add(bss_registry, val);
 
 	return val;
 }
@@ -37,46 +37,46 @@ hostapd_ucode_iface_get_uval(struct hostapd_iface *hapd)
 		return wpa_ucode_registry_get(iface_registry, hapd->ucode.idx);
 
 	val = uc_resource_new(iface_type, hapd);
-	wpa_ucode_registry_add(iface_registry, val, &hapd->ucode.idx);
+	hapd->ucode.idx = wpa_ucode_registry_add(iface_registry, val);
 
 	return val;
 }
 
 static void
-hostapd_ucode_update_bss_list(struct hostapd_iface *iface)
+hostapd_ucode_update_bss_list(struct hostapd_iface *iface, uc_value_t *if_bss, uc_value_t *bss)
 {
-	uc_value_t *ifval, *list;
+	uc_value_t *list;
 	int i;
 
 	list = ucv_array_new(vm);
 	for (i = 0; i < iface->num_bss; i++) {
 		struct hostapd_data *hapd = iface->bss[i];
 		uc_value_t *val = hostapd_ucode_bss_get_uval(hapd);
-		uc_value_t *proto = ucv_prototype_get(val);
 
-		ucv_object_add(proto, "name", ucv_get(ucv_string_new(hapd->conf->iface)));
-		ucv_object_add(proto, "index", ucv_int64_new(i));
-		ucv_array_set(list, i, ucv_get(val));
+		ucv_array_set(list, i, ucv_get(ucv_string_new(hapd->conf->iface)));
+		ucv_object_add(bss, hapd->conf->iface, ucv_get(val));
 	}
-
-	ifval = hostapd_ucode_iface_get_uval(iface);
-	ucv_object_add(ucv_prototype_get(ifval), "bss", ucv_get(list));
+	ucv_object_add(if_bss, iface->phy, ucv_get(list));
 }
 
 static void
 hostapd_ucode_update_interfaces(void)
 {
 	uc_value_t *ifs = ucv_object_new(vm);
+	uc_value_t *if_bss = ucv_array_new(vm);
+	uc_value_t *bss = ucv_object_new(vm);
 	int i;
 
 	for (i = 0; i < interfaces->count; i++) {
 		struct hostapd_iface *iface = interfaces->iface[i];
 
 		ucv_object_add(ifs, iface->phy, ucv_get(hostapd_ucode_iface_get_uval(iface)));
-		hostapd_ucode_update_bss_list(iface);
+		hostapd_ucode_update_bss_list(iface, if_bss, bss);
 	}
 
 	ucv_object_add(ucv_prototype_get(global), "interfaces", ucv_get(ifs));
+	ucv_object_add(ucv_prototype_get(global), "interface_bss", ucv_get(if_bss));
+	ucv_object_add(ucv_prototype_get(global), "bss", ucv_get(bss));
 	ucv_gc(vm);
 }
 
@@ -199,7 +199,7 @@ uc_hostapd_bss_delete(uc_vm_t *vm, size_t nargs)
 	hostapd_config_free_bss(hapd->conf);
 	os_free(hapd);
 
-	hostapd_ucode_update_bss_list(iface);
+	hostapd_ucode_update_interfaces();
 	ucv_gc(vm);
 
 	return NULL;
@@ -252,7 +252,7 @@ uc_hostapd_iface_add_bss(uc_vm_t *vm, size_t nargs)
 	iface->conf->bss[iface->conf->num_bss] = bss;
 	conf->bss[idx] = NULL;
 	ret = hostapd_ucode_bss_get_uval(hapd);
-	hostapd_ucode_update_bss_list(iface);
+	hostapd_ucode_update_interfaces();
 	goto out;
 
 deinit_ctrl:

+ 2 - 19
package/network/services/hostapd/src/src/utils/ucode.c

@@ -271,21 +271,7 @@ uc_value_t *wpa_ucode_global_init(const char *name, uc_resource_type_t *global_t
 	return global;
 }
 
-static uc_value_t *wpa_ucode_prototype_clone(uc_value_t *uval)
-{
-	uc_value_t *proto, *proto_new;
-
-	proto = ucv_prototype_get(uval);
-	proto_new = ucv_object_new(&vm);
-
-	ucv_object_foreach(proto, key, val)
-		ucv_object_add(proto_new, key, ucv_get(val));
-	ucv_prototype_set(uval, ucv_get(proto));
-
-	return proto;
-}
-
-void wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val, int *idx)
+int wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val)
 {
 	uc_value_t *data;
 	int i = 0;
@@ -295,10 +281,7 @@ void wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val, int *idx)
 
 	ucv_array_set(reg, i, ucv_get(val));
 
-	data = ucv_object_new(&vm);
-	ucv_object_add(wpa_ucode_prototype_clone(val), "data", ucv_get(data));
-
-	*idx = i + 1;
+	return i + 1;
 }
 
 uc_value_t *wpa_ucode_registry_get(uc_value_t *reg, int idx)

+ 1 - 1
package/network/services/hostapd/src/src/utils/ucode.h

@@ -17,7 +17,7 @@ void wpa_ucode_free_vm(void);
 
 uc_value_t *wpa_ucode_global_init(const char *name, uc_resource_type_t *global_type);
 
-void wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val, int *idx);
+int wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val);
 uc_value_t *wpa_ucode_registry_get(uc_value_t *reg, int idx);
 uc_value_t *wpa_ucode_registry_remove(uc_value_t *reg, int idx);
 

+ 6 - 4
package/network/services/hostapd/src/wpa_supplicant/ucode.c

@@ -21,7 +21,7 @@ wpas_ucode_iface_get_uval(struct wpa_supplicant *wpa_s)
 		return wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx);
 
 	val = uc_resource_new(iface_type, wpa_s);
-	wpa_ucode_registry_add(iface_registry, val, &wpa_s->ucode.idx);
+	wpa_s->ucode.idx = wpa_ucode_registry_add(iface_registry, val);
 
 	return val;
 }
@@ -84,9 +84,10 @@ void wpas_ucode_update_state(struct wpa_supplicant *wpa_s)
 		return;
 
 	state = wpa_supplicant_state_txt(wpa_s->wpa_state);
+	uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname)));
 	uc_value_push(ucv_get(val));
 	uc_value_push(ucv_get(ucv_string_new(state)));
-	ucv_put(wpa_ucode_call(2));
+	ucv_put(wpa_ucode_call(3));
 	ucv_gc(vm);
 }
 
@@ -105,6 +106,7 @@ void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_d
 	if (wpa_ucode_call_prepare("event"))
 		return;
 
+	uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname)));
 	uc_value_push(ucv_get(val));
 	uc_value_push(ucv_get(ucv_string_new(event_to_string(event))));
 	val = ucv_object_new(vm);
@@ -118,7 +120,7 @@ void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_d
 		ucv_object_add(val, "center_freq2", ucv_int64_new(data->ch_switch.cf2));
 	}
 
-	ucv_put(wpa_ucode_call(3));
+	ucv_put(wpa_ucode_call(4));
 	ucv_gc(vm);
 }
 
@@ -245,7 +247,7 @@ int wpas_ucode_init(struct wpa_global *gl)
 	iface_type = uc_type_declare(vm, "wpas.iface", iface_fns, NULL);
 
 	iface_registry = ucv_array_new(vm);
-	uc_vm_registry_set(vm, "hostap.iface_registry", iface_registry);
+	uc_vm_registry_set(vm, "wpas.iface_registry", iface_registry);
 
 	global = wpa_ucode_global_init("wpas", global_type);