From a0a5b976746b6bbe94c664ac17efc95ce944f8d1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 12 Aug 2023 00:36:13 +0200 Subject: [PATCH] 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 --- .../network/services/hostapd/files/hostapd.uc | 14 ++++++---- .../services/hostapd/files/wpa_supplicant.uc | 22 ++++++++------- .../services/hostapd/src/src/ap/ucode.c | 28 +++++++++---------- .../services/hostapd/src/src/utils/ucode.c | 21 ++------------ .../services/hostapd/src/src/utils/ucode.h | 2 +- .../hostapd/src/wpa_supplicant/ucode.c | 10 ++++--- 6 files changed, 44 insertions(+), 53 deletions(-) diff --git a/package/network/services/hostapd/files/hostapd.uc b/package/network/services/hostapd/files/hostapd.uc index 070d70a964..f9f0c31bab 100644 --- a/package/network/services/hostapd/files/hostapd.uc +++ b/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; diff --git a/package/network/services/hostapd/files/wpa_supplicant.uc b/package/network/services/hostapd/files/wpa_supplicant.uc index 6308fd54e2..e3a3afcff2 100644 --- a/package/network/services/hostapd/files/wpa_supplicant.uc +++ b/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}`); diff --git a/package/network/services/hostapd/src/src/ap/ucode.c b/package/network/services/hostapd/src/src/ap/ucode.c index fe99c3f667..053171b142 100644 --- a/package/network/services/hostapd/src/src/ap/ucode.c +++ b/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: diff --git a/package/network/services/hostapd/src/src/utils/ucode.c b/package/network/services/hostapd/src/src/utils/ucode.c index b9e7d871c7..44169f0bf0 100644 --- a/package/network/services/hostapd/src/src/utils/ucode.c +++ b/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) diff --git a/package/network/services/hostapd/src/src/utils/ucode.h b/package/network/services/hostapd/src/src/utils/ucode.h index 6f0dd4408e..2c1886976e 100644 --- a/package/network/services/hostapd/src/src/utils/ucode.h +++ b/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); diff --git a/package/network/services/hostapd/src/wpa_supplicant/ucode.c b/package/network/services/hostapd/src/wpa_supplicant/ucode.c index 96e1057913..d0a78d1625 100644 --- a/package/network/services/hostapd/src/wpa_supplicant/ucode.c +++ b/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); -- 2.30.2