diff --git a/feeds/ipq807x_v5.4/hostapd/Makefile b/feeds/ipq807x_v5.4/hostapd/Makefile index 24638ed38..2698b4bd6 100644 --- a/feeds/ipq807x_v5.4/hostapd/Makefile +++ b/feeds/ipq807x_v5.4/hostapd/Makefile @@ -84,6 +84,8 @@ ifneq ($(CONFIG_DRIVER_11AX_SUPPORT),) HOSTAPD_IEEE80211AX:=y endif +CORE_DEPENDS = +libubus +libucode +ucode-mod-fs +ucode-mod-nl80211 +ucode-mod-ubus +ucode-mod-uloop +libblobmsg-json + DRIVER_MAKEOPTS= \ CONFIG_ACS=$(CONFIG_PACKAGE_kmod-cfg80211) \ CONFIG_DRIVER_NL80211=$(CONFIG_PACKAGE_kmod-cfg80211) \ @@ -91,6 +93,7 @@ DRIVER_MAKEOPTS= \ CONFIG_IEEE80211AC=$(HOSTAPD_IEEE80211AC) \ CONFIG_IEEE80211AX=$(HOSTAPD_IEEE80211AX) \ CONFIG_DRIVER_WEXT=$(CONFIG_DRIVER_WEXT_SUPPORT) \ + CONFIG_UCODE=y ifeq ($(SSL_VARIANT),openssl) DRIVER_MAKEOPTS += CONFIG_TLS=openssl CONFIG_SAE=y @@ -142,7 +145,7 @@ define Package/hostapd/Default SUBMENU:=WirelessAPD TITLE:=IEEE 802.1x Authenticator URL:=http://hostap.epitest.fi/ - DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus + DEPENDS:=$(DRV_DEPENDS) +hostapd-common $(CORE_DEPENDS) USERID:=network=101:network=101 PROVIDES:=hostapd CONFLICTS:=$(HOSTAPD_PROVIDERS) @@ -226,7 +229,7 @@ define Package/wpad/Default CATEGORY:=Network SUBMENU:=WirelessAPD TITLE:=IEEE 802.1x Auth/Supplicant - DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus + DEPENDS:=$(DRV_DEPENDS) +hostapd-common $(CORE_DEPENDS) USERID:=network=101:network=101 URL:=http://hostap.epitest.fi/ PROVIDES:=hostapd wpa-supplicant @@ -341,7 +344,7 @@ define Package/wpa-supplicant/Default SUBMENU:=WirelessAPD TITLE:=WPA Supplicant URL:=http://hostap.epitest.fi/wpa_supplicant/ - DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus + DEPENDS:=$(DRV_DEPENDS) +hostapd-common $(CORE_DEPENDS) USERID:=network=101:network=101 PROVIDES:=wpa-supplicant CONFLICTS:=$(SUPPLICANT_PROVIDERS) @@ -446,7 +449,7 @@ define Package/eapol-test/Default SECTION:=net SUBMENU:=WirelessAPD CATEGORY:=Network - DEPENDS:=$(DRV_DEPENDS) +libubus + DEPENDS:=$(DRV_DEPENDS) $(CORE_DEPENDS) endef define Package/eapol-test @@ -503,7 +506,7 @@ TARGET_CPPFLAGS := \ $(if $(CONFIG_WPA_MSG_MIN_PRIORITY),-DCONFIG_MSG_MIN_PRIORITY=$(CONFIG_WPA_MSG_MIN_PRIORITY)) TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto -TARGET_LDFLAGS += -Wl,--gc-sections -flto=jobserver -fuse-linker-plugin -lubox -lubus +TARGET_LDFLAGS += -Wl,--gc-sections -flto=jobserver -fuse-linker-plugin -lubox -lubus -lucode ifdef CONFIG_PACKAGE_kmod-cfg80211 TARGET_LDFLAGS += -lm -lnl-tiny @@ -587,20 +590,24 @@ define Build/Compile endef define Install/hostapd - $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/share/hostap + $(INSTALL_DATA) ./files/hostapd.uc $(1)/usr/share/hostap/ endef define Install/supplicant - $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/share/hostap + $(INSTALL_DATA) ./files/wpa_supplicant.uc $(1)/usr/share/hostap/ endef define Package/hostapd-common/install - $(INSTALL_DIR) $(1)/etc/capabilities $(1)/etc/rc.button $(1)/etc/hotplug.d/ieee80211 $(1)/etc/init.d $(1)/lib/netifd $(1)/usr/share/acl.d + $(INSTALL_DIR) $(1)/etc/capabilities $(1)/etc/rc.button $(1)/etc/hotplug.d/ieee80211 $(1)/etc/init.d $(1)/lib/netifd $(1)/usr/share/acl.d $(1)/usr/share/hostap $(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/netifd/hostapd.sh $(INSTALL_BIN) ./files/wpad.init $(1)/etc/init.d/wpad $(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps $(INSTALL_DATA) ./files/wpad_acl.json $(1)/usr/share/acl.d $(INSTALL_DATA) ./files/wpad.json $(1)/etc/capabilities + $(INSTALL_DATA) ./files/common.uc $(1)/usr/share/hostap/ + $(INSTALL_DATA) ./files/wdev.uc $(1)/usr/share/hostap/ endef define Package/hostapd/install diff --git a/feeds/ipq807x_v5.4/hostapd/files/common.uc b/feeds/ipq807x_v5.4/hostapd/files/common.uc new file mode 100644 index 000000000..9ece3b1af --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/files/common.uc @@ -0,0 +1,168 @@ +import * as nl80211 from "nl80211"; +import * as rtnl from "rtnl"; +import { readfile } from "fs"; + +const iftypes = { + ap: nl80211.const.NL80211_IFTYPE_AP, + mesh: nl80211.const.NL80211_IFTYPE_MESH_POINT, + sta: nl80211.const.NL80211_IFTYPE_STATION, + adhoc: nl80211.const.NL80211_IFTYPE_ADHOC, + monitor: nl80211.const.NL80211_IFTYPE_MONITOR, +}; + +function wdev_remove(name) +{ + nl80211.request(nl80211.const.NL80211_CMD_DEL_INTERFACE, 0, { dev: name }); +} + +function __phy_is_fullmac(phyidx) +{ + let data = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, 0, { wiphy: phyidx }); + + return !data.software_iftypes.ap_vlan; +} + +function phy_is_fullmac(phy) +{ + let phyidx = int(trim(readfile(`/sys/class/ieee80211/${phy}/index`))); + + return __phy_is_fullmac(phyidx); +} + +function find_reusable_wdev(phyidx) +{ + if (!__phy_is_fullmac(phyidx)) + return null; + + let data = nl80211.request( + nl80211.const.NL80211_CMD_GET_INTERFACE, + nl80211.const.NLM_F_DUMP, + { wiphy: phyidx }); + for (let res in data) + if (trim(readfile(`/sys/class/net/${res.ifname}/operstate`)) == "down") + return res.ifname; + return null; +} + +function wdev_create(phy, name, data) +{ + let phyidx = int(readfile(`/sys/class/ieee80211/${phy}/index`)); + + wdev_remove(name); + + if (!iftypes[data.mode]) + return `Invalid mode: ${data.mode}`; + + let req = { + wiphy: phyidx, + ifname: name, + iftype: iftypes[data.mode], + }; + + if (data["4addr"]) + req["4addr"] = data["4addr"]; + if (data.macaddr) + req.mac = data.macaddr; + + nl80211.error(); + + let reuse_ifname = find_reusable_wdev(phyidx); + if (reuse_ifname && + (reuse_ifname == name || + rtnl.request(rtnl.const.RTM_SETLINK, 0, { dev: reuse_ifname, ifname: name}) != false)) + nl80211.request( + nl80211.const.NL80211_CMD_SET_INTERFACE, 0, { + wiphy: phyidx, + dev: name, + iftype: iftypes[data.mode], + }); + else + nl80211.request( + nl80211.const.NL80211_CMD_NEW_INTERFACE, + nl80211.const.NLM_F_CREATE, + req); + + let error = nl80211.error(); + if (error) + return error; + + if (data.powersave != null) { + nl80211.request(nl80211.const.NL80211_CMD_SET_POWER_SAVE, 0, + { dev: name, ps_state: data.powersave ? 1 : 0}); + } + + return null; +} + +const vlist_proto = { + update: function(values, arg) { + let data = this.data; + let cb = this.cb; + let seq = { }; + let new_data = {}; + let old_data = {}; + + this.data = new_data; + + if (type(values) == "object") { + for (let key in values) { + old_data[key] = data[key]; + new_data[key] = values[key]; + delete data[key]; + } + } else { + for (let val in values) { + let cur_key = val[0]; + let cur_obj = val[1]; + + old_data[cur_key] = data[cur_key]; + new_data[cur_key] = val[1]; + delete data[cur_key]; + } + } + + for (let key in data) { + cb(null, data[key], arg); + delete data[key]; + } + for (let key in new_data) + cb(new_data[key], old_data[key], arg); + } +}; + +function is_equal(val1, val2) { + let t1 = type(val1); + + if (t1 != type(val2)) + return false; + + if (t1 == "array") { + if (length(val1) != length(val2)) + return false; + + for (let i = 0; i < length(val1); i++) + if (!is_equal(val1[i], val2[i])) + return false; + + return true; + } else if (t1 == "object") { + for (let key in val1) + if (!is_equal(val1[key], val2[key])) + return false; + for (let key in val2) + if (!val1[key]) + return false; + return true; + } else { + return val1 == val2; + } +} + +function vlist_new(cb) { + return proto({ + cb: cb, + data: {} + }, vlist_proto); +} + +export { wdev_remove, wdev_create, is_equal, vlist_new, phy_is_fullmac }; diff --git a/feeds/ipq807x_v5.4/hostapd/files/hostapd.sh b/feeds/ipq807x_v5.4/hostapd/files/hostapd.sh index d22e12454..90d921041 100644 --- a/feeds/ipq807x_v5.4/hostapd/files/hostapd.sh +++ b/feeds/ipq807x_v5.4/hostapd/files/hostapd.sh @@ -1203,9 +1203,6 @@ hostapd_set_bss_options() { append bss_conf "$val" "$N" done - bss_md5sum=$(echo $bss_conf | md5sum | cut -d" " -f1) - append bss_conf "config_id=$bss_md5sum" "$N" - append "$var" "$bss_conf" "$N" return 0 } diff --git a/feeds/ipq807x_v5.4/hostapd/files/hostapd.uc b/feeds/ipq807x_v5.4/hostapd/files/hostapd.uc new file mode 100644 index 000000000..f9f0c31ba --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/files/hostapd.uc @@ -0,0 +1,486 @@ +let libubus = require("ubus"); +import { open, readfile } from "fs"; +import { wdev_create, wdev_remove, is_equal, vlist_new, phy_is_fullmac } from "common"; + +let ubus = libubus.connect(); + +hostapd.data.config = {}; + +hostapd.data.file_fields = { + vlan_file: true, + wpa_psk_file: true, + accept_mac_file: true, + deny_mac_file: true, + eap_user_file: true, + ca_cert: true, + server_cert: true, + server_cert2: true, + private_key: true, + private_key2: true, + dh_file: true, + eap_sim_db: true, +}; + +function iface_remove(cfg) +{ + if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname) + return; + + hostapd.remove_iface(cfg.bss[0].ifname); + for (let bss in cfg.bss) + wdev_remove(bss.ifname); +} + +function iface_gen_config(phy, config) +{ + let str = `data: +${join("\n", config.radio.data)} +channel=${config.radio.channel} +`; + + for (let i = 0; i < length(config.bss); i++) { + let bss = config.bss[i]; + let type = i > 0 ? "bss" : "interface"; + + str += ` +${type}=${bss.ifname} +${join("\n", bss.data)} +`; + } + + return str; +} + +function iface_restart(phy, config, old_config) +{ + iface_remove(old_config); + iface_remove(config); + + if (!config.bss || !config.bss[0]) { + hostapd.printf(`No bss for phy ${phy}`); + return; + } + + let bss = config.bss[0]; + let err = wdev_create(phy, bss.ifname, { mode: "ap" }); + if (err) + hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`); + let config_inline = iface_gen_config(phy, config); + + let ubus = hostapd.data.ubus; + ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: true }); + if (hostapd.add_iface(`bss_config=${bss.ifname}:${config_inline}`) < 0) + hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`); + ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: false }); +} + +function array_to_obj(arr, key, start) +{ + let obj = {}; + + start ??= 0; + for (let i = start; i < length(arr); i++) { + let cur = arr[i]; + obj[cur[key]] = cur; + } + + return obj; +} + +function find_array_idx(arr, key, val) +{ + for (let i = 0; i < length(arr); i++) + if (arr[i][key] == val) + return i; + + return -1; +} + +function bss_reload_psk(bss, config, old_config) +{ + if (is_equal(old_config.hash.wpa_psk_file, config.hash.wpa_psk_file)) + return; + + old_config.hash.wpa_psk_file = config.hash.wpa_psk_file; + if (!is_equal(old_config, config)) + return; + + let ret = bss.ctrl("RELOAD_WPA_PSK"); + ret ??= "failed"; + + hostapd.printf(`Reload WPA PSK file for bss ${config.ifname}: ${ret}`); +} + +function iface_reload_config(phy, config, old_config) +{ + if (!old_config || !is_equal(old_config.radio, config.radio)) + return false; + + if (is_equal(old_config.bss, config.bss)) + return true; + + if (!old_config.bss || !old_config.bss[0]) + return false; + + if (config.bss[0].ifname != old_config.bss[0].ifname) + return false; + + 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(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; + + if (config.bss[0].bssid != old_config.bss[0].bssid) + return false; + + hostapd.printf(`Reload config for bss '${config.bss[0].ifname}' on phy '${phy}'`); + if (first_bss.set_config(config_inline, 0) < 0) { + hostapd.printf(`Failed to set config`); + return false; + } + } + + 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 = hostapd.bss[name]; + if (!bss) { + hostapd.printf(`bss '${name}' not found`); + return false; + } + + if (!new_cfg[name]) { + hostapd.printf(`Remove bss '${name}' on phy '${phy}'`); + bss.delete(); + wdev_remove(name); + continue; + } + + let new_cfg_data = new_cfg[name]; + delete new_cfg[name]; + + if (is_equal(old_cfg[name], new_cfg_data)) + continue; + + hostapd.printf(`Reload config for bss '${name}' on phy '${phy}'`); + let idx = find_array_idx(config.bss, "ifname", name); + if (idx < 0) { + hostapd.printf(`bss index not found`); + return false; + } + + if (bss.set_config(config_inline, idx) < 0) { + hostapd.printf(`Failed to set config`); + return false; + } + } + + for (let name in new_cfg) { + hostapd.printf(`Add bss '${name}' on phy '${phy}'`); + + let idx = find_array_idx(config.bss, "ifname", name); + if (idx < 0) { + hostapd.printf(`bss index not found`); + return false; + } + + if (iface.add_bss(config_inline, idx) < 0) { + hostapd.printf(`Failed to add bss`); + return false; + } + } + + return true; +} + +function iface_set_config(phy, config) +{ + let old_config = hostapd.data.config[phy]; + + hostapd.data.config[phy] = config; + + if (!config) + return iface_remove(old_config); + + let ret = iface_reload_config(phy, config, old_config); + if (ret) { + hostapd.printf(`Reloaded settings for phy ${phy}`); + return 0; + } + + hostapd.printf(`Restart interface for phy ${phy}`); + return iface_restart(phy, config, old_config); +} + +function config_add_bss(config, name) +{ + let bss = { + ifname: name, + data: [], + hash: {} + }; + + push(config.bss, bss); + + return bss; +} + +function iface_load_config(filename) +{ + let f = open(filename, "r"); + if (!f) + return null; + + let config = { + radio: { + data: [] + }, + bss: [], + orig_file: filename, + }; + + let bss; + let line; + while ((line = trim(f.read("line"))) != null) { + let val = split(line, "=", 2); + if (!val[0]) + continue; + + if (val[0] == "interface") { + bss = config_add_bss(config, val[1]); + break; + } + + if (val[0] == "channel") { + config.radio.channel = val[1]; + continue; + } + + push(config.radio.data, line); + } + + while ((line = trim(f.read("line"))) != null) { + let val = split(line, "=", 2); + if (!val[0]) + continue; + + if (val[0] == "bssid") + bss.bssid = val[1]; + + if (val[0] == "bss") { + bss = config_add_bss(config, val[1]); + continue; + } + + if (hostapd.data.file_fields[val[0]]) + bss.hash[val[0]] = hostapd.sha1(readfile(val[1])); + + push(bss.data, line); + } + f.close(); + + return config; +} + + + +let main_obj = { + reload: { + args: { + phy: "", + }, + call: function(req) { + try { + let phy_list = req.args.phy ? [ req.args.phy ] : keys(hostapd.data.config); + for (let phy_name in phy_list) { + let phy = hostapd.data.config[phy_name]; + let config = iface_load_config(phy.orig_file); + iface_set_config(phy_name, config); + } + } catch(e) { + hostapd.printf(`Error reloading config: ${e}\n${e.stacktrace[0].context}`); + return libubus.STATUS_INVALID_ARGUMENT; + } + + return 0; + } + }, + apsta_state: { + args: { + phy: "", + up: true, + frequency: 0, + sec_chan_offset: 0, + csa: true, + csa_count: 0, + }, + call: function(req) { + if (req.args.up == null || !req.args.phy) + return libubus.STATUS_INVALID_ARGUMENT; + + let phy = req.args.phy; + let config = hostapd.data.config[phy]; + if (!config || !config.bss || !config.bss[0] || !config.bss[0].ifname) + return 0; + + let iface = hostapd.interfaces[config.bss[0].ifname]; + if (!iface) + return 0; + + if (!req.args.up) { + iface.stop(); + return 0; + } + + let freq = req.args.frequency; + if (!freq) + return libubus.STATUS_INVALID_ARGUMENT; + + let sec_offset = req.args.sec_chan_offset; + if (sec_offset != -1 && sec_offset != 1) + sec_offset = 0; + + let width = 0; + for (let line in config.radio.data) { + if (!sec_offset && match(line, /^ht_capab=.*HT40/)) { + sec_offset = null; // auto-detect + continue; + } + + let val = match(line, /^(vht_oper_chwidth|he_oper_chwidth)=(\d+)/); + if (!val) + continue; + + val = int(val[2]); + if (val > width) + width = val; + } + + if (freq < 4000) + width = 0; + + let freq_info = hostapd.freq_info(freq, sec_offset, width); + if (!freq_info) + return libubus.STATUS_UNKNOWN_ERROR; + + let ret; + if (req.args.csa) { + freq_info.csa_count = req.args.csa_count ?? 10; + ret = iface.switch_channel(freq_info); + } else { + iface.stop(); + ret = iface.start(freq_info); + } + if (!ret) + return libubus.STATUS_UNKNOWN_ERROR; + + return 0; + } + }, + config_set: { + args: { + phy: "", + config: "", + prev_config: "", + }, + call: function(req) { + let phy = req.args.phy; + let file = req.args.config; + let prev_file = req.args.prev_config; + + if (!phy) + return libubus.STATUS_INVALID_ARGUMENT; + + try { + if (prev_file && !hostapd.data.config[phy]) { + let config = iface_load_config(prev_file); + if (config) + config.radio.data = []; + hostapd.data.config[phy] = config; + } + + let config = iface_load_config(file); + + hostapd.printf(`Set new config for phy ${phy}: ${file}`); + iface_set_config(phy, config); + } catch(e) { + hostapd.printf(`Error loading config: ${e}\n${e.stacktrace[0].context}`); + return libubus.STATUS_INVALID_ARGUMENT; + } + + return { + pid: hostapd.getpid() + }; + } + }, + config_add: { + args: { + iface: "", + config: "", + }, + call: function(req) { + if (!req.args.iface || !req.args.config) + return libubus.STATUS_INVALID_ARGUMENT; + + if (hostapd.add_iface(`bss_config=${req.args.iface}:${req.args.config}`) < 0) + return libubus.STATUS_INVALID_ARGUMENT; + + return { + pid: hostapd.getpid() + }; + } + }, + config_remove: { + args: { + iface: "" + }, + call: function(req) { + if (!req.args.iface) + return libubus.STATUS_INVALID_ARGUMENT; + + hostapd.remove_iface(req.args.iface); + return 0; + } + }, +}; + +hostapd.data.ubus = ubus; +hostapd.data.obj = ubus.publish("hostapd", main_obj); + +function bss_event(type, name, data) { + let ubus = hostapd.data.ubus; + + data ??= {}; + data.name = name; + hostapd.data.obj.notify(`bss.${type}`, data, null, null, null, -1); + ubus.call("service", "event", { type: `hostapd.${name}.${type}`, data: {} }); +} + +return { + shutdown: function() { + for (let phy in hostapd.data.config) + iface_set_config(phy, null); + hostapd.ubus.disconnect(); + }, + bss_add: function(name, obj) { + bss_event("add", name); + }, + bss_reload: function(name, obj, reconf) { + bss_event("reload", name, { reconf: reconf != 0 }); + }, + bss_remove: function(name, obj) { + bss_event("remove", name); + } +}; diff --git a/feeds/ipq807x_v5.4/hostapd/files/wdev.uc b/feeds/ipq807x_v5.4/hostapd/files/wdev.uc new file mode 100644 index 000000000..5b321423e --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/files/wdev.uc @@ -0,0 +1,156 @@ +#!/usr/bin/env ucode +'use strict'; +import { vlist_new, is_equal, wdev_create, wdev_remove } from "/usr/share/hostap/common.uc"; +import { readfile, writefile, basename, readlink, glob } from "fs"; + +let keep_devices = {}; +let phy = shift(ARGV); +let new_config = shift(ARGV); +const mesh_params = [ + "mesh_retry_timeout", "mesh_confirm_timeout", "mesh_holding_timeout", "mesh_max_peer_links", + "mesh_max_retries", "mesh_ttl", "mesh_element_ttl", "mesh_hwmp_max_preq_retries", + "mesh_path_refresh_time", "mesh_min_discovery_timeout", "mesh_hwmp_active_path_timeout", + "mesh_hwmp_preq_min_interval", "mesh_hwmp_net_diameter_traversal_time", "mesh_hwmp_rootmode", + "mesh_hwmp_rann_interval", "mesh_gate_announcements", "mesh_sync_offset_max_neighor", + "mesh_rssi_threshold", "mesh_hwmp_active_path_to_root_timeout", "mesh_hwmp_root_interval", + "mesh_hwmp_confirmation_interval", "mesh_awake_window", "mesh_plink_timeout", + "mesh_auto_open_plinks", "mesh_fwding", "mesh_power_mode" +]; + +function iface_stop(wdev) +{ + if (keep_devices[wdev.ifname]) + return; + + wdev_remove(wdev.ifname); +} + +function iface_start(wdev) +{ + let ifname = wdev.ifname; + + if (readfile(`/sys/class/net/${ifname}/ifindex`)) { + system([ "ip", "link", "set", "dev", ifname, "down" ]); + wdev_remove(ifname); + } + wdev_create(phy, ifname, wdev); + system([ "ip", "link", "set", "dev", ifname, "up" ]); + if (wdev.freq) + system(`iw dev ${ifname} set freq ${wdev.freq} ${wdev.htmode}`); + if (wdev.mode == "adhoc") { + let cmd = ["iw", "dev", ifname, "ibss", "join", wdev.ssid, wdev.freq, wdev.htmode, "fixed-freq" ]; + if (wdev.bssid) + push(cmd, wdev.bssid); + for (let key in [ "beacon-interval", "basic-rates", "mcast-rate", "keys" ]) + if (wdev[key]) + push(cmd, key, wdev[key]); + system(cmd); + } else if (wdev.mode == "mesh") { + let cmd = [ "iw", "dev", ifname, "mesh", "join", wdev.ssid, "freq", wdev.freq, wdev.htmode ]; + for (let key in [ "beacon-interval", "mcast-rate" ]) + if (wdev[key]) + push(cmd, key, wdev[key]); + system(cmd); + + cmd = ["iw", "dev", ifname, "set", "mesh_param" ]; + let len = length(cmd); + + for (let param in mesh_params) + if (wdev[param]) + push(cmd, param, wdev[param]); + + if (len == length(cmd)) + return; + + system(cmd); + } + +} + +function iface_cb(new_if, old_if) +{ + if (old_if && new_if && is_equal(old_if, new_if)) + return; + + if (old_if) + iface_stop(old_if); + if (new_if) + iface_start(new_if); +} + +function drop_inactive(config) +{ + for (let key in config) { + if (!readfile(`/sys/class/net/${key}/ifindex`)) + delete config[key]; + } +} + +function add_ifname(config) +{ + for (let key in config) + config[key].ifname = key; +} + +function delete_ifname(config) +{ + for (let key in config) + delete config[key].ifname; +} + +function add_existing(phy, config) +{ + let wdevs = glob(`/sys/class/ieee80211/${phy}/device/net/*`); + wdevs = map(wdevs, (arg) => basename(arg)); + for (let wdev in wdevs) { + if (config[wdev]) + continue; + + if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != phy) + continue; + + if (trim(readfile(`/sys/class/net/${wdev}/operstate`)) == "down") + config[wdev] = {}; + } +} + + +let statefile = `/var/run/wdev-${phy}.json`; + +for (let dev in ARGV) + keep_devices[dev] = true; + +if (!phy || !new_config) { + warn(`Usage: ${basename(sourcepath())} [ if (!chan) { --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -9872,6 +9872,10 @@ static int nl80211_switch_channel(void * +@@ -9797,6 +9797,10 @@ static int nl80211_switch_channel(void * if (ret) goto error; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/020-mesh-make-forwarding-configurable.patch b/feeds/ipq807x_v5.4/hostapd/patches/020-mesh-make-forwarding-configurable.patch index 75726a675..0473b66ec 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/020-mesh-make-forwarding-configurable.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/020-mesh-make-forwarding-configurable.patch @@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle }; #define MAX_STA_COUNT 2007 -@@ -696,6 +697,7 @@ struct hostapd_bss_config { +@@ -694,6 +695,7 @@ struct hostapd_bss_config { #define MESH_ENABLED BIT(0) int mesh; @@ -59,7 +59,7 @@ Signed-off-by: Daniel Golle --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -10456,6 +10456,9 @@ static int nl80211_put_mesh_config(struc +@@ -10381,6 +10381,9 @@ static int nl80211_put_mesh_config(struc if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) && nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, params->auto_plinks)) || diff --git a/feeds/ipq807x_v5.4/hostapd/patches/021-fix-sta-add-after-previous-connection.patch b/feeds/ipq807x_v5.4/hostapd/patches/021-fix-sta-add-after-previous-connection.patch index 124fd8bdf..accf2fdc2 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/021-fix-sta-add-after-previous-connection.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/021-fix-sta-add-after-previous-connection.patch @@ -1,6 +1,6 @@ --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c -@@ -4942,6 +4942,13 @@ static int add_associated_sta(struct hos +@@ -4810,6 +4810,13 @@ static int add_associated_sta(struct hos * drivers to accept the STA parameter configuration. Since this is * after a new FT-over-DS exchange, a new TK has been derived, so key * reinstallation is not a concern for this case. @@ -14,7 +14,7 @@ */ wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)", -@@ -4955,7 +4962,8 @@ static int add_associated_sta(struct hos +@@ -4823,7 +4830,8 @@ static int add_associated_sta(struct hos (!(sta->flags & WLAN_STA_AUTHORIZED) || (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) || (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) && diff --git a/feeds/ipq807x_v5.4/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch b/feeds/ipq807x_v5.4/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch index c7da33f02..b6f291928 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch @@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -3431,7 +3431,7 @@ static int hostapd_change_config_freq(st +@@ -3403,7 +3403,7 @@ static int hostapd_change_config_freq(st struct hostapd_freq_params *old_params) { int channel; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch b/feeds/ipq807x_v5.4/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch index e8a78e355..4d7671439 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch @@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau #include #include #include -@@ -5284,26 +5281,29 @@ fail: +@@ -5233,26 +5230,29 @@ fail: static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr) { @@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau if (err < 0) { wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for " MACSTR " ifindex=%d failed: %s", MAC2STR(addr), -@@ -5313,9 +5313,8 @@ static void rtnl_neigh_delete_fdb_entry( +@@ -5262,9 +5262,8 @@ static void rtnl_neigh_delete_fdb_entry( MACSTR, MAC2STR(addr)); } @@ -76,7 +76,7 @@ Signed-off-by: Felix Fietkau } -@@ -7691,7 +7690,6 @@ static void *i802_init(struct hostapd_da +@@ -7633,7 +7632,6 @@ static void *i802_init(struct hostapd_da (params->num_bridge == 0 || !params->bridge[0])) add_ifidx(drv, br_ifindex, drv->ifindex); @@ -84,7 +84,7 @@ Signed-off-by: Felix Fietkau if (bss->added_if_into_bridge || bss->already_in_bridge) { int err; -@@ -7708,7 +7706,6 @@ static void *i802_init(struct hostapd_da +@@ -7650,7 +7648,6 @@ static void *i802_init(struct hostapd_da goto failed; } } @@ -92,7 +92,7 @@ Signed-off-by: Felix Fietkau if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { wpa_printf(MSG_DEBUG, -@@ -10655,13 +10652,14 @@ static int wpa_driver_br_add_ip_neigh(vo +@@ -10581,13 +10578,14 @@ static int wpa_driver_br_add_ip_neigh(vo const u8 *ipaddr, int prefixlen, const u8 *addr) { @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau int res; if (!ipaddr || prefixlen == 0 || !addr) -@@ -10680,85 +10678,66 @@ static int wpa_driver_br_add_ip_neigh(vo +@@ -10606,85 +10604,66 @@ static int wpa_driver_br_add_ip_neigh(vo } if (version == 4) { @@ -220,7 +220,7 @@ Signed-off-by: Felix Fietkau addrsize = 16; } else { return -EINVAL; -@@ -10776,41 +10755,30 @@ static int wpa_driver_br_delete_ip_neigh +@@ -10702,41 +10681,30 @@ static int wpa_driver_br_delete_ip_neigh return -1; } diff --git a/feeds/ipq807x_v5.4/hostapd/patches/200-multicall.patch b/feeds/ipq807x_v5.4/hostapd/patches/200-multicall.patch index 8dce26087..3d0e8035a 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/200-multicall.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/200-multicall.patch @@ -72,7 +72,7 @@ include ../src/build.rules ifdef LIBS -@@ -359,7 +360,9 @@ endif +@@ -354,7 +355,9 @@ endif ifdef CONFIG_IBSS_RSN NEED_RSN_AUTHENTICATOR=y CFLAGS += -DCONFIG_IBSS_RSN @@ -82,7 +82,7 @@ OBJS += ibss_rsn.o endif -@@ -897,6 +900,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS +@@ -886,6 +889,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS LIBS += -ldl -rdynamic endif @@ -93,7 +93,7 @@ endif ifdef CONFIG_AP -@@ -904,9 +911,11 @@ NEED_EAP_COMMON=y +@@ -893,9 +900,11 @@ NEED_EAP_COMMON=y NEED_RSN_AUTHENTICATOR=y CFLAGS += -DCONFIG_AP OBJS += ap.o @@ -105,7 +105,7 @@ OBJS += ../src/ap/hostapd.o OBJS += ../src/ap/wpa_auth_glue.o OBJS += ../src/ap/utils.o -@@ -986,6 +995,12 @@ endif +@@ -975,6 +984,12 @@ endif ifdef CONFIG_HS20 OBJS += ../src/ap/hs20.o endif @@ -118,7 +118,7 @@ endif ifdef CONFIG_MBO -@@ -994,7 +1009,9 @@ CFLAGS += -DCONFIG_MBO +@@ -983,7 +998,9 @@ CFLAGS += -DCONFIG_MBO endif ifdef NEED_RSN_AUTHENTICATOR @@ -128,7 +128,7 @@ NEED_AES_WRAP=y OBJS += ../src/ap/wpa_auth.o OBJS += ../src/ap/wpa_auth_ie.o -@@ -1889,6 +1906,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) +@@ -1878,6 +1895,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv) _OBJS_VAR := OBJS include ../src/objs.mk @@ -141,7 +141,7 @@ wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) @$(E) " LD " $@ -@@ -2021,6 +2044,12 @@ eap_gpsk.so: $(SRC_EAP_GPSK) +@@ -1983,6 +2006,12 @@ eap_eke.so: ../src/eap_peer/eap_eke.c .. $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ @$(E) " sed" $< @@ -156,7 +156,7 @@ wpa_cli.exe: wpa_cli --- a/src/drivers/driver.h +++ b/src/drivers/driver.h -@@ -6025,8 +6025,8 @@ union wpa_event_data { +@@ -6018,8 +6018,8 @@ union wpa_event_data { * Driver wrapper code should call this function whenever an event is received * from the driver. */ @@ -167,7 +167,7 @@ /** * wpa_supplicant_event_global - Report a driver event for wpa_supplicant -@@ -6038,7 +6038,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -6031,7 +6031,7 @@ void wpa_supplicant_event(void *ctx, enu * Same as wpa_supplicant_event(), but we search for the interface in * wpa_global. */ @@ -178,7 +178,7 @@ /* --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c -@@ -1836,8 +1836,8 @@ err: +@@ -1827,8 +1827,8 @@ err: #endif /* CONFIG_OWE */ @@ -189,7 +189,7 @@ { struct hostapd_data *hapd = ctx; #ifndef CONFIG_NO_STDOUT_DEBUG -@@ -2082,7 +2082,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -2073,7 +2073,7 @@ void wpa_supplicant_event(void *ctx, enu } @@ -231,7 +231,7 @@ os_memset(&global, 0, sizeof(global)); --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c -@@ -4665,8 +4665,8 @@ static void wpas_event_unprot_beacon(str +@@ -4666,8 +4666,8 @@ static void wpas_event_unprot_beacon(str } @@ -242,7 +242,7 @@ { struct wpa_supplicant *wpa_s = ctx; int resched; -@@ -5511,7 +5511,7 @@ void wpa_supplicant_event(void *ctx, enu +@@ -5512,7 +5512,7 @@ void wpa_supplicant_event(void *ctx, enu } @@ -253,7 +253,7 @@ struct wpa_supplicant *wpa_s; --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -6819,7 +6819,6 @@ struct wpa_interface * wpa_supplicant_ma +@@ -6814,7 +6814,6 @@ struct wpa_interface * wpa_supplicant_ma return NULL; } @@ -261,7 +261,7 @@ /** * wpa_supplicant_match_existing - Match existing interfaces * @global: Pointer to global data from wpa_supplicant_init() -@@ -6854,6 +6853,11 @@ static int wpa_supplicant_match_existing +@@ -6849,6 +6848,11 @@ static int wpa_supplicant_match_existing #endif /* CONFIG_MATCH_IFACE */ @@ -273,7 +273,7 @@ /** * wpa_supplicant_add_iface - Add a new network interface -@@ -7110,6 +7114,8 @@ struct wpa_global * wpa_supplicant_init( +@@ -7105,6 +7109,8 @@ struct wpa_global * wpa_supplicant_init( #ifndef CONFIG_NO_WPA_MSG wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb); #endif /* CONFIG_NO_WPA_MSG */ @@ -333,7 +333,7 @@ const struct wpa_driver_ops *const wpa_drivers[] = { NULL }; -@@ -1291,6 +1296,10 @@ static void usage(void) +@@ -1292,6 +1297,10 @@ static void usage(void) "option several times.\n"); } @@ -344,7 +344,7 @@ int main(int argc, char *argv[]) { -@@ -1311,6 +1320,8 @@ int main(int argc, char *argv[]) +@@ -1312,6 +1321,8 @@ int main(int argc, char *argv[]) if (os_program_init()) return -1; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/300-noscan.patch b/feeds/ipq807x_v5.4/hostapd/patches/300-noscan.patch index 93b093428..98a431770 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/300-noscan.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/300-noscan.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3459,6 +3459,10 @@ static int hostapd_config_fill(struct ho +@@ -3439,6 +3439,10 @@ static int hostapd_config_fill(struct ho if (bss->ocv && !bss->ieee80211w) bss->ieee80211w = 1; #endif /* CONFIG_OCV */ @@ -13,7 +13,7 @@ } else if (os_strcmp(buf, "ht_capab") == 0) { --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -1009,6 +1009,8 @@ struct hostapd_config { +@@ -995,6 +995,8 @@ struct hostapd_config { int ht_op_mode_fixed; u16 ht_capab; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/310-rescan_immediately.patch b/feeds/ipq807x_v5.4/hostapd/patches/310-rescan_immediately.patch index 7f5e20706..41f1b1e49 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/310-rescan_immediately.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/310-rescan_immediately.patch @@ -1,6 +1,6 @@ --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -5154,7 +5154,7 @@ wpa_supplicant_alloc(struct wpa_supplica +@@ -5147,7 +5147,7 @@ wpa_supplicant_alloc(struct wpa_supplica if (wpa_s == NULL) return NULL; wpa_s->scan_req = INITIAL_SCAN_REQ; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/320-optional_rfkill.patch b/feeds/ipq807x_v5.4/hostapd/patches/320-optional_rfkill.patch index 01537790e..a703c7e13 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/320-optional_rfkill.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/320-optional_rfkill.patch @@ -1,6 +1,6 @@ --- a/src/drivers/drivers.mak +++ b/src/drivers/drivers.mak -@@ -54,7 +54,6 @@ NEED_SME=y +@@ -50,7 +50,6 @@ NEED_SME=y NEED_AP_MLME=y NEED_NETLINK=y NEED_LINUX_IOCTL=y @@ -8,7 +8,7 @@ NEED_RADIOTAP=y NEED_LIBNL=y endif -@@ -111,7 +110,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT +@@ -107,7 +106,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT CONFIG_WIRELESS_EXTENSION=y NEED_NETLINK=y NEED_LINUX_IOCTL=y @@ -16,7 +16,7 @@ endif ifdef CONFIG_DRIVER_NDIS -@@ -137,7 +135,6 @@ endif +@@ -133,7 +131,6 @@ endif ifdef CONFIG_WIRELESS_EXTENSION DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION DRV_WPA_OBJS += ../src/drivers/driver_wext.o @@ -24,7 +24,7 @@ endif ifdef NEED_NETLINK -@@ -146,6 +143,7 @@ endif +@@ -142,6 +139,7 @@ endif ifdef NEED_RFKILL DRV_OBJS += ../src/drivers/rfkill.o diff --git a/feeds/ipq807x_v5.4/hostapd/patches/330-nl80211_fix_set_freq.patch b/feeds/ipq807x_v5.4/hostapd/patches/330-nl80211_fix_set_freq.patch index 9ced08801..e1070d0f4 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/330-nl80211_fix_set_freq.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/330-nl80211_fix_set_freq.patch @@ -1,6 +1,6 @@ --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -4973,7 +4973,7 @@ static int nl80211_set_channel(struct i8 +@@ -4919,7 +4919,7 @@ static int nl80211_set_channel(struct i8 freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled, freq->bandwidth, freq->center_freq1, freq->center_freq2); diff --git a/feeds/ipq807x_v5.4/hostapd/patches/340-reload_freq_change.patch b/feeds/ipq807x_v5.4/hostapd/patches/340-reload_freq_change.patch deleted file mode 100644 index 3d51a47a1..000000000 --- a/feeds/ipq807x_v5.4/hostapd/patches/340-reload_freq_change.patch +++ /dev/null @@ -1,75 +0,0 @@ ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -115,6 +115,28 @@ static void hostapd_reload_bss(struct ho - #endif /* CONFIG_NO_RADIUS */ - - ssid = &hapd->conf->ssid; -+ -+ hostapd_set_freq(hapd, hapd->iconf->hw_mode, hapd->iface->freq, -+ hapd->iconf->channel, -+ hapd->iconf->enable_edmg, -+ hapd->iconf->edmg_channel, -+ hapd->iconf->ieee80211n, -+ hapd->iconf->ieee80211ac, -+ hapd->iconf->ieee80211ax, -+ hapd->iconf->secondary_channel, -+ hostapd_get_oper_chwidth(hapd->iconf), -+ hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf), -+ hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf)); -+ -+ if (hapd->iface->current_mode) { -+ if (hostapd_prepare_rates(hapd->iface, hapd->iface->current_mode)) { -+ wpa_printf(MSG_ERROR, "Failed to prepare rates table."); -+ hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, -+ HOSTAPD_LEVEL_WARNING, -+ "Failed to prepare rates table."); -+ } -+ } -+ - if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next && - ssid->wpa_passphrase_set && ssid->wpa_passphrase) { - /* -@@ -216,6 +238,7 @@ int hostapd_reload_config(struct hostapd - struct hostapd_data *hapd = iface->bss[0]; - struct hostapd_config *newconf, *oldconf; - size_t j; -+ int i; - - if (iface->config_fname == NULL) { - /* Only in-memory config in use - assume it has been updated */ -@@ -266,24 +289,20 @@ int hostapd_reload_config(struct hostapd - } - iface->conf = newconf; - -+ for (i = 0; i < iface->num_hw_features; i++) { -+ struct hostapd_hw_modes *mode = &iface->hw_features[i]; -+ if (mode->mode == iface->conf->hw_mode) { -+ iface->current_mode = mode; -+ break; -+ } -+ } -+ -+ if (iface->conf->channel) -+ iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel); -+ - for (j = 0; j < iface->num_bss; j++) { - hapd = iface->bss[j]; - hapd->iconf = newconf; -- hapd->iconf->channel = oldconf->channel; -- hapd->iconf->acs = oldconf->acs; -- hapd->iconf->secondary_channel = oldconf->secondary_channel; -- hapd->iconf->ieee80211n = oldconf->ieee80211n; -- hapd->iconf->ieee80211ac = oldconf->ieee80211ac; -- hapd->iconf->ht_capab = oldconf->ht_capab; -- hapd->iconf->vht_capab = oldconf->vht_capab; -- hostapd_set_oper_chwidth(hapd->iconf, -- hostapd_get_oper_chwidth(oldconf)); -- hostapd_set_oper_centr_freq_seg0_idx( -- hapd->iconf, -- hostapd_get_oper_centr_freq_seg0_idx(oldconf)); -- hostapd_set_oper_centr_freq_seg1_idx( -- hapd->iconf, -- hostapd_get_oper_centr_freq_seg1_idx(oldconf)); - hapd->conf = newconf->bss[j]; - hostapd_reload_bss(hapd); - } diff --git a/feeds/ipq807x_v5.4/hostapd/patches/350-nl80211_del_beacon_bss.patch b/feeds/ipq807x_v5.4/hostapd/patches/350-nl80211_del_beacon_bss.patch index 1f9b74e97..41e427c22 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/350-nl80211_del_beacon_bss.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/350-nl80211_del_beacon_bss.patch @@ -1,6 +1,6 @@ --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -2918,10 +2918,15 @@ static int wpa_driver_nl80211_del_beacon +@@ -2891,10 +2891,15 @@ static int wpa_driver_nl80211_del_beacon struct nl_msg *msg; struct wpa_driver_nl80211_data *drv = bss->drv; @@ -18,7 +18,7 @@ return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); } -@@ -5602,7 +5607,7 @@ static void nl80211_teardown_ap(struct i +@@ -5550,7 +5555,7 @@ static void nl80211_teardown_ap(struct i nl80211_mgmt_unsubscribe(bss, "AP teardown"); nl80211_put_wiphy_data_ap(bss); @@ -27,7 +27,7 @@ } -@@ -8051,8 +8056,6 @@ static int wpa_driver_nl80211_if_remove( +@@ -7990,8 +7995,6 @@ static int wpa_driver_nl80211_if_remove( } else { wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context"); nl80211_teardown_ap(bss); @@ -36,7 +36,7 @@ nl80211_destroy_bss(bss); if (!bss->added_if) i802_set_iface_flags(bss, 0); -@@ -8449,7 +8452,6 @@ static int wpa_driver_nl80211_deinit_ap( +@@ -8388,7 +8391,6 @@ static int wpa_driver_nl80211_deinit_ap( if (!is_ap_interface(drv->nlmode)) return -1; wpa_driver_nl80211_del_beacon(bss); @@ -44,7 +44,7 @@ /* * If the P2P GO interface was dynamically added, then it is -@@ -8469,7 +8471,6 @@ static int wpa_driver_nl80211_stop_ap(vo +@@ -8408,7 +8410,6 @@ static int wpa_driver_nl80211_stop_ap(vo if (!is_ap_interface(drv->nlmode)) return -1; wpa_driver_nl80211_del_beacon(bss); diff --git a/feeds/ipq807x_v5.4/hostapd/patches/360-ctrl_iface_reload.patch b/feeds/ipq807x_v5.4/hostapd/patches/360-ctrl_iface_reload.patch deleted file mode 100644 index 349522e06..000000000 --- a/feeds/ipq807x_v5.4/hostapd/patches/360-ctrl_iface_reload.patch +++ /dev/null @@ -1,106 +0,0 @@ ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -67,6 +67,7 @@ - #include "fst/fst_ctrl_iface.h" - #include "config_file.h" - #include "ctrl_iface.h" -+#include "config_file.h" - - - #define HOSTAPD_CLI_DUP_VALUE_MAX_LEN 256 -@@ -82,6 +83,7 @@ static void hostapd_ctrl_iface_send(stru - enum wpa_msg_type type, - const char *buf, size_t len); - -+static char *reload_opts = NULL; - - static int hostapd_ctrl_iface_attach(struct hostapd_data *hapd, - struct sockaddr_storage *from, -@@ -133,6 +135,61 @@ static int hostapd_ctrl_iface_new_sta(st - return 0; - } - -+static char *get_option(char *opt, char *str) -+{ -+ int len = strlen(str); -+ -+ if (!strncmp(opt, str, len)) -+ return opt + len; -+ else -+ return NULL; -+} -+ -+static struct hostapd_config *hostapd_ctrl_iface_config_read(const char *fname) -+{ -+ struct hostapd_config *conf; -+ char *opt, *val; -+ -+ conf = hostapd_config_read(fname); -+ if (!conf) -+ return NULL; -+ -+ for (opt = strtok(reload_opts, " "); -+ opt; -+ opt = strtok(NULL, " ")) { -+ -+ if ((val = get_option(opt, "channel="))) -+ conf->channel = atoi(val); -+ else if ((val = get_option(opt, "ht_capab="))) -+ conf->ht_capab = atoi(val); -+ else if ((val = get_option(opt, "ht_capab_mask="))) -+ conf->ht_capab &= atoi(val); -+ else if ((val = get_option(opt, "sec_chan="))) -+ conf->secondary_channel = atoi(val); -+ else if ((val = get_option(opt, "hw_mode="))) -+ conf->hw_mode = atoi(val); -+ else if ((val = get_option(opt, "ieee80211n="))) -+ conf->ieee80211n = atoi(val); -+ else -+ break; -+ } -+ -+ return conf; -+} -+ -+static int hostapd_ctrl_iface_update(struct hostapd_data *hapd, char *txt) -+{ -+ struct hostapd_config * (*config_read_cb)(const char *config_fname); -+ struct hostapd_iface *iface = hapd->iface; -+ -+ config_read_cb = iface->interfaces->config_read_cb; -+ iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read; -+ reload_opts = txt; -+ -+ hostapd_reload_config(iface); -+ -+ iface->interfaces->config_read_cb = config_read_cb; -+} - - #ifdef NEED_AP_MLME - static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd, -@@ -3754,6 +3811,8 @@ static int hostapd_ctrl_iface_receive_pr - } else if (os_strncmp(buf, "VENDOR ", 7) == 0) { - reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply, - reply_size); -+ } else if (os_strncmp(buf, "UPDATE ", 7) == 0) { -+ hostapd_ctrl_iface_update(hapd, buf + 7); - } else if (os_strcmp(buf, "ERP_FLUSH") == 0) { - ieee802_1x_erp_flush(hapd); - #ifdef RADIUS_SERVER ---- a/src/ap/ctrl_iface_ap.c -+++ b/src/ap/ctrl_iface_ap.c -@@ -919,7 +919,13 @@ int hostapd_parse_csa_settings(const cha - - int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd) - { -- return hostapd_drv_stop_ap(hapd); -+ struct hostapd_iface *iface = hapd->iface; -+ int i; -+ -+ for (i = 0; i < iface->num_bss; i++) -+ hostapd_drv_stop_ap(iface->bss[i]); -+ -+ return 0; - } - - diff --git a/feeds/ipq807x_v5.4/hostapd/patches/370-ap_sta_support.patch b/feeds/ipq807x_v5.4/hostapd/patches/370-ap_sta_support.patch deleted file mode 100644 index 9ffd7e2a0..000000000 --- a/feeds/ipq807x_v5.4/hostapd/patches/370-ap_sta_support.patch +++ /dev/null @@ -1,414 +0,0 @@ -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/Makefile -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile -@@ -103,6 +103,8 @@ OBJS_c += ../src/utils/common.o - OBJS_c += ../src/common/cli.o - OBJS += wmm_ac.o - -+OBJS += ../src/common/wpa_ctrl.o -+ - ifndef CONFIG_OS - ifdef CONFIG_NATIVE_WINDOWS - CONFIG_OS=win32 -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/bss.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/bss.c -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/bss.c -@@ -11,6 +11,7 @@ - #include "utils/common.h" - #include "utils/eloop.h" - #include "common/ieee802_11_defs.h" -+#include "common/ieee802_11_common.h" - #include "drivers/driver.h" - #include "eap_peer/eap.h" - #include "wpa_supplicant_i.h" -@@ -282,6 +283,10 @@ void calculate_update_time(const struct - static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src, - struct os_reltime *fetch_time) - { -+ struct ieee80211_ht_capabilities *capab; -+ struct ieee80211_ht_operation *oper; -+ struct ieee802_11_elems elems; -+ - dst->flags = src->flags; - os_memcpy(dst->bssid, src->bssid, ETH_ALEN); - dst->freq = src->freq; -@@ -294,6 +299,15 @@ static void wpa_bss_copy_res(struct wpa_ - dst->est_throughput = src->est_throughput; - dst->snr = src->snr; - -+ memset(&elems, 0, sizeof(elems)); -+ ieee802_11_parse_elems((u8 *) (src + 1), src->ie_len, &elems, 0); -+ capab = (struct ieee80211_ht_capabilities *) elems.ht_capabilities; -+ oper = (struct ieee80211_ht_operation *) elems.ht_operation; -+ if (capab) -+ dst->ht_capab = le_to_host16(capab->ht_capabilities_info); -+ if (oper) -+ dst->ht_param = oper->ht_param; -+ - calculate_update_time(fetch_time, src->age, &dst->last_update); - } - -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/bss.h -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/bss.h -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/bss.h -@@ -94,6 +94,10 @@ struct wpa_bss { - u8 ssid[SSID_MAX_LEN]; - /** Length of SSID */ - size_t ssid_len; -+ /** HT capabilities */ -+ u16 ht_capab; -+ /* Five octets of HT Operation Information */ -+ u8 ht_param; - /** Frequency of the channel in MHz (e.g., 2412 = channel 1) */ - int freq; - /** Beacon interval in TUs (host byte order) */ -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/main.c -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c -@@ -34,7 +34,7 @@ static void usage(void) - "vW] [-P] " - "[-g] \\\n" - " [-G] \\\n" -- " -i -c [-C] [-D] " -+ " -i -c [-C] [-D] [-H] " - "[-p] \\\n" - " [-b] [-e]" - #ifdef CONFIG_DEBUG_FILE -@@ -74,6 +74,7 @@ static void usage(void) - " -g = global ctrl_interface\n" - " -G = global ctrl_interface group\n" - " -h = show this help text\n" -+ " -H = connect to a hostapd instance to manage state changes\n" - " -i = interface name\n" - " -I = additional configuration file\n" - " -K = include keys (passwords, etc.) in debug output\n" -@@ -201,7 +202,7 @@ int main(int argc, char *argv[]) - - for (;;) { - c = getopt(argc, argv, -- "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW"); -+ "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuvW"); - if (c < 0) - break; - switch (c) { -@@ -248,6 +249,9 @@ int main(int argc, char *argv[]) - usage(); - exitcode = 0; - goto out; -+ case 'H': -+ iface->hostapd_ctrl = optarg; -+ break; - case 'i': - iface->ifname = optarg; - break; -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.c -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c -@@ -130,6 +130,54 @@ static void wpas_update_fils_connect_par - static void wpas_update_owe_connect_params(struct wpa_supplicant *wpa_s); - #endif /* CONFIG_OWE */ - -+static int hostapd_stop(struct wpa_supplicant *wpa_s) -+{ -+ const char *cmd = "STOP_AP"; -+ char buf[256]; -+ size_t len = sizeof(buf); -+ -+ if (wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL) < 0) { -+ wpa_printf(MSG_ERROR, "\nFailed to stop hostapd AP interfaces\n"); -+ return -1; -+ } -+ return 0; -+} -+ -+static int hostapd_reload(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) -+{ -+ char *cmd = NULL; -+ char buf[256]; -+ size_t len = sizeof(buf); -+ enum hostapd_hw_mode hw_mode; -+ u8 channel; -+ int sec_chan = 0; -+ int ret; -+ -+ if (!bss) -+ return -1; -+ -+ if (bss->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) { -+ int sec = bss->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK; -+ if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE) -+ sec_chan = 1; -+ else if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW) -+ sec_chan = -1; -+ } -+ -+ hw_mode = ieee80211_freq_to_chan(bss->freq, &channel); -+ if (asprintf(&cmd, "UPDATE channel=%d sec_chan=%d hw_mode=%d", -+ channel, sec_chan, hw_mode) < 0) -+ return -1; -+ -+ ret = wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL); -+ free(cmd); -+ -+ if (ret < 0) { -+ wpa_printf(MSG_ERROR, "\nFailed to reload hostapd AP interfaces\n"); -+ return -1; -+ } -+ return 0; -+} - - #ifdef CONFIG_WEP - /* Configure default/group WEP keys for static WEP */ -@@ -1007,6 +1055,8 @@ void wpa_supplicant_set_state(struct wpa - - sme_sched_obss_scan(wpa_s, 1); - -+ if (wpa_s->hostapd) -+ hostapd_reload(wpa_s, wpa_s->current_bss); - #if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL) - if (!fils_hlp_sent && ssid && ssid->eap.erp) - update_fils_connect_params = true; -@@ -1017,6 +1067,8 @@ void wpa_supplicant_set_state(struct wpa - #endif /* CONFIG_OWE */ - } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING || - state == WPA_ASSOCIATED) { -+ if (wpa_s->hostapd) -+ hostapd_stop(wpa_s); - wpa_s->new_connection = 1; - wpa_drv_set_operstate(wpa_s, 0); - #ifndef IEEE8021X_EAPOL -@@ -2276,6 +2328,8 @@ void wpa_supplicant_associate(struct wpa - return; - } - wpa_s->current_bss = bss; -+ if (wpa_s->hostapd) -+ hostapd_reload(wpa_s, wpa_s->current_bss); - #else /* CONFIG_MESH */ - wpa_msg(wpa_s, MSG_ERROR, - "mesh mode support not included in the build"); -@@ -6419,6 +6473,16 @@ static int wpa_supplicant_init_iface(str - sizeof(wpa_s->bridge_ifname)); - } - -+ if (iface->hostapd_ctrl) { -+ wpa_s->hostapd = wpa_ctrl_open(iface->hostapd_ctrl); -+ if (!wpa_s->hostapd) { -+ wpa_printf(MSG_ERROR, "\nFailed to connect to hostapd\n"); -+ return -1; -+ } -+ if (hostapd_stop(wpa_s) < 0) -+ return -1; -+ } -+ - /* RSNA Supplicant Key Management - INITIALIZE */ - eapol_sm_notify_portEnabled(wpa_s->eapol, false); - eapol_sm_notify_portValid(wpa_s->eapol, false); -@@ -6756,6 +6820,11 @@ static void wpa_supplicant_deinit_iface( - if (terminate) - wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING); - -+ if (wpa_s->hostapd) { -+ wpa_ctrl_close(wpa_s->hostapd); -+ wpa_s->hostapd = NULL; -+ } -+ - if (wpa_s->ctrl_iface) { - wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); - wpa_s->ctrl_iface = NULL; -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant_i.h -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h -@@ -103,6 +103,11 @@ struct wpa_interface { - const char *ifname; - - /** -+ * hostapd_ctrl - path to hostapd control socket for notification -+ */ -+ const char *hostapd_ctrl; -+ -+ /** - * bridge_ifname - Optional bridge interface name - * - * If the driver interface (ifname) is included in a Linux bridge -@@ -611,6 +616,8 @@ struct wpa_supplicant { - #endif /* CONFIG_CTRL_IFACE_BINDER */ - char bridge_ifname[16]; - -+ struct wpa_ctrl *hostapd; -+ - char *confname; - char *confanother; - -Index: hostapd-2021-02-20-59e9794c/hostapd/ctrl_iface.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/hostapd/ctrl_iface.c -+++ hostapd-2021-02-20-59e9794c/hostapd/ctrl_iface.c -@@ -2781,6 +2781,11 @@ static int hostapd_ctrl_iface_chan_switc - return 0; - } - -+ if (os_strstr(pos, " auto-ht")) { -+ settings.freq_params.ht_enabled = iface->conf->ieee80211n; -+ settings.freq_params.vht_enabled = iface->conf->ieee80211ac; -+ } -+ - for (i = 0; i < iface->num_bss; i++) { - - /* Save CHAN_SWITCH VHT and HE config */ -Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/beacon.c -+++ hostapd-2021-02-20-59e9794c/src/ap/beacon.c -@@ -1753,11 +1753,6 @@ int ieee802_11_set_beacon(struct hostapd - struct wpabuf *beacon, *proberesp, *assocresp; - int res, ret = -1; - -- if (hapd->csa_in_progress) { -- wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period"); -- return -1; -- } -- - hapd->beacon_set_done = 1; - - if (ieee802_11_build_ap_params(hapd, ¶ms) < 0) -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/events.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/events.c -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/events.c -@@ -4666,6 +4666,60 @@ static void wpas_event_unprot_beacon(str - } - - -+static void -+supplicant_ch_switch_started(struct wpa_supplicant *wpa_s, -+ union wpa_event_data *data) -+{ -+ char buf[256]; -+ size_t len = sizeof(buf); -+ char *cmd = NULL; -+ int width = 20; -+ int ret; -+ -+ if (!wpa_s->hostapd) -+ return; -+ -+ wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CHANNEL_SWITCH -+ "count=%d freq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d", -+ data->ch_switch.count, -+ data->ch_switch.freq, -+ data->ch_switch.ht_enabled, -+ data->ch_switch.ch_offset, -+ channel_width_to_string(data->ch_switch.ch_width), -+ data->ch_switch.cf1, -+ data->ch_switch.cf2); -+ -+ switch (data->ch_switch.ch_width) { -+ case CHAN_WIDTH_20_NOHT: -+ case CHAN_WIDTH_20: -+ width = 20; -+ break; -+ case CHAN_WIDTH_40: -+ width = 40; -+ break; -+ case CHAN_WIDTH_80: -+ width = 80; -+ break; -+ case CHAN_WIDTH_160: -+ case CHAN_WIDTH_80P80: -+ width = 160; -+ break; -+ } -+ -+ asprintf(&cmd, "CHAN_SWITCH %d %d sec_channel_offset=%d center_freq1=%d center_freq2=%d, bandwidth=%d auto-ht\n", -+ data->ch_switch.count - 1, -+ data->ch_switch.freq, -+ data->ch_switch.ch_offset, -+ data->ch_switch.cf1, -+ data->ch_switch.cf2, -+ width); -+ ret = wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL); -+ free(cmd); -+ -+ if (ret < 0) -+ wpa_printf(MSG_ERROR, "\nFailed to reload hostapd AP interfaces\n"); -+} -+ - void supplicant_event(void *ctx, enum wpa_event_type event, - union wpa_event_data *data) - { -@@ -4981,8 +5035,10 @@ void supplicant_event(void *ctx, enum wp - channel_width_to_string(data->ch_switch.ch_width), - data->ch_switch.cf1, - data->ch_switch.cf2); -- if (event == EVENT_CH_SWITCH_STARTED) -+ if (event == EVENT_CH_SWITCH_STARTED) { -+ supplicant_ch_switch_started(wpa_s, data); - break; -+ } - - wpa_s->assoc_freq = data->ch_switch.freq; - wpa_s->current_ssid->frequency = data->ch_switch.freq; -Index: hostapd-2021-02-20-59e9794c/src/drivers/driver.h -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/drivers/driver.h -+++ hostapd-2021-02-20-59e9794c/src/drivers/driver.h -@@ -5822,6 +5822,7 @@ union wpa_event_data { - - /** - * struct ch_switch -+ * @count: Count until channel switch activates - * @freq: Frequency of new channel in MHz - * @ht_enabled: Whether this is an HT channel - * @ch_offset: Secondary channel offset -@@ -5830,6 +5831,7 @@ union wpa_event_data { - * @cf2: Center frequency 2 - */ - struct ch_switch { -+ int count; - int freq; - int ht_enabled; - int ch_offset; -Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211_event.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/drivers/driver_nl80211_event.c -+++ hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211_event.c -@@ -655,7 +655,7 @@ static void mlme_event_ch_switch(struct - struct nlattr *ifindex, struct nlattr *freq, - struct nlattr *type, struct nlattr *bw, - struct nlattr *cf1, struct nlattr *cf2, -- int finished) -+ struct nlattr *count, int finished) - { - struct i802_bss *bss; - union wpa_event_data data; -@@ -714,6 +714,8 @@ static void mlme_event_ch_switch(struct - data.ch_switch.cf1 = nla_get_u32(cf1); - if (cf2) - data.ch_switch.cf2 = nla_get_u32(cf2); -+ if (count) -+ data.ch_switch.count = nla_get_u32(count); - - if (finished) - bss->freq = data.ch_switch.freq; -@@ -2886,6 +2888,7 @@ static void do_process_drv_event(struct - tb[NL80211_ATTR_CHANNEL_WIDTH], - tb[NL80211_ATTR_CENTER_FREQ1], - tb[NL80211_ATTR_CENTER_FREQ2], -+ tb[NL80211_ATTR_CH_SWITCH_COUNT], - 0); - break; - case NL80211_CMD_CH_SWITCH_NOTIFY: -@@ -2896,6 +2899,7 @@ static void do_process_drv_event(struct - tb[NL80211_ATTR_CHANNEL_WIDTH], - tb[NL80211_ATTR_CENTER_FREQ1], - tb[NL80211_ATTR_CENTER_FREQ2], -+ NULL, - 1); - break; - case NL80211_CMD_DISCONNECT: diff --git a/feeds/ipq807x_v5.4/hostapd/patches/380-disable_ctrl_iface_mib.patch b/feeds/ipq807x_v5.4/hostapd/patches/380-disable_ctrl_iface_mib.patch index ca634077b..80500414b 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/380-disable_ctrl_iface_mib.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/380-disable_ctrl_iface_mib.patch @@ -12,7 +12,7 @@ else --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c -@@ -3569,6 +3569,7 @@ static int hostapd_ctrl_iface_receive_pr +@@ -3388,6 +3388,7 @@ static int hostapd_ctrl_iface_receive_pr reply_size); } else if (os_strcmp(buf, "STATUS-DRIVER") == 0) { reply_len = hostapd_drv_status(hapd, reply, reply_size); @@ -20,7 +20,7 @@ } else if (os_strcmp(buf, "MIB") == 0) { reply_len = ieee802_11_get_mib(hapd, reply, reply_size); if (reply_len >= 0) { -@@ -3610,6 +3611,7 @@ static int hostapd_ctrl_iface_receive_pr +@@ -3429,6 +3430,7 @@ static int hostapd_ctrl_iface_receive_pr } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply, reply_size); @@ -30,7 +30,7 @@ reply_len = -1; --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -955,6 +955,9 @@ ifdef CONFIG_FILS +@@ -942,6 +942,9 @@ ifdef CONFIG_FILS OBJS += ../src/ap/fils_hlp.o endif ifdef CONFIG_CTRL_IFACE @@ -42,7 +42,7 @@ --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c -@@ -2308,7 +2308,7 @@ static int wpa_supplicant_ctrl_iface_sta +@@ -2294,7 +2294,7 @@ static int wpa_supplicant_ctrl_iface_sta pos += ret; } @@ -51,7 +51,7 @@ if (wpa_s->ap_iface) { pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, end - pos, -@@ -10919,6 +10919,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -10602,6 +10602,7 @@ char * wpa_supplicant_ctrl_iface_process reply_len = -1; } else if (os_strncmp(buf, "NOTE ", 5) == 0) { wpa_printf(MSG_INFO, "NOTE: %s", buf + 5); @@ -59,7 +59,7 @@ } else if (os_strcmp(buf, "MIB") == 0) { reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); if (reply_len >= 0) { -@@ -10931,6 +10932,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -10614,6 +10615,7 @@ char * wpa_supplicant_ctrl_iface_process reply_size - reply_len); #endif /* CONFIG_MACSEC */ } @@ -67,7 +67,7 @@ } else if (os_strncmp(buf, "STATUS", 6) == 0) { reply_len = wpa_supplicant_ctrl_iface_status( wpa_s, buf + 6, reply, reply_size); -@@ -11419,6 +11421,7 @@ char * wpa_supplicant_ctrl_iface_process +@@ -11102,6 +11104,7 @@ char * wpa_supplicant_ctrl_iface_process reply_len = wpa_supplicant_ctrl_iface_bss( wpa_s, buf + 4, reply, reply_size); #ifdef CONFIG_AP @@ -75,7 +75,7 @@ } else if (os_strcmp(buf, "STA-FIRST") == 0) { reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size); } else if (os_strncmp(buf, "STA ", 4) == 0) { -@@ -11427,12 +11430,15 @@ char * wpa_supplicant_ctrl_iface_process +@@ -11110,12 +11113,15 @@ char * wpa_supplicant_ctrl_iface_process } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) { reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply, reply_size); @@ -144,7 +144,7 @@ static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx) --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c -@@ -4519,6 +4519,7 @@ static const char * wpa_bool_txt(int val +@@ -4503,6 +4503,7 @@ static const char * wpa_bool_txt(int val return val ? "TRUE" : "FALSE"; } @@ -152,7 +152,7 @@ #define RSN_SUITE "%02x-%02x-%02x-%d" #define RSN_SUITE_ARG(s) \ -@@ -4669,7 +4670,7 @@ int wpa_get_mib_sta(struct wpa_state_mac +@@ -4653,7 +4654,7 @@ int wpa_get_mib_sta(struct wpa_state_mac return len; } @@ -163,7 +163,7 @@ { --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c -@@ -2767,6 +2767,8 @@ static u32 wpa_key_mgmt_suite(struct wpa +@@ -2763,6 +2763,8 @@ static u32 wpa_key_mgmt_suite(struct wpa } @@ -172,7 +172,7 @@ #define RSN_SUITE "%02x-%02x-%02x-%d" #define RSN_SUITE_ARG(s) \ ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff -@@ -2848,6 +2850,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch +@@ -2844,6 +2846,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch return (int) len; } diff --git a/feeds/ipq807x_v5.4/hostapd/patches/420-indicate-features.patch b/feeds/ipq807x_v5.4/hostapd/patches/420-indicate-features.patch index f9dff6607..f74db4c02 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/420-indicate-features.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/420-indicate-features.patch @@ -36,16 +36,16 @@ #include "fst/fst.h" #include "wpa_supplicant_i.h" #include "driver_i.h" -@@ -202,7 +203,7 @@ int main(int argc, char *argv[]) +@@ -201,7 +202,7 @@ int main(int argc, char *argv[]) for (;;) { c = getopt(argc, argv, -- "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuvW"); -+ "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuv::W"); +- "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW"); ++ "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuv::W"); if (c < 0) break; switch (c) { -@@ -305,8 +306,12 @@ int main(int argc, char *argv[]) +@@ -301,8 +302,12 @@ int main(int argc, char *argv[]) break; #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ case 'v': diff --git a/feeds/ipq807x_v5.4/hostapd/patches/430-hostapd_cli_ifdef.patch b/feeds/ipq807x_v5.4/hostapd/patches/430-hostapd_cli_ifdef.patch index dc1fa3d29..49ad781d4 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/430-hostapd_cli_ifdef.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/430-hostapd_cli_ifdef.patch @@ -32,7 +32,7 @@ static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc, -@@ -1579,13 +1575,10 @@ static const struct hostapd_cli_cmd host +@@ -1571,13 +1567,10 @@ static const struct hostapd_cli_cmd host { "disassociate", hostapd_cli_cmd_disassociate, hostapd_complete_stations, " = disassociate a station" }, @@ -46,7 +46,7 @@ { "wps_pin", hostapd_cli_cmd_wps_pin, NULL, " [timeout] [addr] = add WPS Enrollee PIN" }, { "wps_check_pin", hostapd_cli_cmd_wps_check_pin, NULL, -@@ -1610,7 +1603,6 @@ static const struct hostapd_cli_cmd host +@@ -1602,7 +1595,6 @@ static const struct hostapd_cli_cmd host " = configure AP" }, { "wps_get_status", hostapd_cli_cmd_wps_get_status, NULL, "= show current WPS status" }, diff --git a/feeds/ipq807x_v5.4/hostapd/patches/450-scan_wait.patch b/feeds/ipq807x_v5.4/hostapd/patches/450-scan_wait.patch deleted file mode 100644 index ac874ad66..000000000 --- a/feeds/ipq807x_v5.4/hostapd/patches/450-scan_wait.patch +++ /dev/null @@ -1,73 +0,0 @@ ---- a/hostapd/main.c -+++ b/hostapd/main.c -@@ -39,6 +39,8 @@ struct hapd_global { - }; - - static struct hapd_global global; -+static int daemonize = 0; -+static char *pid_file = NULL; - - - #ifndef CONFIG_NO_HOSTAPD_LOGGER -@@ -146,6 +148,14 @@ static void hostapd_logger_cb(void *ctx, - } - #endif /* CONFIG_NO_HOSTAPD_LOGGER */ - -+static void hostapd_setup_complete_cb(void *ctx) -+{ -+ if (daemonize && os_daemonize(pid_file)) { -+ perror("daemon"); -+ return; -+ } -+ daemonize = 0; -+} - - /** - * hostapd_driver_init - Preparate driver interface -@@ -164,6 +174,8 @@ static int hostapd_driver_init(struct ho - return -1; - } - -+ hapd->setup_complete_cb = hostapd_setup_complete_cb; -+ - /* Initialize the driver interface */ - if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) - b = NULL; -@@ -404,8 +416,6 @@ static void hostapd_global_deinit(const - #endif /* CONFIG_NATIVE_WINDOWS */ - - eap_server_unregister_methods(); -- -- os_daemonize_terminate(pid_file); - } - - -@@ -431,18 +441,6 @@ static int hostapd_global_run(struct hap - } - #endif /* EAP_SERVER_TNC */ - -- if (daemonize) { -- if (os_daemonize(pid_file)) { -- wpa_printf(MSG_ERROR, "daemon: %s", strerror(errno)); -- return -1; -- } -- if (eloop_sock_requeue()) { -- wpa_printf(MSG_ERROR, "eloop_sock_requeue: %s", -- strerror(errno)); -- return -1; -- } -- } -- - eloop_run(); - - return 0; -@@ -645,8 +643,7 @@ int main(int argc, char *argv[]) - struct hapd_interfaces interfaces; - int ret = 1; - size_t i, j; -- int c, debug = 0, daemonize = 0; -- char *pid_file = NULL; -+ int c, debug = 0; - const char *log_file = NULL; - const char *entropy_file = NULL; - char **bss_config = NULL, **tmp_bss; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/feeds/ipq807x_v5.4/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch index e0e687e16..e395faaf3 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch @@ -174,7 +174,7 @@ Signed-hostap: Antonio Quartulli * macsec_policy - Determines the policy for MACsec secure session --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -3726,6 +3726,12 @@ static void wpas_start_assoc_cb(struct w +@@ -3673,6 +3673,12 @@ static void wpas_start_assoc_cb(struct w params.beacon_int = ssid->beacon_int; else params.beacon_int = wpa_s->conf->beacon_int; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch b/feeds/ipq807x_v5.4/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch index 1d2a053fa..19165d028 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch @@ -10,7 +10,7 @@ Signed-hostap: Antonio Quartulli --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -5951,7 +5951,7 @@ static int wpa_driver_nl80211_ibss(struc +@@ -5886,7 +5886,7 @@ static int wpa_driver_nl80211_ibss(struc struct wpa_driver_associate_params *params) { struct nl_msg *msg; @@ -19,7 +19,7 @@ Signed-hostap: Antonio Quartulli int count = 0; wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex); -@@ -5978,6 +5978,37 @@ retry: +@@ -5913,6 +5913,37 @@ retry: nl80211_put_beacon_int(msg, params->beacon_int)) goto fail; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/463-add-mcast_rate-to-11s.patch b/feeds/ipq807x_v5.4/hostapd/patches/463-add-mcast_rate-to-11s.patch index 1794befe9..395c6d31b 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/463-add-mcast_rate-to-11s.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/463-add-mcast_rate-to-11s.patch @@ -29,7 +29,7 @@ Tested-by: Simon Wunderlich struct wpa_driver_set_key_params { --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c -@@ -10476,6 +10476,18 @@ static int nl80211_put_mesh_id(struct nl +@@ -10398,6 +10398,18 @@ static int nl80211_put_mesh_id(struct nl } @@ -48,7 +48,7 @@ Tested-by: Simon Wunderlich static int nl80211_put_mesh_config(struct nl_msg *msg, struct wpa_driver_mesh_bss_params *params) { -@@ -10537,6 +10549,7 @@ static int nl80211_join_mesh(struct i802 +@@ -10459,6 +10471,7 @@ static int nl80211_join_mesh(struct i802 nl80211_put_basic_rates(msg, params->basic_rates) || nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) || nl80211_put_beacon_int(msg, params->beacon_int) || diff --git a/feeds/ipq807x_v5.4/hostapd/patches/464-fix-mesh-obss-check.patch b/feeds/ipq807x_v5.4/hostapd/patches/464-fix-mesh-obss-check.patch index 4c7cb9ea3..0e9d2590d 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/464-fix-mesh-obss-check.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/464-fix-mesh-obss-check.patch @@ -1,6 +1,6 @@ --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c -@@ -2457,11 +2457,13 @@ void ibss_mesh_setup_freq(struct wpa_sup +@@ -2403,11 +2403,13 @@ void ibss_mesh_setup_freq(struct wpa_sup for (j = 0; j < wpa_s->last_scan_res_used; j++) { struct wpa_bss *bss = wpa_s->last_scan_res[j]; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/470-survey_data_fallback.patch b/feeds/ipq807x_v5.4/hostapd/patches/470-survey_data_fallback.patch index efd82599d..57a78ee86 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/470-survey_data_fallback.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/470-survey_data_fallback.patch @@ -20,7 +20,7 @@ total = survey->channel_time; -@@ -422,20 +416,19 @@ static int acs_usable_bw160_chan(const s +@@ -415,20 +409,19 @@ static int acs_usable_vht160_chan(const static int acs_survey_is_sufficient(struct freq_survey *survey) { if (!(survey->filled & SURVEY_HAS_NF)) { diff --git a/feeds/ipq807x_v5.4/hostapd/patches/500-lto-jobserver-support.patch b/feeds/ipq807x_v5.4/hostapd/patches/500-lto-jobserver-support.patch index 1475590d0..7ba3e096e 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/500-lto-jobserver-support.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/500-lto-jobserver-support.patch @@ -20,7 +20,7 @@ NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS) --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile -@@ -1918,31 +1918,31 @@ wpa_supplicant_multi.a: .config $(BCHECK +@@ -1905,31 +1905,31 @@ wpa_supplicant_multi.a: .config $(BCHECK @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs) diff --git a/feeds/ipq807x_v5.4/hostapd/patches/550-WNM-allow-specifying-dialog-token.patch b/feeds/ipq807x_v5.4/hostapd/patches/550-WNM-allow-specifying-dialog-token.patch index 6c080adc0..4d3f524f9 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/550-WNM-allow-specifying-dialog-token.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/550-WNM-allow-specifying-dialog-token.patch @@ -19,7 +19,7 @@ Signed-off-by: David Bauer --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c -@@ -897,7 +897,7 @@ static int hostapd_ctrl_iface_bss_tm_req +@@ -840,7 +840,7 @@ static int hostapd_ctrl_iface_bss_tm_req const char *pos, *end; int disassoc_timer = 0; struct sta_info *sta; @@ -28,7 +28,7 @@ Signed-off-by: David Bauer u8 bss_term_dur[12]; char *url = NULL; int ret; -@@ -935,6 +935,12 @@ static int hostapd_ctrl_iface_bss_tm_req +@@ -878,6 +878,12 @@ static int hostapd_ctrl_iface_bss_tm_req valid_int = atoi(pos); } @@ -41,7 +41,7 @@ Signed-off-by: David Bauer pos = os_strstr(cmd, " bss_term="); if (pos) { pos += 10; -@@ -1041,7 +1047,7 @@ static int hostapd_ctrl_iface_bss_tm_req +@@ -984,7 +990,7 @@ static int hostapd_ctrl_iface_bss_tm_req #endif /* CONFIG_MBO */ ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer, diff --git a/feeds/ipq807x_v5.4/hostapd/patches/590-rrm-wnm-statistics.patch b/feeds/ipq807x_v5.4/hostapd/patches/590-rrm-wnm-statistics.patch index ee3ab7938..737fdbb5d 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/590-rrm-wnm-statistics.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/590-rrm-wnm-statistics.patch @@ -1,6 +1,6 @@ --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h -@@ -150,6 +150,21 @@ struct hostapd_sae_commit_queue { +@@ -148,6 +148,21 @@ struct hostapd_sae_commit_queue { }; /** @@ -22,7 +22,7 @@ * struct hostapd_data - hostapd per-BSS data structure */ struct hostapd_data { -@@ -163,6 +178,9 @@ struct hostapd_data { +@@ -161,6 +176,9 @@ struct hostapd_data { u8 own_addr[ETH_ALEN]; @@ -71,7 +71,7 @@ if (disassoc_timer) { /* send disassociation frame after time-out */ set_disassoc_timer(hapd, sta, disassoc_timer); -@@ -857,6 +862,7 @@ int wnm_send_bss_tm_req(struct hostapd_d +@@ -856,6 +861,7 @@ int wnm_send_bss_tm_req(struct hostapd_d } os_free(buf); diff --git a/feeds/ipq807x_v5.4/hostapd/patches/600-ubus_support.patch b/feeds/ipq807x_v5.4/hostapd/patches/600-ubus_support.patch index e0aa18737..afcb8eb47 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/600-ubus_support.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/600-ubus_support.patch @@ -1,23 +1,20 @@ -Index: hostapd-2021-02-20-59e9794c/hostapd/Makefile -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/hostapd/Makefile -+++ hostapd-2021-02-20-59e9794c/hostapd/Makefile -@@ -166,6 +166,11 @@ OBJS += ../src/common/hw_features_common +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -166,6 +166,12 @@ OBJS += ../src/common/hw_features_common OBJS += ../src/eapol_auth/eapol_auth_sm.o +ifdef CONFIG_UBUS +CFLAGS += -DUBUS_SUPPORT ++OBJS += ../src/utils/uloop.o +OBJS += ../src/ap/ubus.o +LIBS += -lubox -lubus +endif ifdef CONFIG_CODE_COVERAGE CFLAGS += -O0 -fprofile-arcs -ftest-coverage -Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.h -+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.h +--- a/src/ap/hostapd.h ++++ b/src/ap/hostapd.h @@ -17,6 +17,7 @@ #include "utils/list.h" #include "ap_config.h" @@ -26,15 +23,6 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h #define OCE_STA_CFON_ENABLED(hapd) \ ((hapd->conf->oce & OCE_STA_CFON) && \ -@@ -80,7 +81,7 @@ struct hapd_interfaces { - #ifdef CONFIG_CTRL_IFACE_UDP - unsigned char ctrl_iface_cookie[CTRL_IFACE_COOKIE_LEN]; - #endif /* CONFIG_CTRL_IFACE_UDP */ -- -+ struct ubus_object ubus; - }; - - enum hostapd_chan_status { @@ -169,6 +170,7 @@ struct hostapd_data { struct hostapd_iface *iface; struct hostapd_config *iconf; @@ -51,11 +39,9 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h void hostapd_interface_deinit(struct hostapd_iface *iface); void hostapd_interface_free(struct hostapd_iface *iface); struct hostapd_iface * hostapd_alloc_iface(void); -Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c -+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c -@@ -395,6 +395,7 @@ void hostapd_free_hapd_data(struct hosta +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -376,6 +376,7 @@ void hostapd_free_hapd_data(struct hosta hapd->beacon_set_done = 0; wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); @@ -63,7 +49,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c accounting_deinit(hapd); hostapd_deinit_wpa(hapd); vlan_deinit(hapd); -@@ -1417,6 +1418,8 @@ static int hostapd_setup_bss(struct host +@@ -1398,6 +1399,8 @@ static int hostapd_setup_bss(struct host if (hapd->driver && hapd->driver->set_operstate) hapd->driver->set_operstate(hapd->drv_priv, 1); @@ -72,7 +58,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c return 0; } -@@ -2002,6 +2005,7 @@ static int hostapd_setup_interface_compl +@@ -1983,6 +1986,7 @@ static int hostapd_setup_interface_compl if (err) goto fail; @@ -80,7 +66,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c wpa_printf(MSG_DEBUG, "Completing interface initialization"); if (iface->freq) { #ifdef NEED_AP_MLME -@@ -2199,6 +2203,7 @@ dfs_offload: +@@ -2180,6 +2184,7 @@ dfs_offload: fail: wpa_printf(MSG_ERROR, "Interface initialization failed"); @@ -88,7 +74,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c hostapd_set_state(iface, HAPD_IFACE_DISABLED); wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); #ifdef CONFIG_FST -@@ -2672,6 +2677,7 @@ void hostapd_interface_deinit_free(struc +@@ -2653,6 +2658,7 @@ void hostapd_interface_deinit_free(struc (unsigned int) iface->conf->num_bss); driver = iface->bss[0]->driver; drv_priv = iface->bss[0]->drv_priv; @@ -96,10 +82,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c hostapd_interface_deinit(iface); wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", __func__, driver, drv_priv); -Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/ieee802_11.c -+++ hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c +--- a/src/ap/ieee802_11.c ++++ b/src/ap/ieee802_11.c @@ -3421,13 +3421,18 @@ static void handle_auth(struct hostapd_d u16 auth_alg, auth_transaction, status_code; u16 resp = WLAN_STATUS_SUCCESS; @@ -186,10 +170,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying " -Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/beacon.c -+++ hostapd-2021-02-20-59e9794c/src/ap/beacon.c +--- a/src/ap/beacon.c ++++ b/src/ap/beacon.c @@ -823,6 +823,12 @@ void handle_probe_req(struct hostapd_dat u16 csa_offs[2]; size_t csa_offs_len; @@ -216,10 +198,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c /* TODO: verify that supp_rates contains at least one matching rate * with AP configuration */ -Index: hostapd-2021-02-20-59e9794c/src/ap/drv_callbacks.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/drv_callbacks.c -+++ hostapd-2021-02-20-59e9794c/src/ap/drv_callbacks.c +--- a/src/ap/drv_callbacks.c ++++ b/src/ap/drv_callbacks.c @@ -145,6 +145,10 @@ int hostapd_notif_assoc(struct hostapd_d u16 reason = WLAN_REASON_UNSPECIFIED; int status = WLAN_STATUS_SUCCESS; @@ -244,10 +224,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/drv_callbacks.c #ifdef CONFIG_P2P if (elems.p2p) { wpabuf_free(sta->p2p_ie); -Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.c -+++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.c +--- a/src/ap/sta_info.c ++++ b/src/ap/sta_info.c @@ -458,6 +458,7 @@ void ap_handle_timer(void *eloop_ctx, vo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " @@ -264,26 +242,70 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c ap_free_sta(hapd, sta); break; } -@@ -1319,6 +1321,7 @@ void ap_sta_set_authorized(struct hostap +@@ -1298,12 +1300,25 @@ void ap_sta_set_authorized(struct hostap + sta->addr, authorized, dev_addr); + + if (authorized) { ++ static const char * const auth_algs[] = { ++ [WLAN_AUTH_OPEN] = "open", ++ [WLAN_AUTH_SHARED_KEY] = "shared", ++ [WLAN_AUTH_FT] = "ft", ++ [WLAN_AUTH_SAE] = "sae", ++ [WLAN_AUTH_FILS_SK] = "fils-sk", ++ [WLAN_AUTH_FILS_SK_PFS] = "fils-sk-pfs", ++ [WLAN_AUTH_FILS_PK] = "fils-pk", ++ [WLAN_AUTH_PASN] = "pasn", ++ }; ++ const char *auth_alg = NULL; + const char *keyid; + char keyid_buf[100]; + char ip_addr[100]; ++ char alg_buf[100]; + + keyid_buf[0] = '\0'; + ip_addr[0] = '\0'; ++ alg_buf[0] = '\0'; + #ifdef CONFIG_P2P + if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) { + os_snprintf(ip_addr, sizeof(ip_addr), +@@ -1313,22 +1328,31 @@ void ap_sta_set_authorized(struct hostap + } + #endif /* CONFIG_P2P */ + ++ if (sta->auth_alg < ARRAY_SIZE(auth_algs)) ++ auth_alg = auth_algs[sta->auth_alg]; ++ ++ if (auth_alg) ++ os_snprintf(alg_buf, sizeof(alg_buf), ++ " auth_alg=%s", auth_alg); ++ + keyid = ap_sta_wpa_get_keyid(hapd, sta); + if (keyid) { + os_snprintf(keyid_buf, sizeof(keyid_buf), " keyid=%s", keyid); } +- wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s", +- buf, ip_addr, keyid_buf); + hostapd_ubus_notify_authorized(hapd, sta); - wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s", - buf, ip_addr, keyid_buf); ++ wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", ++ buf, ip_addr, keyid_buf, alg_buf); -@@ -1329,6 +1332,7 @@ void ap_sta_set_authorized(struct hostap - buf, ip_addr, keyid_buf); + if (hapd->msg_ctx_parent && + hapd->msg_ctx_parent != hapd->msg_ctx) + wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO, +- AP_STA_CONNECTED "%s%s%s", +- buf, ip_addr, keyid_buf); ++ AP_STA_CONNECTED "%s%s%s%s", ++ buf, ip_addr, keyid_buf, alg_buf); } else { wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); + hostapd_ubus_notify(hapd, "disassoc", sta->addr); if (hapd->msg_ctx_parent && hapd->msg_ctx_parent != hapd->msg_ctx) -Index: hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_glue.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/wpa_auth_glue.c -+++ hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_glue.c +--- a/src/ap/wpa_auth_glue.c ++++ b/src/ap/wpa_auth_glue.c @@ -265,6 +265,7 @@ static void hostapd_wpa_auth_psk_failure struct hostapd_data *hapd = ctx; wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, @@ -292,24 +314,23 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_glue.c } -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/Makefile -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile -@@ -171,6 +171,12 @@ ifdef CONFIG_EAPOL_TEST +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -169,6 +169,13 @@ ifdef CONFIG_EAPOL_TEST CFLAGS += -Werror -DEAPOL_TEST endif +ifdef CONFIG_UBUS +CFLAGS += -DUBUS_SUPPORT +OBJS += ubus.o ++OBJS += ../src/utils/uloop.o +LIBS += -lubox -lubus +endif + ifdef CONFIG_CODE_COVERAGE CFLAGS += -O0 -fprofile-arcs -ftest-coverage LIBS += -lgcov -@@ -948,6 +954,9 @@ ifdef CONFIG_CTRL_IFACE_MIB +@@ -946,6 +953,9 @@ ifdef CONFIG_CTRL_IFACE_MIB CFLAGS += -DCONFIG_CTRL_IFACE_MIB endif OBJS += ../src/ap/ctrl_iface_ap.o @@ -319,11 +340,9 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile endif CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.c -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c -@@ -7012,6 +7012,8 @@ struct wpa_supplicant * wpa_supplicant_a +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -6943,6 +6943,8 @@ struct wpa_supplicant * wpa_supplicant_a } #endif /* CONFIG_P2P */ @@ -332,7 +351,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c return wpa_s; } -@@ -7038,6 +7040,8 @@ int wpa_supplicant_remove_iface(struct w +@@ -6969,6 +6971,8 @@ int wpa_supplicant_remove_iface(struct w struct wpa_supplicant *parent = wpa_s->parent; #endif /* CONFIG_MESH */ @@ -341,7 +360,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c /* Remove interface from the global list of interfaces */ prev = global->ifaces; if (prev == wpa_s) { -@@ -7341,8 +7345,12 @@ int wpa_supplicant_run(struct wpa_global +@@ -7272,8 +7276,12 @@ int wpa_supplicant_run(struct wpa_global eloop_register_signal_terminate(wpa_supplicant_terminate, global); eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); @@ -354,10 +373,8 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c return 0; } -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant_i.h -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h +--- a/wpa_supplicant/wpa_supplicant_i.h ++++ b/wpa_supplicant/wpa_supplicant_i.h @@ -19,6 +19,7 @@ #include "wps/wps_defs.h" #include "config_ssid.h" @@ -366,7 +383,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h extern const char *const wpa_supplicant_version; extern const char *const wpa_supplicant_license; -@@ -321,6 +322,8 @@ struct wpa_global { +@@ -316,6 +317,8 @@ struct wpa_global { #endif /* CONFIG_WIFI_DISPLAY */ struct psk_list_entry *add_psk; /* From group formation */ @@ -375,7 +392,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h }; -@@ -601,6 +604,7 @@ struct wpa_supplicant { +@@ -596,6 +599,7 @@ struct wpa_supplicant { unsigned char own_addr[ETH_ALEN]; unsigned char perm_addr[ETH_ALEN]; char ifname[100]; @@ -383,10 +400,8 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h #ifdef CONFIG_MATCH_IFACE int matched; #endif /* CONFIG_MATCH_IFACE */ -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wps_supplicant.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wps_supplicant.c -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wps_supplicant.c +--- a/wpa_supplicant/wps_supplicant.c ++++ b/wpa_supplicant/wps_supplicant.c @@ -33,6 +33,7 @@ #include "p2p/p2p.h" #include "p2p_supplicant.h" @@ -404,40 +419,18 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wps_supplicant.c if (wpa_s->conf->wps_cred_processing == 1) return 0; -Index: hostapd-2021-02-20-59e9794c/hostapd/main.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/hostapd/main.c -+++ hostapd-2021-02-20-59e9794c/hostapd/main.c -@@ -895,6 +895,7 @@ int main(int argc, char *argv[]) - } - - hostapd_global_ctrl_iface_init(&interfaces); -+ hostapd_ubus_add(&interfaces); - - if (hostapd_global_run(&interfaces, daemonize, pid_file)) { - wpa_printf(MSG_ERROR, "Failed to start eloop"); -@@ -904,6 +905,7 @@ int main(int argc, char *argv[]) - ret = 0; - - out: -+ hostapd_ubus_free(&interfaces); - hostapd_global_ctrl_iface_deinit(&interfaces); - /* Deinitialize all interfaces */ - for (i = 0; i < interfaces.count; i++) { -Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/main.c -+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c -@@ -203,7 +203,7 @@ int main(int argc, char *argv[]) +--- a/wpa_supplicant/main.c ++++ b/wpa_supplicant/main.c +@@ -202,7 +202,7 @@ int main(int argc, char *argv[]) for (;;) { c = getopt(argc, argv, -- "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuv::W"); -+ "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:nNo:O:p:P:qsTtuv::W"); +- "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuv::W"); ++ "b:Bc:C:D:de:f:g:G:hi:I:KLMm:nNo:O:p:P:qsTtuv::W"); if (c < 0) break; switch (c) { -@@ -271,6 +271,9 @@ int main(int argc, char *argv[]) +@@ -267,6 +267,9 @@ int main(int argc, char *argv[]) params.conf_p2p_dev = optarg; break; #endif /* CONFIG_P2P */ @@ -447,10 +440,8 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c case 'o': params.override_driver = optarg; break; -Index: hostapd-2021-02-20-59e9794c/src/ap/rrm.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/rrm.c -+++ hostapd-2021-02-20-59e9794c/src/ap/rrm.c +--- a/src/ap/rrm.c ++++ b/src/ap/rrm.c @@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report return; wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s", @@ -461,10 +452,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/rrm.c } -Index: hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/vlan_init.c -+++ hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c +--- a/src/ap/vlan_init.c ++++ b/src/ap/vlan_init.c @@ -22,6 +22,7 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, int existsok) @@ -501,11 +490,9 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c return hostapd_vlan_if_remove(hapd, vlan->ifname); } -Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/dfs.c -+++ hostapd-2021-02-20-59e9794c/src/ap/dfs.c -@@ -1193,6 +1193,8 @@ int hostapd_dfs_radar_detected(struct ho +--- a/src/ap/dfs.c ++++ b/src/ap/dfs.c +@@ -1226,6 +1226,8 @@ int hostapd_dfs_nop_finished(struct host "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", freq, ht_enabled, chan_offset, chan_width, cf1, cf2); @@ -514,10 +501,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c /* Proceed only if DFS is not offloaded to the driver */ if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) return 0; -Index: hostapd-2021-02-20-59e9794c/src/ap/airtime_policy.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/airtime_policy.c -+++ hostapd-2021-02-20-59e9794c/src/ap/airtime_policy.c +--- a/src/ap/airtime_policy.c ++++ b/src/ap/airtime_policy.c @@ -108,8 +108,14 @@ static void set_sta_weights(struct hosta { struct sta_info *sta; @@ -547,10 +532,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/airtime_policy.c if (weight) return sta_set_airtime_weight(hapd, sta, weight); } -Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.h -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.h -+++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.h +--- a/src/ap/sta_info.h ++++ b/src/ap/sta_info.h @@ -323,6 +323,7 @@ struct sta_info { #endif /* CONFIG_TESTING_OPTIONS */ #ifdef CONFIG_AIRTIME_POLICY @@ -559,10 +542,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.h struct os_reltime backlogged_until; #endif /* CONFIG_AIRTIME_POLICY */ -Index: hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/wnm_ap.c -+++ hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c +--- a/src/ap/wnm_ap.c ++++ b/src/ap/wnm_ap.c @@ -442,7 +442,8 @@ static void ieee802_11_rx_bss_trans_mgmt wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", pos, end - pos); @@ -601,3 +582,151 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", pos, end - pos); } +--- a/src/utils/eloop.c ++++ b/src/utils/eloop.c +@@ -77,6 +77,9 @@ struct eloop_sock_table { + struct eloop_data { + int max_sock; + ++ eloop_timeout_poll_handler timeout_poll_cb; ++ eloop_poll_handler poll_cb; ++ + size_t count; /* sum of all table counts */ + #ifdef CONFIG_ELOOP_POLL + size_t max_pollfd_map; /* number of pollfds_map currently allocated */ +@@ -1116,6 +1119,12 @@ void eloop_run(void) + os_reltime_sub(&timeout->time, &now, &tv); + else + tv.sec = tv.usec = 0; ++ } ++ ++ if (eloop.timeout_poll_cb && eloop.timeout_poll_cb(&tv, !!timeout)) ++ timeout = (void *)1; ++ ++ if (timeout) { + #if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) + timeout_ms = tv.sec * 1000 + tv.usec / 1000; + #endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */ +@@ -1185,7 +1194,8 @@ void eloop_run(void) + eloop.exceptions.changed = 0; + + eloop_process_pending_signals(); +- ++ if (eloop.poll_cb) ++ eloop.poll_cb(); + + /* check if some registered timeouts have occurred */ + timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, +@@ -1247,6 +1257,14 @@ out: + return; + } + ++int eloop_register_cb(eloop_poll_handler poll_cb, ++ eloop_timeout_poll_handler timeout_cb) ++{ ++ eloop.poll_cb = poll_cb; ++ eloop.timeout_poll_cb = timeout_cb; ++ ++ return 0; ++} + + void eloop_terminate(void) + { +--- a/src/utils/eloop.h ++++ b/src/utils/eloop.h +@@ -65,6 +65,9 @@ typedef void (*eloop_timeout_handler)(vo + */ + typedef void (*eloop_signal_handler)(int sig, void *signal_ctx); + ++typedef bool (*eloop_timeout_poll_handler)(struct os_reltime *tv, bool tv_set); ++typedef void (*eloop_poll_handler)(void); ++ + /** + * eloop_init() - Initialize global event loop data + * Returns: 0 on success, -1 on failure +@@ -73,6 +76,9 @@ typedef void (*eloop_signal_handler)(int + */ + int eloop_init(void); + ++int eloop_register_cb(eloop_poll_handler poll_cb, ++ eloop_timeout_poll_handler timeout_cb); ++ + /** + * eloop_register_read_sock - Register handler for read events + * @sock: File descriptor number for the socket +@@ -320,6 +326,8 @@ int eloop_register_signal_reconfig(eloop + */ + int eloop_sock_requeue(void); + ++void eloop_add_uloop(void); ++ + /** + * eloop_run - Start the event loop + * +--- /dev/null ++++ b/src/utils/uloop.c +@@ -0,0 +1,64 @@ ++#include ++#include "includes.h" ++#include "common.h" ++#include "eloop.h" ++ ++static void eloop_uloop_event_cb(int sock, void *eloop_ctx, void *sock_ctx) ++{ ++} ++ ++static void eloop_uloop_fd_cb(struct uloop_fd *fd, unsigned int events) ++{ ++ unsigned int changed = events ^ fd->flags; ++ ++ if (changed & ULOOP_READ) { ++ if (events & ULOOP_READ) ++ eloop_register_sock(fd->fd, EVENT_TYPE_READ, eloop_uloop_event_cb, fd, fd); ++ else ++ eloop_unregister_sock(fd->fd, EVENT_TYPE_READ); ++ } ++ ++ if (changed & ULOOP_WRITE) { ++ if (events & ULOOP_WRITE) ++ eloop_register_sock(fd->fd, EVENT_TYPE_WRITE, eloop_uloop_event_cb, fd, fd); ++ else ++ eloop_unregister_sock(fd->fd, EVENT_TYPE_WRITE); ++ } ++} ++ ++static bool uloop_timeout_poll_handler(struct os_reltime *tv, bool tv_set) ++{ ++ struct os_reltime tv_uloop; ++ int timeout_ms = uloop_get_next_timeout(); ++ ++ if (timeout_ms < 0) ++ return false; ++ ++ tv_uloop.sec = timeout_ms / 1000; ++ tv_uloop.usec = (timeout_ms % 1000) * 1000; ++ ++ if (!tv_set || os_reltime_before(&tv_uloop, tv)) { ++ *tv = tv_uloop; ++ return true; ++ } ++ ++ return false; ++} ++ ++static void uloop_poll_handler(void) ++{ ++ uloop_run_timeout(0); ++} ++ ++void eloop_add_uloop(void) ++{ ++ static bool init_done = false; ++ ++ if (!init_done) { ++ uloop_init(); ++ uloop_fd_set_cb = eloop_uloop_fd_cb; ++ init_done = true; ++ } ++ ++ eloop_register_cb(uloop_poll_handler, uloop_timeout_poll_handler); ++} diff --git a/feeds/ipq807x_v5.4/hostapd/patches/601-ucode_support.patch b/feeds/ipq807x_v5.4/hostapd/patches/601-ucode_support.patch new file mode 100644 index 000000000..d542f3b2b --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/patches/601-ucode_support.patch @@ -0,0 +1,350 @@ +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -168,9 +168,21 @@ OBJS += ../src/eapol_auth/eapol_auth_sm. + + ifdef CONFIG_UBUS + CFLAGS += -DUBUS_SUPPORT +-OBJS += ../src/utils/uloop.o + OBJS += ../src/ap/ubus.o +-LIBS += -lubox -lubus ++LIBS += -lubus ++NEED_ULOOP:=y ++endif ++ ++ifdef CONFIG_UCODE ++CFLAGS += -DUCODE_SUPPORT ++OBJS += ../src/utils/ucode.o ++OBJS += ../src/ap/ucode.o ++NEED_ULOOP:=y ++endif ++ ++ifdef NEED_ULOOP ++OBJS += ../src/utils/uloop.o ++LIBS += -lubox + endif + + ifdef CONFIG_CODE_COVERAGE +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -898,6 +898,7 @@ int main(int argc, char *argv[]) + } + + hostapd_global_ctrl_iface_init(&interfaces); ++ hostapd_ucode_init(&interfaces); + + if (hostapd_global_run(&interfaces, daemonize, pid_file)) { + wpa_printf(MSG_ERROR, "Failed to start eloop"); +@@ -907,6 +908,7 @@ int main(int argc, char *argv[]) + ret = 0; + + out: ++ hostapd_ucode_free(); + hostapd_global_ctrl_iface_deinit(&interfaces); + /* Deinitialize all interfaces */ + for (i = 0; i < interfaces.count; i++) { +--- a/src/ap/hostapd.h ++++ b/src/ap/hostapd.h +@@ -18,6 +18,7 @@ + #include "ap_config.h" + #include "drivers/driver.h" + #include "ubus.h" ++#include "ucode.h" + + #define OCE_STA_CFON_ENABLED(hapd) \ + ((hapd->conf->oce & OCE_STA_CFON) && \ +@@ -50,6 +51,10 @@ struct hapd_interfaces { + struct hostapd_config * (*config_read_cb)(const char *config_fname); + int (*ctrl_iface_init)(struct hostapd_data *hapd); + void (*ctrl_iface_deinit)(struct hostapd_data *hapd); ++ int (*ctrl_iface_recv)(struct hostapd_data *hapd, ++ char *buf, char *reply, int reply_size, ++ struct sockaddr_storage *from, ++ socklen_t fromlen); + int (*for_each_interface)(struct hapd_interfaces *interfaces, + int (*cb)(struct hostapd_iface *iface, + void *ctx), void *ctx); +@@ -171,6 +176,7 @@ struct hostapd_data { + struct hostapd_config *iconf; + struct hostapd_bss_config *conf; + struct hostapd_ubus_bss ubus; ++ struct hostapd_ucode_bss ucode; + int interface_added; /* virtual interface added for this BSS */ + unsigned int started:1; + unsigned int disabled:1; +@@ -463,6 +469,7 @@ struct hostapd_sta_info { + */ + struct hostapd_iface { + struct hapd_interfaces *interfaces; ++ struct hostapd_ucode_iface ucode; + void *owner; + char *config_fname; + struct hostapd_config *conf; +@@ -637,6 +644,8 @@ struct hostapd_iface * hostapd_init(stru + struct hostapd_iface * + hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy, + const char *config_fname, int debug); ++int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon); ++void hostapd_bss_deinit(struct hostapd_data *hapd); + void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, + int reassoc); + void hostapd_interface_deinit_free(struct hostapd_iface *iface); +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -216,6 +216,8 @@ int hostapd_reload_config(struct hostapd + struct hostapd_config *newconf, *oldconf; + size_t j; + ++ hostapd_ucode_reload_bss(hapd); ++ + if (iface->config_fname == NULL) { + /* Only in-memory config in use - assume it has been updated */ + hostapd_clear_old(iface); +@@ -376,6 +378,7 @@ void hostapd_free_hapd_data(struct hosta + hapd->beacon_set_done = 0; + + wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); ++ hostapd_ucode_free_bss(hapd); + hostapd_ubus_free_bss(hapd); + accounting_deinit(hapd); + hostapd_deinit_wpa(hapd); +@@ -530,6 +533,7 @@ void hostapd_cleanup_iface_partial(struc + static void hostapd_cleanup_iface(struct hostapd_iface *iface) + { + wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); ++ hostapd_ucode_free_iface(iface); + eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); + eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface, + NULL); +@@ -1104,7 +1108,7 @@ static int db_table_create_radius_attrib + * initialized. Most of the modules that are initialized here will be + * deinitialized in hostapd_cleanup(). + */ +-static int hostapd_setup_bss(struct hostapd_data *hapd, int first) ++int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool set_beacon) + { + struct hostapd_bss_config *conf = hapd->conf; + u8 ssid[SSID_MAX_LEN + 1]; +@@ -1400,6 +1404,7 @@ static int hostapd_setup_bss(struct host + hapd->driver->set_operstate(hapd->drv_priv, 1); + + hostapd_ubus_add_bss(hapd); ++ hostapd_ucode_add_bss(hapd); + + return 0; + } +@@ -2090,7 +2095,7 @@ static int hostapd_setup_interface_compl + hapd = iface->bss[j]; + if (j) + os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); +- if (hostapd_setup_bss(hapd, j == 0)) { ++ if (hostapd_setup_bss(hapd, j == 0, true)) { + for (;;) { + hapd = iface->bss[j]; + hostapd_bss_deinit_no_free(hapd); +@@ -2368,7 +2373,7 @@ hostapd_alloc_bss_data(struct hostapd_if + } + + +-static void hostapd_bss_deinit(struct hostapd_data *hapd) ++void hostapd_bss_deinit(struct hostapd_data *hapd) + { + if (!hapd) + return; +@@ -2985,7 +2990,7 @@ int hostapd_add_iface(struct hapd_interf + + if (start_ctrl_iface_bss(hapd) < 0 || + (hapd_iface->state == HAPD_IFACE_ENABLED && +- hostapd_setup_bss(hapd, -1))) { ++ hostapd_setup_bss(hapd, -1, true))) { + hostapd_cleanup(hapd); + hapd_iface->bss[hapd_iface->num_bss - 1] = NULL; + hapd_iface->conf->num_bss--; +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -172,8 +172,20 @@ endif + ifdef CONFIG_UBUS + CFLAGS += -DUBUS_SUPPORT + OBJS += ubus.o ++LIBS += -lubus ++NEED_ULOOP:=y ++endif ++ ++ifdef CONFIG_UCODE ++CFLAGS += -DUCODE_SUPPORT ++OBJS += ../src/utils/ucode.o ++OBJS += ucode.o ++NEED_ULOOP:=y ++endif ++ ++ifdef NEED_ULOOP + OBJS += ../src/utils/uloop.o +-LIBS += -lubox -lubus ++LIBS += -lubox + endif + + ifdef CONFIG_CODE_COVERAGE +@@ -956,6 +968,9 @@ OBJS += ../src/ap/ctrl_iface_ap.o + ifdef CONFIG_UBUS + OBJS += ../src/ap/ubus.o + endif ++ifdef CONFIG_UCODE ++OBJS += ../src/ap/ucode.o ++endif + endif + + CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -1025,6 +1025,7 @@ void wpa_supplicant_set_state(struct wpa + sme_sched_obss_scan(wpa_s, 0); + } + wpa_s->wpa_state = state; ++ wpas_ucode_update_state(wpa_s); + + #ifdef CONFIG_BGSCAN + if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid) +@@ -6944,6 +6945,7 @@ struct wpa_supplicant * wpa_supplicant_a + #endif /* CONFIG_P2P */ + + wpas_ubus_add_bss(wpa_s); ++ wpas_ucode_add_bss(wpa_s); + + return wpa_s; + } +@@ -6971,6 +6973,7 @@ int wpa_supplicant_remove_iface(struct w + struct wpa_supplicant *parent = wpa_s->parent; + #endif /* CONFIG_MESH */ + ++ wpas_ucode_free_bss(wpa_s); + wpas_ubus_free_bss(wpa_s); + + /* Remove interface from the global list of interfaces */ +@@ -7238,6 +7241,7 @@ struct wpa_global * wpa_supplicant_init( + + eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0, + wpas_periodic, global, NULL); ++ wpas_ucode_init(global); + + return global; + } +@@ -7276,12 +7280,8 @@ int wpa_supplicant_run(struct wpa_global + eloop_register_signal_terminate(wpa_supplicant_terminate, global); + eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); + +- wpas_ubus_add(global); +- + eloop_run(); + +- wpas_ubus_free(global); +- + return 0; + } + +@@ -7314,6 +7314,8 @@ void wpa_supplicant_deinit(struct wpa_gl + + wpas_notify_supplicant_deinitialized(global); + ++ wpas_ucode_free(); ++ + eap_peer_unregister_methods(); + #ifdef CONFIG_AP + eap_server_unregister_methods(); +--- a/wpa_supplicant/wpa_supplicant_i.h ++++ b/wpa_supplicant/wpa_supplicant_i.h +@@ -20,6 +20,7 @@ + #include "config_ssid.h" + #include "wmm_ac.h" + #include "ubus.h" ++#include "ucode.h" + + extern const char *const wpa_supplicant_version; + extern const char *const wpa_supplicant_license; +@@ -600,6 +601,7 @@ struct wpa_supplicant { + unsigned char perm_addr[ETH_ALEN]; + char ifname[100]; + struct wpas_ubus_bss ubus; ++ struct wpas_ucode_bss ucode; + #ifdef CONFIG_MATCH_IFACE + int matched; + #endif /* CONFIG_MATCH_IFACE */ +--- a/hostapd/ctrl_iface.c ++++ b/hostapd/ctrl_iface.c +@@ -4877,6 +4877,7 @@ try_again: + return -1; + } + ++ interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process; + wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb); + + return 0; +@@ -4978,6 +4979,7 @@ fail: + os_free(fname); + + interface->global_ctrl_sock = s; ++ interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process; + eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive, + interface, NULL); + +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -5827,6 +5827,7 @@ union wpa_event_data { + + /** + * struct ch_switch ++ * @count: Count until channel switch activates + * @freq: Frequency of new channel in MHz + * @ht_enabled: Whether this is an HT channel + * @ch_offset: Secondary channel offset +@@ -5835,6 +5836,7 @@ union wpa_event_data { + * @cf2: Center frequency 2 + */ + struct ch_switch { ++ int count; + int freq; + int ht_enabled; + int ch_offset; +--- a/src/drivers/driver_nl80211_event.c ++++ b/src/drivers/driver_nl80211_event.c +@@ -655,6 +655,7 @@ static void mlme_event_ch_switch(struct + struct nlattr *ifindex, struct nlattr *freq, + struct nlattr *type, struct nlattr *bw, + struct nlattr *cf1, struct nlattr *cf2, ++ struct nlattr *count, + int finished) + { + struct i802_bss *bss; +@@ -714,6 +715,8 @@ static void mlme_event_ch_switch(struct + data.ch_switch.cf1 = nla_get_u32(cf1); + if (cf2) + data.ch_switch.cf2 = nla_get_u32(cf2); ++ if (count) ++ data.ch_switch.count = nla_get_u32(count); + + if (finished) + bss->freq = data.ch_switch.freq; +@@ -2886,6 +2889,7 @@ static void do_process_drv_event(struct + tb[NL80211_ATTR_CHANNEL_WIDTH], + tb[NL80211_ATTR_CENTER_FREQ1], + tb[NL80211_ATTR_CENTER_FREQ2], ++ tb[NL80211_ATTR_CH_SWITCH_COUNT], + 0); + break; + case NL80211_CMD_CH_SWITCH_NOTIFY: +@@ -2896,6 +2900,7 @@ static void do_process_drv_event(struct + tb[NL80211_ATTR_CHANNEL_WIDTH], + tb[NL80211_ATTR_CENTER_FREQ1], + tb[NL80211_ATTR_CENTER_FREQ2], ++ NULL, + 1); + break; + case NL80211_CMD_DISCONNECT: +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -4702,6 +4702,7 @@ void supplicant_event(void *ctx, enum wp + event_to_string(event), event); + #endif /* CONFIG_NO_STDOUT_DEBUG */ + ++ wpas_ucode_event(wpa_s, event, data); + switch (event) { + case EVENT_AUTH: + #ifdef CONFIG_FST diff --git a/feeds/ipq807x_v5.4/hostapd/patches/700-wifi-reload.patch b/feeds/ipq807x_v5.4/hostapd/patches/700-wifi-reload.patch deleted file mode 100644 index 5993b0d44..000000000 --- a/feeds/ipq807x_v5.4/hostapd/patches/700-wifi-reload.patch +++ /dev/null @@ -1,220 +0,0 @@ ---- a/hostapd/config_file.c -+++ b/hostapd/config_file.c -@@ -2453,6 +2453,8 @@ static int hostapd_config_fill(struct ho - bss->isolate = atoi(pos); - } else if (os_strcmp(buf, "ap_max_inactivity") == 0) { - bss->ap_max_inactivity = atoi(pos); -+ } else if (os_strcmp(buf, "config_id") == 0) { -+ bss->config_id = os_strdup(pos); - } else if (os_strcmp(buf, "skip_inactivity_poll") == 0) { - bss->skip_inactivity_poll = atoi(pos); - } else if (os_strcmp(buf, "country_code") == 0) { -@@ -3153,6 +3155,8 @@ static int hostapd_config_fill(struct ho - } - } else if (os_strcmp(buf, "acs_exclude_dfs") == 0) { - conf->acs_exclude_dfs = atoi(pos); -+ } else if (os_strcmp(buf, "radio_config_id") == 0) { -+ conf->config_id = os_strdup(pos); - } else if (os_strcmp(buf, "op_class") == 0) { - conf->op_class = atoi(pos); - } else if (os_strcmp(buf, "channel") == 0) { ---- a/src/ap/ap_config.c -+++ b/src/ap/ap_config.c -@@ -791,6 +791,7 @@ void hostapd_config_free_bss(struct host - os_free(conf->radius_req_attr_sqlite); - os_free(conf->rsn_preauth_interfaces); - os_free(conf->ctrl_interface); -+ os_free(conf->config_id); - os_free(conf->ca_cert); - os_free(conf->server_cert); - os_free(conf->server_cert2); -@@ -987,6 +988,7 @@ void hostapd_config_free(struct hostapd_ - - for (i = 0; i < conf->num_bss; i++) - hostapd_config_free_bss(conf->bss[i]); -+ os_free(conf->config_id); - os_free(conf->bss); - os_free(conf->supported_rates); - os_free(conf->basic_rates); ---- a/src/ap/ap_config.h -+++ b/src/ap/ap_config.h -@@ -279,6 +279,8 @@ struct hostapd_bss_config { - char vlan_bridge[IFNAMSIZ + 1]; - char wds_bridge[IFNAMSIZ + 1]; - -+ char *config_id; -+ - enum hostapd_logger_level logger_syslog_level, logger_stdout_level; - - unsigned int logger_syslog; /* module bitfield */ -@@ -938,6 +940,7 @@ struct spatial_reuse { - struct hostapd_config { - struct hostapd_bss_config **bss, *last_bss; - size_t num_bss; -+ char *config_id; - - u16 beacon_int; - int rts_threshold; ---- a/src/ap/hostapd.c -+++ b/src/ap/hostapd.c -@@ -219,6 +219,10 @@ static int hostapd_iface_conf_changed(st - { - size_t i; - -+ if (newconf->config_id != oldconf->config_id) -+ if (strcmp(newconf->config_id, oldconf->config_id)) -+ return 1; -+ - if (newconf->num_bss != oldconf->num_bss) - return 1; - -@@ -232,7 +236,7 @@ static int hostapd_iface_conf_changed(st - } - - --int hostapd_reload_config(struct hostapd_iface *iface) -+int hostapd_reload_config(struct hostapd_iface *iface, int reconf) - { - struct hapd_interfaces *interfaces = iface->interfaces; - struct hostapd_data *hapd = iface->bss[0]; -@@ -255,13 +259,16 @@ int hostapd_reload_config(struct hostapd - if (newconf == NULL) - return -1; - -- hostapd_clear_old(iface); -- - oldconf = hapd->iconf; - if (hostapd_iface_conf_changed(newconf, oldconf)) { - char *fname; - int res; - -+ if (reconf) -+ return -1; -+ -+ hostapd_clear_old(iface); -+ - wpa_printf(MSG_DEBUG, - "Configuration changes include interface/BSS modification - force full disable+enable sequence"); - fname = os_strdup(iface->config_fname); -@@ -286,6 +293,24 @@ int hostapd_reload_config(struct hostapd - wpa_printf(MSG_ERROR, - "Failed to enable interface on config reload"); - return res; -+ } else { -+ for (j = 0; j < iface->num_bss; j++) { -+ hapd = iface->bss[j]; -+ if (!hapd->config_id || strcmp(hapd->config_id, newconf->bss[j]->config_id)) { -+ hostapd_flush_old_stations(iface->bss[j], -+ WLAN_REASON_PREV_AUTH_NOT_VALID); -+#ifdef CONFIG_WEP -+ hostapd_broadcast_wep_clear(iface->bss[j]); -+#endif -+ -+#ifndef CONFIG_NO_RADIUS -+ /* TODO: update dynamic data based on changed configuration -+ * items (e.g., open/close sockets, etc.) */ -+ radius_client_flush(iface->bss[j]->radius, 0); -+#endif /* CONFIG_NO_RADIUS */ -+ wpa_printf(MSG_INFO, "bss %zu changed", j); -+ } -+ } - } - iface->conf = newconf; - -@@ -302,6 +327,12 @@ int hostapd_reload_config(struct hostapd - - for (j = 0; j < iface->num_bss; j++) { - hapd = iface->bss[j]; -+ if (hapd->config_id) { -+ os_free(hapd->config_id); -+ hapd->config_id = NULL; -+ } -+ if (newconf->bss[j]->config_id) -+ hapd->config_id = strdup(newconf->bss[j]->config_id); - hapd->iconf = newconf; - hapd->conf = newconf->bss[j]; - hostapd_reload_bss(hapd); -@@ -2397,6 +2428,10 @@ hostapd_alloc_bss_data(struct hostapd_if - hapd->iconf = conf; - hapd->conf = bss; - hapd->iface = hapd_iface; -+ if (bss && bss->config_id) -+ hapd->config_id = strdup(bss->config_id); -+ else -+ hapd->config_id = NULL; - if (conf) - hapd->driver = conf->driver; - hapd->ctrl_sock = -1; ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h -@@ -46,7 +46,7 @@ struct mesh_conf; - struct hostapd_iface; - - struct hapd_interfaces { -- int (*reload_config)(struct hostapd_iface *iface); -+ int (*reload_config)(struct hostapd_iface *iface, int reconf); - struct hostapd_config * (*config_read_cb)(const char *config_fname); - int (*ctrl_iface_init)(struct hostapd_data *hapd); - void (*ctrl_iface_deinit)(struct hostapd_data *hapd); -@@ -156,6 +156,7 @@ struct hostapd_data { - struct hostapd_config *iconf; - struct hostapd_bss_config *conf; - struct hostapd_ubus_bss ubus; -+ char *config_id; - int interface_added; /* virtual interface added for this BSS */ - unsigned int started:1; - unsigned int disabled:1; -@@ -604,7 +605,7 @@ struct hostapd_iface { - int hostapd_for_each_interface(struct hapd_interfaces *interfaces, - int (*cb)(struct hostapd_iface *iface, - void *ctx), void *ctx); --int hostapd_reload_config(struct hostapd_iface *iface); -+int hostapd_reload_config(struct hostapd_iface *iface, int reconf); - void hostapd_reconfig_encryption(struct hostapd_data *hapd); - struct hostapd_data * - hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, ---- a/src/drivers/driver_nl80211.c -+++ b/src/drivers/driver_nl80211.c -@@ -4820,6 +4820,9 @@ static int wpa_driver_nl80211_set_ap(voi - if (ret) { - wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)", - ret, strerror(-ret)); -+ if (!bss->beacon_set) -+ ret = 0; -+ bss->beacon_set = 0; - } else { - bss->beacon_set = 1; - nl80211_set_bss(bss, params->cts_protect, params->preamble, ---- a/hostapd/ctrl_iface.c -+++ b/hostapd/ctrl_iface.c -@@ -186,7 +186,7 @@ static int hostapd_ctrl_iface_update(str - iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read; - reload_opts = txt; - -- hostapd_reload_config(iface); -+ hostapd_reload_config(iface, 0); - - iface->interfaces->config_read_cb = config_read_cb; - } ---- a/hostapd/main.c -+++ b/hostapd/main.c -@@ -317,7 +317,7 @@ static void handle_term(int sig, void *s - - static int handle_reload_iface(struct hostapd_iface *iface, void *ctx) - { -- if (hostapd_reload_config(iface) < 0) { -+ if (hostapd_reload_config(iface, 0) < 0) { - wpa_printf(MSG_WARNING, "Failed to read new configuration " - "file - continuing with old."); - } ---- a/src/ap/wps_hostapd.c -+++ b/src/ap/wps_hostapd.c -@@ -315,7 +315,7 @@ static void wps_reload_config(void *eloo - - wpa_printf(MSG_DEBUG, "WPS: Reload configuration data"); - if (iface->interfaces == NULL || -- iface->interfaces->reload_config(iface) < 0) { -+ iface->interfaces->reload_config(iface, 1) < 0) { - wpa_printf(MSG_WARNING, "WPS: Failed to reload the updated " - "configuration"); - } diff --git a/feeds/ipq807x_v5.4/hostapd/patches/701-reload_config_inline.patch b/feeds/ipq807x_v5.4/hostapd/patches/701-reload_config_inline.patch new file mode 100644 index 000000000..2f68e73e0 --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/patches/701-reload_config_inline.patch @@ -0,0 +1,33 @@ +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -4699,7 +4699,12 @@ struct hostapd_config * hostapd_config_r + int errors = 0; + size_t i; + +- f = fopen(fname, "r"); ++ if (!strncmp(fname, "data:", 5)) { ++ f = fmemopen((void *)(fname + 5), strlen(fname + 5), "r"); ++ fname = ""; ++ } else { ++ f = fopen(fname, "r"); ++ } + if (f == NULL) { + wpa_printf(MSG_ERROR, "Could not open configuration file '%s' " + "for reading.", fname); +--- a/wpa_supplicant/config_file.c ++++ b/wpa_supplicant/config_file.c +@@ -318,8 +318,13 @@ struct wpa_config * wpa_config_read(cons + while (cred_tail && cred_tail->next) + cred_tail = cred_tail->next; + ++ if (!strncmp(name, "data:", 5)) { ++ f = fmemopen((void *)(name + 5), strlen(name + 5), "r"); ++ name = ""; ++ } else { ++ f = fopen(name, "r"); ++ } + wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name); +- f = fopen(name, "r"); + if (f == NULL) { + wpa_printf(MSG_ERROR, "Failed to open config file '%s', " + "error: %s", name, strerror(errno)); diff --git a/feeds/ipq807x_v5.4/hostapd/patches/710-vlan_no_bridge.patch b/feeds/ipq807x_v5.4/hostapd/patches/710-vlan_no_bridge.patch index 73db32e54..0459bd478 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/710-vlan_no_bridge.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/710-vlan_no_bridge.patch @@ -30,7 +30,7 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3366,6 +3366,8 @@ static int hostapd_config_fill(struct ho +@@ -3342,6 +3342,8 @@ static int hostapd_config_fill(struct ho #ifndef CONFIG_NO_VLAN } else if (os_strcmp(buf, "dynamic_vlan") == 0) { bss->ssid.dynamic_vlan = atoi(pos); diff --git a/feeds/ipq807x_v5.4/hostapd/patches/711-wds_bridge_force.patch b/feeds/ipq807x_v5.4/hostapd/patches/711-wds_bridge_force.patch index 76a354780..f8bb39186 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/711-wds_bridge_force.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/711-wds_bridge_force.patch @@ -1,8 +1,6 @@ -Index: hostapd-2021-05-22-b102f19b/hostapd/config_file.c -=================================================================== ---- hostapd-2021-05-22-b102f19b.orig/hostapd/config_file.c -+++ hostapd-2021-05-22-b102f19b/hostapd/config_file.c -@@ -2357,6 +2357,8 @@ static int hostapd_config_fill(struct ho +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -2341,6 +2341,8 @@ static int hostapd_config_fill(struct ho sizeof(conf->bss[0]->iface)); } else if (os_strcmp(buf, "bridge") == 0) { os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); @@ -11,10 +9,8 @@ Index: hostapd-2021-05-22-b102f19b/hostapd/config_file.c } else if (os_strcmp(buf, "vlan_bridge") == 0) { os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); } else if (os_strcmp(buf, "wds_bridge") == 0) { -Index: hostapd-2021-05-22-b102f19b/src/ap/ap_drv_ops.c -=================================================================== ---- hostapd-2021-05-22-b102f19b.orig/src/ap/ap_drv_ops.c -+++ hostapd-2021-05-22-b102f19b/src/ap/ap_drv_ops.c +--- a/src/ap/ap_drv_ops.c ++++ b/src/ap/ap_drv_ops.c @@ -340,8 +340,6 @@ int hostapd_set_wds_sta(struct hostapd_d return -1; if (hapd->conf->wds_bridge[0]) diff --git a/feeds/ipq807x_v5.4/hostapd/patches/720-iface_max_num_sta.patch b/feeds/ipq807x_v5.4/hostapd/patches/720-iface_max_num_sta.patch index b93a0bcbe..cecc6d3f4 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/720-iface_max_num_sta.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/720-iface_max_num_sta.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2873,6 +2873,14 @@ static int hostapd_config_fill(struct ho +@@ -2853,6 +2853,14 @@ static int hostapd_config_fill(struct ho line, bss->max_num_sta, MAX_STA_COUNT); return 1; } @@ -17,7 +17,7 @@ } else if (os_strcmp(buf, "extended_key_id") == 0) { --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h -@@ -648,6 +648,7 @@ void hostapd_cleanup_cs_params(struct ho +@@ -672,6 +672,7 @@ void hostapd_cleanup_cs_params(struct ho void hostapd_periodic_iface(struct hostapd_iface *iface); int hostapd_owe_trans_get_info(struct hostapd_data *hapd); void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx); @@ -27,7 +27,7 @@ int hostapd_register_probereq_cb(struct hostapd_data *hapd, --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -236,6 +236,30 @@ static int hostapd_iface_conf_changed(st +@@ -209,6 +209,30 @@ static int hostapd_iface_conf_changed(st } @@ -55,7 +55,7 @@ + return 0; +} + - int hostapd_reload_config(struct hostapd_iface *iface, int reconf) + int hostapd_reload_config(struct hostapd_iface *iface) { struct hapd_interfaces *interfaces = iface->interfaces; --- a/src/ap/beacon.c @@ -71,7 +71,7 @@ " since no room for additional STA", --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -976,6 +976,8 @@ struct hostapd_config { +@@ -959,6 +959,8 @@ struct hostapd_config { unsigned int track_sta_max_num; unsigned int track_sta_max_age; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/730-ft_iface.patch b/feeds/ipq807x_v5.4/hostapd/patches/730-ft_iface.patch index 793e8e019..6bf85bfa5 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/730-ft_iface.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/730-ft_iface.patch @@ -1,6 +1,6 @@ --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -3031,6 +3031,8 @@ static int hostapd_config_fill(struct ho +@@ -3011,6 +3011,8 @@ static int hostapd_config_fill(struct ho wpa_printf(MSG_INFO, "Line %d: Obsolete peerkey parameter ignored", line); #ifdef CONFIG_IEEE80211R_AP @@ -11,7 +11,7 @@ hexstr2bin(pos, bss->mobility_domain, --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -277,6 +277,7 @@ struct airtime_sta_weight { +@@ -275,6 +275,7 @@ struct airtime_sta_weight { struct hostapd_bss_config { char iface[IFNAMSIZ + 1]; char bridge[IFNAMSIZ + 1]; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/740-snoop_iface.patch b/feeds/ipq807x_v5.4/hostapd/patches/740-snoop_iface.patch index 6e60cde84..94816ee0e 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/740-snoop_iface.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/740-snoop_iface.patch @@ -1,8 +1,6 @@ -Index: hostapd-2021-05-22-b102f19b/src/ap/ap_config.h -=================================================================== ---- hostapd-2021-05-22-b102f19b.orig/src/ap/ap_config.h -+++ hostapd-2021-05-22-b102f19b/src/ap/ap_config.h -@@ -278,6 +278,7 @@ struct hostapd_bss_config { +--- a/src/ap/ap_config.h ++++ b/src/ap/ap_config.h +@@ -276,6 +276,7 @@ struct hostapd_bss_config { char iface[IFNAMSIZ + 1]; char bridge[IFNAMSIZ + 1]; char ft_iface[IFNAMSIZ + 1]; @@ -10,10 +8,8 @@ Index: hostapd-2021-05-22-b102f19b/src/ap/ap_config.h char vlan_bridge[IFNAMSIZ + 1]; char wds_bridge[IFNAMSIZ + 1]; -Index: hostapd-2021-05-22-b102f19b/src/ap/x_snoop.c -=================================================================== ---- hostapd-2021-05-22-b102f19b.orig/src/ap/x_snoop.c -+++ hostapd-2021-05-22-b102f19b/src/ap/x_snoop.c +--- a/src/ap/x_snoop.c ++++ b/src/ap/x_snoop.c @@ -31,14 +31,16 @@ int x_snoop_init(struct hostapd_data *ha return -1; } @@ -57,11 +53,9 @@ Index: hostapd-2021-05-22-b102f19b/src/ap/x_snoop.c if (l2 == NULL) { wpa_printf(MSG_DEBUG, "x_snoop: Failed to initialize L2 packet processing %s", -Index: hostapd-2021-05-22-b102f19b/hostapd/config_file.c -=================================================================== ---- hostapd-2021-05-22-b102f19b.orig/hostapd/config_file.c -+++ hostapd-2021-05-22-b102f19b/hostapd/config_file.c -@@ -2359,6 +2359,8 @@ static int hostapd_config_fill(struct ho +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -2343,6 +2343,8 @@ static int hostapd_config_fill(struct ho os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); if (!bss->wds_bridge[0]) os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); diff --git a/feeds/ipq807x_v5.4/hostapd/patches/750-wispr.patch b/feeds/ipq807x_v5.4/hostapd/patches/750-wispr.patch index d5772a4c0..f40cc2b90 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/750-wispr.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/750-wispr.patch @@ -1,7 +1,5 @@ -Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_1x.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/ieee802_1x.c -+++ hostapd-2021-02-20-59e9794c/src/ap/ieee802_1x.c +--- a/src/ap/ieee802_1x.c ++++ b/src/ap/ieee802_1x.c @@ -1904,6 +1904,25 @@ static int ieee802_1x_update_vlan(struct } #endif /* CONFIG_NO_VLAN */ @@ -36,11 +34,9 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_1x.c break; case RADIUS_CODE_ACCESS_REJECT: sm->eap_if->aaaFail = true; -Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.h -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.h -+++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.h -@@ -117,6 +117,7 @@ struct sta_info { +--- a/src/ap/sta_info.h ++++ b/src/ap/sta_info.h +@@ -116,6 +116,7 @@ struct sta_info { u8 supported_rates[WLAN_SUPP_RATES_MAX]; int supported_rates_len; u8 qosinfo; /* Valid when WLAN_STA_WMM is set */ @@ -48,10 +44,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.h #ifdef CONFIG_MESH enum mesh_plink_state plink_state; -Index: hostapd-2021-02-20-59e9794c/src/radius/radius.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/radius/radius.c -+++ hostapd-2021-02-20-59e9794c/src/radius/radius.c +--- a/src/radius/radius.c ++++ b/src/radius/radius.c @@ -1182,6 +1182,35 @@ radius_msg_get_cisco_keys(struct radius_ return keys; } @@ -88,10 +82,8 @@ Index: hostapd-2021-02-20-59e9794c/src/radius/radius.c int radius_msg_add_mppe_keys(struct radius_msg *msg, const u8 *req_authenticator, -Index: hostapd-2021-02-20-59e9794c/src/radius/radius.h -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/radius/radius.h -+++ hostapd-2021-02-20-59e9794c/src/radius/radius.h +--- a/src/radius/radius.h ++++ b/src/radius/radius.h @@ -205,6 +205,10 @@ enum { RADIUS_VENDOR_ATTR_WFA_HS20_T_C_URL = 10, }; @@ -111,16 +103,3 @@ Index: hostapd-2021-02-20-59e9794c/src/radius/radius.h int radius_msg_add_mppe_keys(struct radius_msg *msg, const u8 *req_authenticator, const u8 *secret, size_t secret_len, -Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.c -+++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.c -@@ -1292,7 +1292,7 @@ void ap_sta_set_authorized(struct hostap - MAC2STR(sta->addr), MAC2STR(dev_addr)); - else - #endif /* CONFIG_P2P */ -- os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr)); -+ os_snprintf(buf, sizeof(buf), MACSTR " %d %d", MAC2STR(sta->addr), sta->bandwidth[0] / 1000000, sta->bandwidth[1] / 1000000); - - if (hapd->sta_authorized_cb) - hapd->sta_authorized_cb(hapd->sta_authorized_cb_ctx, diff --git a/feeds/ipq807x_v5.4/hostapd/patches/760-acs_exclude_dfs.patch b/feeds/ipq807x_v5.4/hostapd/patches/760-acs_exclude_dfs.patch index 52d63c5ff..27b3a6161 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/760-acs_exclude_dfs.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/760-acs_exclude_dfs.patch @@ -1,8 +1,6 @@ -Index: hostapd-2021-02-20-59e9794c/src/ap/acs.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/acs.c -+++ hostapd-2021-02-20-59e9794c/src/ap/acs.c -@@ -672,6 +672,10 @@ acs_find_ideal_chan_mode(struct hostapd_ +--- a/src/ap/acs.c ++++ b/src/ap/acs.c +@@ -668,6 +668,10 @@ acs_find_ideal_chan_mode(struct hostapd_ continue; } diff --git a/feeds/ipq807x_v5.4/hostapd/patches/760-dynamic_own_ip.patch b/feeds/ipq807x_v5.4/hostapd/patches/760-dynamic_own_ip.patch index 3d2b59e8c..ad6fa287f 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/760-dynamic_own_ip.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/760-dynamic_own_ip.patch @@ -1,6 +1,6 @@ --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h -@@ -311,6 +311,7 @@ struct hostapd_bss_config { +@@ -301,6 +301,7 @@ struct hostapd_bss_config { unsigned int eap_sim_db_timeout; int eap_server_erp; /* Whether ERP is enabled on internal EAP server */ struct hostapd_ip_addr own_ip_addr; @@ -10,7 +10,7 @@ int acct_interim_interval; --- a/src/radius/radius_client.c +++ b/src/radius/radius_client.c -@@ -163,6 +163,8 @@ struct radius_client_data { +@@ -162,6 +162,8 @@ struct radius_client_data { */ void *ctx; @@ -19,7 +19,7 @@ /** * conf - RADIUS client configuration (list of RADIUS servers to use) */ -@@ -720,6 +722,30 @@ static void radius_client_list_add(struc +@@ -719,6 +721,30 @@ static void radius_client_list_add(struc /** @@ -50,7 +50,7 @@ * radius_client_send - Send a RADIUS request * @radius: RADIUS client context from radius_client_init() * @msg: RADIUS message to be sent -@@ -1238,6 +1264,10 @@ radius_change_server(struct radius_clien +@@ -1219,6 +1245,10 @@ radius_change_server(struct radius_clien wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", inet_ntoa(claddr.sin_addr), ntohs(claddr.sin_port)); @@ -61,7 +61,7 @@ } break; #ifdef CONFIG_IPV6 -@@ -1249,6 +1279,10 @@ radius_change_server(struct radius_clien +@@ -1230,6 +1260,10 @@ radius_change_server(struct radius_clien inet_ntop(AF_INET6, &claddr6.sin6_addr, abuf, sizeof(abuf)), ntohs(claddr6.sin6_port)); @@ -74,7 +74,7 @@ } --- a/src/radius/radius_client.h +++ b/src/radius/radius_client.h -@@ -249,6 +249,8 @@ int radius_client_register(struct radius +@@ -244,6 +244,8 @@ int radius_client_register(struct radius void radius_client_set_interim_error_cb(struct radius_client_data *radius, void (*cb)(const u8 *addr, void *ctx), void *ctx); @@ -98,7 +98,7 @@ hapd->conf->own_ip_addr.af == AF_INET && --- a/hostapd/config_file.c +++ b/hostapd/config_file.c -@@ -2681,6 +2681,8 @@ static int hostapd_config_fill(struct ho +@@ -2696,6 +2696,8 @@ static int hostapd_config_fill(struct ho } else if (os_strcmp(buf, "iapp_interface") == 0) { wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used"); #endif /* CONFIG_IAPP */ diff --git a/feeds/ipq807x_v5.4/hostapd/patches/770-wds-hack.patch b/feeds/ipq807x_v5.4/hostapd/patches/770-wds-hack.patch index c9df6a616..5fa58585f 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/770-wds-hack.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/770-wds-hack.patch @@ -1,7 +1,5 @@ -Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c -+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c @@ -11,6 +11,8 @@ #include #endif /* CONFIG_SQLITE */ @@ -10,8 +8,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c + #include "utils/common.h" #include "utils/eloop.h" - #include "common/ieee802_11_defs.h" -@@ -1316,6 +1318,22 @@ static int hostapd_setup_bss(struct host + #include "utils/crc32.h" +@@ -1198,6 +1200,22 @@ int hostapd_setup_bss(struct hostapd_dat os_memcpy(hapd->own_addr, if_addr, ETH_ALEN); } @@ -32,5 +30,5 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c + } + if (conf->wmm_enabled < 0) - conf->wmm_enabled = hapd->iconf->ieee80211n | hapd->iconf->ieee80211ax; + conf->wmm_enabled = hapd->iconf->ieee80211n; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/780-maxassoc.patch b/feeds/ipq807x_v5.4/hostapd/patches/780-maxassoc.patch index 98840f382..07fc54e14 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/780-maxassoc.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/780-maxassoc.patch @@ -1,7 +1,5 @@ -Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.c -+++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.c +--- a/src/ap/sta_info.c ++++ b/src/ap/sta_info.c @@ -717,7 +717,7 @@ struct sta_info * ap_sta_add(struct host return sta; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/800-fix-ap-sta-channel-setup-failed.patch b/feeds/ipq807x_v5.4/hostapd/patches/800-fix-ap-sta-channel-setup-failed.patch index de7a61158..67e3d078c 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/800-fix-ap-sta-channel-setup-failed.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/800-fix-ap-sta-channel-setup-failed.patch @@ -1,8 +1,6 @@ -diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c -index ad2aebf..355b4a8 100644 --- a/src/common/hw_features_common.c +++ b/src/common/hw_features_common.c -@@ -615,9 +615,21 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data, +@@ -609,9 +609,21 @@ int hostapd_set_freq_params(struct hosta center_segment0 == channel - 6) data->center_freq1 = 5000 + center_segment0 * 5; else { diff --git a/feeds/ipq807x_v5.4/hostapd/patches/900-coa.patch b/feeds/ipq807x_v5.4/hostapd/patches/900-coa.patch index a46ec8212..3e1213a4d 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/900-coa.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/900-coa.patch @@ -1,7 +1,5 @@ -Index: hostapd-2021-02-20-59e9794c/src/radius/radius_das.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/radius/radius_das.c -+++ hostapd-2021-02-20-59e9794c/src/radius/radius_das.c +--- a/src/radius/radius_das.c ++++ b/src/radius/radius_das.c @@ -48,6 +48,8 @@ static struct radius_msg * radius_das_di RADIUS_ATTR_EVENT_TIMESTAMP, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, diff --git a/feeds/ipq807x_v5.4/hostapd/patches/900-coa_multi.patch b/feeds/ipq807x_v5.4/hostapd/patches/900-coa_multi.patch index 7516b7349..24927ea73 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/900-coa_multi.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/900-coa_multi.patch @@ -10,7 +10,7 @@ unsigned int time_window; --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -1367,6 +1367,7 @@ static int hostapd_setup_bss(struct host +@@ -1325,6 +1325,7 @@ int hostapd_setup_bss(struct hostapd_dat struct radius_das_conf das_conf; os_memset(&das_conf, 0, sizeof(das_conf)); das_conf.port = conf->radius_das_port; @@ -48,7 +48,7 @@ size_t shared_secret_len; struct hostapd_ip_addr client_addr; unsigned int time_window; -@@ -378,56 +391,17 @@ fail: +@@ -379,56 +392,17 @@ fail: } @@ -111,7 +111,7 @@ if (radius_msg_verify_das_req(msg, das->shared_secret, das->shared_secret_len, -@@ -494,9 +468,8 @@ static void radius_das_receive(int sock, +@@ -495,9 +469,8 @@ static void radius_das_receive(int sock, radius_msg_dump(reply); rbuf = radius_msg_get_buf(reply); @@ -123,7 +123,11 @@ if (res < 0) { wpa_printf(MSG_ERROR, "DAS: sendto(to %s:%d): %s", abuf, from_port, strerror(errno)); -@@ -508,6 +481,72 @@ fail: +@@ -505,10 +478,76 @@ static void radius_das_receive(int sock, + } + + fail: +- radius_msg_free(msg); radius_msg_free(reply); } @@ -189,6 +193,7 @@ + fromlen, abuf, from_port); + } + ++ radius_msg_free(msg); + if (!found) + wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); +} @@ -196,7 +201,7 @@ static int radius_das_open_socket(int port) { -@@ -533,6 +572,49 @@ static int radius_das_open_socket(int po +@@ -534,6 +573,49 @@ static int radius_das_open_socket(int po } @@ -246,7 +251,7 @@ struct radius_das_data * radius_das_init(struct radius_das_conf *conf) { -@@ -553,6 +635,8 @@ radius_das_init(struct radius_das_conf * +@@ -554,6 +636,8 @@ radius_das_init(struct radius_das_conf * das->ctx = conf->ctx; das->disconnect = conf->disconnect; das->coa = conf->coa; @@ -255,7 +260,7 @@ os_memcpy(&das->client_addr, conf->client_addr, sizeof(das->client_addr)); -@@ -565,19 +649,15 @@ radius_das_init(struct radius_das_conf * +@@ -566,19 +650,15 @@ radius_das_init(struct radius_das_conf * } das->shared_secret_len = conf->shared_secret_len; @@ -278,7 +283,7 @@ return das; } -@@ -588,11 +668,14 @@ void radius_das_deinit(struct radius_das +@@ -589,11 +669,14 @@ void radius_das_deinit(struct radius_das if (das == NULL) return; diff --git a/feeds/ipq807x_v5.4/hostapd/patches/901-cfg-section.patch b/feeds/ipq807x_v5.4/hostapd/patches/901-cfg-section.patch index dcfdd658f..b640f17db 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/901-cfg-section.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/901-cfg-section.patch @@ -1,7 +1,5 @@ -Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c -+++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c @@ -2366,6 +2366,8 @@ static int hostapd_config_fill(struct ho return 1; } @@ -11,23 +9,19 @@ Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c } else if (os_strcmp(buf, "driver_params") == 0) { os_free(conf->driver_params); conf->driver_params = os_strdup(pos); -Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.h -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/ap_config.h -+++ hostapd-2021-02-20-59e9794c/src/ap/ap_config.h +--- a/src/ap/ap_config.h ++++ b/src/ap/ap_config.h @@ -279,6 +279,7 @@ struct hostapd_bss_config { char snoop_iface[IFNAMSIZ + 1]; char vlan_bridge[IFNAMSIZ + 1]; char wds_bridge[IFNAMSIZ + 1]; + char *uci_section; - char *config_id; + enum hostapd_logger_level logger_syslog_level, logger_stdout_level; -Index: hostapd-2021-02-20-59e9794c/src/ap/ubus.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/ubus.c -+++ hostapd-2021-02-20-59e9794c/src/ap/ubus.c -@@ -467,6 +467,9 @@ hostapd_bss_get_status(struct ubus_conte +--- a/src/ap/ubus.c ++++ b/src/ap/ubus.c +@@ -424,6 +424,9 @@ hostapd_bss_get_status(struct ubus_conte hapd->iface->cac_started ? hapd->iface->dfs_cac_ms / 1000 - now.sec : 0); blobmsg_close_table(&b, dfs_table); @@ -37,15 +31,13 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ubus.c ubus_send_reply(ctx, req, b.head); return 0; -Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/ap_config.c -+++ hostapd-2021-02-20-59e9794c/src/ap/ap_config.c +--- a/src/ap/ap_config.c ++++ b/src/ap/ap_config.c @@ -785,6 +785,7 @@ void hostapd_config_free_bss(struct host os_free(conf->radius_req_attr_sqlite); os_free(conf->rsn_preauth_interfaces); os_free(conf->ctrl_interface); + os_free(conf->uci_section); - os_free(conf->config_id); os_free(conf->ca_cert); os_free(conf->server_cert); + os_free(conf->server_cert2); diff --git a/feeds/ipq807x_v5.4/hostapd/patches/920-sta_driver_data.patch b/feeds/ipq807x_v5.4/hostapd/patches/920-sta_driver_data.patch new file mode 100644 index 000000000..6bf5e5661 --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/patches/920-sta_driver_data.patch @@ -0,0 +1,91 @@ +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -2175,6 +2175,10 @@ struct hostap_sta_driver_data { + u8 tx_mcs; + u8 rx_vht_nss; + u8 tx_vht_nss; ++ u8 rx_hemcs; ++ u8 tx_hemcs; ++ u8 rx_he_nss; ++ u8 tx_he_nss; + }; + + struct hostapd_sta_add_params { +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -7010,6 +7010,8 @@ static int get_sta_handler(struct nl_msg + [NL80211_RATE_INFO_VHT_MCS] = { .type = NLA_U8 }, + [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG }, + [NL80211_RATE_INFO_VHT_NSS] = { .type = NLA_U8 }, ++ [NL80211_RATE_INFO_HE_NSS] = { .type = NLA_U8 }, ++ [NL80211_RATE_INFO_HE_MCS] = { .type = NLA_U8 }, + }; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), +@@ -7102,6 +7104,10 @@ static int get_sta_handler(struct nl_msg + nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]); + data->flags |= STA_DRV_DATA_TX_VHT_NSS; + } ++ if (rate[NL80211_RATE_INFO_HE_MCS]) ++ data->tx_hemcs = nla_get_u8(rate[NL80211_RATE_INFO_HE_MCS]); ++ if (rate[NL80211_RATE_INFO_HE_NSS]) ++ data->tx_he_nss = nla_get_u8(rate[NL80211_RATE_INFO_HE_NSS]); + } + + if (stats[NL80211_STA_INFO_RX_BITRATE] && +@@ -7132,11 +7138,16 @@ static int get_sta_handler(struct nl_msg + nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]); + data->flags |= STA_DRV_DATA_RX_VHT_NSS; + } ++ if (rate[NL80211_RATE_INFO_HE_MCS]) ++ data->rx_hemcs = nla_get_u8(rate[NL80211_RATE_INFO_HE_MCS]); ++ if (rate[NL80211_RATE_INFO_HE_NSS]) ++ data->rx_he_nss = nla_get_u8(rate[NL80211_RATE_INFO_HE_NSS]); + } + + if (stats[NL80211_STA_INFO_TID_STATS]) + get_sta_tid_stats(data, stats[NL80211_STA_INFO_TID_STATS]); + ++ + return NL_SKIP; + } + +--- a/src/ap/ubus.c ++++ b/src/ap/ubus.c +@@ -306,6 +306,36 @@ hostapd_bss_get_clients(struct ubus_cont + blobmsg_add_u32(&b, "tx", sta_driver_data.current_tx_rate * 100); + blobmsg_close_table(&b, r); + blobmsg_add_u32(&b, "signal", sta_driver_data.signal); ++ ++ r = blobmsg_open_table(&b, "mcs"); ++ if (sta_driver_data.rx_hemcs) { ++ blobmsg_add_u32(&b, "he", 1); ++ blobmsg_add_u32(&b, "rx", sta_driver_data.rx_hemcs); ++ blobmsg_add_u32(&b, "tx", sta_driver_data.tx_hemcs); ++ } else if (sta_driver_data.rx_vhtmcs) { ++ blobmsg_add_u32(&b, "vht", 1); ++ blobmsg_add_u32(&b, "rx", sta_driver_data.rx_vhtmcs); ++ blobmsg_add_u32(&b, "tx", sta_driver_data.tx_vhtmcs); ++ } else { ++ blobmsg_add_u32(&b, "rx", sta_driver_data.rx_mcs); ++ blobmsg_add_u32(&b, "tx", sta_driver_data.tx_mcs); ++ } ++ blobmsg_close_table(&b, r); ++ ++ r = blobmsg_open_table(&b, "nss"); ++ if (sta_driver_data.rx_he_nss) { ++ blobmsg_add_u32(&b, "he", 1); ++ blobmsg_add_u32(&b, "rx", sta_driver_data.rx_he_nss); ++ blobmsg_add_u32(&b, "tx", sta_driver_data.tx_he_nss); ++ } else if (sta_driver_data.rx_vht_nss) { ++ blobmsg_add_u32(&b, "vht", 1); ++ blobmsg_add_u32(&b, "rx", sta_driver_data.rx_vht_nss); ++ blobmsg_add_u32(&b, "tx", sta_driver_data.tx_vht_nss); ++ } else { ++ blobmsg_add_u32(&b, "rx", sta_driver_data.rx_mcs); ++ blobmsg_add_u32(&b, "tx", sta_driver_data.tx_mcs); ++ } ++ blobmsg_close_table(&b, r); + } + + hostapd_parse_capab_blobmsg(sta); diff --git a/feeds/ipq807x_v5.4/hostapd/patches/999-probe-request.patch b/feeds/ipq807x_v5.4/hostapd/patches/999-probe-request.patch index 3b79338c2..a239c8432 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/999-probe-request.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/999-probe-request.patch @@ -1,8 +1,6 @@ -Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c -+++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c -@@ -3339,6 +3339,8 @@ static int hostapd_config_fill(struct ho +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -3337,6 +3337,8 @@ static int hostapd_config_fill(struct ho bss->ignore_broadcast_ssid = atoi(pos); } else if (os_strcmp(buf, "no_probe_resp_if_max_sta") == 0) { bss->no_probe_resp_if_max_sta = atoi(pos); @@ -11,11 +9,9 @@ Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c #ifdef CONFIG_WEP } else if (os_strcmp(buf, "wep_default_key") == 0) { bss->ssid.wep.idx = atoi(pos); -Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.h -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/ap_config.h -+++ hostapd-2021-02-20-59e9794c/src/ap/ap_config.h -@@ -460,6 +460,7 @@ struct hostapd_bss_config { +--- a/src/ap/ap_config.h ++++ b/src/ap/ap_config.h +@@ -459,6 +459,7 @@ struct hostapd_bss_config { int ap_max_inactivity; int ignore_broadcast_ssid; int no_probe_resp_if_max_sta; @@ -23,10 +19,8 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.h int wmm_enabled; int wmm_uapsd; -Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/beacon.c -+++ hostapd-2021-02-20-59e9794c/src/ap/beacon.c +--- a/src/ap/beacon.c ++++ b/src/ap/beacon.c @@ -920,7 +920,8 @@ void handle_probe_req(struct hostapd_dat } #endif /* CONFIG_P2P */ diff --git a/feeds/ipq807x_v5.4/hostapd/patches/999-ssi_signal.patch b/feeds/ipq807x_v5.4/hostapd/patches/999-ssi_signal.patch new file mode 100644 index 000000000..bdd0a0ede --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/patches/999-ssi_signal.patch @@ -0,0 +1,95 @@ +--- a/src/ap/ieee802_11.c ++++ b/src/ap/ieee802_11.c +@@ -57,6 +57,15 @@ + #include "gas_query_ap.h" + + ++static int ++ewma(int new, int old) ++{ ++ #define ALPHA 10 ++ if (new >= 0) ++ return old; ++ return ((ALPHA * new) + ((100 - ALPHA) * old)) / 100; ++} ++ + #ifdef CONFIG_FILS + static struct wpabuf * + prepare_auth_resp_fils(struct hostapd_data *hapd, +@@ -5873,7 +5882,7 @@ static int robust_action_frame(u8 catego + + static int handle_action(struct hostapd_data *hapd, + const struct ieee80211_mgmt *mgmt, size_t len, +- unsigned int freq) ++ unsigned int freq, int ssi_signal) + { + struct sta_info *sta; + u8 *action __maybe_unused; +@@ -5930,6 +5939,7 @@ static int handle_action(struct hostapd_ + + sta->last_seq_ctrl = seq_ctrl; + sta->last_subtype = WLAN_FC_STYPE_ACTION; ++ sta->signal_mgmt = ewma(ssi_signal, sta->signal_mgmt);; + } + + switch (mgmt->u.action.category) { +@@ -6109,6 +6119,8 @@ int ieee802_11_mgmt(struct hostapd_data + unsigned int freq; + int ssi_signal = fi ? fi->ssi_signal : 0; + ++ hapd->signal_mgmt = ewma(ssi_signal, hapd->signal_mgmt);; ++ + if (len < 24) + return 0; + +@@ -6208,7 +6220,7 @@ int ieee802_11_mgmt(struct hostapd_data + break; + case WLAN_FC_STYPE_ACTION: + wpa_printf(MSG_DEBUG, "mgmt::action"); +- ret = handle_action(hapd, mgmt, len, freq); ++ ret = handle_action(hapd, mgmt, len, freq, ssi_signal); + break; + default: + hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, +--- a/src/ap/sta_info.h ++++ b/src/ap/sta_info.h +@@ -331,6 +331,7 @@ struct sta_info { + #ifdef CONFIG_PASN + struct pasn_data *pasn; + #endif /* CONFIG_PASN */ ++ int signal_mgmt; + }; + + +--- a/src/ap/ubus.c ++++ b/src/ap/ubus.c +@@ -336,6 +336,9 @@ hostapd_bss_get_clients(struct ubus_cont + blobmsg_add_u32(&b, "tx", sta_driver_data.tx_mcs); + } + blobmsg_close_table(&b, r); ++ ++ if (sta->signal_mgmt) ++ blobmsg_add_u32(&b, "signal_mgmt", sta->signal_mgmt); + } + + hostapd_parse_capab_blobmsg(sta); +@@ -457,6 +460,9 @@ hostapd_bss_get_status(struct ubus_conte + if (hapd->conf->uci_section) + blobmsg_add_string(&b, "uci_section", hapd->conf->uci_section); + ++ if (hapd->signal_mgmt) ++ blobmsg_add_u32(&b, "signal_mgmt", hapd->signal_mgmt); ++ + ubus_send_reply(ctx, req, b.head); + + return 0; +--- a/src/ap/hostapd.h ++++ b/src/ap/hostapd.h +@@ -451,6 +451,7 @@ struct hostapd_data { + #ifdef CONFIG_CTRL_IFACE_UDP + unsigned char ctrl_iface_cookie[CTRL_IFACE_COOKIE_LEN]; + #endif /* CONFIG_CTRL_IFACE_UDP */ ++ int signal_mgmt; + }; + + diff --git a/feeds/ipq807x_v5.4/hostapd/patches/d00-011-01-multiple_bssid-add-the-config-file.patch b/feeds/ipq807x_v5.4/hostapd/patches/d00-011-01-multiple_bssid-add-the-config-file.patch index 8e815452f..60857e356 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/d00-011-01-multiple_bssid-add-the-config-file.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/d00-011-01-multiple_bssid-add-the-config-file.patch @@ -16,7 +16,7 @@ Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c =================================================================== --- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c +++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c -@@ -4683,6 +4683,8 @@ static int hostapd_config_fill(struct ho +@@ -4685,6 +4685,8 @@ static int hostapd_config_fill(struct ho } bss->mka_psk_set |= MKA_PSK_SET_CKN; #endif /* CONFIG_MACSEC */ @@ -69,7 +69,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c void hostapd_reconfig_encryption(struct hostapd_data *hapd) { if (hapd->wpa_auth) -@@ -1208,6 +1228,13 @@ static int hostapd_setup_bss(struct host +@@ -1162,6 +1182,13 @@ int hostapd_setup_bss(struct hostapd_dat if (!first || first == -1) { u8 *addr = hapd->own_addr; @@ -83,7 +83,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c if (!is_zero_ether_addr(conf->bssid)) { /* Allocate the configured BSSID. */ -@@ -1235,7 +1262,7 @@ static int hostapd_setup_bss(struct host +@@ -1189,7 +1216,7 @@ int hostapd_setup_bss(struct hostapd_dat conf->iface, addr, hapd, &hapd->drv_priv, force_ifname, if_addr, conf->bridge[0] ? conf->bridge : NULL, @@ -96,13 +96,13 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h =================================================================== --- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.h +++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.h -@@ -621,6 +621,8 @@ struct hostapd_iface { +@@ -628,6 +628,8 @@ struct hostapd_iface { int hostapd_for_each_interface(struct hapd_interfaces *interfaces, int (*cb)(struct hostapd_iface *iface, void *ctx), void *ctx); +int hostapd_get_bss_index(struct hostapd_data *hapd); +struct hostapd_data * hostapd_get_primary_bss(struct hostapd_data *hapd); - int hostapd_reload_config(struct hostapd_iface *iface, int reconf); + int hostapd_reload_config(struct hostapd_iface *iface); void hostapd_reconfig_encryption(struct hostapd_data *hapd); struct hostapd_data * Index: hostapd-2021-02-20-59e9794c/src/ap/ap_drv_ops.c @@ -203,7 +203,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c if (len < IEEE80211_HDRLEN) return; ie = ((const u8 *) mgmt) + IEEE80211_HDRLEN; -@@ -1085,7 +1097,7 @@ void handle_probe_req(struct hostapd_dat +@@ -1087,7 +1099,7 @@ void handle_probe_req(struct hostapd_dat hapd->cs_c_off_ecsa_proberesp; } @@ -212,7 +212,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c csa_offs_len ? csa_offs : NULL, csa_offs_len, 0); -@@ -1746,6 +1758,8 @@ void ieee802_11_free_ap_params(struct wp +@@ -1748,6 +1760,8 @@ void ieee802_11_free_ap_params(struct wp params->head = NULL; os_free(params->proberesp); params->proberesp = NULL; @@ -221,7 +221,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c #ifdef CONFIG_FILS os_free(params->fd_frame_tmpl); params->fd_frame_tmpl = NULL; -@@ -1802,6 +1816,22 @@ int ieee802_11_set_beacon(struct hostapd +@@ -1809,6 +1823,22 @@ int ieee802_11_set_beacon(struct hostapd params.unsol_bcast_probe_resp_tmpl = hostapd_unsol_bcast_probe_resp(hapd, ¶ms); #endif /* CONFIG_IEEE80211AX */ @@ -299,7 +299,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver.h }; struct wpa_driver_mesh_bss_params { -@@ -3344,7 +3381,8 @@ struct wpa_driver_ops { +@@ -3348,7 +3385,8 @@ struct wpa_driver_ops { int (*if_add)(void *priv, enum wpa_driver_if_type type, const char *ifname, const u8 *addr, void *bss_ctx, void **drv_priv, char *force_ifname, u8 *if_addr, @@ -354,7 +354,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c ret = send_and_recv_msgs_owner(drv, msg, get_connect_handle(bss), 1, NULL, NULL, NULL, NULL); if (ret) { -@@ -5405,13 +5426,13 @@ const char * nl80211_iftype_str(enum nl8 +@@ -5402,13 +5423,13 @@ const char * nl80211_iftype_str(enum nl8 } } @@ -370,7 +370,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c { struct nl_msg *msg; int ifidx; -@@ -5440,6 +5461,17 @@ static int nl80211_create_iface_once(str +@@ -5437,6 +5458,17 @@ static int nl80211_create_iface_once(str goto fail; } @@ -388,7 +388,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c /* * Tell cfg80211 that the interface belongs to the socket that created * it, and the interface should be deleted when the socket is closed. -@@ -5497,12 +5529,15 @@ int nl80211_create_iface(struct wpa_driv +@@ -5494,12 +5526,15 @@ int nl80211_create_iface(struct wpa_driv const char *ifname, enum nl80211_iftype iftype, const u8 *addr, int wds, int (*handler)(struct nl_msg *, void *), @@ -406,7 +406,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c /* if error occurred and interface exists already */ if (ret == -ENFILE && if_nametoindex(ifname)) { -@@ -5528,7 +5563,9 @@ int nl80211_create_iface(struct wpa_driv +@@ -5525,7 +5560,9 @@ int nl80211_create_iface(struct wpa_driv /* Try to create the interface again */ ret = nl80211_create_iface_once(drv, ifname, iftype, addr, @@ -417,7 +417,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c } if (ret >= 0 && is_p2p_net_interface(iftype)) { -@@ -7518,7 +7555,7 @@ static int i802_set_wds_sta(void *priv, +@@ -7526,7 +7563,7 @@ static int i802_set_wds_sta(void *priv, if (!if_nametoindex(name)) { if (nl80211_create_iface(drv, name, NL80211_IFTYPE_AP_VLAN, @@ -426,7 +426,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c 0) return -1; if (bridge_ifname && -@@ -7863,7 +7900,9 @@ static int wpa_driver_nl80211_if_add(voi +@@ -7871,7 +7908,9 @@ static int wpa_driver_nl80211_if_add(voi void *bss_ctx, void **drv_priv, char *force_ifname, u8 *if_addr, const char *bridge, int use_existing, @@ -437,7 +437,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c { enum nl80211_iftype nlmode; struct i802_bss *bss = priv; -@@ -7880,7 +7919,8 @@ static int wpa_driver_nl80211_if_add(voi +@@ -7888,7 +7927,8 @@ static int wpa_driver_nl80211_if_add(voi os_memset(&p2pdev_info, 0, sizeof(p2pdev_info)); ifidx = nl80211_create_iface(drv, ifname, nlmode, addr, 0, nl80211_wdev_handler, @@ -447,7 +447,7 @@ Index: hostapd-2021-02-20-59e9794c/src/drivers/driver_nl80211.c if (!p2pdev_info.wdev_id_set || ifidx != 0) { wpa_printf(MSG_ERROR, "nl80211: Failed to create a P2P Device interface %s", ifname); -@@ -7896,7 +7936,9 @@ static int wpa_driver_nl80211_if_add(voi +@@ -7904,7 +7944,9 @@ static int wpa_driver_nl80211_if_add(voi (long long unsigned int) p2pdev_info.wdev_id); } else { ifidx = nl80211_create_iface(drv, ifname, nlmode, addr, @@ -537,7 +537,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c #include "utils/includes.h" #ifndef CONFIG_NATIVE_WINDOWS -@@ -3859,7 +3860,11 @@ int hostapd_get_aid(struct hostapd_data +@@ -3868,7 +3869,11 @@ int hostapd_get_aid(struct hostapd_data } if (j == 32) return -1; @@ -550,7 +550,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c if (aid > 2007) return -1; -@@ -5560,7 +5565,7 @@ static void handle_assoc(struct hostapd_ +@@ -5569,7 +5574,7 @@ static void handle_assoc(struct hostapd_ goto fail; omit_rsnxe = !get_ie(pos, left, WLAN_EID_RSNX); @@ -559,7 +559,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "No room for more AIDs"); resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; -@@ -6969,4 +6974,117 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct +@@ -6981,4 +6986,117 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct return eid; } diff --git a/feeds/ipq807x_v5.4/hostapd/patches/e00-008-multiple_bssid-DTIM-setting.patch b/feeds/ipq807x_v5.4/hostapd/patches/e00-008-multiple_bssid-DTIM-setting.patch index cc303fa6b..0b8a198b5 100644 --- a/feeds/ipq807x_v5.4/hostapd/patches/e00-008-multiple_bssid-DTIM-setting.patch +++ b/feeds/ipq807x_v5.4/hostapd/patches/e00-008-multiple_bssid-DTIM-setting.patch @@ -33,7 +33,7 @@ Signed-off-by: Aloka Dixit --- a/src/ap/beacon.c +++ b/src/ap/beacon.c -@@ -1788,6 +1788,7 @@ int ieee802_11_build_ap_params(struct ho +@@ -1774,6 +1774,7 @@ int ieee802_11_build_ap_params(struct ho if ((params->multiple_bssid_ie_count <= 1) && (ext_cap_len >= 13) && (ext_cap_pos[12] & 0x08)) ext_cap_pos[12] |= 0x01; @@ -43,10 +43,10 @@ Signed-off-by: Aloka Dixit return 0; --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c -@@ -1109,19 +1109,60 @@ static int db_table_create_radius_attrib - +@@ -1203,11 +1203,52 @@ static int db_table_create_radius_attrib #endif /* CONFIG_NO_RADIUS */ + +static int hostapd_set_beacon(struct hostapd_data *hapd) +{ + struct hostapd_bss_config *conf = hapd->conf; @@ -84,7 +84,7 @@ Signed-off-by: Aloka Dixit + hostapd_ubus_add_bss(hapd); + return 0; +} - ++ /** * hostapd_setup_bss - Per-BSS setup (initialization) * @hapd: Pointer to BSS data @@ -96,16 +96,7 @@ Signed-off-by: Aloka Dixit * * This function is used to initialize all per-BSS data structures and * resources. This gets called in a loop for each BSS when an interface is - * initialized. Most of the modules that are initialized here will be - * deinitialized in hostapd_cleanup(). - */ --static int hostapd_setup_bss(struct hostapd_data *hapd, int first) -+static int hostapd_setup_bss(struct hostapd_data *hapd, int first, -+ bool set_beacon) - { - struct hostapd_bss_config *conf = hapd->conf; - u8 ssid[SSID_MAX_LEN + 1]; -@@ -1393,31 +1434,8 @@ static int hostapd_setup_bss(struct host +@@ -1503,32 +1544,8 @@ int hostapd_setup_bss(struct hostapd_dat return -1; } @@ -134,22 +125,23 @@ Signed-off-by: Aloka Dixit - hapd->driver->set_operstate(hapd->drv_priv, 1); - - hostapd_ubus_add_bss(hapd); +- hostapd_ucode_add_bss(hapd); + if (set_beacon) + return hostapd_set_beacon(hapd); return 0; } -@@ -2109,7 +2127,8 @@ static int hostapd_setup_interface_compl +@@ -2223,7 +2240,8 @@ static int hostapd_setup_interface_compl hapd = iface->bss[j]; if (j) os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); -- if (hostapd_setup_bss(hapd, j == 0)) { +- if (hostapd_setup_bss(hapd, j == 0, true)) { + if (hostapd_setup_bss(hapd, j == 0, + hapd->iconf->multiple_bssid? 0 : 1)) { for (;;) { hapd = iface->bss[j]; hostapd_bss_deinit_no_free(hapd); -@@ -2123,6 +2142,24 @@ static int hostapd_setup_interface_compl +@@ -2237,6 +2255,24 @@ static int hostapd_setup_interface_compl if (is_zero_ether_addr(hapd->conf->bssid)) prev_addr = hapd->own_addr; } @@ -174,18 +166,18 @@ Signed-off-by: Aloka Dixit hapd = iface->bss[0]; hostapd_tx_queue_params(iface); -@@ -2989,7 +3026,7 @@ int hostapd_add_iface(struct hapd_interf +@@ -3123,7 +3159,7 @@ int hostapd_add_iface(struct hapd_interf if (start_ctrl_iface_bss(hapd) < 0 || (hapd_iface->state == HAPD_IFACE_ENABLED && -- hostapd_setup_bss(hapd, -1))) { +- hostapd_setup_bss(hapd, -1, true))) { + hostapd_setup_bss(hapd, -1, 1))) { hostapd_cleanup(hapd); hapd_iface->bss[hapd_iface->num_bss - 1] = NULL; hapd_iface->conf->num_bss--; --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c -@@ -5721,7 +5721,7 @@ int hostapd_eid_multiple_bssid_len(struc +@@ -7036,7 +7036,7 @@ int hostapd_eid_multiple_bssid_len(struc static u8 * hostapd_eid_multiple_bssid_chunk(struct hostapd_data *hapd, u8 *eid, u8 *end, int *count, @@ -194,7 +186,7 @@ Signed-off-by: Aloka Dixit { u8 *size_offset, *num_offset; int i; -@@ -5753,6 +5753,7 @@ static u8 * hostapd_eid_multiple_bssid_c +@@ -7068,6 +7068,7 @@ static u8 * hostapd_eid_multiple_bssid_c index_size_offset = eid++; *eid++ = i; if (is_beacon) { @@ -202,7 +194,7 @@ Signed-off-by: Aloka Dixit *eid++ = bss->conf->dtim_period; *eid++ = 0xFF; } -@@ -5783,17 +5784,53 @@ u8 * hostapd_eid_multiple_bssid(struct h +@@ -7098,17 +7099,53 @@ u8 * hostapd_eid_multiple_bssid(struct h u8 is_beacon, u8 **eid_offsets, int *eid_count, int eid_max, u8 ema_beacon) { diff --git a/feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.c b/feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.c index 199738698..65f9fb834 100644 --- a/feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.c +++ b/feeds/ipq807x_v5.4/hostapd/src/src/ap/ubus.c @@ -29,11 +29,6 @@ static struct ubus_context *ctx; static struct blob_buf b; static int ctx_ref; -static inline struct hapd_interfaces *get_hapd_interfaces_from_object(struct ubus_object *obj) -{ - return container_of(obj, struct hapd_interfaces, ubus); -} - static inline struct hostapd_data *get_hapd_from_object(struct ubus_object *obj) { return container_of(obj, struct hostapd_data, ubus.obj); @@ -44,12 +39,6 @@ struct ubus_banned_client { u8 addr[ETH_ALEN]; }; -static void ubus_receive(int sock, void *eloop_ctx, void *sock_ctx) -{ - struct ubus_context *ctx = eloop_ctx; - ubus_handle_event(ctx); -} - static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) { if (ubus_reconnect(ctx, NULL)) { @@ -57,12 +46,12 @@ static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) return; } - eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); + ubus_add_uloop(ctx); } static void hostapd_ubus_connection_lost(struct ubus_context *ctx) { - eloop_unregister_read_sock(ctx->sock.fd); + uloop_fd_delete(&ctx->sock); eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); } @@ -71,12 +60,14 @@ static bool hostapd_ubus_init(void) if (ctx) return true; + eloop_add_uloop(); ctx = ubus_connect(NULL); if (!ctx) return false; ctx->connection_lost = hostapd_ubus_connection_lost; - eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); + ubus_add_uloop(ctx); + return true; } @@ -94,7 +85,7 @@ static void hostapd_ubus_ref_dec(void) if (ctx_ref) return; - eloop_unregister_read_sock(ctx->sock.fd); + uloop_fd_delete(&ctx->sock); ubus_free(ctx); ctx = NULL; } @@ -127,38 +118,6 @@ static void hostapd_notify_ubus(struct ubus_object *obj, char *bssname, char *ev free(event_type); } -static void hostapd_send_procd_event(char *bssname, char *event) -{ - char *name, *s; - uint32_t id; - void *v; - - if (!ctx || ubus_lookup_id(ctx, "service", &id)) - return; - - if (asprintf(&name, "hostapd.%s.%s", bssname, event) < 0) - return; - - blob_buf_init(&b, 0); - - s = blobmsg_alloc_string_buffer(&b, "type", strlen(name) + 1); - sprintf(s, "%s", name); - blobmsg_add_string_buffer(&b); - - v = blobmsg_open_table(&b, "data"); - blobmsg_close_table(&b, v); - - ubus_invoke(ctx, id, "event", b.head, NULL, NULL, 1000); - - free(name); -} - -static void hostapd_send_shared_event(struct ubus_object *obj, char *bssname, char *event) -{ - hostapd_send_procd_event(bssname, event); - hostapd_notify_ubus(obj, bssname, event); -} - static void hostapd_bss_del_ban(void *eloop_data, void *user_ctx) { @@ -203,10 +162,8 @@ hostapd_bss_reload(struct ubus_context *ctx, struct ubus_object *obj, struct blob_attr *msg) { struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); - int ret = hostapd_reload_config(hapd->iface, 1); - hostapd_send_shared_event(&hapd->iface->interfaces->ubus, hapd->conf->iface, "reload"); - return ret; + return hostapd_reload_config(hapd->iface); } @@ -693,68 +650,6 @@ enum { __CONFIG_MAX }; -static const struct blobmsg_policy config_add_policy[__CONFIG_MAX] = { - [CONFIG_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, - [CONFIG_FILE] = { "config", BLOBMSG_TYPE_STRING }, -}; - -static int -hostapd_config_add(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__CONFIG_MAX]; - struct hapd_interfaces *interfaces = get_hapd_interfaces_from_object(obj); - char buf[128]; - - blobmsg_parse(config_add_policy, __CONFIG_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[CONFIG_FILE] || !tb[CONFIG_IFACE]) - return UBUS_STATUS_INVALID_ARGUMENT; - - snprintf(buf, sizeof(buf), "bss_config=%s:%s", - blobmsg_get_string(tb[CONFIG_IFACE]), - blobmsg_get_string(tb[CONFIG_FILE])); - - if (hostapd_add_iface(interfaces, buf)) - return UBUS_STATUS_INVALID_ARGUMENT; - - blob_buf_init(&b, 0); - blobmsg_add_u32(&b, "pid", getpid()); - ubus_send_reply(ctx, req, b.head); - - return UBUS_STATUS_OK; -} - -enum { - CONFIG_REM_IFACE, - __CONFIG_REM_MAX -}; - -static const struct blobmsg_policy config_remove_policy[__CONFIG_REM_MAX] = { - [CONFIG_REM_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, -}; - -static int -hostapd_config_remove(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__CONFIG_REM_MAX]; - struct hapd_interfaces *interfaces = get_hapd_interfaces_from_object(obj); - char buf[128]; - - blobmsg_parse(config_remove_policy, __CONFIG_REM_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[CONFIG_REM_IFACE]) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (hostapd_remove_iface(interfaces, blobmsg_get_string(tb[CONFIG_REM_IFACE]))) - return UBUS_STATUS_INVALID_ARGUMENT; - - return UBUS_STATUS_OK; -} - enum { CSA_FREQ, CSA_BCN_COUNT, @@ -1622,8 +1517,6 @@ void hostapd_ubus_add_bss(struct hostapd_data *hapd) obj->n_methods = bss_object_type.n_methods; ret = ubus_add_object(ctx, obj); hostapd_ubus_ref_inc(); - - hostapd_send_shared_event(&hapd->iface->interfaces->ubus, hapd->conf->iface, "add"); } void hostapd_ubus_free_bss(struct hostapd_data *hapd) @@ -1639,8 +1532,6 @@ void hostapd_ubus_free_bss(struct hostapd_data *hapd) if (!ctx) return; - hostapd_send_shared_event(&hapd->iface->interfaces->ubus, hapd->conf->iface, "remove"); - if (obj->id) { ubus_remove_object(ctx, obj); hostapd_ubus_ref_dec(); @@ -1686,47 +1577,6 @@ void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vl hostapd_ubus_vlan_action(hapd, vlan, "vlan_remove"); } -static const struct ubus_method daemon_methods[] = { - UBUS_METHOD("config_add", hostapd_config_add, config_add_policy), - UBUS_METHOD("config_remove", hostapd_config_remove, config_remove_policy), -}; - -static struct ubus_object_type daemon_object_type = - UBUS_OBJECT_TYPE("hostapd", daemon_methods); - -void hostapd_ubus_add(struct hapd_interfaces *interfaces) -{ - struct ubus_object *obj = &interfaces->ubus; - int ret; - - if (!hostapd_ubus_init()) - return; - - obj->name = strdup("hostapd"); - - obj->type = &daemon_object_type; - obj->methods = daemon_object_type.methods; - obj->n_methods = daemon_object_type.n_methods; - ret = ubus_add_object(ctx, obj); - hostapd_ubus_ref_inc(); -} - -void hostapd_ubus_free(struct hapd_interfaces *interfaces) -{ - struct ubus_object *obj = &interfaces->ubus; - char *name = (char *) obj->name; - - if (!ctx) - return; - - if (obj->id) { - ubus_remove_object(ctx, obj); - hostapd_ubus_ref_dec(); - } - - free(name); -} - struct ubus_event_req { struct ubus_notify_request nreq; int resp; diff --git a/feeds/ipq807x_v5.4/hostapd/src/src/ap/ucode.c b/feeds/ipq807x_v5.4/hostapd/src/src/ap/ucode.c new file mode 100644 index 000000000..02413c70b --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/src/src/ap/ucode.c @@ -0,0 +1,544 @@ +#include + +#include "utils/includes.h" +#include "utils/common.h" +#include "utils/ucode.h" +#include "hostapd.h" +#include "beacon.h" +#include "hw_features.h" +#include "ap_drv_ops.h" +#include + +static uc_resource_type_t *global_type, *bss_type, *iface_type; +static struct hapd_interfaces *interfaces; +static uc_value_t *global, *bss_registry, *iface_registry; +static uc_vm_t *vm; + +static uc_value_t * +hostapd_ucode_bss_get_uval(struct hostapd_data *hapd) +{ + uc_value_t *val; + + if (hapd->ucode.idx) + return wpa_ucode_registry_get(bss_registry, hapd->ucode.idx); + + val = uc_resource_new(bss_type, hapd); + hapd->ucode.idx = wpa_ucode_registry_add(bss_registry, val); + + return val; +} + +static uc_value_t * +hostapd_ucode_iface_get_uval(struct hostapd_iface *hapd) +{ + uc_value_t *val; + + if (hapd->ucode.idx) + return wpa_ucode_registry_get(iface_registry, hapd->ucode.idx); + + val = uc_resource_new(iface_type, hapd); + hapd->ucode.idx = wpa_ucode_registry_add(iface_registry, val); + + return val; +} + +static void +hostapd_ucode_update_bss_list(struct hostapd_iface *iface, uc_value_t *if_bss, uc_value_t *bss) +{ + 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); + + ucv_array_set(list, i, ucv_get(ucv_string_new(hapd->conf->iface))); + ucv_object_add(bss, hapd->conf->iface, ucv_get(val)); + } + 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, 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); +} + +static uc_value_t * +uc_hostapd_add_iface(uc_vm_t *vm, size_t nargs) +{ + uc_value_t *iface = uc_fn_arg(0); + int ret; + + if (ucv_type(iface) != UC_STRING) + return ucv_int64_new(-1); + + ret = hostapd_add_iface(interfaces, ucv_string_get(iface)); + hostapd_ucode_update_interfaces(); + + return ucv_int64_new(ret); +} + +static uc_value_t * +uc_hostapd_remove_iface(uc_vm_t *vm, size_t nargs) +{ + uc_value_t *iface = uc_fn_arg(0); + + if (ucv_type(iface) != UC_STRING) + return NULL; + + hostapd_remove_iface(interfaces, ucv_string_get(iface)); + hostapd_ucode_update_interfaces(); + + return NULL; +} + +static uc_value_t * +uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs) +{ + struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss"); + struct hostapd_bss_config *old_bss; + struct hostapd_iface *iface; + struct hostapd_config *conf; + uc_value_t *file = uc_fn_arg(0); + uc_value_t *index = uc_fn_arg(1); + unsigned int i, idx = 0; + int ret = -1; + + if (!hapd || ucv_type(file) != UC_STRING) + goto out; + + if (ucv_type(index) == UC_INTEGER) + idx = ucv_int64_get(index); + + iface = hapd->iface; + conf = interfaces->config_read_cb(ucv_string_get(file)); + if (!conf || idx > conf->num_bss || !conf->bss[idx]) + goto out; + + hostapd_bss_deinit_no_free(hapd); + hostapd_drv_stop_ap(hapd); + hostapd_free_hapd_data(hapd); + + old_bss = hapd->conf; + for (i = 0; i < iface->conf->num_bss; i++) + if (iface->conf->bss[i] == hapd->conf) + iface->conf->bss[i] = conf->bss[idx]; + hapd->conf = conf->bss[idx]; + conf->bss[idx] = old_bss; + hostapd_config_free(conf); + + hostapd_setup_bss(hapd, hapd == iface->bss[0], !iface->conf->multiple_bssid); + + ret = 0; + +out: + return ucv_int64_new(ret); +} + +static void +hostapd_remove_iface_bss_conf(struct hostapd_config *iconf, + struct hostapd_bss_config *conf) +{ + int i; + + for (i = 0; i < iconf->num_bss; i++) + if (iconf->bss[i] == conf) + break; + + if (i == iconf->num_bss) + return; + + for (i++; i < iconf->num_bss; i++) + iconf->bss[i - 1] = iconf->bss[i]; + iconf->num_bss--; +} + + +static uc_value_t * +uc_hostapd_bss_delete(uc_vm_t *vm, size_t nargs) +{ + struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss"); + struct hostapd_iface *iface; + int i, idx; + + if (!hapd || hapd == hapd->iface->bss[0]) + return NULL; + + iface = hapd->iface; + for (idx = 0; idx < iface->num_bss; idx++) + if (iface->bss[idx] == hapd) + break; + + if (idx == iface->num_bss) + return NULL; + + for (i = idx + 1; i < iface->num_bss; i++) + iface->bss[i - 1] = iface->bss[i]; + iface->num_bss--; + + hostapd_drv_stop_ap(hapd); + hostapd_bss_deinit(hapd); + hostapd_remove_iface_bss_conf(iface->conf, hapd->conf); + hostapd_config_free_bss(hapd->conf); + os_free(hapd); + + hostapd_ucode_update_interfaces(); + ucv_gc(vm); + + return NULL; +} + +static uc_value_t * +uc_hostapd_iface_add_bss(uc_vm_t *vm, size_t nargs) +{ + struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); + struct hostapd_bss_config *bss; + struct hostapd_config *conf; + struct hostapd_data *hapd; + uc_value_t *file = uc_fn_arg(0); + uc_value_t *index = uc_fn_arg(1); + unsigned int idx = 0; + uc_value_t *ret = NULL; + + if (!iface || ucv_type(file) != UC_STRING) + goto out; + + if (ucv_type(index) == UC_INTEGER) + idx = ucv_int64_get(index); + + conf = interfaces->config_read_cb(ucv_string_get(file)); + if (!conf || idx > conf->num_bss || !conf->bss[idx]) + goto out; + + bss = conf->bss[idx]; + hapd = hostapd_alloc_bss_data(iface, iface->conf, bss); + if (!hapd) + goto out; + + hapd->driver = iface->bss[0]->driver; + hapd->drv_priv = iface->bss[0]->drv_priv; + if (interfaces->ctrl_iface_init && + interfaces->ctrl_iface_init(hapd) < 0) + goto free_hapd; + + if (iface->state == HAPD_IFACE_ENABLED && + hostapd_setup_bss(hapd, -1, true)) + goto deinit_ctrl; + + iface->bss = os_realloc_array(iface->bss, iface->num_bss + 1, + sizeof(*iface->bss)); + iface->bss[iface->num_bss++] = hapd; + + iface->conf->bss = os_realloc_array(iface->conf->bss, + iface->conf->num_bss + 1, + sizeof(*iface->conf->bss)); + iface->conf->bss[iface->conf->num_bss] = bss; + conf->bss[idx] = NULL; + ret = hostapd_ucode_bss_get_uval(hapd); + hostapd_ucode_update_interfaces(); + goto out; + +deinit_ctrl: + if (interfaces->ctrl_iface_deinit) + interfaces->ctrl_iface_deinit(hapd); +free_hapd: + hostapd_free_hapd_data(hapd); + os_free(hapd); +out: + hostapd_config_free(conf); + return ret; +} + +static uc_value_t * +uc_hostapd_bss_ctrl(uc_vm_t *vm, size_t nargs) +{ + struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss"); + uc_value_t *arg = uc_fn_arg(0); + struct sockaddr_storage from = {}; + static char reply[4096]; + int reply_len; + + if (!hapd || !interfaces->ctrl_iface_recv || + ucv_type(arg) != UC_STRING) + return NULL; + + reply_len = interfaces->ctrl_iface_recv(hapd, ucv_string_get(arg), + reply, sizeof(reply), + &from, sizeof(from)); + if (reply_len < 0) + return NULL; + + if (reply_len && reply[reply_len - 1] == '\n') + reply_len--; + + return ucv_string_new_length(reply, reply_len); +} + +static uc_value_t * +uc_hostapd_iface_stop(uc_vm_t *vm, size_t nargs) +{ + struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); + int i; + + for (i = 0; i < iface->num_bss; i++) { + struct hostapd_data *hapd = iface->bss[i]; + + hostapd_drv_stop_ap(hapd); + hapd->started = 0; + } +} + +static uc_value_t * +uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs) +{ + struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); + uc_value_t *info = uc_fn_arg(0); + struct hostapd_config *conf; + uint64_t intval; + int i; + + if (!iface) + return NULL; + + if (!info) + goto out; + + if (ucv_type(info) != UC_OBJECT) + return NULL; + + conf = iface->conf; + if ((intval = ucv_int64_get(ucv_object_get(info, "op_class", NULL))) && !errno) + conf->op_class = intval; + if ((intval = ucv_int64_get(ucv_object_get(info, "hw_mode", NULL))) && !errno) + conf->hw_mode = intval; + if ((intval = ucv_int64_get(ucv_object_get(info, "channel", NULL))) && !errno) + conf->channel = intval; + if ((intval = ucv_int64_get(ucv_object_get(info, "sec_channel", NULL))) && !errno) + conf->secondary_channel = intval; +#ifdef CONFIG_IEEE80211AC + if ((intval = ucv_int64_get(ucv_object_get(info, "center_seg0_idx", NULL))) && !errno) { + conf->vht_oper_centr_freq_seg0_idx = intval; +#ifdef CONFIG_IEEE80211AX + conf->he_oper_centr_freq_seg0_idx = intval; +#endif +#ifdef CONFIG_IEEE80211BE + conf->eht_oper_centr_freq_seg0_idx = intval; +#endif + } + if ((intval = ucv_int64_get(ucv_object_get(info, "center_seg1_idx", NULL))) && !errno) { + conf->vht_oper_centr_freq_seg1_idx = intval; +#ifdef CONFIG_IEEE80211AX + conf->he_oper_centr_freq_seg1_idx = intval; +#endif +#ifdef CONFIG_IEEE80211BE + conf->eht_oper_centr_freq_seg1_idx = intval; +#endif + } + intval = ucv_int64_get(ucv_object_get(info, "oper_chwidth", NULL)); + if (!errno) { + conf->vht_oper_chwidth = intval; +#ifdef CONFIG_IEEE80211AX + conf->he_oper_chwidth = intval; +#endif +#ifdef CONFIG_IEEE80211BE + conf->eht_oper_chwidth = intval; +#endif + } +#endif + +out: + if (conf->channel) + iface->freq = hostapd_hw_get_freq(iface->bss[0], conf->channel); + + for (i = 0; i < iface->num_bss; i++) { + struct hostapd_data *hapd = iface->bss[i]; + int ret; + + hapd->started = 1; + hostapd_set_freq(hapd, conf->hw_mode, iface->freq, + conf->channel, + conf->enable_edmg, + conf->edmg_channel, + conf->ieee80211n, + conf->ieee80211ac, + conf->ieee80211ax, + conf->secondary_channel, + hostapd_get_oper_chwidth(conf), + hostapd_get_oper_centr_freq_seg0_idx(conf), + hostapd_get_oper_centr_freq_seg1_idx(conf)); + + ieee802_11_set_beacon(hapd); + } + + return ucv_boolean_new(true); +} + +static uc_value_t * +uc_hostapd_iface_switch_channel(uc_vm_t *vm, size_t nargs) +{ + struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); + uc_value_t *info = uc_fn_arg(0); + struct hostapd_config *conf; + struct csa_settings csa = {}; + uint64_t intval; + int i, ret = 0; + + if (!iface || ucv_type(info) != UC_OBJECT) + return NULL; + + conf = iface->conf; + if ((intval = ucv_int64_get(ucv_object_get(info, "csa_count", NULL))) && !errno) + csa.cs_count = intval; + if ((intval = ucv_int64_get(ucv_object_get(info, "sec_channel", NULL))) && !errno) + csa.freq_params.sec_channel_offset = intval; + + csa.freq_params.ht_enabled = conf->ieee80211n; + csa.freq_params.vht_enabled = conf->ieee80211ac; + csa.freq_params.he_enabled = conf->ieee80211ax; +#ifdef CONFIG_IEEE80211BE + csa.freq_params.eht_enabled = conf->ieee80211be; +#endif + intval = ucv_int64_get(ucv_object_get(info, "oper_chwidth", NULL)); + if (errno) + intval = hostapd_get_oper_chwidth(conf); + if (intval) + csa.freq_params.bandwidth = 40 << intval; + else + csa.freq_params.bandwidth = csa.freq_params.sec_channel_offset ? 40 : 20; + + if ((intval = ucv_int64_get(ucv_object_get(info, "frequency", NULL))) && !errno) + csa.freq_params.freq = intval; + if ((intval = ucv_int64_get(ucv_object_get(info, "center_freq1", NULL))) && !errno) + csa.freq_params.center_freq1 = intval; + if ((intval = ucv_int64_get(ucv_object_get(info, "center_freq2", NULL))) && !errno) + csa.freq_params.center_freq2 = intval; + + for (i = 0; i < iface->num_bss; i++) + ret = hostapd_switch_channel(iface->bss[i], &csa); + + return ucv_boolean_new(!ret); +} + +int hostapd_ucode_init(struct hapd_interfaces *ifaces) +{ + static const uc_function_list_t global_fns[] = { + { "printf", uc_wpa_printf }, + { "getpid", uc_wpa_getpid }, + { "sha1", uc_wpa_sha1 }, + { "freq_info", uc_wpa_freq_info }, + { "add_iface", uc_hostapd_add_iface }, + { "remove_iface", uc_hostapd_remove_iface }, + }; + static const uc_function_list_t bss_fns[] = { + { "ctrl", uc_hostapd_bss_ctrl }, + { "set_config", uc_hostapd_bss_set_config }, + { "delete", uc_hostapd_bss_delete }, + }; + static const uc_function_list_t iface_fns[] = { + { "add_bss", uc_hostapd_iface_add_bss }, + { "stop", uc_hostapd_iface_stop }, + { "start", uc_hostapd_iface_start }, + { "switch_channel", uc_hostapd_iface_switch_channel }, + }; + uc_value_t *data, *proto; + + interfaces = ifaces; + vm = wpa_ucode_create_vm(); + + global_type = uc_type_declare(vm, "hostapd.global", global_fns, NULL); + bss_type = uc_type_declare(vm, "hostapd.bss", bss_fns, NULL); + iface_type = uc_type_declare(vm, "hostapd.iface", iface_fns, NULL); + + bss_registry = ucv_array_new(vm); + uc_vm_registry_set(vm, "hostap.bss_registry", bss_registry); + + iface_registry = ucv_array_new(vm); + uc_vm_registry_set(vm, "hostap.iface_registry", iface_registry); + + global = wpa_ucode_global_init("hostapd", global_type); + + if (wpa_ucode_run(HOSTAPD_UC_PATH "hostapd.uc")) + goto free_vm; + ucv_gc(vm); + + return 0; + +free_vm: + wpa_ucode_free_vm(); + return -1; +} + +void hostapd_ucode_free(void) +{ + if (wpa_ucode_call_prepare("shutdown") == 0) + ucv_put(wpa_ucode_call(0)); + wpa_ucode_free_vm(); +} + +void hostapd_ucode_free_iface(struct hostapd_iface *iface) +{ + wpa_ucode_registry_remove(iface_registry, iface->ucode.idx); +} + +void hostapd_ucode_add_bss(struct hostapd_data *hapd) +{ + uc_value_t *val; + + if (wpa_ucode_call_prepare("bss_add")) + return; + + val = hostapd_ucode_bss_get_uval(hapd); + uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface))); + uc_value_push(ucv_get(val)); + ucv_put(wpa_ucode_call(2)); + ucv_gc(vm); +} + +void hostapd_ucode_reload_bss(struct hostapd_data *hapd) +{ + uc_value_t *val; + + if (wpa_ucode_call_prepare("bss_reload")) + return; + + val = hostapd_ucode_bss_get_uval(hapd); + uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface))); + uc_value_push(ucv_get(val)); + ucv_put(wpa_ucode_call(2)); + ucv_gc(vm); +} + +void hostapd_ucode_free_bss(struct hostapd_data *hapd) +{ + uc_value_t *val; + + val = wpa_ucode_registry_remove(bss_registry, hapd->ucode.idx); + if (!val) + return; + + hapd->ucode.idx = 0; + if (wpa_ucode_call_prepare("bss_remove")) + return; + + uc_value_push(ucv_string_new(hapd->conf->iface)); + uc_value_push(ucv_get(val)); + ucv_put(wpa_ucode_call(2)); + ucv_gc(vm); +} diff --git a/feeds/ipq807x_v5.4/hostapd/src/src/ap/ucode.h b/feeds/ipq807x_v5.4/hostapd/src/src/ap/ucode.h new file mode 100644 index 000000000..d00b78716 --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/src/src/ap/ucode.h @@ -0,0 +1,54 @@ +#ifndef __HOSTAPD_AP_UCODE_H +#define __HOSTAPD_AP_UCODE_H + +#include "utils/ucode.h" + +struct hostapd_data; + +struct hostapd_ucode_bss { +#ifdef UCODE_SUPPORT + int idx; +#endif +}; + +struct hostapd_ucode_iface { +#ifdef UCODE_SUPPORT + int idx; +#endif +}; + +#ifdef UCODE_SUPPORT + +int hostapd_ucode_init(struct hapd_interfaces *ifaces); + +void hostapd_ucode_free(void); +void hostapd_ucode_free_iface(struct hostapd_iface *iface); +void hostapd_ucode_add_bss(struct hostapd_data *hapd); +void hostapd_ucode_free_bss(struct hostapd_data *hapd); +void hostapd_ucode_reload_bss(struct hostapd_data *hapd); + +#else + +static inline int hostapd_ucode_init(struct hapd_interfaces *ifaces) +{ + return -EINVAL; +} +static inline void hostapd_ucode_free(void) +{ +} +static inline void hostapd_ucode_free_iface(struct hostapd_iface *iface) +{ +} +static inline void hostapd_ucode_reload_bss(struct hostapd_data *hapd) +{ +} +static inline void hostapd_ucode_add_bss(struct hostapd_data *hapd) +{ +} +static inline void hostapd_ucode_free_bss(struct hostapd_data *hapd) +{ +} + +#endif + +#endif diff --git a/feeds/ipq807x_v5.4/hostapd/src/src/utils/build_features.h b/feeds/ipq807x_v5.4/hostapd/src/src/utils/build_features.h index 3ab5246c7..553769ece 100644 --- a/feeds/ipq807x_v5.4/hostapd/src/src/utils/build_features.h +++ b/feeds/ipq807x_v5.4/hostapd/src/src/utils/build_features.h @@ -7,10 +7,6 @@ static inline int has_feature(const char *feat) if (!strcmp(feat, "eap")) return 1; #endif -#ifdef CONFIG_IEEE80211N - if (!strcmp(feat, "11n")) - return 1; -#endif #ifdef CONFIG_IEEE80211AC if (!strcmp(feat, "11ac")) return 1; @@ -50,6 +46,18 @@ static inline int has_feature(const char *feat) #ifdef CONFIG_WPS if (!strcmp(feat, "wps")) return 1; +#endif +#ifdef CONFIG_FILS + if (!strcmp(feat, "fils")) + return 1; +#endif +#ifdef CONFIG_OCV + if (!strcmp(feat, "ocv")) + return 1; +#endif +#ifdef CONFIG_MESH + if (!strcmp(feat, "mesh")) + return 1; #endif return 0; } diff --git a/feeds/ipq807x_v5.4/hostapd/src/src/utils/ucode.c b/feeds/ipq807x_v5.4/hostapd/src/src/utils/ucode.c new file mode 100644 index 000000000..b106d856f --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/src/src/utils/ucode.c @@ -0,0 +1,326 @@ +#include +#include "ucode.h" +#include "utils/eloop.h" +#include "crypto/crypto.h" +#include "crypto/sha1.h" +#include "common/ieee802_11_common.h" +#include +#include + +static uc_value_t *registry; +static uc_vm_t vm; +static struct uloop_timeout gc_timer; + +static void uc_gc_timer(struct uloop_timeout *timeout) +{ + ucv_gc(&vm); +} + +uc_value_t *uc_wpa_printf(uc_vm_t *vm, size_t nargs) +{ + uc_value_t *level = uc_fn_arg(0); + uc_value_t *ret, **args; + uc_cfn_ptr_t _sprintf; + int l = MSG_INFO; + int i, start = 0; + + _sprintf = uc_stdlib_function("sprintf"); + if (!sprintf) + return NULL; + + if (ucv_type(level) == UC_INTEGER) { + l = ucv_int64_get(level); + start++; + } + + if (nargs <= start) + return NULL; + + ret = _sprintf(vm, nargs - start); + if (ucv_type(ret) != UC_STRING) + return NULL; + + wpa_printf(l, "%s", ucv_string_get(ret)); + ucv_put(ret); + + return NULL; +} + +uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs) +{ + uc_value_t *freq = uc_fn_arg(0); + uc_value_t *sec = uc_fn_arg(1); + int width = ucv_uint64_get(uc_fn_arg(2)); + int freq_val, center_idx, center_ofs; + enum hostapd_hw_mode hw_mode; + u8 op_class, channel, tmp_channel; + const char *modestr; + int sec_channel = 0; + uc_value_t *ret; + int chanwidth; + + if (ucv_type(freq) != UC_INTEGER) + return NULL; + + freq_val = ucv_int64_get(freq); + if (ucv_type(sec) == UC_INTEGER) + sec_channel = ucv_int64_get(sec); + else if (sec) + return NULL; + else if (freq_val > 4000) + sec_channel = (freq_val / 20) & 1 ? 1 : -1; + else + sec_channel = freq_val < 2442 ? 1 : -1; + + if (sec_channel != -1 && sec_channel != 1 && sec_channel != 0) + return NULL; + + switch (width) { + case 0: + chanwidth = CHANWIDTH_USE_HT; + break; + case 1: + chanwidth = CHANWIDTH_80MHZ; + break; + case 2: + chanwidth = CHANWIDTH_160MHZ; + break; + default: + return NULL; + } + + hw_mode = ieee80211_freq_to_channel_ext(freq_val, sec_channel, + chanwidth, &op_class, &channel); + switch (hw_mode) { + case HOSTAPD_MODE_IEEE80211B: + modestr = "b"; + break; + case HOSTAPD_MODE_IEEE80211G: + modestr = "g"; + break; + case HOSTAPD_MODE_IEEE80211A: + modestr = "a"; + break; + case HOSTAPD_MODE_IEEE80211AD: + modestr = "ad"; + break; + default: + return NULL; + } + + ret = ucv_object_new(vm); + ucv_object_add(ret, "op_class", ucv_int64_new(op_class)); + ucv_object_add(ret, "channel", ucv_int64_new(channel)); + ucv_object_add(ret, "hw_mode", ucv_int64_new(hw_mode)); + ucv_object_add(ret, "hw_mode_str", ucv_get(ucv_string_new(modestr))); + ucv_object_add(ret, "sec_channel", ucv_int64_new(sec_channel)); + ucv_object_add(ret, "frequency", ucv_int64_new(freq_val)); + + if (!sec_channel) + return ret; + + if (freq_val >= 5900) + center_ofs = 0; + else if (freq_val >= 5745) + center_ofs = 20; + else + center_ofs = 35; + tmp_channel = channel - center_ofs; + tmp_channel &= ~((8 << width) - 1); + center_idx = tmp_channel + center_ofs + (4 << width) - 1; + + ucv_object_add(ret, "center_seg0_idx", ucv_int64_new(center_idx)); + center_idx = (center_idx - channel) * 5 + freq_val; + ucv_object_add(ret, "center_freq1", ucv_int64_new(center_idx)); + +out: + return ret; +} + +uc_value_t *uc_wpa_getpid(uc_vm_t *vm, size_t nargs) +{ + return ucv_int64_new(getpid()); +} + +uc_value_t *uc_wpa_sha1(uc_vm_t *vm, size_t nargs) +{ + u8 hash[SHA1_MAC_LEN]; + char hash_hex[2 * ARRAY_SIZE(hash) + 1]; + uc_value_t *val; + size_t *lens; + const u8 **args; + int i; + + if (!nargs) + return NULL; + + args = alloca(nargs * sizeof(*args)); + lens = alloca(nargs * sizeof(*lens)); + for (i = 0; i < nargs; i++) { + val = uc_fn_arg(i); + if (ucv_type(val) != UC_STRING) + return NULL; + + args[i] = ucv_string_get(val); + lens[i] = ucv_string_length(val); + } + + if (sha1_vector(nargs, args, lens, hash)) + return NULL; + + for (i = 0; i < ARRAY_SIZE(hash); i++) + sprintf(hash_hex + 2 * i, "%02x", hash[i]); + + return ucv_string_new_length(hash_hex, 2 * ARRAY_SIZE(hash)); +} + +uc_vm_t *wpa_ucode_create_vm(void) +{ + static uc_parse_config_t config = { + .strict_declarations = true, + .lstrip_blocks = true, + .trim_blocks = true, + .raw_mode = true + }; + + uc_search_path_init(&config.module_search_path); + uc_search_path_add(&config.module_search_path, HOSTAPD_UC_PATH "*.so"); + uc_search_path_add(&config.module_search_path, HOSTAPD_UC_PATH "*.uc"); + + uc_vm_init(&vm, &config); + + uc_stdlib_load(uc_vm_scope_get(&vm)); + eloop_add_uloop(); + gc_timer.cb = uc_gc_timer; + + return &vm; +} + +int wpa_ucode_run(const char *script) +{ + uc_source_t *source; + uc_program_t *prog; + uc_value_t *ops; + char *err; + int ret; + + source = uc_source_new_file(script); + if (!source) + return -1; + + prog = uc_compile(vm.config, source, &err); + uc_source_put(source); + if (!prog) { + wpa_printf(MSG_ERROR, "Error loading ucode: %s\n", err); + return -1; + } + + ret = uc_vm_execute(&vm, prog, &ops); + uc_program_put(prog); + if (ret || !ops) + return -1; + + registry = ucv_array_new(&vm); + uc_vm_registry_set(&vm, "hostap.registry", registry); + ucv_array_set(registry, 0, ucv_get(ops)); + + return 0; +} + +int wpa_ucode_call_prepare(const char *fname) +{ + uc_value_t *obj, *func; + + if (!registry) + return -1; + + obj = ucv_array_get(registry, 0); + if (!obj) + return -1; + + func = ucv_object_get(obj, fname, NULL); + if (!ucv_is_callable(func)) + return -1; + + uc_vm_stack_push(&vm, ucv_get(obj)); + uc_vm_stack_push(&vm, ucv_get(func)); + + return 0; +} + +uc_value_t *wpa_ucode_global_init(const char *name, uc_resource_type_t *global_type) +{ + uc_value_t *global = uc_resource_new(global_type, NULL); + uc_value_t *proto; + + uc_vm_registry_set(&vm, "hostap.global", global); + proto = ucv_prototype_get(global); + ucv_object_add(proto, "data", ucv_get(ucv_object_new(&vm))); + +#define ADD_CONST(x) ucv_object_add(proto, #x, ucv_int64_new(x)) + ADD_CONST(MSG_EXCESSIVE); + ADD_CONST(MSG_MSGDUMP); + ADD_CONST(MSG_DEBUG); + ADD_CONST(MSG_INFO); + ADD_CONST(MSG_WARNING); + ADD_CONST(MSG_ERROR); +#undef ADD_CONST + + ucv_object_add(uc_vm_scope_get(&vm), name, ucv_get(global)); + + return global; +} + +int wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val) +{ + uc_value_t *data; + int i = 0; + + while (ucv_array_get(reg, i)) + i++; + + ucv_array_set(reg, i, ucv_get(val)); + + return i + 1; +} + +uc_value_t *wpa_ucode_registry_get(uc_value_t *reg, int idx) +{ + if (!idx) + return NULL; + + return ucv_array_get(reg, idx - 1); +} + +uc_value_t *wpa_ucode_registry_remove(uc_value_t *reg, int idx) +{ + uc_value_t *val = wpa_ucode_registry_get(reg, idx); + + if (val) + ucv_array_set(reg, idx - 1, NULL); + + return val; +} + + +uc_value_t *wpa_ucode_call(size_t nargs) +{ + if (uc_vm_call(&vm, true, nargs) != EXCEPTION_NONE) + return NULL; + + if (!gc_timer.pending) + uloop_timeout_set(&gc_timer, 10); + + return uc_vm_stack_pop(&vm); +} + +void wpa_ucode_free_vm(void) +{ + if (!vm.config) + return; + + uc_search_path_free(&vm.config->module_search_path); + uc_vm_free(&vm); + registry = NULL; + vm = (uc_vm_t){}; +} diff --git a/feeds/ipq807x_v5.4/hostapd/src/src/utils/ucode.h b/feeds/ipq807x_v5.4/hostapd/src/src/utils/ucode.h new file mode 100644 index 000000000..2c1886976 --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/src/src/utils/ucode.h @@ -0,0 +1,29 @@ +#ifndef __HOSTAPD_UTILS_UCODE_H +#define __HOSTAPD_UTILS_UCODE_H + +#include "utils/includes.h" +#include "utils/common.h" +#include +#include + +#define HOSTAPD_UC_PATH "/usr/share/hostap/" + +extern uc_value_t *uc_registry; +uc_vm_t *wpa_ucode_create_vm(void); +int wpa_ucode_run(const char *script); +int wpa_ucode_call_prepare(const char *fname); +uc_value_t *wpa_ucode_call(size_t nargs); +void wpa_ucode_free_vm(void); + +uc_value_t *wpa_ucode_global_init(const char *name, uc_resource_type_t *global_type); + +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); + +uc_value_t *uc_wpa_printf(uc_vm_t *vm, size_t nargs); +uc_value_t *uc_wpa_getpid(uc_vm_t *vm, size_t nargs); +uc_value_t *uc_wpa_sha1(uc_vm_t *vm, size_t nargs); +uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs); + +#endif diff --git a/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ubus.c b/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ubus.c index 16a68c507..1c477f0c0 100644 --- a/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ubus.c +++ b/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ubus.c @@ -30,12 +30,6 @@ static inline struct wpa_supplicant *get_wpas_from_object(struct ubus_object *ob return container_of(obj, struct wpa_supplicant, ubus.obj); } -static void ubus_receive(int sock, void *eloop_ctx, void *sock_ctx) -{ - struct ubus_context *ctx = eloop_ctx; - ubus_handle_event(ctx); -} - static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) { if (ubus_reconnect(ctx, NULL)) { @@ -43,12 +37,12 @@ static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) return; } - eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); + ubus_add_uloop(ctx); } static void wpas_ubus_connection_lost(struct ubus_context *ctx) { - eloop_unregister_read_sock(ctx->sock.fd); + uloop_fd_delete(&ctx->sock); eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); } @@ -57,12 +51,14 @@ static bool wpas_ubus_init(void) if (ctx) return true; + eloop_add_uloop(); ctx = ubus_connect(NULL); if (!ctx) return false; ctx->connection_lost = wpas_ubus_connection_lost; - eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); + ubus_add_uloop(ctx); + return true; } @@ -80,7 +76,7 @@ static void wpas_ubus_ref_dec(void) if (ctx_ref) return; - eloop_unregister_read_sock(ctx->sock.fd); + uloop_fd_delete(&ctx->sock); ubus_free(ctx); ctx = NULL; } @@ -211,152 +207,6 @@ void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s) free(name); } -enum { - WPAS_CONFIG_DRIVER, - WPAS_CONFIG_IFACE, - WPAS_CONFIG_BRIDGE, - WPAS_CONFIG_HOSTAPD_CTRL, - WPAS_CONFIG_CTRL, - WPAS_CONFIG_FILE, - __WPAS_CONFIG_MAX -}; - -static const struct blobmsg_policy wpas_config_add_policy[__WPAS_CONFIG_MAX] = { - [WPAS_CONFIG_DRIVER] = { "driver", BLOBMSG_TYPE_STRING }, - [WPAS_CONFIG_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, - [WPAS_CONFIG_BRIDGE] = { "bridge", BLOBMSG_TYPE_STRING }, - [WPAS_CONFIG_HOSTAPD_CTRL] = { "hostapd_ctrl", BLOBMSG_TYPE_STRING }, - [WPAS_CONFIG_CTRL] = { "ctrl", BLOBMSG_TYPE_STRING }, - [WPAS_CONFIG_FILE] = { "config", BLOBMSG_TYPE_STRING }, -}; - -static int -wpas_config_add(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__WPAS_CONFIG_MAX]; - struct wpa_global *global = get_wpa_global_from_object(obj); - struct wpa_interface *iface; - - blobmsg_parse(wpas_config_add_policy, __WPAS_CONFIG_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[WPAS_CONFIG_FILE] || !tb[WPAS_CONFIG_IFACE] || !tb[WPAS_CONFIG_DRIVER]) - return UBUS_STATUS_INVALID_ARGUMENT; - - iface = os_zalloc(sizeof(struct wpa_interface)); - if (iface == NULL) - return UBUS_STATUS_UNKNOWN_ERROR; - - iface->driver = blobmsg_get_string(tb[WPAS_CONFIG_DRIVER]); - iface->ifname = blobmsg_get_string(tb[WPAS_CONFIG_IFACE]); - iface->confname = blobmsg_get_string(tb[WPAS_CONFIG_FILE]); - - if (tb[WPAS_CONFIG_BRIDGE]) - iface->bridge_ifname = blobmsg_get_string(tb[WPAS_CONFIG_BRIDGE]); - - if (tb[WPAS_CONFIG_CTRL]) - iface->ctrl_interface = blobmsg_get_string(tb[WPAS_CONFIG_CTRL]); - - if (tb[WPAS_CONFIG_HOSTAPD_CTRL]) - iface->hostapd_ctrl = blobmsg_get_string(tb[WPAS_CONFIG_HOSTAPD_CTRL]); - - if (!wpa_supplicant_add_iface(global, iface, NULL)) - return UBUS_STATUS_INVALID_ARGUMENT; - - blob_buf_init(&b, 0); - blobmsg_add_u32(&b, "pid", getpid()); - ubus_send_reply(ctx, req, b.head); - - return UBUS_STATUS_OK; -} - -enum { - WPAS_CONFIG_REM_IFACE, - __WPAS_CONFIG_REM_MAX -}; - -static const struct blobmsg_policy wpas_config_remove_policy[__WPAS_CONFIG_REM_MAX] = { - [WPAS_CONFIG_REM_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, -}; - -static int -wpas_config_remove(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__WPAS_CONFIG_REM_MAX]; - struct wpa_global *global = get_wpa_global_from_object(obj); - struct wpa_supplicant *wpa_s = NULL; - unsigned int found = 0; - - blobmsg_parse(wpas_config_remove_policy, __WPAS_CONFIG_REM_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[WPAS_CONFIG_REM_IFACE]) - return UBUS_STATUS_INVALID_ARGUMENT; - - /* find wpa_s object for to-be-removed interface */ - for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { - if (!strncmp(wpa_s->ifname, - blobmsg_get_string(tb[WPAS_CONFIG_REM_IFACE]), - sizeof(wpa_s->ifname))) - { - found = 1; - break; - } - } - - if (!found) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (wpa_supplicant_remove_iface(global, wpa_s, 0)) - return UBUS_STATUS_INVALID_ARGUMENT; - - return UBUS_STATUS_OK; -} - -static const struct ubus_method wpas_daemon_methods[] = { - UBUS_METHOD("config_add", wpas_config_add, wpas_config_add_policy), - UBUS_METHOD("config_remove", wpas_config_remove, wpas_config_remove_policy), -}; - -static struct ubus_object_type wpas_daemon_object_type = - UBUS_OBJECT_TYPE("wpa_supplicant", wpas_daemon_methods); - -void wpas_ubus_add(struct wpa_global *global) -{ - struct ubus_object *obj = &global->ubus_global; - int ret; - - if (!wpas_ubus_init()) - return; - - obj->name = strdup("wpa_supplicant"); - - obj->type = &wpas_daemon_object_type; - obj->methods = wpas_daemon_object_type.methods; - obj->n_methods = wpas_daemon_object_type.n_methods; - ret = ubus_add_object(ctx, obj); - wpas_ubus_ref_inc(); -} - -void wpas_ubus_free(struct wpa_global *global) -{ - struct ubus_object *obj = &global->ubus_global; - char *name = (char *) obj->name; - - if (!ctx) - return; - - if (obj->id) { - ubus_remove_object(ctx, obj); - wpas_ubus_ref_dec(); - } - - free(name); -} - - #ifdef CONFIG_WPS void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred) { diff --git a/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ubus.h b/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ubus.h index bf92b98c0..f6681cb26 100644 --- a/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ubus.h +++ b/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ubus.h @@ -24,9 +24,6 @@ struct wpas_ubus_bss { void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s); void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s); -void wpas_ubus_add(struct wpa_global *global); -void wpas_ubus_free(struct wpa_global *global); - #ifdef CONFIG_WPS void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred); #endif @@ -34,14 +31,6 @@ void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential #else struct wpas_ubus_bss {}; -static inline void wpas_ubus_add_iface(struct wpa_supplicant *wpa_s) -{ -} - -static inline void wpas_ubus_free_iface(struct wpa_supplicant *wpa_s) -{ -} - static inline void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s) { } diff --git a/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ucode.c b/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ucode.c new file mode 100644 index 000000000..d0a78d162 --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ucode.c @@ -0,0 +1,270 @@ +#include "utils/includes.h" +#include "utils/common.h" +#include "utils/ucode.h" +#include "drivers/driver.h" +#include "wpa_supplicant_i.h" +#include "wps_supplicant.h" +#include "bss.h" +#include "ucode.h" + +static struct wpa_global *wpa_global; +static uc_resource_type_t *global_type, *iface_type; +static uc_value_t *global, *iface_registry; +static uc_vm_t *vm; + +static uc_value_t * +wpas_ucode_iface_get_uval(struct wpa_supplicant *wpa_s) +{ + uc_value_t *val; + + if (wpa_s->ucode.idx) + return wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx); + + val = uc_resource_new(iface_type, wpa_s); + wpa_s->ucode.idx = wpa_ucode_registry_add(iface_registry, val); + + return val; +} + +static void +wpas_ucode_update_interfaces(void) +{ + uc_value_t *ifs = ucv_object_new(vm); + struct wpa_supplicant *wpa_s; + int i; + + for (wpa_s = wpa_global->ifaces; wpa_s; wpa_s = wpa_s->next) + ucv_object_add(ifs, wpa_s->ifname, ucv_get(wpas_ucode_iface_get_uval(wpa_s))); + + ucv_object_add(ucv_prototype_get(global), "interfaces", ucv_get(ifs)); + ucv_gc(vm); +} + +void wpas_ucode_add_bss(struct wpa_supplicant *wpa_s) +{ + uc_value_t *val; + + if (wpa_ucode_call_prepare("iface_add")) + return; + + uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname))); + uc_value_push(ucv_get(wpas_ucode_iface_get_uval(wpa_s))); + ucv_put(wpa_ucode_call(2)); + ucv_gc(vm); +} + +void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s) +{ + uc_value_t *val; + + val = wpa_ucode_registry_remove(iface_registry, wpa_s->ucode.idx); + if (!val) + return; + + wpa_s->ucode.idx = 0; + if (wpa_ucode_call_prepare("iface_remove")) + return; + + uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname))); + uc_value_push(ucv_get(val)); + ucv_put(wpa_ucode_call(2)); + ucv_gc(vm); +} + +void wpas_ucode_update_state(struct wpa_supplicant *wpa_s) +{ + const char *state; + uc_value_t *val; + + val = wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx); + if (!val) + return; + + if (wpa_ucode_call_prepare("state")) + 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(3)); + ucv_gc(vm); +} + +void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_data *data) +{ + const char *state; + uc_value_t *val; + + if (event != EVENT_CH_SWITCH_STARTED) + return; + + val = wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx); + if (!val) + return; + + 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); + uc_value_push(ucv_get(val)); + + if (event == EVENT_CH_SWITCH_STARTED) { + ucv_object_add(val, "csa_count", ucv_int64_new(data->ch_switch.count)); + ucv_object_add(val, "frequency", ucv_int64_new(data->ch_switch.freq)); + ucv_object_add(val, "sec_chan_offset", ucv_int64_new(data->ch_switch.ch_offset)); + ucv_object_add(val, "center_freq1", ucv_int64_new(data->ch_switch.cf1)); + ucv_object_add(val, "center_freq2", ucv_int64_new(data->ch_switch.cf2)); + } + + ucv_put(wpa_ucode_call(4)); + ucv_gc(vm); +} + +static const char *obj_stringval(uc_value_t *obj, const char *name) +{ + uc_value_t *val = ucv_object_get(obj, name, NULL); + + return ucv_string_get(val); +} + +static uc_value_t * +uc_wpas_add_iface(uc_vm_t *vm, size_t nargs) +{ + uc_value_t *info = uc_fn_arg(0); + uc_value_t *ifname = ucv_object_get(info, "iface", NULL); + uc_value_t *bridge = ucv_object_get(info, "bridge", NULL); + uc_value_t *config = ucv_object_get(info, "config", NULL); + uc_value_t *ctrl = ucv_object_get(info, "ctrl", NULL); + struct wpa_interface iface; + int ret = -1; + + if (ucv_type(info) != UC_OBJECT) + goto out; + + iface = (struct wpa_interface){ + .driver = "nl80211", + .ifname = ucv_string_get(ifname), + .bridge_ifname = ucv_string_get(bridge), + .confname = ucv_string_get(config), + .ctrl_interface = ucv_string_get(ctrl), + }; + + if (!iface.ifname || !iface.confname) + goto out; + + ret = wpa_supplicant_add_iface(wpa_global, &iface, 0) ? 0 : -1; + wpas_ucode_update_interfaces(); + +out: + return ucv_int64_new(ret); +} + +static uc_value_t * +uc_wpas_remove_iface(uc_vm_t *vm, size_t nargs) +{ + struct wpa_supplicant *wpa_s = NULL; + uc_value_t *ifname_arg = uc_fn_arg(0); + const char *ifname = ucv_string_get(ifname_arg); + int ret = -1; + + if (!ifname) + goto out; + + for (wpa_s = wpa_global->ifaces; wpa_s; wpa_s = wpa_s->next) + if (!strcmp(wpa_s->ifname, ifname)) + break; + + if (!wpa_s) + goto out; + + ret = wpa_supplicant_remove_iface(wpa_global, wpa_s, 0); + wpas_ucode_update_interfaces(); + +out: + return ucv_int64_new(ret); +} + +static uc_value_t * +uc_wpas_iface_status(uc_vm_t *vm, size_t nargs) +{ + struct wpa_supplicant *wpa_s = uc_fn_thisval("wpas.iface"); + struct wpa_bss *bss; + uc_value_t *ret, *val; + + if (!wpa_s) + return NULL; + + ret = ucv_object_new(vm); + + val = ucv_string_new(wpa_supplicant_state_txt(wpa_s->wpa_state)); + ucv_object_add(ret, "state", ucv_get(val)); + + bss = wpa_s->current_bss; + if (bss) { + int sec_chan = 0; + const u8 *ie; + + ie = wpa_bss_get_ie(bss, WLAN_EID_HT_OPERATION); + if (ie && ie[1] >= 2) { + const struct ieee80211_ht_operation *ht_oper; + + ht_oper = (const void *) (ie + 2); + if (ht_oper->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE) + sec_chan = 1; + else if (ht_oper->ht_param & + HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW) + sec_chan = -1; + } + + ucv_object_add(ret, "sec_chan_offset", ucv_int64_new(sec_chan)); + ucv_object_add(ret, "frequency", ucv_int64_new(bss->freq)); + } + + return ret; +} + +int wpas_ucode_init(struct wpa_global *gl) +{ + static const uc_function_list_t global_fns[] = { + { "printf", uc_wpa_printf }, + { "getpid", uc_wpa_getpid }, + { "add_iface", uc_wpas_add_iface }, + { "remove_iface", uc_wpas_remove_iface }, + }; + static const uc_function_list_t iface_fns[] = { + { "status", uc_wpas_iface_status }, + }; + uc_value_t *data, *proto; + + wpa_global = gl; + vm = wpa_ucode_create_vm(); + + global_type = uc_type_declare(vm, "wpas.global", global_fns, NULL); + iface_type = uc_type_declare(vm, "wpas.iface", iface_fns, NULL); + + iface_registry = ucv_array_new(vm); + uc_vm_registry_set(vm, "wpas.iface_registry", iface_registry); + + global = wpa_ucode_global_init("wpas", global_type); + + if (wpa_ucode_run(HOSTAPD_UC_PATH "wpa_supplicant.uc")) + goto free_vm; + + ucv_gc(vm); + return 0; + +free_vm: + wpa_ucode_free_vm(); + return -1; +} + +void wpas_ucode_free(void) +{ + if (wpa_ucode_call_prepare("shutdown") == 0) + ucv_put(wpa_ucode_call(0)); + wpa_ucode_free_vm(); +} diff --git a/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ucode.h b/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ucode.h new file mode 100644 index 000000000..a429a0ed8 --- /dev/null +++ b/feeds/ipq807x_v5.4/hostapd/src/wpa_supplicant/ucode.h @@ -0,0 +1,49 @@ +#ifndef __WPAS_UCODE_H +#define __WPAS_UCODE_H + +#include "utils/ucode.h" + +struct wpa_global; +union wpa_event_data; +struct wpa_supplicant; + +struct wpas_ucode_bss { +#ifdef UCODE_SUPPORT + unsigned int idx; +#endif +}; + +#ifdef UCODE_SUPPORT +int wpas_ucode_init(struct wpa_global *gl); +void wpas_ucode_free(void); +void wpas_ucode_add_bss(struct wpa_supplicant *wpa_s); +void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s); +void wpas_ucode_update_state(struct wpa_supplicant *wpa_s); +void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_data *data); +#else +static inline int wpas_ucode_init(struct wpa_global *gl) +{ + return -EINVAL; +} +static inline void wpas_ucode_free(void) +{ +} +static inline void wpas_ucode_add_bss(struct wpa_supplicant *wpa_s) +{ +} + +static inline void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s) +{ +} + +static inline void wpas_ucode_update_state(struct wpa_supplicant *wpa_s) +{ +} + +static inline void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_data *data) +{ +} + +#endif + +#endif diff --git a/feeds/ipq807x_v5.4/mac80211/files/lib/netifd/wireless/mac80211.sh b/feeds/ipq807x_v5.4/mac80211/files/lib/netifd/wireless/mac80211.sh index 0ef9607ab..dcf41441e 100644 --- a/feeds/ipq807x_v5.4/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/feeds/ipq807x_v5.4/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -1,6 +1,7 @@ #!/bin/sh . /lib/netifd/netifd-wireless.sh . /lib/netifd/hostapd.sh +. /lib/functions/system.sh init_wireless_driver "$@" @@ -14,12 +15,9 @@ MP_CONFIG_INT="mesh_retry_timeout mesh_confirm_timeout mesh_holding_timeout mesh MP_CONFIG_BOOL="mesh_auto_open_plinks mesh_fwding" MP_CONFIG_STRING="mesh_power_mode" -NEWAPLIST= -OLDAPLIST= -NEWSPLIST= -OLDSPLIST= -NEWUMLIST= -OLDUMLIST= +wdev_tool() { + ucode /usr/share/hostap/wdev.uc "$@" +} drv_mac80211_init_device_config() { hostapd_common_add_device_config @@ -28,9 +26,9 @@ drv_mac80211_init_device_config() { config_add_string tx_burst config_add_string distance config_add_int beacon_int chanbw frag rts - config_add_int rxantenna txantenna antenna_gain txpower + config_add_int rxantenna txantenna antenna_gain txpower min_tx_power config_add_int num_global_macaddr - config_add_boolean noscan ht_coex acs_exclude_dfs + config_add_boolean noscan ht_coex acs_exclude_dfs background_radar config_add_array ht_capab config_add_array channels config_add_array scan_list @@ -140,13 +138,15 @@ mac80211_hostapd_setup_base() { [ -n "$acs_exclude_dfs" ] && [ "$acs_exclude_dfs" -gt 0 ] && append base_cfg "acs_exclude_dfs=1" "$N" - json_get_vars noscan ht_coex - json_get_values ht_capab_list ht_capab tx_burst + json_get_vars noscan ht_coex min_tx_power:0 tx_burst + json_get_values ht_capab_list ht_capab json_get_values channel_list channels [ "$auto_channel" = 0 ] && [ -z "$channel_list" ] && \ channel_list="$channel" + [ "$min_tx_power" -gt 0 ] && append base_cfg "min_tx_power=$min_tx_power" + set_default noscan 0 [ "$noscan" -gt 0 ] && hostapd_noscan=1 @@ -276,6 +276,11 @@ mac80211_hostapd_setup_base() { vht_center_seg0=$idx ;; esac + [ "$band" = "5g" ] && { + json_get_vars background_radar:0 + + [ "$background_radar" -eq 1 ] && append base_cfg "enable_background_radar=1" "$N" + } [ "$band" = "6g" ] && { op_class= case "$htmode" in @@ -409,20 +414,21 @@ mac80211_hostapd_setup_base() { if [ "$enable_ax" != "0" ]; then json_get_vars \ he_su_beamformer:1 \ - he_su_beamformee:0 \ + he_su_beamformee:1 \ he_mu_beamformer:1 \ he_twt_required:0 \ - he_spr_sr_control:0 \ - he_spr_non_srg_obss_pd_max_offset:1 \ - he_bss_color + he_spr_sr_control:3 \ + he_spr_psr_enabled:0 \ + he_spr_non_srg_obss_pd_max_offset:0 \ + he_bss_color:128 \ + he_bss_color_enabled:1 - he_phy_cap=$(iw phy "$phy" info | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1) + he_phy_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1) he_phy_cap=${he_phy_cap:2} - he_mac_cap=$(iw phy "$phy" info | awk -F "[()]" '/HE MAC Capabilities/ { print $2 }' | head -1) + he_mac_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE MAC Capabilities/ { print $2 }' | head -1) he_mac_cap=${he_mac_cap:2} append base_cfg "ieee80211ax=1" "$N" - [ -n "$he_bss_color" ] && append base_cfg "he_bss_color=$he_bss_color" "$N" [ "$hwmode" = "a" ] && { append base_cfg "he_oper_chwidth=$vht_oper_chwidth" "$N" append base_cfg "he_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N" @@ -432,10 +438,21 @@ mac80211_hostapd_setup_base() { he_su_beamformer:${he_phy_cap:6:2}:0x80:$he_su_beamformer \ he_su_beamformee:${he_phy_cap:8:2}:0x1:$he_su_beamformee \ he_mu_beamformer:${he_phy_cap:8:2}:0x2:$he_mu_beamformer \ - he_spr_sr_control:${he_phy_cap:14:2}:0x1:$he_spr_sr_control \ + he_spr_psr_enabled:${he_phy_cap:14:2}:0x1:$he_spr_psr_enabled \ he_twt_required:${he_mac_cap:0:2}:0x6:$he_twt_required - [ "$he_spr_sr_control" -gt 0 ] && append base_cfg "he_spr_non_srg_obss_pd_max_offset=$he_spr_non_srg_obss_pd_max_offset" "$N" + if [ "$he_bss_color_enabled" -gt 0 ]; then + append base_cfg "he_bss_color=$he_bss_color" "$N" + [ "$he_spr_non_srg_obss_pd_max_offset" -gt 0 ] && { \ + append base_cfg "he_spr_non_srg_obss_pd_max_offset=$he_spr_non_srg_obss_pd_max_offset" "$N" + he_spr_sr_control=$((he_spr_sr_control | (1 << 2))) + } + [ "$he_spr_psr_enabled" -gt 0 ] || he_spr_sr_control=$((he_spr_sr_control | (1 << 0))) + append base_cfg "he_spr_sr_control=$he_spr_sr_control" "$N" + else + append base_cfg "he_bss_color_disabled=1" "$N" + fi + append base_cfg "he_default_pe_duration=4" "$N" append base_cfg "he_rts_threshold=1023" "$N" @@ -475,8 +492,6 @@ $base_cfg EOF json_select .. - radio_md5sum=$(md5sum $hostapd_conf_file | cut -d" " -f1) - echo "radio_config_id=${radio_md5sum}" >> $hostapd_conf_file } mac80211_hostapd_setup_bss() { @@ -490,7 +505,7 @@ mac80211_hostapd_setup_bss() { hostapd_set_bss_options hostapd_cfg "$phy" "$vif" || return 1 json_get_vars wds wds_bridge dtim_period max_listen_int start_disabled - json_get_vars fils_discovery_max_interval + json_get_vars fils_discovery_max_interval set_default wds 0 set_default start_disabled 0 @@ -533,7 +548,7 @@ mac80211_generate_mac() { local ref="$(cat /sys/class/ieee80211/${phy}/macaddress)" local mask="$(cat /sys/class/ieee80211/${phy}/address_mask)" - [ "$mask" = "00:00:00:00:00:00" ] && { + [ "$mask" = "00:00:00:00:00:00" -a "$multiple_bssid" != 1 ] && { mask="ff:ff:ff:ff:ff:ff"; [ "$(wc -l < /sys/class/ieee80211/${phy}/addresses)" -gt $id ] && { @@ -598,76 +613,7 @@ mac80211_check_ap() { has_ap=1 } -mac80211_iw_interface_add() { - local phy="$1" - local ifname="$2" - local type="$3" - local wdsflag="$4" - local rc - local oldifname - - iw phy "$phy" interface add "$ifname" type "$type" $wdsflag >/dev/null 2>&1 - rc="$?" - - [ "$rc" = 233 ] && { - # Device might have just been deleted, give the kernel some time to finish cleaning it up - sleep 1 - - iw phy "$phy" interface add "$ifname" type "$type" $wdsflag >/dev/null 2>&1 - rc="$?" - } - - [ "$rc" = 233 ] && { - # Keep matching pre-existing interface - [ -d "/sys/class/ieee80211/${phy}/device/net/${ifname}" ] && \ - case "$(iw dev $ifname info | grep "^\ttype" | cut -d' ' -f2- 2>/dev/null)" in - "AP") - [ "$type" = "__ap" ] && rc=0 - ;; - "IBSS") - [ "$type" = "adhoc" ] && rc=0 - ;; - "managed") - [ "$type" = "managed" ] && rc=0 - ;; - "mesh point") - [ "$type" = "mp" ] && rc=0 - ;; - "monitor") - [ "$type" = "monitor" ] && rc=0 - ;; - esac - } - - [ "$rc" = 233 ] && { - iw dev "$ifname" del >/dev/null 2>&1 - [ "$?" = 0 ] && { - sleep 1 - - iw phy "$phy" interface add "$ifname" type "$type" $wdsflag >/dev/null 2>&1 - rc="$?" - } - } - - [ "$rc" != 0 ] && { - # Device might not support virtual interfaces, so the interface never got deleted in the first place. - # Check if the interface already exists, and avoid failing in this case. - [ -d "/sys/class/ieee80211/${phy}/device/net/${ifname}" ] && rc=0 - } - - [ "$rc" != 0 ] && { - # Device doesn't support virtual interfaces and may have existing interface other than ifname. - oldifname="$(basename "/sys/class/ieee80211/${phy}/device/net"/* 2>/dev/null)" - [ "$oldifname" ] && ip link set "$oldifname" name "$ifname" 1>/dev/null 2>&1 - rc="$?" - } - - [ "$rc" != 0 ] && echo "Failed to create interface $ifname" - return $rc -} - mac80211_prepare_vif() { - local multiple_bssid=$1 json_select config json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file vlan_file @@ -675,19 +621,18 @@ mac80211_prepare_vif() { [ -n "$ifname" ] || ifname="wlan${phy#phy}${if_idx:+-$if_idx}" if_idx=$((${if_idx:-0} + 1)) + append active_ifnames "$ifname" set_default wds 0 set_default powersave 0 - - json_select .. + json_add_string _ifname "$ifname" [ -n "$macaddr" ] || { macaddr="$(mac80211_generate_mac $phy $multiple_bssid)" - macidx="$(($macidx + 1))" + macidx="$(($macidx + 1))" } + json_add_string _macaddr "$macaddr" + json_select .. - json_add_object data - json_add_string ifname "$ifname" - json_close_object [ "$mode" == "ap" ] && { [ -z "$wpa_psk_file" ] && hostapd_set_psk "$ifname" @@ -698,9 +643,6 @@ mac80211_prepare_vif() { # It is far easier to delete and create the desired interface case "$mode" in - adhoc) - mac80211_iw_interface_add "$phy" "$ifname" adhoc || return - ;; ap) # Hostapd will handle recreating the interface and # subsequent virtual APs belonging to the same PHY @@ -712,119 +654,20 @@ mac80211_prepare_vif() { mac80211_hostapd_setup_bss "$phy" "$ifname" "$macaddr" "$type" || return - NEWAPLIST="${NEWAPLIST}$ifname " [ -n "$hostapd_ctrl" ] || { ap_ifname="${ifname}" hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd/$ifname}" } ;; - mesh) - mac80211_iw_interface_add "$phy" "$ifname" mp || return - ;; - monitor) - mac80211_iw_interface_add "$phy" "$ifname" monitor || return - ;; - sta) - local wdsflag= - [ "$enable" = 0 ] || staidx="$(($staidx + 1))" - [ "$wds" -gt 0 ] && wdsflag="4addr on" - mac80211_iw_interface_add "$phy" "$ifname" managed "$wdsflag" || return - if [ "$wds" -gt 0 ]; then - echo 1 > /sys/kernel/debug/ieee80211/$phy/netdev\:$ifname/disable_offload - iw "$ifname" set 4addr on - else - iw "$ifname" set 4addr off - fi - [ "$powersave" -gt 0 ] && powersave="on" || powersave="off" - iw "$ifname" set power_save "$powersave" - ;; esac - case "$mode" in - monitor|mesh) - [ "$auto_channel" -gt 0 ] || iw dev "$ifname" set channel "$channel" $iw_htmode - ;; - esac - - if [ "$mode" != "ap" ]; then - # ALL ap functionality will be passed to hostapd - # All interfaces must have unique mac addresses - # which can either be explicitly set in the device - # section, or automatically generated - ip link set dev "$ifname" address "$macaddr" - fi - json_select .. } -mac80211_setup_supplicant() { - local enable=$1 - local add_sp=0 - local spobj="$(ubus -S list | grep wpa_supplicant.${ifname})" - - [ "$enable" = 0 ] && { - ubus call wpa_supplicant.${phy} config_remove "{\"iface\":\"$ifname\"}" - ip link set dev "$ifname" down - iw dev "$ifname" del - return 0 - } - - wpa_supplicant_prepare_interface "$ifname" nl80211 || { - iw dev "$ifname" del - return 1 - } - if [ "$mode" = "sta" ]; then - wpa_supplicant_add_network "$ifname" - else - wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan" - fi - - NEWSPLIST="${NEWSPLIST}$ifname " - - if [ "${NEWAPLIST%% *}" != "${OLDAPLIST%% *}" ]; then - [ "$spobj" ] && ubus call wpa_supplicant config_remove "{\"iface\":\"$ifname\"}" - add_sp=1 - fi - [ -z "$spobj" ] && add_sp=1 - - NEW_MD5_SP=$(test -e "${_config}" && md5sum ${_config}) - OLD_MD5_SP=$(uci -q -P /var/state get wireless._${phy}.md5_${ifname}) - if [ "$add_sp" = "1" ]; then - wpa_supplicant_run "$ifname" "$hostapd_ctrl" - else - [ "${NEW_MD5_SP}" == "${OLD_MD5_SP}" ] || ubus call $spobj reload - fi - uci -q -P /var/state set wireless._${phy}.md5_${ifname}="${NEW_MD5_SP}" - return 0 -} - -mac80211_setup_supplicant_noctl() { - local enable=$1 - local spobj="$(ubus -S list | grep wpa_supplicant.${ifname})" - wpa_supplicant_prepare_interface "$ifname" nl80211 || { - iw dev "$ifname" del - return 1 - } - - wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan" - - NEWSPLIST="${NEWSPLIST}$ifname " - [ "$enable" = 0 ] && { - ubus call wpa_supplicant config_remove "{\"iface\":\"$ifname\"}" - ip link set dev "$ifname" down - return 0 - } - if [ -z "$spobj" ]; then - wpa_supplicant_run "$ifname" - else - ubus call $spobj reload - fi -} - mac80211_prepare_iw_htmode() { case "$htmode" in - VHT20|HT20) iw_htmode=HT20;; - HT40*|VHT40|VHT160) + VHT20|HT20|HE20) iw_htmode=HT20;; + HT40*|VHT40|VHT160|HE40) case "$band" in 2g) case "$htmode" in @@ -848,7 +691,7 @@ mac80211_prepare_iw_htmode() { esac [ "$auto_channel" -gt 0 ] && iw_htmode="HT40+" ;; - VHT80) + VHT80|HE80) iw_htmode="80MHZ" ;; NONE|NOHT) @@ -858,6 +701,13 @@ mac80211_prepare_iw_htmode() { esac } +mac80211_add_mesh_params() { + for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING; do + eval "mp_val=\"\$$var\"" + [ -n "$mp_val" ] && json_add_string "$var" "$mp_val" + done +} + mac80211_setup_adhoc() { local enable=$1 json_get_vars bssid ssid key mcast_rate @@ -899,81 +749,218 @@ mac80211_setup_adhoc() { mcval= [ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" - iw dev "$ifname" ibss join "$ssid" $freq $iw_htmode fixed-freq $bssid \ - beacon-interval $beacon_int \ - ${brstr:+basic-rates $brstr} \ - ${mcval:+mcast-rate $mcval} \ - ${keyspec:+keys $keyspec} + local prev + json_set_namespace wdev_uc prev + + json_add_object "$ifname" + json_add_string mode adhoc + json_add_string macaddr "$macaddr" + json_add_string ssid "$ssid" + json_add_string freq "$freq" + json_add_string htmode "$iw_htmode" + [ -n "$bssid" ] && json_add_string bssid "$bssid" + json_add_int beacon-interval "$beacon_int" + [ -n "$brstr" ] && json_add_string basic-rates "$brstr" + [ -n "$mcval" ] && json_add_string mcast-rate "$mcval" + [ -n "$keyspec" ] && json_add_string keys "$keyspec" + json_close_object + + json_set_namespace "$prev" } mac80211_setup_mesh() { - local enable=$1 json_get_vars ssid mesh_id mcast_rate - NEWUMLIST="${NEWUMLIST}$ifname " - - [ "$enable" = 0 ] && { - ip link set dev "$ifname" down - return 0 - } - mcval= [ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" [ -n "$mesh_id" ] && ssid="$mesh_id" - iw dev "$ifname" mesh join "$ssid" freq $freq $iw_htmode \ - ${mcval:+mcast-rate $mcval} \ - beacon-interval $beacon_int + local prev + json_set_namespace wdev_uc prev + + json_add_object "$ifname" + json_add_string mode mesh + json_add_string macaddr "$macaddr" + json_add_string ssid "$ssid" + json_add_string freq "$freq" + json_add_string htmode "$iw_htmode" + [ -n "$mcval" ] && json_add_string mcast-rate "$mcval" + json_add_int beacon-interval "$beacon_int" + mac80211_add_mesh_params + + json_close_object + + json_set_namespace "$prev" +} + +mac80211_setup_monitor() { + local prev + json_set_namespace wdev_uc prev + + json_add_object "$ifname" + json_add_string mode monitor + [ -n "$freq" ] && json_add_string freq "$freq" + json_add_string htmode "$iw_htmode" + json_close_object + + json_set_namespace "$prev" +} + +mac80211_set_vif_txpower() { + local name="$1" + + json_select config + json_get_var ifname _ifname + json_get_vars vif_txpower wds + json_select .. + + set_default wds 0 + [ -z "$vif_txpower" ] || iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00" + [ "$wds" -gt 0 ] && echo 1 > /sys/kernel/debug/ieee80211/$phy/netdev\:$ifname/disable_offload +} + +wpa_supplicant_init_config() { + json_set_namespace wpa_supp prev + + json_init + json_add_array config + + json_set_namespace "$prev" +} + +wpa_supplicant_add_interface() { + local ifname="$1" + local mode="$2" + local hostapd_ctrl="$3" + local prev + + _wpa_supplicant_common "$ifname" + + json_set_namespace wpa_supp prev + + json_add_object + json_add_string ctrl "$_rpath" + json_add_string iface "$ifname" + json_add_string mode "$mode" + json_add_string config "$_config" + json_add_string macaddr "$macaddr" + [ -n "$network_bridge" ] && json_add_string bridge "$network_bridge" + [ -n "$hostapd_ctrl" ] && json_add_string hostapd_ctrl "$hostapd_ctrl" + [ -n "$wds" ] && json_add_boolean 4addr "$wds" + json_add_boolean powersave "$powersave" + [ "$mode" = "mesh" ] && mac80211_add_mesh_params + json_close_object + + json_set_namespace "$prev" + + wpa_supp_init=1 +} + +wpa_supplicant_set_config() { + local phy="$1" + local prev + + json_set_namespace wpa_supp prev + json_close_array + json_add_string phy "$phy" + json_add_boolean defer 1 + local data="$(json_dump)" + + json_cleanup + json_set_namespace "$prev" + + ubus -S -t 0 wait_for wpa_supplicant || { + [ -n "$wpa_supp_init" ] || return 0 + + ubus wait_for wpa_supplicant + } + + local supplicant_res="$(ubus call wpa_supplicant config_set "$data")" + ret="$?" + [ "$ret" != 0 -o -z "$supplicant_res" ] && wireless_setup_vif_failed WPA_SUPPLICANT_FAILED + + wireless_add_process "$(jsonfilter -s "$supplicant_res" -l 1 -e @.pid)" "/usr/sbin/wpa_supplicant" 1 1 + +} + +hostapd_set_config() { + [ -n "$hostapd_ctrl" ] || { + ubus call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"${hostapd_conf_file}.prev"'" }' > /dev/null + return 0; + } + + ubus wait_for hostapd + local hostapd_res="$(ubus call hostapd config_set "{ \"phy\": \"$phy\", \"config\":\"${hostapd_conf_file}\", \"prev_config\": \"${hostapd_conf_file}.prev\"}")" + ret="$?" + [ "$ret" != 0 -o -z "$hostapd_res" ] && { + wireless_setup_failed HOSTAPD_START_FAILED + return + } + wireless_add_process "$(jsonfilter -s "$hostapd_res" -l 1 -e @.pid)" "/usr/sbin/hostapd" 1 1 +} + + +wpa_supplicant_start() { + local phy="$1" + + [ -n "$wpa_supp_init" ] || return 0 + + ubus call wpa_supplicant config_set '{ "phy": "'"$phy"'" }' > /dev/null +} + +mac80211_setup_supplicant() { + local enable=$1 + local add_sp=0 + + wpa_supplicant_prepare_interface "$ifname" nl80211 || return 1 + + if [ "$mode" = "sta" ]; then + wpa_supplicant_add_network "$ifname" + else + wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan" + fi + + wpa_supplicant_add_interface "$ifname" "$mode" "$hostapd_ctrl" + + return 0 } mac80211_setup_vif() { local name="$1" local failed - local action=up - - json_select data - json_get_vars ifname - json_select .. json_select config - json_get_vars mode - json_get_var vif_txpower - json_get_var vif_enable enable 1 + json_get_var ifname _ifname + json_get_var macaddr _macaddr + json_get_vars mode wds powersave - [ "$vif_enable" = 1 ] || action=down - if [ "$mode" != "ap" ] || [ "$ifname" = "$ap_ifname" ]; then - ip link set dev "$ifname" "$action" || { - wireless_setup_vif_failed IFUP_ERROR - json_select .. - return - } - [ -z "$vif_txpower" ] || iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00" - fi + set_default powersave 0 + set_default wds 0 case "$mode" in mesh) + json_get_vars $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING wireless_vif_parse_encryption [ -z "$htmode" ] && htmode="NOHT"; - if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ] || chan_is_dfs "$phy" "$channel"; then - mac80211_setup_supplicant $vif_enable || failed=1 + if wpa_supplicant -vmesh; then + mac80211_setup_supplicant || failed=1 else - mac80211_setup_mesh $vif_enable + mac80211_setup_mesh fi - for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING; do - json_get_var mp_val "$var" - [ -n "$mp_val" ] && iw dev "$ifname" set mesh_param "$var" "$mp_val" - done ;; adhoc) wireless_vif_parse_encryption if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then - mac80211_setup_supplicant_noctl $vif_enable || failed=1 + mac80211_setup_supplicant || failed=1 else - mac80211_setup_adhoc $vif_enable + mac80211_setup_adhoc fi ;; sta) - mac80211_setup_supplicant $vif_enable || failed=1 + mac80211_setup_supplicant || failed=1 + ;; + monitor) + mac80211_setup_monitor ;; esac @@ -1006,7 +993,6 @@ band_match && $3 == "MHz" && $4 == channel { ' } - chan_is_dfs() { local phy="$1" local chan="$2" @@ -1014,27 +1000,6 @@ chan_is_dfs() { return $! } -mac80211_vap_cleanup() { - local service="$1" - local vaps="$2" - - for wdev in $vaps; do - [ "$service" != "none" ] && ubus call ${service} config_remove "{\"iface\":\"$wdev\"}" - ip link set dev "$wdev" down 2>/dev/null - iw dev "$wdev" del - done -} - -mac80211_interface_cleanup() { - local phy="$1" - local primary_ap=$(uci -q -P /var/state get wireless._${phy}.aplist) - primary_ap=${primary_ap%% *} - - mac80211_vap_cleanup hostapd "${primary_ap}" - mac80211_vap_cleanup wpa_supplicant "$(uci -q -P /var/state get wireless._${phy}.splist)" - mac80211_vap_cleanup none "$(uci -q -P /var/state get wireless._${phy}.umlist)" -} - mac80211_set_noscan() { hostapd_noscan=1 } @@ -1043,6 +1008,15 @@ drv_mac80211_cleanup() { hostapd_common_cleanup } +mac80211_reset_config() { + local phy="$1" + + hostapd_conf_file="/var/run/hostapd-$phy.conf" + ubus call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"$hostapd_conf_file"'" }' > /dev/null + ubus call wpa_supplicant config_set '{ "phy": "'"$phy"'", "config": [] }' > /dev/null + wdev_tool "$phy" '{}' +} + drv_mac80211_setup() { json_select config json_get_vars \ @@ -1057,39 +1031,24 @@ drv_mac80211_setup() { json_get_values scan_list scan_list json_select .. + json_select data && { + json_get_var prev_rxantenna rxantenna + json_get_var prev_txantenna txantenna + json_select .. + } + find_phy || { echo "Could not find PHY for device '$1'" wireless_set_retry 0 return 1 } - [ "$band" = "6g" ] && multiple_bssid=1 - - wireless_set_data phy="$phy" - [ -z "$(uci -q -P /var/state show wireless._${phy})" ] && uci -q -P /var/state set wireless._${phy}=phy - - OLDAPLIST=$(uci -q -P /var/state get wireless._${phy}.aplist) - OLDSPLIST=$(uci -q -P /var/state get wireless._${phy}.splist) - OLDUMLIST=$(uci -q -P /var/state get wireless._${phy}.umlist) + [ "$band" = "6g" ] && set_default multiple_bssid 1 local wdev local cwdev local found - for wdev in $(list_phy_interfaces "$phy"); do - found=0 - for cwdev in $OLDAPLIST $OLDSPLIST $OLDUMLIST; do - if [ "$wdev" = "$cwdev" ]; then - found=1 - break - fi - done - if [ "$found" = "0" ]; then - ip link set dev "$wdev" down - iw dev "$wdev" del - fi - done - # convert channel to frequency [ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel" "$band")" @@ -1102,7 +1061,6 @@ drv_mac80211_setup() { hostapd_conf_file="/var/run/hostapd-$phy.conf" - no_ap=1 macidx=0 staidx=0 @@ -1121,6 +1079,9 @@ drv_mac80211_setup() { [ "$txantenna" = "all" ] && txantenna=0xffffffff [ "$rxantenna" = "all" ] && rxantenna=0xffffffff + [ "$rxantenna" = "$prev_rxantenna" -a "$txantenna" = "$prev_txantenna" ] || mac80211_reset_config "$phy" + wireless_set_data phy="$phy" txantenna="$txantenna" rxantenna="$rxantenna" + iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1 iw phy "$phy" set antenna_gain $antenna_gain >/dev/null 2>&1 iw phy "$phy" set distance "$distance" >/dev/null 2>&1 @@ -1138,81 +1099,36 @@ drv_mac80211_setup() { hostapd_ctrl= ap_ifname= hostapd_noscan= + wpa_supp_init= for_each_interface "ap" mac80211_check_ap - rm -f "$hostapd_conf_file" + [ -f "$hostapd_conf_file" ] && mv "$hostapd_conf_file" "$hostapd_conf_file.prev" for_each_interface "sta adhoc mesh" mac80211_set_noscan [ -n "$has_ap" ] && mac80211_hostapd_setup_base "$phy" + local prev + json_set_namespace wdev_uc prev + json_init + json_set_namespace "$prev" + + wpa_supplicant_init_config + mac80211_prepare_iw_htmode - for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif - NEWAPLIST= - for_each_interface "ap" mac80211_prepare_vif ${multiple_bssid} - NEW_MD5=$(test -e "${hostapd_conf_file}" && md5sum ${hostapd_conf_file}) - OLD_MD5=$(uci -q -P /var/state get wireless._${phy}.md5) - if [ "${NEWAPLIST}" != "${OLDAPLIST}" ]; then - mac80211_vap_cleanup hostapd "${OLDAPLIST}" - fi - [ -n "${NEWAPLIST}" ] && mac80211_iw_interface_add "$phy" "${NEWAPLIST%% *}" __ap - local add_ap=0 - local primary_ap=${NEWAPLIST%% *} - [ -n "$hostapd_ctrl" ] && { - local no_reload=1 - if [ -n "$(ubus list | grep hostapd.$primary_ap)" ]; then - no_reload=0 - [ "${NEW_MD5}" = "${OLD_MD5}" ] || { - ubus call hostapd.$primary_ap reload - no_reload=$? - if [ "$no_reload" != "0" ]; then - mac80211_vap_cleanup hostapd "${OLDAPLIST}" - mac80211_vap_cleanup wpa_supplicant "$(uci -q -P /var/state get wireless._${phy}.splist)" - mac80211_vap_cleanup none "$(uci -q -P /var/state get wireless._${phy}.umlist)" - sleep 2 - mac80211_iw_interface_add "$phy" "${NEWAPLIST%% *}" __ap - for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif - fi - } - fi - if [ "$no_reload" != "0" ]; then - add_ap=1 - ubus wait_for hostapd - local hostapd_res - [ -f /tmp/wifi_fail_test ] || hostapd_res="$(ubus call hostapd config_add "{\"iface\":\"$primary_ap\", \"config\":\"${hostapd_conf_file}\"}")" - ret="$?" - rm -f /tmp/wifi_fail_test - [ "$ret" != 0 -o -z "$hostapd_res" ] && { - logger failed to start wifi trying again - # wireless_setup_failed HOSTAPD_START_FAILED - return - } - wireless_add_process "$(jsonfilter -s "$hostapd_res" -l 1 -e @.pid)" "/usr/sbin/hostapd" 1 1 - fi - } - uci -q -P /var/state set wireless._${phy}.aplist="${NEWAPLIST}" - uci -q -P /var/state set wireless._${phy}.md5="${NEW_MD5}" + active_ifnames= + for_each_interface "ap sta adhoc mesh monitor" mac80211_prepare_vif ${multiple_bssid} + for_each_interface "ap sta adhoc mesh monitor" mac80211_setup_vif - [ "${add_ap}" = 1 ] && sleep 1 - for_each_interface "ap" mac80211_setup_vif + [ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_set_config "$phy" + [ -x /usr/sbin/hostapd ] && hostapd_set_config "$phy" - NEWSPLIST= - NEWUMLIST= + [ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_start "$phy" - for_each_interface "sta adhoc mesh monitor" mac80211_setup_vif + json_set_namespace wdev_uc prev + wdev_tool "$phy" "$(json_dump)" $active_ifnames + json_set_namespace "$prev" - uci -q -P /var/state set wireless._${phy}.splist="${NEWSPLIST}" - uci -q -P /var/state set wireless._${phy}.umlist="${NEWUMLIST}" - - local foundvap - local dropvap="" - for oldvap in $OLDSPLIST; do - foundvap=0 - for newvap in $NEWSPLIST; do - [ "$oldvap" = "$newvap" ] && foundvap=1 - done - [ "$foundvap" = "0" ] && dropvap="$dropvap $oldvap" - done - [ -n "$dropvap" ] && mac80211_vap_cleanup wpa_supplicant "$dropvap" + for_each_interface "ap sta adhoc mesh monitor" mac80211_set_vif_txpower wireless_set_up } @@ -1243,8 +1159,12 @@ drv_mac80211_teardown() { return 1 } - mac80211_interface_cleanup "$phy" - uci -q -P /var/state revert wireless._${phy} + mac80211_reset_config "$phy" + + for wdev in $(list_phy_interfaces "$phy"); do + ip link set dev "$wdev" down + iw dev "$wdev" del + done } add_driver mac80211