[openwrt/openwrt] hostapd: add support for querying bss config parameters via ubus

LEDE Commits lede-commits at lists.infradead.org
Tue Oct 22 04:09:38 PDT 2024


nbd pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/ed484caa030e9276ea8fee02ef4f069df9477aae

commit ed484caa030e9276ea8fee02ef4f069df9477aae
Author: Felix Fietkau <nbd at nbd.name>
AuthorDate: Tue Oct 22 10:59:55 2024 +0200

    hostapd: add support for querying bss config parameters via ubus
    
    Supports reading the same parameters currently being used by iwinfo.
    Preparation for replacing iwinfo with a rewrite in ucode.
    
    Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 package/network/services/hostapd/files/hostapd.uc  | 54 ++++++++++++++++++++++
 .../services/hostapd/files/wpa_supplicant.uc       | 27 +++++++++++
 .../services/hostapd/src/wpa_supplicant/ucode.c    | 27 +++++++++++
 3 files changed, 108 insertions(+)

diff --git a/package/network/services/hostapd/files/hostapd.uc b/package/network/services/hostapd/files/hostapd.uc
index 6bcb32131d..62fb9cf777 100644
--- a/package/network/services/hostapd/files/hostapd.uc
+++ b/package/network/services/hostapd/files/hostapd.uc
@@ -30,6 +30,23 @@ hostapd.data.iface_fields = {
 	iapp_interface: true,
 };
 
+hostapd.data.bss_info_fields = {
+	// radio
+	hw_mode: true,
+	channel: true,
+	ieee80211ac: true,
+	ieee80211ax: true,
+
+	// bss
+	bssid: true,
+	ssid: true,
+	wpa: true,
+	wpa_key_mgmt: true,
+	wpa_pairwise: true,
+	auth_algs: true,
+	ieee80211w: true,
+};
+
 function iface_remove(cfg)
 {
 	if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname)
@@ -752,6 +769,17 @@ function ex_wrap(func) {
 	};
 }
 
+function bss_config(bss_name) {
+	for (let phy, config in hostapd.data.config) {
+		if (!config)
+			continue;
+
+		for (let bss in config.bss)
+			if (bss.ifname == bss_name)
+				return [ config, bss ];
+	}
+}
+
 let main_obj = {
 	reload: {
 		args: {
@@ -896,6 +924,32 @@ let main_obj = {
 			return 0;
 		})
 	},
+	bss_info: {
+		args: {
+			iface: ""
+		},
+		call: ex_wrap(function(req) {
+			if (!req.args.iface)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			let config = bss_config(req.args.iface);
+			if (!config)
+				return libubus.STATUS_NOT_FOUND;
+
+			let bss = config[1];
+			config = config[0];
+			let ret = {};
+
+			for (let line in [ ...config.radio.data, ...bss.data ]) {
+				let fields = split(line, "=", 2);
+				let name = fields[0];
+				if (hostapd.data.bss_info_fields[name])
+					ret[name] = fields[1];
+			}
+
+			return ret;
+		})
+	},
 };
 
 hostapd.data.ubus = ubus;
diff --git a/package/network/services/hostapd/files/wpa_supplicant.uc b/package/network/services/hostapd/files/wpa_supplicant.uc
index 31d4534625..eed34f8513 100644
--- a/package/network/services/hostapd/files/wpa_supplicant.uc
+++ b/package/network/services/hostapd/files/wpa_supplicant.uc
@@ -245,6 +245,33 @@ let main_obj = {
 			return 0;
 		}
 	},
+	bss_info: {
+		args: {
+			iface: "",
+		},
+		call: function(req) {
+			let ifname = req.args.iface;
+			if (!ifname)
+				return libubus.STATUS_INVALID_ARGUMENT;
+
+			let iface = wpas.interfaces[ifname];
+			if (!iface)
+				return libubus.STATUS_NOT_FOUND;
+
+			let status = iface.ctrl("STATUS");
+			if (!status)
+				return libubus.STATUS_NOT_FOUND;
+
+			let ret = {};
+			status = split(status, "\n");
+			for (let line in status) {
+				line = split(line, "=", 2);
+				ret[line[0]] = line[1];
+			}
+
+			return ret;
+		}
+	},
 };
 
 wpas.data.ubus = ubus;
diff --git a/package/network/services/hostapd/src/wpa_supplicant/ucode.c b/package/network/services/hostapd/src/wpa_supplicant/ucode.c
index 397f85bde7..9380b301c3 100644
--- a/package/network/services/hostapd/src/wpa_supplicant/ucode.c
+++ b/package/network/services/hostapd/src/wpa_supplicant/ucode.c
@@ -5,6 +5,7 @@
 #include "ap/hostapd.h"
 #include "wpa_supplicant_i.h"
 #include "wps_supplicant.h"
+#include "ctrl_iface.h"
 #include "bss.h"
 #include "ucode.h"
 
@@ -255,6 +256,31 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs)
 	return ret;
 }
 
+static uc_value_t *
+uc_wpas_iface_ctrl(uc_vm_t *vm, size_t nargs)
+{
+	struct wpa_supplicant *wpa_s = uc_fn_thisval("wpas.iface");
+	uc_value_t *arg = uc_fn_arg(0);
+	size_t reply_len;
+	uc_value_t *ret;
+	char *reply;
+
+	if (!wpa_s || ucv_type(arg) != UC_STRING)
+		return NULL;
+
+	reply = wpa_supplicant_ctrl_iface_process(wpa_s, ucv_string_get(arg), &reply_len);
+	if (reply_len < 0)
+		return NULL;
+
+	if (reply_len && reply[reply_len - 1] == '\n')
+		reply_len--;
+
+	ret = ucv_string_new_length(reply, reply_len);
+	free(reply);
+
+	return ret;
+}
+
 int wpas_ucode_init(struct wpa_global *gl)
 {
 	static const uc_function_list_t global_fns[] = {
@@ -266,6 +292,7 @@ int wpas_ucode_init(struct wpa_global *gl)
 	};
 	static const uc_function_list_t iface_fns[] = {
 		{ "status", uc_wpas_iface_status },
+		{ "ctrl", uc_wpas_iface_ctrl },
 	};
 	uc_value_t *data, *proto;
 




More information about the lede-commits mailing list