hostapd: do not store data in object prototype
authorFelix Fietkau <nbd@nbd.name>
Fri, 11 Aug 2023 22:36:13 +0000 (00:36 +0200)
committerFelix Fietkau <nbd@nbd.name>
Sat, 12 Aug 2023 06:42:12 +0000 (08:42 +0200)
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 <nbd@nbd.name>
package/network/services/hostapd/files/hostapd.uc
package/network/services/hostapd/files/wpa_supplicant.uc
package/network/services/hostapd/src/src/ap/ucode.c
package/network/services/hostapd/src/src/utils/ucode.c
package/network/services/hostapd/src/src/utils/ucode.h
package/network/services/hostapd/src/wpa_supplicant/ucode.c

index 070d70a96420e176861ec5fa57e25dabc68acae7..f9f0c31babc21c8faec8f3cbbc1289d19c13e528 100644 (file)
@@ -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;
index 6308fd54e2d332140c3e914f3d5689c3a2340a8c..e3a3afcff21004361e0bedd2cd330ffd1f6d3476 100644 (file)
@@ -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}`);
index fe99c3f667ccd86cf9f42dadb60face4373f8e36..053171b1429ffb12e609734abd5deb0f35d2df50 100644 (file)
@@ -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:
index b9e7d871c7a5e456c16fcc204bc15a97d4ae4c24..44169f0bf0a6ff84e1324228862d287804970b16 100644 (file)
@@ -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)
index 6f0dd4408ef93474b6b6e2b9b67c1df9aac3325f..2c1886976ee5a2a576bb9a3710d541942cc71019 100644 (file)
@@ -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);
 
index 96e105791395959aa96a6705f2e21eb6dbd15e44..d0a78d16253539ba6810ed30036d07278d1cba5d 100644 (file)
@@ -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);