Merge branch 'openwrt:master' into master
This commit is contained in:
commit
3685fe2e5d
32 changed files with 1180 additions and 393 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, ¶ms);
|
||||
- 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);
|
|
@ -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
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
})
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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: ""
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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:
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) ||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 },
|
||||
|
|
Loading…
Reference in a new issue