Merge branch 'openwrt:master' into master

This commit is contained in:
Hayzam Sherif 2023-09-13 20:35:56 +05:30 committed by GitHub
commit 3685fe2e5d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 1180 additions and 393 deletions

View file

@ -416,7 +416,10 @@ define KernelPackage/brcmfmac
DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +@DRIVER_11AC_SUPPORT \
+kmod-brcmutil +BRCMFMAC_SDIO:kmod-mmc @!TARGET_uml \
+BRCMFMAC_USB:kmod-usb-core +BRCMFMAC_USB:brcmfmac-firmware-usb
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko \
$(foreach type,bca cyw wcc, \
$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmfmac/$(type)/brcmfmac-$(type).ko)
AUTOLOAD:=$(call AutoProbe,brcmfmac)
endef

View file

@ -27,6 +27,7 @@ drv_mac80211_init_device_config() {
config_add_string distance
config_add_int beacon_int chanbw frag rts
config_add_int rxantenna txantenna txpower min_tx_power
config_add_int num_global_macaddr multiple_bssid
config_add_boolean noscan ht_coex acs_exclude_dfs background_radar
config_add_array ht_capab
config_add_array channels
@ -487,6 +488,8 @@ ${channel:+channel=$channel}
${channel_list:+chanlist=$channel_list}
${hostapd_noscan:+noscan=1}
${tx_burst:+tx_queue_data2_burst=$tx_burst}
mbssid=$multiple_bssid
#num_global_macaddr=$num_global_macaddr
$base_cfg
EOF
@ -517,6 +520,7 @@ mac80211_hostapd_setup_bss() {
cat >> /var/run/hostapd-$phy.conf <<EOF
$hostapd_cfg
bssid=$macaddr
${default_macaddr:+#default_macaddr}
${dtim_period:+dtim_period=$dtim_period}
${max_listen_int:+max_listen_interval=$max_listen_int}
EOF
@ -533,47 +537,7 @@ mac80211_generate_mac() {
local phy="$1"
local id="${macidx:-0}"
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="ff:ff:ff:ff:ff:ff";
[ "$(wc -l < /sys/class/ieee80211/${phy}/addresses)" -gt $id ] && {
addr="$(mac80211_get_addr "$phy" "$id")"
[ -n "$addr" ] && {
echo "$addr"
return
}
}
}
local oIFS="$IFS"; IFS=":"; set -- $mask; IFS="$oIFS"
local mask1=$1
local mask6=$6
local oIFS="$IFS"; IFS=":"; set -- $ref; IFS="$oIFS"
macidx=$(($id + 1))
[ "$((0x$mask1))" -gt 0 ] && {
b1="0x$1"
[ "$id" -gt 0 ] && \
b1=$(($b1 ^ ((($id - !($b1 & 2)) << 2)) | 0x2))
printf "%02x:%s:%s:%s:%s:%s" $b1 $2 $3 $4 $5 $6
return
}
[ "$((0x$mask6))" -lt 255 ] && {
printf "%s:%s:%s:%s:%s:%02x" $1 $2 $3 $4 $5 $(( 0x$6 ^ $id ))
return
}
off2=$(( (0x$6 + $id) / 0x100 ))
printf "%s:%s:%s:%s:%02x:%02x" \
$1 $2 $3 $4 \
$(( (0x$5 + $off2) % 0x100 )) \
$(( (0x$6 + $id) % 0x100 ))
wdev_tool "$phy" get_macaddr id=$id num_global=$num_global_macaddr mbssid=$multiple_bssid
}
get_board_phy_name() (
@ -684,13 +648,16 @@ mac80211_prepare_vif() {
set_default powersave 0
json_add_string _ifname "$ifname"
default_macaddr=
if [ -z "$macaddr" ]; then
macaddr="$(mac80211_generate_mac $phy)"
macidx="$(($macidx + 1))"
default_macaddr=1
elif [ "$macaddr" = 'random' ]; then
macaddr="$(macaddr_random)"
fi
json_add_string _macaddr "$macaddr"
json_add_string _default_macaddr "$default_macaddr"
json_select ..
@ -814,7 +781,7 @@ mac80211_setup_adhoc() {
json_add_object "$ifname"
json_add_string mode adhoc
json_add_string macaddr "$macaddr"
[ -n "$default_macaddr" ] || json_add_string macaddr "$macaddr"
json_add_string ssid "$ssid"
json_add_string freq "$freq"
json_add_string htmode "$iw_htmode"
@ -840,7 +807,7 @@ mac80211_setup_mesh() {
json_add_object "$ifname"
json_add_string mode mesh
json_add_string macaddr "$macaddr"
[ -n "$default_macaddr" ] || json_add_string macaddr "$macaddr"
json_add_string ssid "$ssid"
json_add_string freq "$freq"
json_add_string htmode "$iw_htmode"
@ -900,7 +867,7 @@ wpa_supplicant_add_interface() {
json_add_string iface "$ifname"
json_add_string mode "$mode"
json_add_string config "$_config"
json_add_string macaddr "$macaddr"
[ -n "$default_macaddr" ] || json_add_string macaddr "$macaddr"
[ -n "$network_bridge" ] && json_add_string bridge "$network_bridge"
[ -n "$wds" ] && json_add_boolean 4addr "$wds"
json_add_boolean powersave "$powersave"
@ -988,6 +955,7 @@ mac80211_setup_vif() {
json_select config
json_get_var ifname _ifname
json_get_var macaddr _macaddr
json_get_var default_macaddr _default_macaddr
json_get_vars mode wds powersave
set_default powersave 0
@ -1070,7 +1038,7 @@ mac80211_reset_config() {
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" '{}'
wdev_tool "$phy" set_config '{}'
}
drv_mac80211_setup() {
@ -1080,7 +1048,8 @@ drv_mac80211_setup() {
country chanbw distance \
txpower \
rxantenna txantenna \
frag rts beacon_int:100 htmode
frag rts beacon_int:100 htmode \
num_global_macaddr:1 multiple_bssid:0
json_get_values basic_rate_list basic_rate
json_get_values scan_list scan_list
json_select ..
@ -1174,7 +1143,7 @@ drv_mac80211_setup() {
[ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_start "$phy"
json_set_namespace wdev_uc prev
wdev_tool "$phy" "$(json_dump)" $active_ifnames
wdev_tool "$phy" set_config "$(json_dump)" $active_ifnames
json_set_namespace "$prev"
for_each_interface "ap sta adhoc mesh monitor" mac80211_set_vif_txpower

View file

@ -0,0 +1,27 @@
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1396,24 +1396,6 @@ int ieee80211_register_hw(struct ieee802
debugfs_hw_add(local);
rate_control_add_debugfs(local);
- rtnl_lock();
- wiphy_lock(hw->wiphy);
-
- /* add one default STA interface if supported */
- if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) &&
- !ieee80211_hw_check(hw, NO_AUTO_VIF)) {
- struct vif_params params = {0};
-
- result = ieee80211_if_add(local, "wlan%d", NET_NAME_ENUM, NULL,
- NL80211_IFTYPE_STATION, &params);
- if (result)
- wiphy_warn(local->hw.wiphy,
- "Failed to add default virtual iface\n");
- }
-
- wiphy_unlock(hw->wiphy);
- rtnl_unlock();
-
#ifdef CONFIG_INET
local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
result = register_inetaddr_notifier(&local->ifa_notifier);

View file

@ -9,9 +9,9 @@ PKG_RELEASE:=2
PKG_SOURCE_URL:=http://w1.fi/hostap.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2023-06-22
PKG_SOURCE_VERSION:=599d00be9de2846c6ea18c1487d8329522ade22b
PKG_MIRROR_HASH:=828810c558ea181e45ed0c8b940f5c41e55775e2979a15aed8cf0ab17dd7723c
PKG_SOURCE_DATE:=2023-09-08
PKG_SOURCE_VERSION:=e5ccbfc69ecf297590341ae8b461edba9d8e964c
PKG_MIRROR_HASH:=fcc6550f46c7f8bbdbf71e63f8f699b9a0878565ad1b90a17855f5ec21283b8f
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_LICENSE:=BSD-3-Clause

View file

@ -1,6 +1,6 @@
import * as nl80211 from "nl80211";
import * as rtnl from "rtnl";
import { readfile } from "fs";
import { readfile, glob, basename, readlink } from "fs";
const iftypes = {
ap: nl80211.const.NL80211_IFTYPE_AP,
@ -94,6 +94,156 @@ function wdev_create(phy, name, data)
return null;
}
function phy_sysfs_file(phy, name)
{
return trim(readfile(`/sys/class/ieee80211/${phy}/${name}`));
}
function macaddr_split(str)
{
return map(split(str, ":"), (val) => hex(val));
}
function macaddr_join(addr)
{
return join(":", map(addr, (val) => sprintf("%02x", val)));
}
function wdev_macaddr(wdev)
{
return trim(readfile(`/sys/class/net/${wdev}/address`));
}
const phy_proto = {
macaddr_init: function(used, options) {
this.macaddr_options = options ?? {};
this.macaddr_list = {};
if (type(used) == "object")
for (let addr in used)
this.macaddr_list[addr] = used[addr];
else
for (let addr in used)
this.macaddr_list[addr] = -1;
this.for_each_wdev((wdev) => {
let macaddr = wdev_macaddr(wdev);
this.macaddr_list[macaddr] ??= -1;
});
return this.macaddr_list;
},
macaddr_generate: function(data) {
let phy = this.name;
let idx = int(data.id ?? 0);
let mbssid = int(data.mbssid ?? 0) > 0;
let num_global = int(data.num_global ?? 1);
let use_global = !mbssid && idx < num_global;
let base_addr = phy_sysfs_file(phy, "macaddress");
if (!base_addr)
return null;
if (!idx && !mbssid)
return base_addr;
let base_mask = phy_sysfs_file(phy, "address_mask");
if (!base_mask)
return null;
if (base_mask == "00:00:00:00:00:00" && idx >= num_global) {
let addrs = split(phy_sysfs_file(phy, "addresses"), "\n");
if (idx < length(addrs))
return addrs[idx];
base_mask = "ff:ff:ff:ff:ff:ff";
}
let addr = macaddr_split(base_addr);
let mask = macaddr_split(base_mask);
let type;
if (mbssid)
type = "b5";
else if (use_global)
type = "add";
else if (mask[0] > 0)
type = "b1";
else if (mask[5] < 0xff)
type = "b5";
else
type = "add";
switch (type) {
case "b1":
if (!(addr[0] & 2))
idx--;
addr[0] |= 2;
addr[0] ^= idx << 2;
break;
case "b5":
if (mbssid)
addr[0] |= 2;
addr[5] ^= idx;
break;
default:
for (let i = 5; i > 0; i--) {
addr[i] += idx;
if (addr[i] < 256)
break;
addr[i] %= 256;
}
break;
}
return macaddr_join(addr);
},
macaddr_next: function(val) {
let data = this.macaddr_options ?? {};
let list = this.macaddr_list;
for (let i = 0; i < 32; i++) {
data.id = i;
let mac = this.macaddr_generate(data);
if (!mac)
return null;
if (list[mac] != null)
continue;
list[mac] = val != null ? val : -1;
return mac;
}
},
for_each_wdev: function(cb) {
let wdevs = glob(`/sys/class/ieee80211/${this.name}/device/net/*`);
wdevs = map(wdevs, (arg) => basename(arg));
for (let wdev in wdevs) {
if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != this.name)
continue;
cb(wdev);
}
}
};
function phy_open(phy)
{
let phyidx = readfile(`/sys/class/ieee80211/${phy}/index`);
if (!phyidx)
return null;
return proto({
name: phy,
idx: int(phyidx)
}, phy_proto);
}
const vlist_proto = {
update: function(values, arg) {
let data = this.data;
@ -165,4 +315,4 @@ function vlist_new(cb) {
}, vlist_proto);
}
export { wdev_remove, wdev_create, is_equal, vlist_new, phy_is_fullmac };
export { wdev_remove, wdev_create, is_equal, vlist_new, phy_is_fullmac, phy_open };

View file

@ -632,8 +632,7 @@ hostapd_set_bss_options() {
[ -n "$wpa_strict_rekey" ] && append bss_conf "wpa_strict_rekey=$wpa_strict_rekey" "$N"
}
set_default nasid "${macaddr//\:}"
append bss_conf "nas_identifier=$nasid" "$N"
[ -n "$nasid" ] && append bss_conf "nas_identifier=$nasid" "$N"
[ -n "$acct_interval" ] && \
append bss_conf "radius_acct_interim_interval=$acct_interval" "$N"

View file

@ -1,6 +1,6 @@
let libubus = require("ubus");
import { open, readfile } from "fs";
import { wdev_create, wdev_remove, is_equal, vlist_new, phy_is_fullmac } from "common";
import { wdev_create, wdev_remove, is_equal, vlist_new, phy_is_fullmac, phy_open } from "common";
let ubus = libubus.connect();
@ -41,10 +41,13 @@ channel=${config.radio.channel}
for (let i = 0; i < length(config.bss); i++) {
let bss = config.bss[i];
let type = i > 0 ? "bss" : "interface";
let nasid = bss.nasid ?? replace(bss.bssid, ":", "");
str += `
${type}=${bss.ifname}
bssid=${bss.bssid}
${join("\n", bss.data)}
nas_identifier=${nasid}
`;
if (start_disabled)
str += `
@ -108,8 +111,22 @@ function iface_add(phy, config, phy_status)
return iface.start(freq_info) >= 0;
}
function iface_restart(phy, config, old_config)
function iface_config_macaddr_list(config)
{
let macaddr_list = {};
for (let i = 0; i < length(config.bss); i++) {
let bss = config.bss[i];
if (!bss.default_macaddr)
macaddr_list[bss.bssid] = i;
}
return macaddr_list;
}
function iface_restart(phydev, config, old_config)
{
let phy = phydev.name;
iface_remove(old_config);
iface_remove(config);
@ -118,6 +135,13 @@ function iface_restart(phy, config, old_config)
return;
}
phydev.macaddr_init(iface_config_macaddr_list(config));
for (let i = 0; i < length(config.bss); i++) {
let bss = config.bss[i];
if (bss.default_macaddr)
bss.bssid = phydev.macaddr_next();
}
let bss = config.bss[0];
let err = wdev_create(phy, bss.ifname, { mode: "ap" });
if (err)
@ -175,8 +199,64 @@ function bss_reload_psk(bss, config, old_config)
hostapd.printf(`Reload WPA PSK file for bss ${config.ifname}: ${ret}`);
}
function iface_reload_config(phy, config, old_config)
function remove_file_fields(config)
{
return filter(config, (line) => !hostapd.data.file_fields[split(line, "=")[0]]);
}
function bss_remove_file_fields(config)
{
let new_cfg = {};
for (let key in config)
new_cfg[key] = config[key];
new_cfg.data = remove_file_fields(new_cfg.data);
new_cfg.hash = {};
for (let key in config.hash)
new_cfg.hash[key] = config.hash[key];
delete new_cfg.hash.wpa_psk_file;
return new_cfg;
}
function bss_config_hash(config)
{
return hostapd.sha1(remove_file_fields(config) + "");
}
function bss_find_existing(config, prev_config, prev_hash)
{
let hash = bss_config_hash(config.data);
for (let i = 0; i < length(prev_config.bss); i++) {
if (!prev_hash[i] || hash != prev_hash[i])
continue;
prev_hash[i] = null;
return i;
}
return -1;
}
function get_config_bss(config, idx)
{
if (!config.bss[idx]) {
hostapd.printf(`Invalid bss index ${idx}`);
return null;
}
let ifname = config.bss[idx].ifname;
if (!ifname)
hostapd.printf(`Could not find bss ${config.bss[idx].ifname}`);
return hostapd.bss[ifname];
}
function iface_reload_config(phydev, config, old_config)
{
let phy = phydev.name;
if (!old_config || !is_equal(old_config.radio, config.radio))
return false;
@ -186,82 +266,231 @@ function iface_reload_config(phy, config, old_config)
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_name = old_config.bss[0].ifname;
let iface = hostapd.interfaces[iface_name];
if (!iface)
if (!iface) {
hostapd.printf(`Could not find previous interface ${iface_name}`);
return false;
}
let first_bss = hostapd.bss[iface_name];
if (!first_bss)
if (!first_bss) {
hostapd.printf(`Could not find bss of previous interface ${iface_name}`);
return false;
}
let macaddr_list = iface_config_macaddr_list(config);
let bss_list = [];
let bss_list_cfg = [];
let prev_bss_hash = [];
for (let bss in old_config.bss) {
let hash = bss_config_hash(bss.data);
push(prev_bss_hash, bss_config_hash(bss.data));
}
// Step 1: find (possibly renamed) interfaces with the same config
// and store them in the new order (with gaps)
for (let i = 0; i < length(config.bss); i++) {
let prev;
// For fullmac devices, the first interface needs to be preserved,
// since it's treated as the master
if (!i && phy_is_fullmac(phy)) {
prev = 0;
prev_bss_hash[0] = null;
} else {
prev = bss_find_existing(config.bss[i], old_config, prev_bss_hash);
}
if (prev < 0)
continue;
let cur_config = config.bss[i];
let prev_config = old_config.bss[prev];
let prev_bss = get_config_bss(old_config, prev);
if (!prev_bss)
return false;
// try to preserve MAC address of this BSS by reassigning another
// BSS if necessary
if (cur_config.default_macaddr &&
!macaddr_list[prev_config.bssid]) {
macaddr_list[prev_config.bssid] = i;
cur_config.bssid = prev_config.bssid;
}
bss_list[i] = prev_bss;
bss_list_cfg[i] = old_config.bss[prev];
}
if (config.mbssid && !bss_list_cfg[0]) {
hostapd.printf("First BSS changed with MBSSID enabled");
return false;
}
// Step 2: if none were found, rename and preserve the first one
if (length(bss_list) == 0) {
// can't change the bssid of the first bss
if (config.bss[0].bssid != old_config.bss[0].bssid) {
if (!config.bss[0].default_macaddr) {
hostapd.printf(`BSSID of first interface changed: ${lc(old_config.bss[0].bssid)} -> ${lc(config.bss[0].bssid)}`);
return false;
}
config.bss[0].bssid = old_config.bss[0].bssid;
}
let prev_bss = get_config_bss(old_config, 0);
if (!prev_bss)
return false;
macaddr_list[config.bss[0].bssid] = 0;
bss_list[0] = prev_bss;
bss_list_cfg[0] = old_config.bss[0];
prev_bss_hash[0] = null;
}
// Step 3: delete all unused old interfaces
for (let i = 0; i < length(prev_bss_hash); i++) {
if (!prev_bss_hash[i])
continue;
let prev_bss = get_config_bss(old_config, i);
if (!prev_bss)
return false;
let ifname = old_config.bss[i].ifname;
hostapd.printf(`Remove bss '${ifname}' on phy '${phy}'`);
prev_bss.delete();
wdev_remove(ifname);
}
// Step 4: rename preserved interfaces, use temporary name on duplicates
let rename_list = [];
for (let i = 0; i < length(bss_list); i++) {
if (!bss_list[i])
continue;
let old_ifname = bss_list_cfg[i].ifname;
let new_ifname = config.bss[i].ifname;
if (old_ifname == new_ifname)
continue;
if (hostapd.bss[new_ifname]) {
new_ifname = "tmp_" + substr(hostapd.sha1(new_ifname), 0, 8);
push(rename_list, i);
}
hostapd.printf(`Rename bss ${old_ifname} to ${new_ifname}`);
if (!bss_list[i].rename(new_ifname)) {
hostapd.printf(`Failed to rename bss ${old_ifname} to ${new_ifname}`);
return false;
}
bss_list_cfg[i].ifname = new_ifname;
}
// Step 5: rename interfaces with temporary names
for (let i in rename_list) {
let new_ifname = config.bss[i].ifname;
if (!bss_list[i].rename(new_ifname)) {
hostapd.printf(`Failed to rename bss to ${new_ifname}`);
return false;
}
bss_list_cfg[i].ifname = new_ifname;
}
// Step 6: assign BSSID for newly created interfaces
let macaddr_data = {
num_global: config.num_global_macaddr ?? 1,
mbssid: config.mbssid ?? 0,
};
macaddr_list = phydev.macaddr_init(macaddr_list, macaddr_data);
for (let i = 0; i < length(config.bss); i++) {
if (bss_list[i])
continue;
let bsscfg = config.bss[i];
let mac_idx = macaddr_list[bsscfg.bssid];
if (mac_idx < 0)
macaddr_list[bsscfg.bssid] = i;
if (mac_idx == i)
continue;
// statically assigned bssid of the new interface is in conflict
// with the bssid of a reused interface. reassign the reused interface
if (!bsscfg.default_macaddr) {
// can't update bssid of the first BSS, need to restart
if (!mac_idx < 0)
return false;
bsscfg = config.bss[mac_idx];
}
let addr = phydev.macaddr_next(i);
if (!addr) {
hostapd.printf(`Failed to generate mac address for phy ${phy}`);
return false;
}
bsscfg.bssid = addr;
}
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;
// Step 7: fill in the gaps with new interfaces
for (let i = 0; i < length(config.bss); i++) {
let ifname = config.bss[i].ifname;
let bss = bss_list[i];
if (config.bss[0].bssid != old_config.bss[0].bssid)
if (bss)
continue;
hostapd.printf(`Add bss ${ifname} on phy ${phy}`);
bss_list[i] = iface.add_bss(config_inline, i);
if (!bss_list[i]) {
hostapd.printf(`Failed to add new bss ${ifname} on phy ${phy}`);
return false;
}
}
// Step 8: update interface bss order
if (!iface.set_bss_order(bss_list)) {
hostapd.printf(`Failed to update BSS order on phy '${phy}'`);
return false;
}
// Step 9: update config
for (let i = 0; i < length(config.bss); i++) {
if (!bss_list_cfg[i])
continue;
let ifname = config.bss[i].ifname;
let bss = bss_list[i];
if (is_equal(config.bss[i], bss_list_cfg[i]))
continue;
if (is_equal(bss_remove_file_fields(config.bss[i]),
bss_remove_file_fields(bss_list_cfg[i]))) {
hostapd.printf(`Update config data files for bss ${ifname}`);
if (bss.set_config(config_inline, i, true) < 0) {
hostapd.printf(`Failed to update config data files for bss ${ifname}`);
return false;
}
bss.ctrl("RELOAD_WPA_PSK");
continue;
}
bss_reload_psk(bss, config.bss[i], bss_list_cfg[i]);
if (is_equal(config.bss[i], bss_list_cfg[i]))
continue;
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`);
hostapd.printf(`old: ${bss_remove_file_fields(bss_list_cfg[i])}`);
hostapd.printf(`new: ${bss_remove_file_fields(config.bss[i])}`);
if (bss.set_config(config_inline, i) < 0) {
hostapd.printf(`Failed to set config for bss ${ifname}`);
return false;
}
}
@ -269,6 +498,14 @@ function iface_reload_config(phy, config, old_config)
return true;
}
function iface_update_supplicant_macaddr(phy, config)
{
let macaddr_list = [];
for (let i = 0; i < length(config.bss); i++)
push(macaddr_list, config.bss[i].bssid);
ubus.call("wpa_supplicant", "phy_set_macaddr_list", { phy: phy, macaddr: macaddr_list });
}
function iface_set_config(phy, config)
{
let old_config = hostapd.data.config[phy];
@ -278,14 +515,28 @@ function iface_set_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;
let phydev = phy_open(phy);
if (!phydev) {
hostapd.printf(`Failed to open phy ${phy}`);
return false;
}
try {
let ret = iface_reload_config(phydev, config, old_config);
if (ret) {
iface_update_supplicant_macaddr(phy, config);
hostapd.printf(`Reloaded settings for phy ${phy}`);
return 0;
}
} catch (e) {
hostapd.printf(`Error reloading config: ${e}\n${e.stacktrace[0].context}`);
}
hostapd.printf(`Restart interface for phy ${phy}`);
return iface_restart(phy, config, old_config);
let ret = iface_restart(phydev, config, old_config);
iface_update_supplicant_macaddr(phy, config);
return ret;
}
function config_add_bss(config, name)
@ -332,16 +583,28 @@ function iface_load_config(filename)
continue;
}
if (val[0] == "#num_global_macaddr" ||
val[0] == "mbssid")
config[val[0]] = int(val[1]);
push(config.radio.data, line);
}
while ((line = trim(f.read("line"))) != null) {
if (line == "#default_macaddr")
bss.default_macaddr = true;
let val = split(line, "=", 2);
if (!val[0])
continue;
if (val[0] == "bssid")
bss.bssid = val[1];
if (val[0] == "bssid") {
bss.bssid = lc(val[1]);
continue;
}
if (val[0] == "nas_identifier")
bss.nasid = val[1];
if (val[0] == "bss") {
bss = config_add_bss(config, val[1]);
@ -358,27 +621,33 @@ function iface_load_config(filename)
return config;
}
function ex_wrap(func) {
return (req) => {
try {
let ret = func(req);
return ret;
} catch(e) {
hostapd.printf(`Exception in ubus function: ${e}\n${e.stacktrace[0].context}`);
}
return libubus.STATUS_UNKNOWN_ERROR;
};
}
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;
call: ex_wrap(function(req) {
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);
}
return 0;
}
})
},
apsta_state: {
args: {
@ -389,7 +658,7 @@ let main_obj = {
csa: true,
csa_count: 0,
},
call: function(req) {
call: ex_wrap(function(req) {
if (req.args.up == null || !req.args.phy)
return libubus.STATUS_INVALID_ARGUMENT;
@ -426,7 +695,28 @@ let main_obj = {
return libubus.STATUS_UNKNOWN_ERROR;
return 0;
}
})
},
config_get_macaddr_list: {
args: {
phy: ""
},
call: ex_wrap(function(req) {
let phy = req.args.phy;
if (!phy)
return libubus.STATUS_INVALID_ARGUMENT;
let ret = {
macaddr: [],
};
let config = hostapd.data.config[phy];
if (!config)
return ret;
ret.macaddr = map(config.bss, (bss) => bss.bssid);
return ret;
})
},
config_set: {
args: {
@ -434,7 +724,7 @@ let main_obj = {
config: "",
prev_config: "",
},
call: function(req) {
call: ex_wrap(function(req) {
let phy = req.args.phy;
let file = req.args.config;
let prev_file = req.args.prev_config;
@ -442,34 +732,29 @@ let main_obj = {
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;
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);
return {
pid: hostapd.getpid()
};
}
})
},
config_add: {
args: {
iface: "",
config: "",
},
call: function(req) {
call: ex_wrap(function(req) {
if (!req.args.iface || !req.args.config)
return libubus.STATUS_INVALID_ARGUMENT;
@ -479,19 +764,19 @@ let main_obj = {
return {
pid: hostapd.getpid()
};
}
})
},
config_remove: {
args: {
iface: ""
},
call: function(req) {
call: ex_wrap(function(req) {
if (!req.args.iface)
return libubus.STATUS_INVALID_ARGUMENT;
hostapd.remove_iface(req.args.iface);
return 0;
}
})
},
};

View file

@ -1,11 +1,14 @@
#!/usr/bin/env ucode
'use strict';
import { vlist_new, is_equal, wdev_create, wdev_remove } from "/usr/share/hostap/common.uc";
import { vlist_new, is_equal, wdev_create, wdev_remove, phy_open } from "/usr/share/hostap/common.uc";
import { readfile, writefile, basename, readlink, glob } from "fs";
let libubus = require("ubus");
let keep_devices = {};
let phy = shift(ARGV);
let new_config = shift(ARGV);
let command = shift(ARGV);
let phydev;
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",
@ -33,6 +36,11 @@ function iface_start(wdev)
system([ "ip", "link", "set", "dev", ifname, "down" ]);
wdev_remove(ifname);
}
let wdev_config = {};
for (let key in wdev)
wdev_config[key] = wdev[key];
if (!wdev_config.macaddr && wdev.mode != "monitor")
wdev_config.macaddr = phydev.macaddr_next();
wdev_create(phy, ifname, wdev);
system([ "ip", "link", "set", "dev", ifname, "up" ]);
if (wdev.freq)
@ -114,43 +122,86 @@ function add_existing(phy, config)
}
}
function usage()
{
warn(`Usage: ${basename(sourcepath())} <phy> <command> [<arguments>]
let statefile = `/var/run/wdev-${phy}.json`;
for (let dev in ARGV)
keep_devices[dev] = true;
if (!phy || !new_config) {
warn(`Usage: ${basename(sourcepath())} <phy> <config> [<device]...]\n`);
Commands:
set_config <config> [<device]...] - set phy configuration
get_macaddr <id> - get phy MAC address for vif index <id>
`);
exit(1);
}
if (!readfile(`/sys/class/ieee80211/${phy}/index`)) {
const commands = {
set_config: function(args) {
let statefile = `/var/run/wdev-${phy}.json`;
let new_config = shift(args);
for (let dev in ARGV)
keep_devices[dev] = true;
if (!new_config)
usage();
new_config = json(new_config);
if (!new_config) {
warn("Invalid configuration\n");
exit(1);
}
let old_config = readfile(statefile);
if (old_config)
old_config = json(old_config);
let config = vlist_new(iface_cb);
if (type(old_config) == "object")
config.data = old_config;
add_existing(phy, config.data);
add_ifname(config.data);
drop_inactive(config.data);
let ubus = libubus.connect();
let data = ubus.call("hostapd", "config_get_macaddr_list", { phy: phy });
let macaddr_list = [];
if (type(data) == "object" && data.macaddr)
macaddr_list = data.macaddr;
ubus.disconnect();
phydev.macaddr_init(macaddr_list);
add_ifname(new_config);
config.update(new_config);
drop_inactive(config.data);
delete_ifname(config.data);
writefile(statefile, sprintf("%J", config.data));
},
get_macaddr: function(args) {
let data = {};
for (let arg in args) {
arg = split(arg, "=", 2);
data[arg[0]] = arg[1];
}
let macaddr = phydev.macaddr_generate(data);
if (!macaddr) {
warn(`Could not get MAC address for phy ${phy}\n`);
exit(1);
}
print(macaddr + "\n");
},
};
if (!phy || !command | !commands[command])
usage();
phydev = phy_open(phy);
if (!phydev) {
warn(`PHY ${phy} does not exist\n`);
exit(1);
}
new_config = json(new_config);
if (!new_config) {
warn("Invalid configuration\n");
exit(1);
}
let old_config = readfile(statefile);
if (old_config)
old_config = json(old_config);
let config = vlist_new(iface_cb);
if (type(old_config) == "object")
config.data = old_config;
add_existing(phy, config.data);
add_ifname(config.data);
drop_inactive(config.data);
add_ifname(new_config);
config.update(new_config);
drop_inactive(config.data);
delete_ifname(config.data);
writefile(statefile, sprintf("%J", config.data));
commands[command](ARGV);

View file

@ -1,11 +1,12 @@
let libubus = require("ubus");
import { open, readfile } from "fs";
import { wdev_create, wdev_remove, is_equal, vlist_new } from "common";
import { wdev_create, wdev_remove, is_equal, vlist_new, phy_open } from "common";
let ubus = libubus.connect();
wpas.data.config = {};
wpas.data.iface_phy = {};
wpas.data.macaddr_list = {};
function iface_stop(iface)
{
@ -20,16 +21,23 @@ function iface_stop(iface)
iface.running = false;
}
function iface_start(phy, iface)
function iface_start(phydev, iface, macaddr_list)
{
let phy = phydev.name;
if (iface.running)
return;
let ifname = iface.config.iface;
let wdev_config = {};
for (let field in iface.config)
wdev_config[field] = iface.config[field];
if (!wdev_config.macaddr)
wdev_config.macaddr = phydev.macaddr_next();
wpas.data.iface_phy[ifname] = phy;
wdev_remove(ifname);
let ret = wdev_create(phy, ifname, iface.config);
let ret = wdev_create(phy, ifname, wdev_config);
if (ret)
wpas.printf(`Failed to create device ${ifname}: ${ret}`);
wpas.add_iface(iface.config);
@ -78,9 +86,22 @@ function set_config(phy_name, config_list)
function start_pending(phy_name)
{
let phy = wpas.data.config[phy_name];
let ubus = wpas.data.ubus;
if (!phy || !phy.data)
return;
let phydev = phy_open(phy_name);
if (!phydev) {
wpas.printf(`Could not open phy ${phy_name}`);
return;
}
let macaddr_list = wpas.data.macaddr_list[phy_name];
phydev.macaddr_init(macaddr_list);
for (let ifname in phy.data)
iface_start(phy_name, phy.data[ifname]);
iface_start(phydev, phy.data[ifname]);
}
let main_obj = {
@ -111,6 +132,20 @@ let main_obj = {
return 0;
}
},
phy_set_macaddr_list: {
args: {
phy: "",
macaddr: [],
},
call: function(req) {
let phy = req.args.phy;
if (!phy)
return libubus.STATUS_INVALID_ARGUMENT;
wpas.data.macaddr_list[phy] = req.args.macaddr;
return 0;
}
},
phy_status: {
args: {
phy: ""

View file

@ -29,7 +29,7 @@ Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
enum dfs_channel_type {
@@ -521,9 +522,14 @@ dfs_get_valid_channel(struct hostapd_ifa
@@ -526,9 +527,14 @@ dfs_get_valid_channel(struct hostapd_ifa
int num_available_chandefs;
int chan_idx, chan_idx2;
int sec_chan_idx_80p80 = -1;
@ -44,7 +44,7 @@ Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
wpa_printf(MSG_DEBUG, "DFS: Selecting random channel");
*secondary_channel = 0;
*oper_centr_freq_seg0_idx = 0;
@@ -543,8 +549,20 @@ dfs_get_valid_channel(struct hostapd_ifa
@@ -548,8 +554,20 @@ dfs_get_valid_channel(struct hostapd_ifa
if (num_available_chandefs == 0)
return NULL;
@ -68,7 +68,7 @@ Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
if (!chan) {
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -10977,6 +10977,10 @@ static int nl80211_switch_channel(void *
@@ -11017,6 +11017,10 @@ static int nl80211_switch_channel(void *
if (ret)
goto error;

View file

@ -1,6 +1,6 @@
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -4601,6 +4601,13 @@ static int add_associated_sta(struct hos
@@ -4621,6 +4621,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)",
@@ -4614,7 +4621,8 @@ static int add_associated_sta(struct hos
@@ -4634,7 +4641,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) &&

View file

@ -92,7 +92,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
wpa_printf(MSG_DEBUG,
@@ -11843,13 +11840,14 @@ static int wpa_driver_br_add_ip_neigh(vo
@@ -11883,13 +11880,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 <nbd@nbd.name>
int res;
if (!ipaddr || prefixlen == 0 || !addr)
@@ -11868,85 +11866,66 @@ static int wpa_driver_br_add_ip_neigh(vo
@@ -11908,85 +11906,66 @@ static int wpa_driver_br_add_ip_neigh(vo
}
if (version == 4) {
@ -220,7 +220,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
addrsize = 16;
} else {
return -EINVAL;
@@ -11964,41 +11943,30 @@ static int wpa_driver_br_delete_ip_neigh
@@ -12004,41 +11983,30 @@ static int wpa_driver_br_delete_ip_neigh
return -1;
}

View file

@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -3012,15 +3012,6 @@ static void handle_auth(struct hostapd_d
@@ -3020,15 +3020,6 @@ static void handle_auth(struct hostapd_d
seq_ctrl);
return;
}

View file

@ -903,7 +903,7 @@ Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
for exp, flags in tests:
hapd.disable()
hapd.set("tls_flags", flags)
@@ -7115,6 +7173,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde
@@ -7138,6 +7196,7 @@ def test_ap_wpa2_eap_assoc_rsn(dev, apde
def test_eap_tls_ext_cert_check(dev, apdev):
"""EAP-TLS and external server certification validation"""
# With internal server certificate chain validation
@ -911,7 +911,7 @@ Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TLS",
identity="tls user",
ca_cert="auth_serv/ca.pem",
@@ -7127,6 +7186,7 @@ def test_eap_tls_ext_cert_check(dev, apd
@@ -7150,6 +7209,7 @@ def test_eap_tls_ext_cert_check(dev, apd
def test_eap_ttls_ext_cert_check(dev, apdev):
"""EAP-TTLS and external server certification validation"""
# Without internal server certificate chain validation
@ -919,7 +919,7 @@ Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
identity="pap user", anonymous_identity="ttls",
password="password", phase2="auth=PAP",
@@ -7137,6 +7197,7 @@ def test_eap_ttls_ext_cert_check(dev, ap
@@ -7160,6 +7220,7 @@ def test_eap_ttls_ext_cert_check(dev, ap
def test_eap_peap_ext_cert_check(dev, apdev):
"""EAP-PEAP and external server certification validation"""
# With internal server certificate chain validation
@ -927,7 +927,7 @@ Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP",
identity="user", anonymous_identity="peap",
ca_cert="auth_serv/ca.pem",
@@ -7147,6 +7208,7 @@ def test_eap_peap_ext_cert_check(dev, ap
@@ -7170,6 +7231,7 @@ def test_eap_peap_ext_cert_check(dev, ap
def test_eap_fast_ext_cert_check(dev, apdev):
"""EAP-FAST and external server certification validation"""
@ -935,7 +935,7 @@ Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
check_eap_capa(dev[0], "FAST")
# With internal server certificate chain validation
dev[0].request("SET blob fast_pac_auth_ext ")
@@ -7161,10 +7223,6 @@ def test_eap_fast_ext_cert_check(dev, ap
@@ -7184,10 +7246,6 @@ def test_eap_fast_ext_cert_check(dev, ap
run_ext_cert_check(dev, apdev, id)
def run_ext_cert_check(dev, apdev, net_id):
@ -948,7 +948,7 @@ Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
--- a/tests/hwsim/test_ap_ft.py
+++ b/tests/hwsim/test_ap_ft.py
@@ -2471,11 +2471,11 @@ def test_ap_ft_ap_oom5(dev, apdev):
@@ -2474,11 +2474,11 @@ def test_ap_ft_ap_oom5(dev, apdev):
# This will fail to roam
dev[0].roam(bssid1, check_bssid=False)
@ -1138,7 +1138,7 @@ Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
heavy_groups = [14, 15, 16]
suitable_groups = [15, 16, 17, 18, 19, 20, 21]
groups = [str(g) for g in sae_groups]
@@ -2188,6 +2193,8 @@ def run_sae_pwe_group(dev, apdev, group)
@@ -2193,6 +2198,8 @@ def run_sae_pwe_group(dev, apdev, group)
logger.info("Add Brainpool EC groups since OpenSSL is new enough")
elif tls.startswith("wolfSSL"):
logger.info("Make sure Brainpool EC groups were enabled when compiling wolfSSL")

View file

@ -120,7 +120,7 @@ Signed-off-by: P Praneesh <ppranees@codeaurora.org>
* Convert 80+80 MHz channel width to new style as interop
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
@@ -808,6 +808,7 @@ int ieee80211ac_cap_check(u32 hw, u32 co
@@ -811,6 +811,7 @@ int ieee80211ac_cap_check(u32 hw, u32 co
VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB);
VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN);
VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN);
@ -130,7 +130,7 @@ Signed-off-by: P Praneesh <ppranees@codeaurora.org>
#undef VHT_CAP_CHECK_MAX
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -1348,6 +1348,8 @@ struct ieee80211_ampe_ie {
@@ -1349,6 +1349,8 @@ struct ieee80211_ampe_ie {
#define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB ((u32) BIT(26) | BIT(27))
#define VHT_CAP_RX_ANTENNA_PATTERN ((u32) BIT(28))
#define VHT_CAP_TX_ANTENNA_PATTERN ((u32) BIT(29))

View file

@ -1,103 +0,0 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Mon, 7 Aug 2023 21:55:57 +0200
Subject: [PATCH] BSS coloring: fix CCA with multiple BSS
Pass bss->ctx instead of drv->ctx in order to avoid multiple reports for
the first bss. The first report would otherwise clear hapd->cca_color and
subsequent reports would cause the iface bss color to be set to 0.
In order to avoid any issues with cancellations, only overwrite the color
based on hapd->cca_color if it was actually set.
Fixes: 33c4dd26cd11 ("BSS coloring: Handle the collision and CCA events coming from the kernel")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -2260,7 +2260,8 @@ void wpa_supplicant_event(void *ctx, enu
case EVENT_CCA_NOTIFY:
wpa_printf(MSG_DEBUG, "CCA finished on on %s",
hapd->conf->iface);
- hapd->iface->conf->he_op.he_bss_color = hapd->cca_color;
+ if (hapd->cca_color)
+ hapd->iface->conf->he_op.he_bss_color = hapd->cca_color;
hostapd_cleanup_cca_params(hapd);
break;
#endif /* CONFIG_IEEE80211AX */
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -3653,7 +3653,7 @@ static void nl80211_assoc_comeback(struc
#ifdef CONFIG_IEEE80211AX
-static void nl80211_obss_color_collision(struct wpa_driver_nl80211_data *drv,
+static void nl80211_obss_color_collision(struct i802_bss *bss,
struct nlattr *tb[])
{
union wpa_event_data data;
@@ -3667,37 +3667,37 @@ static void nl80211_obss_color_collision
wpa_printf(MSG_DEBUG, "nl80211: BSS color collision - bitmap %08llx",
(long long unsigned int) data.bss_color_collision.bitmap);
- wpa_supplicant_event(drv->ctx, EVENT_BSS_COLOR_COLLISION, &data);
+ wpa_supplicant_event(bss->ctx, EVENT_BSS_COLOR_COLLISION, &data);
}
static void
-nl80211_color_change_announcement_started(struct wpa_driver_nl80211_data *drv)
+nl80211_color_change_announcement_started(struct i802_bss *bss)
{
union wpa_event_data data = {};
wpa_printf(MSG_DEBUG, "nl80211: CCA started");
- wpa_supplicant_event(drv->ctx, EVENT_CCA_STARTED_NOTIFY, &data);
+ wpa_supplicant_event(bss->ctx, EVENT_CCA_STARTED_NOTIFY, &data);
}
static void
-nl80211_color_change_announcement_aborted(struct wpa_driver_nl80211_data *drv)
+nl80211_color_change_announcement_aborted(struct i802_bss *bss)
{
union wpa_event_data data = {};
wpa_printf(MSG_DEBUG, "nl80211: CCA aborted");
- wpa_supplicant_event(drv->ctx, EVENT_CCA_ABORTED_NOTIFY, &data);
+ wpa_supplicant_event(bss->ctx, EVENT_CCA_ABORTED_NOTIFY, &data);
}
static void
-nl80211_color_change_announcement_completed(struct wpa_driver_nl80211_data *drv)
+nl80211_color_change_announcement_completed(struct i802_bss *bss)
{
union wpa_event_data data = {};
wpa_printf(MSG_DEBUG, "nl80211: CCA completed");
- wpa_supplicant_event(drv->ctx, EVENT_CCA_NOTIFY, &data);
+ wpa_supplicant_event(bss->ctx, EVENT_CCA_NOTIFY, &data);
}
#endif /* CONFIG_IEEE80211AX */
@@ -3957,16 +3957,16 @@ static void do_process_drv_event(struct
break;
#ifdef CONFIG_IEEE80211AX
case NL80211_CMD_OBSS_COLOR_COLLISION:
- nl80211_obss_color_collision(drv, tb);
+ nl80211_obss_color_collision(bss, tb);
break;
case NL80211_CMD_COLOR_CHANGE_STARTED:
- nl80211_color_change_announcement_started(drv);
+ nl80211_color_change_announcement_started(bss);
break;
case NL80211_CMD_COLOR_CHANGE_ABORTED:
- nl80211_color_change_announcement_aborted(drv);
+ nl80211_color_change_announcement_aborted(bss);
break;
case NL80211_CMD_COLOR_CHANGE_COMPLETED:
- nl80211_color_change_announcement_completed(drv);
+ nl80211_color_change_announcement_completed(bss);
break;
#endif /* CONFIG_IEEE80211AX */
default:

View file

@ -156,7 +156,7 @@
wpa_cli.exe: wpa_cli
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -6651,8 +6651,8 @@ union wpa_event_data {
@@ -6667,8 +6667,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
@@ -6664,7 +6664,7 @@ void wpa_supplicant_event(void *ctx, enu
@@ -6680,7 +6680,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
@@ -1994,8 +1994,8 @@ err:
@@ -2184,8 +2184,8 @@ err:
#endif /* CONFIG_OWE */
@ -189,7 +189,7 @@
{
struct hostapd_data *hapd = ctx;
#ifndef CONFIG_NO_STDOUT_DEBUG
@@ -2272,7 +2272,7 @@ void wpa_supplicant_event(void *ctx, enu
@@ -2489,7 +2489,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
@@ -5345,8 +5345,8 @@ static void wpas_link_reconfig(struct wp
@@ -5353,8 +5353,8 @@ static void wpas_link_reconfig(struct wp
}
@ -242,7 +242,7 @@
{
struct wpa_supplicant *wpa_s = ctx;
int resched;
@@ -6264,7 +6264,7 @@ void wpa_supplicant_event(void *ctx, enu
@@ -6272,7 +6272,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
@@ -7435,7 +7435,6 @@ struct wpa_interface * wpa_supplicant_ma
@@ -7462,7 +7462,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()
@@ -7470,6 +7469,11 @@ static int wpa_supplicant_match_existing
@@ -7497,6 +7496,11 @@ static int wpa_supplicant_match_existing
#endif /* CONFIG_MATCH_IFACE */
@ -273,7 +273,7 @@
/**
* wpa_supplicant_add_iface - Add a new network interface
@@ -7726,6 +7730,8 @@ struct wpa_global * wpa_supplicant_init(
@@ -7753,6 +7757,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 */
@ -284,7 +284,7 @@
wpa_debug_open_file(params->wpa_debug_file_path);
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -685,6 +685,11 @@ fail:
@@ -698,6 +698,11 @@ fail:
return -1;
}
@ -296,7 +296,7 @@
#ifdef CONFIG_WPS
static int gen_uuid(const char *txt_addr)
@@ -778,6 +783,8 @@ int main(int argc, char *argv[])
@@ -791,6 +796,8 @@ int main(int argc, char *argv[])
return -1;
#endif /* CONFIG_DPP */

View file

@ -13,7 +13,7 @@
} else if (os_strcmp(buf, "ht_capab") == 0) {
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -1072,6 +1072,8 @@ struct hostapd_config {
@@ -1075,6 +1075,8 @@ struct hostapd_config {
int ht_op_mode_fixed;
u16 ht_capab;
@ -24,7 +24,7 @@
int no_pri_sec_switch;
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -517,7 +517,8 @@ static int ieee80211n_check_40mhz(struct
@@ -546,7 +546,8 @@ static int ieee80211n_check_40mhz(struct
int ret;
/* Check that HT40 is used and PRI / SEC switch is allowed */

View file

@ -1,6 +1,6 @@
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -5740,7 +5740,7 @@ wpa_supplicant_alloc(struct wpa_supplica
@@ -5767,7 +5767,7 @@ wpa_supplicant_alloc(struct wpa_supplica
if (wpa_s == NULL)
return NULL;
wpa_s->scan_req = INITIAL_SCAN_REQ;

View file

@ -51,7 +51,7 @@
if (wpa_s->ap_iface) {
pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
end - pos,
@@ -11964,6 +11964,7 @@ char * wpa_supplicant_ctrl_iface_process
@@ -12087,6 +12087,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) {
@@ -11976,6 +11977,7 @@ char * wpa_supplicant_ctrl_iface_process
@@ -12099,6 +12100,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);
@@ -12464,6 +12466,7 @@ char * wpa_supplicant_ctrl_iface_process
@@ -12587,6 +12589,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) {
@@ -12472,12 +12475,15 @@ char * wpa_supplicant_ctrl_iface_process
@@ -12595,12 +12598,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);

View file

@ -1,6 +1,6 @@
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -2719,6 +2719,31 @@ u32 wpa_akm_to_suite(int akm)
@@ -2841,6 +2841,31 @@ u32 wpa_akm_to_suite(int akm)
}
@ -32,7 +32,7 @@
int wpa_compare_rsn_ie(int ft_initial_assoc,
const u8 *ie1, size_t ie1len,
const u8 *ie2, size_t ie2len)
@@ -2726,8 +2751,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
@@ -2848,8 +2873,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
if (ie1 == NULL || ie2 == NULL)
return -1;

View file

@ -9,7 +9,7 @@
struct hapd_global {
void **drv_priv;
@@ -786,7 +786,7 @@ int main(int argc, char *argv[])
@@ -799,7 +799,7 @@ int main(int argc, char *argv[])
wpa_supplicant_event = hostapd_wpa_event;
wpa_supplicant_event_global = hostapd_wpa_event_global;
for (;;) {
@ -18,7 +18,7 @@
if (c < 0)
break;
switch (c) {
@@ -823,6 +823,8 @@ int main(int argc, char *argv[])
@@ -836,6 +836,8 @@ int main(int argc, char *argv[])
break;
#endif /* CONFIG_DEBUG_LINUX_TRACING */
case 'v':

View file

@ -174,7 +174,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
* macsec_policy - Determines the policy for MACsec secure session
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -4149,6 +4149,12 @@ static void wpas_start_assoc_cb(struct w
@@ -4175,6 +4175,12 @@ static void wpas_start_assoc_cb(struct w
params.beacon_int = ssid->beacon_int;
else
params.beacon_int = wpa_s->conf->beacon_int;

View file

@ -29,7 +29,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
struct wpa_driver_set_key_params {
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -11626,6 +11626,18 @@ static int nl80211_put_mesh_id(struct nl
@@ -11666,6 +11666,18 @@ static int nl80211_put_mesh_id(struct nl
}
@ -48,7 +48,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
static int nl80211_put_mesh_config(struct nl_msg *msg,
struct wpa_driver_mesh_bss_params *params)
{
@@ -11687,6 +11699,7 @@ static int nl80211_join_mesh(struct i802
@@ -11727,6 +11739,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) ||

View file

@ -84,7 +84,7 @@
__func__, driver, drv_priv);
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2778,7 +2778,7 @@ static void handle_auth(struct hostapd_d
@@ -2786,7 +2786,7 @@ static void handle_auth(struct hostapd_d
u16 auth_alg, auth_transaction, status_code;
u16 resp = WLAN_STATUS_SUCCESS;
struct sta_info *sta = NULL;
@ -93,7 +93,7 @@
u16 fc;
const u8 *challenge = NULL;
u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
@@ -2787,6 +2787,11 @@ static void handle_auth(struct hostapd_d
@@ -2795,6 +2795,11 @@ static void handle_auth(struct hostapd_d
struct radius_sta rad_info;
const u8 *dst, *sa, *bssid;
bool mld_sta = false;
@ -105,7 +105,7 @@
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
@@ -2978,6 +2983,13 @@ static void handle_auth(struct hostapd_d
@@ -2986,6 +2991,13 @@ static void handle_auth(struct hostapd_d
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail;
}
@ -119,7 +119,7 @@
if (res == HOSTAPD_ACL_PENDING)
return;
@@ -5141,7 +5153,7 @@ static void handle_assoc(struct hostapd_
@@ -5161,7 +5173,7 @@ static void handle_assoc(struct hostapd_
int resp = WLAN_STATUS_SUCCESS;
u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
const u8 *pos;
@ -128,7 +128,7 @@
struct sta_info *sta;
u8 *tmp = NULL;
#ifdef CONFIG_FILS
@@ -5354,6 +5366,11 @@ static void handle_assoc(struct hostapd_
@@ -5374,6 +5386,11 @@ static void handle_assoc(struct hostapd_
left = res;
}
#endif /* CONFIG_FILS */
@ -140,7 +140,7 @@
/* followed by SSID and Supported rates; and HT capabilities if 802.11n
* is used */
@@ -5452,6 +5469,13 @@ static void handle_assoc(struct hostapd_
@@ -5472,6 +5489,13 @@ static void handle_assoc(struct hostapd_
}
#endif /* CONFIG_FILS */
@ -154,7 +154,7 @@
fail:
/*
@@ -5733,6 +5757,7 @@ static void handle_disassoc(struct hosta
@@ -5753,6 +5777,7 @@ static void handle_disassoc(struct hosta
(unsigned long) len);
return;
}
@ -162,7 +162,7 @@
sta = ap_get_sta(hapd, mgmt->sa);
if (!sta) {
@@ -5764,6 +5789,8 @@ static void handle_deauth(struct hostapd
@@ -5784,6 +5809,8 @@ static void handle_deauth(struct hostapd
/* Clear the PTKSA cache entries for PASN */
ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE);
@ -201,7 +201,7 @@
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -145,6 +145,10 @@ int hostapd_notif_assoc(struct hostapd_d
@@ -260,6 +260,10 @@ int hostapd_notif_assoc(struct hostapd_d
u16 reason = WLAN_REASON_UNSPECIFIED;
int status = WLAN_STATUS_SUCCESS;
const u8 *p2p_dev_addr = NULL;
@ -212,7 +212,7 @@
if (addr == NULL) {
/*
@@ -237,6 +241,12 @@ int hostapd_notif_assoc(struct hostapd_d
@@ -396,6 +400,12 @@ int hostapd_notif_assoc(struct hostapd_d
goto fail;
}
@ -348,7 +348,7 @@
CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -7566,6 +7566,8 @@ struct wpa_supplicant * wpa_supplicant_a
@@ -7593,6 +7593,8 @@ struct wpa_supplicant * wpa_supplicant_a
}
#endif /* CONFIG_P2P */
@ -357,7 +357,7 @@
return wpa_s;
}
@@ -7592,6 +7594,8 @@ int wpa_supplicant_remove_iface(struct w
@@ -7619,6 +7621,8 @@ int wpa_supplicant_remove_iface(struct w
struct wpa_supplicant *parent = wpa_s->parent;
#endif /* CONFIG_MESH */
@ -366,7 +366,7 @@
/* Remove interface from the global list of interfaces */
prev = global->ifaces;
if (prev == wpa_s) {
@@ -7938,8 +7942,12 @@ int wpa_supplicant_run(struct wpa_global
@@ -7965,8 +7969,12 @@ int wpa_supplicant_run(struct wpa_global
eloop_register_signal_terminate(wpa_supplicant_terminate, global);
eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
@ -398,7 +398,7 @@
};
@@ -650,6 +653,7 @@ struct wpa_supplicant {
@@ -685,6 +688,7 @@ struct wpa_supplicant {
unsigned char own_addr[ETH_ALEN];
unsigned char perm_addr[ETH_ALEN];
char ifname[100];
@ -508,7 +508,7 @@
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -1211,6 +1211,8 @@ int hostapd_dfs_pre_cac_expired(struct h
@@ -1216,6 +1216,8 @@ int hostapd_dfs_pre_cac_expired(struct h
"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
freq, ht_enabled, chan_offset, chan_width, cf1, cf2);

View file

@ -26,7 +26,7 @@
ifdef CONFIG_CODE_COVERAGE
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -994,6 +994,7 @@ int main(int argc, char *argv[])
@@ -1007,6 +1007,7 @@ int main(int argc, char *argv[])
}
hostapd_global_ctrl_iface_init(&interfaces);
@ -34,7 +34,7 @@
if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
wpa_printf(MSG_ERROR, "Failed to start eloop");
@@ -1003,6 +1004,7 @@ int main(int argc, char *argv[])
@@ -1016,6 +1017,7 @@ int main(int argc, char *argv[])
ret = 0;
out:
@ -186,7 +186,7 @@
#ifdef CONFIG_BGSCAN
if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid)
@@ -7567,6 +7568,7 @@ struct wpa_supplicant * wpa_supplicant_a
@@ -7594,6 +7595,7 @@ struct wpa_supplicant * wpa_supplicant_a
#endif /* CONFIG_P2P */
wpas_ubus_add_bss(wpa_s);
@ -194,7 +194,7 @@
return wpa_s;
}
@@ -7594,6 +7596,7 @@ int wpa_supplicant_remove_iface(struct w
@@ -7621,6 +7623,7 @@ int wpa_supplicant_remove_iface(struct w
struct wpa_supplicant *parent = wpa_s->parent;
#endif /* CONFIG_MESH */
@ -202,7 +202,7 @@
wpas_ubus_free_bss(wpa_s);
/* Remove interface from the global list of interfaces */
@@ -7904,6 +7907,7 @@ struct wpa_global * wpa_supplicant_init(
@@ -7931,6 +7934,7 @@ struct wpa_global * wpa_supplicant_init(
eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
wpas_periodic, global, NULL);
@ -210,7 +210,7 @@
return global;
}
@@ -7942,12 +7946,8 @@ int wpa_supplicant_run(struct wpa_global
@@ -7969,12 +7973,8 @@ int wpa_supplicant_run(struct wpa_global
eloop_register_signal_terminate(wpa_supplicant_terminate, global);
eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
@ -223,7 +223,7 @@
return 0;
}
@@ -7980,6 +7980,8 @@ void wpa_supplicant_deinit(struct wpa_gl
@@ -8007,6 +8007,8 @@ void wpa_supplicant_deinit(struct wpa_gl
wpas_notify_supplicant_deinitialized(global);
@ -242,7 +242,7 @@
extern const char *const wpa_supplicant_version;
extern const char *const wpa_supplicant_license;
@@ -654,6 +655,7 @@ struct wpa_supplicant {
@@ -689,6 +690,7 @@ struct wpa_supplicant {
unsigned char perm_addr[ETH_ALEN];
char ifname[100];
struct wpas_ubus_bss ubus;
@ -270,7 +270,33 @@
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -6426,6 +6426,7 @@ union wpa_event_data {
@@ -3787,6 +3787,25 @@ struct wpa_driver_ops {
const char *ifname);
/**
+ * if_rename - Rename a virtual interface
+ * @priv: Private driver interface data
+ * @type: Interface type
+ * @ifname: Interface name of the virtual interface to be renamed
+ * (NULL when renaming the AP BSS interface)
+ * @new_name: New interface name of the virtual interface
+ * Returns: 0 on success, -1 on failure
+ */
+ int (*if_rename)(void *priv, enum wpa_driver_if_type type,
+ const char *ifname, const char *new_name);
+
+ /**
+ * set_first_bss - Make a virtual interface the first (primary) bss
+ * @priv: Private driver interface data
+ * Returns: 0 on success, -1 on failure
+ */
+ int (*set_first_bss)(void *priv);
+
+ /**
* set_sta_vlan - Bind a station into a specific interface (AP only)
* @priv: Private driver interface data
* @ifname: Interface (main or virtual BSS or VLAN)
@@ -6440,6 +6459,7 @@ union wpa_event_data {
/**
* struct ch_switch
@ -278,7 +304,7 @@
* @freq: Frequency of new channel in MHz
* @ht_enabled: Whether this is an HT channel
* @ch_offset: Secondary channel offset
@@ -6436,6 +6437,7 @@ union wpa_event_data {
@@ -6450,6 +6470,7 @@ union wpa_event_data {
* @punct_bitmap: Puncturing bitmap
*/
struct ch_switch {
@ -305,7 +331,7 @@
if (finished)
bss->flink->freq = data.ch_switch.freq;
@@ -3848,6 +3851,7 @@ static void do_process_drv_event(struct
@@ -3912,6 +3915,7 @@ static void do_process_drv_event(struct
tb[NL80211_ATTR_CENTER_FREQ1],
tb[NL80211_ATTR_CENTER_FREQ2],
tb[NL80211_ATTR_PUNCT_BITMAP],
@ -313,7 +339,7 @@
0);
break;
case NL80211_CMD_CH_SWITCH_NOTIFY:
@@ -3860,6 +3864,7 @@ static void do_process_drv_event(struct
@@ -3924,6 +3928,7 @@ static void do_process_drv_event(struct
tb[NL80211_ATTR_CENTER_FREQ1],
tb[NL80211_ATTR_CENTER_FREQ2],
tb[NL80211_ATTR_PUNCT_BITMAP],
@ -323,7 +349,7 @@
case NL80211_CMD_DISCONNECT:
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -5381,6 +5381,7 @@ void supplicant_event(void *ctx, enum wp
@@ -5389,6 +5389,7 @@ void supplicant_event(void *ctx, enum wp
event_to_string(event), event);
#endif /* CONFIG_NO_STDOUT_DEBUG */
@ -331,3 +357,187 @@
switch (event) {
case EVENT_AUTH:
#ifdef CONFIG_FST
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -393,6 +393,23 @@ static inline int hostapd_drv_stop_ap(st
return hapd->driver->stop_ap(hapd->drv_priv);
}
+static inline int hostapd_drv_if_rename(struct hostapd_data *hapd,
+ enum wpa_driver_if_type type,
+ const char *ifname,
+ const char *new_name)
+{
+ if (!hapd->driver || !hapd->driver->if_rename || !hapd->drv_priv)
+ return -1;
+ return hapd->driver->if_rename(hapd->drv_priv, type, ifname, new_name);
+}
+
+static inline int hostapd_drv_set_first_bss(struct hostapd_data *hapd)
+{
+ if (!hapd->driver || !hapd->driver->set_first_bss || !hapd->drv_priv)
+ return 0;
+ return hapd->driver->set_first_bss(hapd->drv_priv);
+}
+
static inline int hostapd_drv_channel_info(struct hostapd_data *hapd,
struct wpa_channel_info *ci)
{
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1333,7 +1333,7 @@ static void wpa_driver_nl80211_event_rtm
}
wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
namebuf, ifname);
- if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
+ if (drv->first_bss->ifindex != ifi->ifi_index) {
wpa_printf(MSG_DEBUG,
"nl80211: Not the main interface (%s) - do not indicate interface down",
drv->first_bss->ifname);
@@ -1369,7 +1369,7 @@ static void wpa_driver_nl80211_event_rtm
}
wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
namebuf, ifname);
- if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
+ if (drv->first_bss->ifindex != ifi->ifi_index) {
wpa_printf(MSG_DEBUG,
"nl80211: Not the main interface (%s) - do not indicate interface up",
drv->first_bss->ifname);
@@ -8432,6 +8432,7 @@ static void *i802_init(struct hostapd_da
char master_ifname[IFNAMSIZ];
int ifindex, br_ifindex = 0;
int br_added = 0;
+ int err;
bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
params->global_priv, 1,
@@ -8491,21 +8492,17 @@ static void *i802_init(struct hostapd_da
(params->num_bridge == 0 || !params->bridge[0]))
add_ifidx(drv, br_ifindex, drv->ifindex);
- if (bss->added_if_into_bridge || bss->already_in_bridge) {
- int err;
-
- drv->rtnl_sk = nl_socket_alloc();
- if (drv->rtnl_sk == NULL) {
- wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
- goto failed;
- }
+ drv->rtnl_sk = nl_socket_alloc();
+ if (drv->rtnl_sk == NULL) {
+ wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
+ goto failed;
+ }
- err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
- if (err) {
- wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
- nl_geterror(err));
- goto failed;
- }
+ err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
+ if (err) {
+ wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
+ nl_geterror(err));
+ goto failed;
}
if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
@@ -8874,6 +8871,50 @@ static int wpa_driver_nl80211_if_remove(
return 0;
}
+static int wpa_driver_nl80211_if_rename(struct i802_bss *bss,
+ enum wpa_driver_if_type type,
+ const char *ifname, const char *new_name)
+{
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ struct ifinfomsg ifi = {
+ .ifi_family = AF_UNSPEC,
+ .ifi_index = bss->ifindex,
+ };
+ struct nl_msg *msg;
+ int res = -ENOMEM;
+
+ if (ifname)
+ ifi.ifi_index = if_nametoindex(ifname);
+
+ msg = nlmsg_alloc_simple(RTM_SETLINK, 0);
+ if (!msg)
+ return res;
+
+ if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
+ goto out;
+
+ if (nla_put_string(msg, IFLA_IFNAME, new_name))
+ goto out;
+
+ res = nl_send_auto_complete(drv->rtnl_sk, msg);
+ if (res < 0)
+ goto out;
+
+ res = nl_wait_for_ack(drv->rtnl_sk);
+ if (res) {
+ wpa_printf(MSG_INFO,
+ "nl80211: Renaming device %s to %s failed: %s",
+ ifname ? ifname : bss->ifname, new_name, nl_geterror(res));
+ goto out;
+ }
+
+ if (type == WPA_IF_AP_BSS && !ifname)
+ os_strlcpy(bss->ifname, new_name, sizeof(bss->ifname));
+
+out:
+ nlmsg_free(msg);
+ return res;
+}
static int cookie_handler(struct nl_msg *msg, void *arg)
{
@@ -10512,6 +10553,37 @@ static int driver_nl80211_if_remove(void
}
+static int driver_nl80211_if_rename(void *priv, enum wpa_driver_if_type type,
+ const char *ifname, const char *new_name)
+{
+ struct i802_bss *bss = priv;
+ return wpa_driver_nl80211_if_rename(bss, type, ifname, new_name);
+}
+
+
+static int driver_nl80211_set_first_bss(void *priv)
+{
+ struct i802_bss *bss = priv, *tbss;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+
+ if (drv->first_bss == bss)
+ return 0;
+
+ for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
+ if (tbss->next != bss)
+ continue;
+
+ tbss->next = bss->next;
+ bss->next = drv->first_bss;
+ drv->first_bss = bss;
+ drv->ctx = bss->ctx;
+ return 0;
+ }
+
+ return -1;
+}
+
+
static int driver_nl80211_send_mlme(void *priv, const u8 *data,
size_t data_len, int noack,
unsigned int freq,
@@ -13696,6 +13768,8 @@ const struct wpa_driver_ops wpa_driver_n
.set_acl = wpa_driver_nl80211_set_acl,
.if_add = wpa_driver_nl80211_if_add,
.if_remove = driver_nl80211_if_remove,
+ .if_rename = driver_nl80211_if_rename,
+ .set_first_bss = driver_nl80211_set_first_bss,
.send_mlme = driver_nl80211_send_mlme,
.get_hw_feature_data = nl80211_get_hw_feature_data,
.sta_add = wpa_driver_nl80211_sta_add,

View file

@ -1,6 +1,6 @@
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -4810,7 +4810,12 @@ struct hostapd_config * hostapd_config_r
@@ -4816,7 +4816,12 @@ struct hostapd_config * hostapd_config_r
int errors = 0;
size_t i;

View file

@ -70,7 +70,7 @@
" since no room for additional STA",
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -1036,6 +1036,8 @@ struct hostapd_config {
@@ -1039,6 +1039,8 @@ struct hostapd_config {
unsigned int track_sta_max_num;
unsigned int track_sta_max_age;

View file

@ -104,7 +104,7 @@
static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd,
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -4206,7 +4206,7 @@ struct wpa_driver_ops {
@@ -4209,7 +4209,7 @@ struct wpa_driver_ops {
* Returns: 0 on success, negative (<0) on failure
*/
int (*br_set_net_param)(void *priv, enum drv_br_net_param param,
@ -115,7 +115,7 @@
* get_wowlan - Get wake-on-wireless status
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -12127,7 +12127,7 @@ static const char * drv_br_net_param_str
@@ -12167,7 +12167,7 @@ static const char * drv_br_net_param_str
static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param,
@ -124,7 +124,7 @@
{
struct i802_bss *bss = priv;
char path[128];
@@ -12153,8 +12153,11 @@ static int wpa_driver_br_set_net_param(v
@@ -12193,8 +12193,11 @@ static int wpa_driver_br_set_net_param(v
return -EINVAL;
}

View file

@ -21,7 +21,7 @@
#ifndef CONFIG_NO_HOSTAPD_LOGGER
static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
@@ -758,6 +759,11 @@ int main(int argc, char *argv[])
@@ -771,6 +772,11 @@ int main(int argc, char *argv[])
if (os_program_init())
return -1;

View file

@ -13,7 +13,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -12640,7 +12640,7 @@ char * wpa_supplicant_ctrl_iface_process
@@ -12763,7 +12763,7 @@ char * wpa_supplicant_ctrl_iface_process
if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18))
reply_len = -1;
#endif /* CONFIG_WNM */
@ -22,7 +22,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
} else if (os_strncmp(buf, "DISASSOC_IMMINENT ", 18) == 0) {
if (ap_ctrl_iface_disassoc_imminent(wpa_s, buf + 18))
reply_len = -1;
@@ -12650,7 +12650,7 @@ char * wpa_supplicant_ctrl_iface_process
@@ -12773,7 +12773,7 @@ char * wpa_supplicant_ctrl_iface_process
} else if (os_strncmp(buf, "BSS_TM_REQ ", 11) == 0) {
if (ap_ctrl_iface_bss_tm_req(wpa_s, buf + 11))
reply_len = -1;

View file

@ -8,6 +8,7 @@
#include "hw_features.h"
#include "ap_drv_ops.h"
#include "dfs.h"
#include "acs.h"
#include <libubox/uloop.h>
static uc_resource_type_t *global_type, *bss_type, *iface_type;
@ -119,6 +120,7 @@ uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs)
struct hostapd_config *conf;
uc_value_t *file = uc_fn_arg(0);
uc_value_t *index = uc_fn_arg(1);
uc_value_t *files_only = uc_fn_arg(2);
unsigned int i, idx = 0;
int ret = -1;
@ -130,9 +132,27 @@ uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs)
iface = hapd->iface;
conf = interfaces->config_read_cb(ucv_string_get(file));
if (!conf || idx > conf->num_bss || !conf->bss[idx])
if (!conf)
goto out;
if (idx > conf->num_bss || !conf->bss[idx])
goto free;
if (ucv_boolean_get(files_only)) {
struct hostapd_bss_config *bss = conf->bss[idx];
struct hostapd_bss_config *old_bss = hapd->conf;
#define swap_field(name) \
do { \
void *ptr = old_bss->name; \
old_bss->name = bss->name; \
bss->name = ptr; \
} while (0)
swap_field(ssid.wpa_psk_file);
goto done;
}
hostapd_bss_deinit_no_free(hapd);
hostapd_drv_stop_ap(hapd);
hostapd_free_hapd_data(hapd);
@ -143,12 +163,14 @@ uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs)
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->mbssid);
hostapd_setup_bss(hapd, hapd == iface->bss[0], true);
hostapd_ucode_update_interfaces();
done:
ret = 0;
free:
hostapd_config_free(conf);
out:
return ucv_int64_new(ret);
}
@ -179,10 +201,15 @@ uc_hostapd_bss_delete(uc_vm_t *vm, size_t nargs)
struct hostapd_iface *iface;
int i, idx;
if (!hapd || hapd == hapd->iface->bss[0])
if (!hapd)
return NULL;
iface = hapd->iface;
if (iface->num_bss == 1) {
wpa_printf(MSG_ERROR, "trying to delete last bss of an iface: %s\n", hapd->conf->iface);
return NULL;
}
for (idx = 0; idx < iface->num_bss; idx++)
if (iface->bss[idx] == hapd)
break;
@ -192,8 +219,13 @@ uc_hostapd_bss_delete(uc_vm_t *vm, size_t nargs)
for (i = idx + 1; i < iface->num_bss; i++)
iface->bss[i - 1] = iface->bss[i];
iface->num_bss--;
iface->bss[0]->interface_added = 0;
hostapd_drv_set_first_bss(iface->bss[0]);
hapd->interface_added = 1;
hostapd_drv_stop_ap(hapd);
hostapd_bss_deinit(hapd);
hostapd_remove_iface_bss_conf(iface->conf, hapd->conf);
@ -267,6 +299,58 @@ out:
return ret;
}
static uc_value_t *
uc_hostapd_iface_set_bss_order(uc_vm_t *vm, size_t nargs)
{
struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
uc_value_t *bss_list = uc_fn_arg(0);
struct hostapd_data **new_bss;
struct hostapd_bss_config **new_conf;
if (!iface)
return NULL;
if (ucv_type(bss_list) != UC_ARRAY ||
ucv_array_length(bss_list) != iface->num_bss)
return NULL;
new_bss = calloc(iface->num_bss, sizeof(*new_bss));
new_conf = calloc(iface->num_bss, sizeof(*new_conf));
for (size_t i = 0; i < iface->num_bss; i++) {
struct hostapd_data *bss;
bss = ucv_resource_data(ucv_array_get(bss_list, i), "hostapd.bss");
if (bss->iface != iface)
goto free;
for (size_t k = 0; k < i; k++)
if (new_bss[k] == bss)
goto free;
new_bss[i] = bss;
new_conf[i] = bss->conf;
}
new_bss[0]->interface_added = 0;
for (size_t i = 1; i < iface->num_bss; i++)
new_bss[i]->interface_added = 1;
free(iface->bss);
iface->bss = new_bss;
free(iface->conf->bss);
iface->conf->bss = new_conf;
iface->conf->num_bss = iface->num_bss;
hostapd_drv_set_first_bss(iface->bss[0]);
return ucv_boolean_new(true);
free:
free(new_bss);
free(new_conf);
return NULL;
}
static uc_value_t *
uc_hostapd_bss_ctrl(uc_vm_t *vm, size_t nargs)
{
@ -298,6 +382,14 @@ uc_hostapd_iface_stop(uc_vm_t *vm, size_t nargs)
struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface");
int i;
#ifdef CONFIG_ACS
if (iface->state == HAPD_IFACE_ACS) {
acs_cleanup(iface);
iface->scan_cb = NULL;
hostapd_disable_iface(iface);
}
#endif
for (i = 0; i < iface->num_bss; i++) {
struct hostapd_data *hapd = iface->bss[i];
@ -318,6 +410,7 @@ uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs)
if (!iface)
return NULL;
iface->freq = 0;
if (!info)
goto out;
@ -346,13 +439,30 @@ uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs)
if (!errno)
hostapd_set_oper_chwidth(conf, intval);
intval = ucv_int64_get(ucv_object_get(info, "frequency", NULL));
if (!errno)
iface->freq = intval;
conf->acs = 0;
out:
if (conf->channel)
switch (iface->state) {
case HAPD_IFACE_DISABLED:
break;
case HAPD_IFACE_ENABLED:
if (!hostapd_is_dfs_required(iface) ||
hostapd_is_dfs_chan_available(iface))
break;
wpa_printf(MSG_INFO, "DFS CAC required on new channel, restart interface");
/* fallthrough */
default:
hostapd_disable_iface(iface);
break;
}
if (conf->channel && !iface->freq)
iface->freq = hostapd_hw_get_freq(iface->bss[0], conf->channel);
if (hostapd_is_dfs_required(iface) && !hostapd_is_dfs_chan_available(iface)) {
wpa_printf(MSG_INFO, "DFS CAC required on new channel, restart interface");
hostapd_disable_iface(iface);
if (iface->state != HAPD_IFACE_ENABLED) {
hostapd_enable_iface(iface);
return ucv_boolean_new(true);
}
@ -428,6 +538,55 @@ uc_hostapd_iface_switch_channel(uc_vm_t *vm, size_t nargs)
return ucv_boolean_new(!ret);
}
static uc_value_t *
uc_hostapd_bss_rename(uc_vm_t *vm, size_t nargs)
{
struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss");
uc_value_t *ifname_arg = uc_fn_arg(0);
char prev_ifname[IFNAMSIZ + 1];
struct sta_info *sta;
const char *ifname;
int ret;
if (!hapd || ucv_type(ifname_arg) != UC_STRING)
return NULL;
os_strlcpy(prev_ifname, hapd->conf->iface, sizeof(prev_ifname));
ifname = ucv_string_get(ifname_arg);
hostapd_ubus_free_bss(hapd);
if (interfaces->ctrl_iface_deinit)
interfaces->ctrl_iface_deinit(hapd);
ret = hostapd_drv_if_rename(hapd, WPA_IF_AP_BSS, NULL, ifname);
if (ret)
goto out;
for (sta = hapd->sta_list; sta; sta = sta->next) {
char cur_name[IFNAMSIZ + 1], new_name[IFNAMSIZ + 1];
if (!(sta->flags & WLAN_STA_WDS) || sta->pending_wds_enable)
continue;
snprintf(cur_name, sizeof(cur_name), "%s.sta%d", prev_ifname, sta->aid);
snprintf(new_name, sizeof(new_name), "%s.sta%d", ifname, sta->aid);
hostapd_drv_if_rename(hapd, WPA_IF_AP_VLAN, cur_name, new_name);
}
if (!strncmp(hapd->conf->ssid.vlan, hapd->conf->iface, sizeof(hapd->conf->ssid.vlan)))
os_strlcpy(hapd->conf->ssid.vlan, ifname, sizeof(hapd->conf->ssid.vlan));
os_strlcpy(hapd->conf->iface, ifname, sizeof(hapd->conf->iface));
hostapd_ubus_add_bss(hapd);
hostapd_ucode_update_interfaces();
out:
if (interfaces->ctrl_iface_init)
interfaces->ctrl_iface_init(hapd);
return ret ? NULL : ucv_boolean_new(true);
}
int hostapd_ucode_init(struct hapd_interfaces *ifaces)
{
static const uc_function_list_t global_fns[] = {
@ -441,9 +600,11 @@ int hostapd_ucode_init(struct hapd_interfaces *ifaces)
static const uc_function_list_t bss_fns[] = {
{ "ctrl", uc_hostapd_bss_ctrl },
{ "set_config", uc_hostapd_bss_set_config },
{ "rename", uc_hostapd_bss_rename },
{ "delete", uc_hostapd_bss_delete },
};
static const uc_function_list_t iface_fns[] = {
{ "set_bss_order", uc_hostapd_iface_set_bss_order },
{ "add_bss", uc_hostapd_iface_add_bss },
{ "stop", uc_hostapd_iface_stop },
{ "start", uc_hostapd_iface_start },