mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2026-03-14 23:09:45 +01:00
hostapd: add support for MLO interfaces in ucode
MLO interface config is provided in a separate ubus call before adding regular per-phy interfaces. Preparation for full MLO support. Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
be2916b1d4
commit
816c2d86e7
12 changed files with 520 additions and 51 deletions
|
|
@ -315,7 +315,7 @@ const phy_proto = {
|
||||||
if (wdev.iftype == nl80211.const.NL80211_IFTYPE_AP_VLAN)
|
if (wdev.iftype == nl80211.const.NL80211_IFTYPE_AP_VLAN)
|
||||||
continue;
|
continue;
|
||||||
if (this.radio != null && wdev.vif_radio_mask != null &&
|
if (this.radio != null && wdev.vif_radio_mask != null &&
|
||||||
!(wdev.vif_radio_mask & (1 << this.radio)))
|
wdev.vif_radio_mask != (1 << this.radio))
|
||||||
continue;
|
continue;
|
||||||
mac_wdev[wdev.mac] = wdev;
|
mac_wdev[wdev.mac] = wdev;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
let libubus = require("ubus");
|
let libubus = require("ubus");
|
||||||
import { open, readfile } from "fs";
|
import { open, readfile } from "fs";
|
||||||
import { wdev_remove, is_equal, vlist_new, phy_is_fullmac, phy_open, wdev_set_radio_mask } from "common";
|
import { wdev_remove, is_equal, vlist_new, phy_is_fullmac, phy_open, wdev_set_radio_mask, wdev_set_up } from "common";
|
||||||
|
|
||||||
let ubus = libubus.connect(null, 60);
|
let ubus = libubus.connect(null, 60);
|
||||||
|
|
||||||
|
|
@ -50,13 +50,16 @@ hostapd.data.bss_info_fields = {
|
||||||
owe_transition_ifname: true,
|
owe_transition_ifname: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hostapd.data.mld = {};
|
||||||
|
|
||||||
function iface_remove(cfg)
|
function iface_remove(cfg)
|
||||||
{
|
{
|
||||||
if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname)
|
if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (let bss in cfg.bss)
|
for (let bss in cfg.bss)
|
||||||
wdev_remove(bss.ifname);
|
if (!bss.mld_ap)
|
||||||
|
wdev_remove(bss.ifname);
|
||||||
}
|
}
|
||||||
|
|
||||||
function iface_gen_config(config, start_disabled)
|
function iface_gen_config(config, start_disabled)
|
||||||
|
|
@ -70,10 +73,12 @@ channel=${config.radio.channel}
|
||||||
let bss = config.bss[i];
|
let bss = config.bss[i];
|
||||||
let type = i > 0 ? "bss" : "interface";
|
let type = i > 0 ? "bss" : "interface";
|
||||||
let nasid = bss.nasid ?? replace(bss.bssid, ":", "");
|
let nasid = bss.nasid ?? replace(bss.bssid, ":", "");
|
||||||
|
let bssid = bss.bssid;
|
||||||
|
if (bss.mld_ap)
|
||||||
|
bssid += "\nmld_addr=" + bss.mld_bssid;
|
||||||
str += `
|
str += `
|
||||||
${type}=${bss.ifname}
|
${type}=${bss.ifname}
|
||||||
bssid=${bss.bssid}
|
bssid=${bssid}
|
||||||
${join("\n", bss.data)}
|
${join("\n", bss.data)}
|
||||||
nas_identifier=${nasid}
|
nas_identifier=${nasid}
|
||||||
`;
|
`;
|
||||||
|
|
@ -142,6 +147,9 @@ function iface_add(phy, config, phy_status)
|
||||||
function iface_config_macaddr_list(config)
|
function iface_config_macaddr_list(config)
|
||||||
{
|
{
|
||||||
let macaddr_list = {};
|
let macaddr_list = {};
|
||||||
|
for (let name, mld in hostapd.data.mld)
|
||||||
|
if (mld.macaddr)
|
||||||
|
macaddr_list[mld.macaddr] = -1;
|
||||||
for (let i = 0; i < length(config.bss); i++) {
|
for (let i = 0; i < length(config.bss); i++) {
|
||||||
let bss = config.bss[i];
|
let bss = config.bss[i];
|
||||||
if (!bss.default_macaddr)
|
if (!bss.default_macaddr)
|
||||||
|
|
@ -154,8 +162,11 @@ function iface_config_macaddr_list(config)
|
||||||
function iface_update_supplicant_macaddr(phydev, config)
|
function iface_update_supplicant_macaddr(phydev, config)
|
||||||
{
|
{
|
||||||
let macaddr_list = [];
|
let macaddr_list = [];
|
||||||
for (let i = 0; i < length(config.bss); i++)
|
for (let name, mld in hostapd.data.mld)
|
||||||
push(macaddr_list, config.bss[i].bssid);
|
if (mld.macaddr)
|
||||||
|
push(macaddr_list, mld.macaddr);
|
||||||
|
for (let bss in config.bss)
|
||||||
|
push(macaddr_list, bss.bssid);
|
||||||
ubus.defer("wpa_supplicant", "phy_set_macaddr_list", {
|
ubus.defer("wpa_supplicant", "phy_set_macaddr_list", {
|
||||||
phy: phydev.name,
|
phy: phydev.name,
|
||||||
radio: phydev.radio ?? -1,
|
radio: phydev.radio ?? -1,
|
||||||
|
|
@ -178,13 +189,15 @@ function __iface_pending_next(pending, state, ret, data)
|
||||||
iface_update_supplicant_macaddr(phydev, config);
|
iface_update_supplicant_macaddr(phydev, config);
|
||||||
return "create_bss";
|
return "create_bss";
|
||||||
case "create_bss":
|
case "create_bss":
|
||||||
let err = phydev.wdev_add(bss.ifname, {
|
if (!bss.mld_ap) {
|
||||||
mode: "ap",
|
let err = phydev.wdev_add(bss.ifname, {
|
||||||
radio: phydev.radio,
|
mode: "ap",
|
||||||
});
|
radio: phydev.radio,
|
||||||
if (err) {
|
});
|
||||||
hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`);
|
if (err) {
|
||||||
return null;
|
hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pending.call("wpa_supplicant", "phy_status", {
|
pending.call("wpa_supplicant", "phy_status", {
|
||||||
|
|
@ -550,6 +563,10 @@ function iface_reload_config(name, phydev, config, old_config)
|
||||||
|
|
||||||
let cur_config = config.bss[i];
|
let cur_config = config.bss[i];
|
||||||
let prev_config = old_config.bss[prev];
|
let prev_config = old_config.bss[prev];
|
||||||
|
if (prev_config.force_reload) {
|
||||||
|
delete prev_config.force_reload;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let prev_bss = get_config_bss(name, old_config, prev);
|
let prev_bss = get_config_bss(name, old_config, prev);
|
||||||
if (!prev_bss)
|
if (!prev_bss)
|
||||||
|
|
@ -606,7 +623,8 @@ function iface_reload_config(name, phydev, config, old_config)
|
||||||
let ifname = old_config.bss[i].ifname;
|
let ifname = old_config.bss[i].ifname;
|
||||||
hostapd.printf(`Remove bss '${ifname}' on phy '${name}'`);
|
hostapd.printf(`Remove bss '${ifname}' on phy '${name}'`);
|
||||||
prev_bss.delete();
|
prev_bss.delete();
|
||||||
wdev_remove(ifname);
|
if (!old_config.bss[i].mld_ap)
|
||||||
|
wdev_remove(ifname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4: rename preserved interfaces, use temporary name on duplicates
|
// Step 4: rename preserved interfaces, use temporary name on duplicates
|
||||||
|
|
@ -737,17 +755,78 @@ function iface_reload_config(name, phydev, config, old_config)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bss_check_mld(phydev, iface_name, bss)
|
||||||
|
{
|
||||||
|
if (!bss.ifname)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let mld_data = hostapd.data.mld[bss.ifname];
|
||||||
|
if (!mld_data || !mld_data.ifname || !mld_data.macaddr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bss.mld_bssid = mld_data.macaddr;
|
||||||
|
mld_data.iface[iface_name] = true;
|
||||||
|
if (mld_data.has_wdev)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hostapd.printf(`Create MLD interface ${bss.ifname} on phy ${phydev.name}, radio mask: ${mld_data.radio_mask}`);
|
||||||
|
let err = phydev.wdev_add(bss.ifname, {
|
||||||
|
mode: "ap",
|
||||||
|
macaddr: mld_data.macaddr,
|
||||||
|
radio_mask: mld_data.radio_mask,
|
||||||
|
});
|
||||||
|
wdev_set_up(bss.ifname, true);
|
||||||
|
if (err) {
|
||||||
|
hostapd.printf(`Failed to create MLD ${bss.ifname} on phy ${phydev.name}: ${err}`);
|
||||||
|
delete mld_data.iface[iface_name];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mld_data.has_wdev = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function iface_check_mld(phydev, name, config)
|
||||||
|
{
|
||||||
|
phydev = phy_open(phydev.phy);
|
||||||
|
|
||||||
|
for (let mld_name, mld_data in hostapd.data.mld)
|
||||||
|
delete mld_data.iface[name];
|
||||||
|
|
||||||
|
for (let i = 0; i < length(config.bss); i++) {
|
||||||
|
let bss = config.bss[i];
|
||||||
|
if (!bss.mld_ap)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!bss_check_mld(phydev, name, bss)) {
|
||||||
|
hostapd.printf(`Skip MLD interface ${name} on phy ${phydev.name}`);
|
||||||
|
splice(config.bss, i--, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let mld_name, mld_data in hostapd.data.mld) {
|
||||||
|
if (length(mld_data.iface) > 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
hostapd.printf(`Remove MLD interface ${mld_name}`);
|
||||||
|
wdev_remove(mld_name);
|
||||||
|
delete mld_data.has_wdev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function iface_config_remove(name, old_config)
|
||||||
|
{
|
||||||
|
hostapd.remove_iface(name);
|
||||||
|
return iface_remove(old_config);
|
||||||
|
}
|
||||||
|
|
||||||
function iface_set_config(name, config)
|
function iface_set_config(name, config)
|
||||||
{
|
{
|
||||||
let old_config = hostapd.data.config[name];
|
let old_config = hostapd.data.config[name];
|
||||||
|
|
||||||
hostapd.data.config[name] = config;
|
hostapd.data.config[name] = config;
|
||||||
|
|
||||||
if (!config) {
|
|
||||||
hostapd.remove_iface(name);
|
|
||||||
return iface_remove(old_config);
|
|
||||||
}
|
|
||||||
|
|
||||||
let phy = config.phy;
|
let phy = config.phy;
|
||||||
let phydev = phy_open(phy, config.radio_idx);
|
let phydev = phy_open(phy, config.radio_idx);
|
||||||
if (!phydev) {
|
if (!phydev) {
|
||||||
|
|
@ -755,6 +834,11 @@ function iface_set_config(name, config)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.orig_bss = [ ...config.bss ];
|
||||||
|
iface_check_mld(phydev, name, config);
|
||||||
|
if (!length(config.bss))
|
||||||
|
return iface_config_remove(name, old_config);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let ret = iface_reload_config(name, phydev, config, old_config);
|
let ret = iface_reload_config(name, phydev, config, old_config);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
@ -787,10 +871,6 @@ function config_add_bss(config, name)
|
||||||
|
|
||||||
function iface_load_config(phy, radio, filename)
|
function iface_load_config(phy, radio, filename)
|
||||||
{
|
{
|
||||||
let f = open(filename, "r");
|
|
||||||
if (!f)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (radio < 0)
|
if (radio < 0)
|
||||||
radio = null;
|
radio = null;
|
||||||
|
|
||||||
|
|
@ -804,6 +884,10 @@ function iface_load_config(phy, radio, filename)
|
||||||
orig_file: filename,
|
orig_file: filename,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let f = open(filename, "r");
|
||||||
|
if (!f)
|
||||||
|
return config;
|
||||||
|
|
||||||
let bss;
|
let bss;
|
||||||
let line;
|
let line;
|
||||||
while ((line = rtrim(f.read("line"), "\n")) != null) {
|
while ((line = rtrim(f.read("line"), "\n")) != null) {
|
||||||
|
|
@ -847,6 +931,9 @@ function iface_load_config(phy, radio, filename)
|
||||||
if (val[0] == "nas_identifier")
|
if (val[0] == "nas_identifier")
|
||||||
bss.nasid = val[1];
|
bss.nasid = val[1];
|
||||||
|
|
||||||
|
if (val[0] == "mld_ap")
|
||||||
|
bss[val[0]] = int(val[1]);
|
||||||
|
|
||||||
if (val[0] == "bss") {
|
if (val[0] == "bss") {
|
||||||
bss = config_add_bss(config, val[1]);
|
bss = config_add_bss(config, val[1]);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -901,6 +988,134 @@ function bss_config(bss_name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mld_rename_bss(data, name)
|
||||||
|
{
|
||||||
|
if (data.ifname == name)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// TODO: handle rename gracefully
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mld_add_bss(name, data, phy_list, i)
|
||||||
|
{
|
||||||
|
let config = data.config;
|
||||||
|
if (!config.phy)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wdev_remove(name);
|
||||||
|
let phydev = phy_list[config.phy];
|
||||||
|
if (!phydev) {
|
||||||
|
phydev = phy_open(config.phy, 0);
|
||||||
|
if (!phydev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let macaddr_list = {};
|
||||||
|
let phy_config = hostapd.data.config[phy_name(config.phy, 0)];
|
||||||
|
if (phy_config)
|
||||||
|
macaddr_list = iface_config_macaddr_list(phy_config);
|
||||||
|
iface_macaddr_init(phydev, data.config, macaddr_list);
|
||||||
|
|
||||||
|
phy_list[config.phy] = phydev;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.macaddr = config.macaddr;
|
||||||
|
if (!data.macaddr) {
|
||||||
|
data.macaddr = phydev.macaddr_next();
|
||||||
|
data.default_macaddr = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let radio_mask = 0;
|
||||||
|
for (let r in config.radios)
|
||||||
|
if (r != null)
|
||||||
|
radio_mask |= 1 << r;
|
||||||
|
|
||||||
|
data.radio_mask = radio_mask;
|
||||||
|
data.ifname = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mld_find_matching_config(list, config)
|
||||||
|
{
|
||||||
|
for (let name, data in list)
|
||||||
|
if (is_equal(data.config, config))
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mld_reload_interface(name)
|
||||||
|
{
|
||||||
|
let config = hostapd.data.config[name];
|
||||||
|
if (!config)
|
||||||
|
return;
|
||||||
|
|
||||||
|
config = { ...config };
|
||||||
|
config.bss = config.orig_bss;
|
||||||
|
|
||||||
|
iface_set_config(name, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mld_set_config(config)
|
||||||
|
{
|
||||||
|
let prev_mld = { ...hostapd.data.mld };
|
||||||
|
let new_mld = {};
|
||||||
|
let phy_list = {};
|
||||||
|
let new_config = !length(prev_mld);
|
||||||
|
|
||||||
|
hostapd.printf(`Set MLD config: ${keys(config)}`);
|
||||||
|
|
||||||
|
// find renamed/new interfaces
|
||||||
|
for (let name, data in config) {
|
||||||
|
let prev = mld_find_matching_config(prev_mld, data);
|
||||||
|
if (prev) {
|
||||||
|
let data = prev_mld[prev];
|
||||||
|
if (mld_rename_bss(data, name)) {
|
||||||
|
new_mld[name] = data;
|
||||||
|
delete prev_mld[prev];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_mld[name] = {
|
||||||
|
config: data,
|
||||||
|
iface: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let reload_iface = {};
|
||||||
|
for (let name, data in prev_mld) {
|
||||||
|
delete hostapd.data.mld[name];
|
||||||
|
|
||||||
|
if (!data.ifname)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (let iface, bss_list in hostapd.bss) {
|
||||||
|
if (!bss_list[name])
|
||||||
|
continue;
|
||||||
|
reload_iface[iface] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let name in reload_iface)
|
||||||
|
mld_reload_interface(name);
|
||||||
|
|
||||||
|
for (let name, data in prev_mld) {
|
||||||
|
if (data.ifname)
|
||||||
|
hostapd.printf(`Remove MLD interface ${name}`);
|
||||||
|
wdev_remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add new interfaces
|
||||||
|
hostapd.data.mld = new_mld;
|
||||||
|
for (let name, data in new_mld)
|
||||||
|
mld_add_bss(name, data, phy_list);
|
||||||
|
|
||||||
|
if (!new_config)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hostapd.printf(`Reload all interfaces`);
|
||||||
|
for (let name in hostapd.data.config)
|
||||||
|
mld_reload_interface(name);
|
||||||
|
}
|
||||||
|
|
||||||
let main_obj = {
|
let main_obj = {
|
||||||
reload: {
|
reload: {
|
||||||
args: {
|
args: {
|
||||||
|
|
@ -988,6 +1203,31 @@ let main_obj = {
|
||||||
return ret;
|
return ret;
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
mld_set: {
|
||||||
|
args: {
|
||||||
|
config: {}
|
||||||
|
},
|
||||||
|
call: ex_wrap(function(req) {
|
||||||
|
if (!req.args.config)
|
||||||
|
return libubus.STATUS_INVALID_ARGUMENT;
|
||||||
|
|
||||||
|
mld_set_config(req.args.config);
|
||||||
|
|
||||||
|
return {
|
||||||
|
pid: hostapd.getpid()
|
||||||
|
};
|
||||||
|
})
|
||||||
|
},
|
||||||
|
config_reset: {
|
||||||
|
args: {
|
||||||
|
},
|
||||||
|
call: ex_wrap(function(req) {
|
||||||
|
for (let name in hostapd.data.config)
|
||||||
|
iface_set_config(name);
|
||||||
|
mld_set_config({});
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
},
|
||||||
config_set: {
|
config_set: {
|
||||||
args: {
|
args: {
|
||||||
phy: "",
|
phy: "",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
From c14e53ea013415a29e9c493e9dacafb6dc5b31ee Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael-CY Lee <michael-cy.lee@mediatek.com>
|
||||||
|
Date: Fri, 8 Nov 2024 10:20:03 +0800
|
||||||
|
Subject: [PATCH] hostapd: Fix hostapd crash if setup a iface with a link bss failed
|
||||||
|
|
||||||
|
The crash occurs while some link bsses is traversing all the links by using
|
||||||
|
for_each_mld_link(), and hostapd access to the link bss which is already
|
||||||
|
been freed.
|
||||||
|
|
||||||
|
If hostapd setup a link bss failed, the link should be removed from
|
||||||
|
its hostapd_mld. However, the function hostapd_bss_link_deinit
|
||||||
|
doesn't remove the link bss correctly if it is the first bss and
|
||||||
|
hapd->drv_priv is null. Therefore we should refator the remove iface flow
|
||||||
|
as hostapd_remove_iface (used in wifi down cmd).
|
||||||
|
|
||||||
|
There are some cases that setup a bss may fail (e.g. afc query failed) or
|
||||||
|
trigger channel switch while hostapd is setting up other links.
|
||||||
|
The failed link would be add into hostapd_mld while driver_init().
|
||||||
|
|
||||||
|
Signed-off-by: Allen Ye <allen.ye@mediatek.com>
|
||||||
|
Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
src/ap/hostapd.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
--- a/src/ap/hostapd.c
|
||||||
|
+++ b/src/ap/hostapd.c
|
||||||
|
@@ -3878,6 +3878,7 @@ int hostapd_add_iface(struct hapd_interf
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostapd_setup_interface(hapd_iface)) {
|
||||||
|
+ hostapd_bss_link_deinit(hapd_iface->bss[0]);
|
||||||
|
hostapd_deinit_driver(
|
||||||
|
hapd_iface->bss[0]->driver,
|
||||||
|
hapd_iface->bss[0]->drv_priv,
|
||||||
|
@@ -5135,6 +5136,9 @@ int hostapd_mld_remove_link(struct hosta
|
||||||
|
if (!mld)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
+ if (!hapd->link.next)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
dl_list_del(&hapd->link);
|
||||||
|
mld->num_links--;
|
||||||
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 3 Jul 2025 11:22:26 +0200
|
||||||
|
Subject: [PATCH] hostapd: add support for specifying the link id in the config
|
||||||
|
|
||||||
|
Makes it easier to dynamically manage links for a MLD at run time.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/hostapd/config_file.c
|
||||||
|
+++ b/hostapd/config_file.c
|
||||||
|
@@ -4934,6 +4934,8 @@ static int hostapd_config_fill(struct ho
|
||||||
|
conf->punct_acs_threshold = val;
|
||||||
|
} else if (os_strcmp(buf, "mld_ap") == 0) {
|
||||||
|
bss->mld_ap = !!atoi(pos);
|
||||||
|
+ } else if (os_strcmp(buf, "mld_link_id") == 0) {
|
||||||
|
+ bss->mld_link_id = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "mld_addr") == 0) {
|
||||||
|
if (hwaddr_aton(pos, bss->mld_addr)) {
|
||||||
|
wpa_printf(MSG_ERROR, "Line %d: Invalid mld_addr",
|
||||||
|
--- a/src/ap/ap_config.c
|
||||||
|
+++ b/src/ap/ap_config.c
|
||||||
|
@@ -177,6 +177,10 @@ void hostapd_config_defaults_bss(struct
|
||||||
|
bss->pasn_comeback_after = 10;
|
||||||
|
bss->pasn_noauth = 1;
|
||||||
|
#endif /* CONFIG_PASN */
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_IEEE80211BE
|
||||||
|
+ bss->mld_link_id = -1;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--- a/src/ap/ap_config.h
|
||||||
|
+++ b/src/ap/ap_config.h
|
||||||
|
@@ -967,6 +967,8 @@ struct hostapd_bss_config {
|
||||||
|
/* The AP's MLD MAC address within the AP MLD */
|
||||||
|
u8 mld_addr[ETH_ALEN];
|
||||||
|
|
||||||
|
+ s8 mld_link_id;
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
/*
|
||||||
|
* If set indicate the AP as disabled in the RNR element included in the
|
||||||
|
--- a/src/ap/hostapd.c
|
||||||
|
+++ b/src/ap/hostapd.c
|
||||||
|
@@ -3105,7 +3105,10 @@ struct hostapd_iface * hostapd_alloc_ifa
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
static void hostapd_bss_alloc_link_id(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
- hapd->mld_link_id = hapd->mld->next_link_id++;
|
||||||
|
+ if (hapd->conf->mld_link_id >= 0)
|
||||||
|
+ hapd->mld_link_id = hapd->conf->mld_link_id;
|
||||||
|
+ else
|
||||||
|
+ hapd->mld_link_id = hapd->mld->next_link_id++;
|
||||||
|
wpa_printf(MSG_DEBUG, "AP MLD: %s: Link ID %d assigned.",
|
||||||
|
hapd->mld->name, hapd->mld_link_id);
|
||||||
|
}
|
||||||
|
|
@ -18,7 +18,7 @@ Subject: [PATCH] Add noscan, no_ht_coex config options
|
||||||
} else if (os_strcmp(buf, "ht_capab") == 0) {
|
} else if (os_strcmp(buf, "ht_capab") == 0) {
|
||||||
--- a/src/ap/ap_config.h
|
--- a/src/ap/ap_config.h
|
||||||
+++ b/src/ap/ap_config.h
|
+++ b/src/ap/ap_config.h
|
||||||
@@ -1105,6 +1105,8 @@ struct hostapd_config {
|
@@ -1107,6 +1107,8 @@ struct hostapd_config {
|
||||||
|
|
||||||
int ht_op_mode_fixed;
|
int ht_op_mode_fixed;
|
||||||
u16 ht_capab;
|
u16 ht_capab;
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,7 @@ probe/assoc/auth requests via object subscribe.
|
||||||
|
|
||||||
if (iface->is_no_ir) {
|
if (iface->is_no_ir) {
|
||||||
hostapd_set_state(iface, HAPD_IFACE_NO_IR);
|
hostapd_set_state(iface, HAPD_IFACE_NO_IR);
|
||||||
@@ -3527,6 +3532,7 @@ void hostapd_interface_deinit_free(struc
|
@@ -3530,6 +3535,7 @@ void hostapd_interface_deinit_free(struc
|
||||||
(unsigned int) iface->conf->num_bss);
|
(unsigned int) iface->conf->num_bss);
|
||||||
driver = iface->bss[0]->driver;
|
driver = iface->bss[0]->driver;
|
||||||
drv_priv = iface->bss[0]->drv_priv;
|
drv_priv = iface->bss[0]->drv_priv;
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,15 @@ as adding/removing interfaces.
|
||||||
hostapd_ubus_free_bss(hapd);
|
hostapd_ubus_free_bss(hapd);
|
||||||
accounting_deinit(hapd);
|
accounting_deinit(hapd);
|
||||||
hostapd_deinit_wpa(hapd);
|
hostapd_deinit_wpa(hapd);
|
||||||
|
@@ -625,7 +628,7 @@ void hostapd_free_hapd_data(struct hosta
|
||||||
|
* If the BSS being removed is the first link, the next link becomes the first
|
||||||
|
* link.
|
||||||
|
*/
|
||||||
|
-static void hostapd_bss_link_deinit(struct hostapd_data *hapd)
|
||||||
|
+void hostapd_bss_link_deinit(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
int i;
|
||||||
@@ -737,6 +740,7 @@ void hostapd_cleanup_iface_partial(struc
|
@@ -737,6 +740,7 @@ void hostapd_cleanup_iface_partial(struc
|
||||||
static void hostapd_cleanup_iface(struct hostapd_iface *iface)
|
static void hostapd_cleanup_iface(struct hostapd_iface *iface)
|
||||||
{
|
{
|
||||||
|
|
@ -139,7 +148,47 @@ as adding/removing interfaces.
|
||||||
{
|
{
|
||||||
struct hostapd_bss_config *conf = hapd->conf;
|
struct hostapd_bss_config *conf = hapd->conf;
|
||||||
u8 ssid[SSID_MAX_LEN + 1];
|
u8 ssid[SSID_MAX_LEN + 1];
|
||||||
@@ -1518,6 +1522,8 @@ setup_mld:
|
@@ -1434,7 +1438,13 @@ static int hostapd_setup_bss(struct host
|
||||||
|
|
||||||
|
if (!first || first == -1) {
|
||||||
|
u8 *addr = hapd->own_addr;
|
||||||
|
+ bool use_existing = first == -1;
|
||||||
|
|
||||||
|
+#ifdef CONFIG_IEEE80211BE
|
||||||
|
+ if (hapd->conf->mld_ap) {
|
||||||
|
+ addr = NULL;
|
||||||
|
+ } else
|
||||||
|
+#endif /* CONFIG_IEEE80211BE */
|
||||||
|
if (!is_zero_ether_addr(conf->bssid)) {
|
||||||
|
/* Allocate the configured BSSID. */
|
||||||
|
os_memcpy(hapd->own_addr, conf->bssid, ETH_ALEN);
|
||||||
|
@@ -1469,6 +1479,7 @@ static int hostapd_setup_bss(struct host
|
||||||
|
hapd->mld_link_id, hapd->conf->iface);
|
||||||
|
goto setup_mld;
|
||||||
|
}
|
||||||
|
+ use_existing = true;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
|
||||||
|
@@ -1477,7 +1488,7 @@ static int hostapd_setup_bss(struct host
|
||||||
|
conf->iface, addr, hapd,
|
||||||
|
&hapd->drv_priv, force_ifname, if_addr,
|
||||||
|
conf->bridge[0] ? conf->bridge : NULL,
|
||||||
|
- first == -1)) {
|
||||||
|
+ use_existing)) {
|
||||||
|
wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
|
||||||
|
MACSTR ")", MAC2STR(hapd->own_addr));
|
||||||
|
hapd->interface_added = 0;
|
||||||
|
@@ -1500,7 +1511,7 @@ static int hostapd_setup_bss(struct host
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
setup_mld:
|
||||||
|
- if (hapd->conf->mld_ap && !first) {
|
||||||
|
+ if (hapd->conf->mld_ap && first != 1) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MLD: Set link_id=%u, mld_addr=" MACSTR
|
||||||
|
", own_addr=" MACSTR,
|
||||||
|
@@ -1518,6 +1529,8 @@ setup_mld:
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_IEEE80211BE */
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
|
||||||
|
|
@ -148,7 +197,16 @@ as adding/removing interfaces.
|
||||||
if (conf->wmm_enabled < 0)
|
if (conf->wmm_enabled < 0)
|
||||||
conf->wmm_enabled = hapd->iconf->ieee80211n |
|
conf->wmm_enabled = hapd->iconf->ieee80211n |
|
||||||
hapd->iconf->ieee80211ax;
|
hapd->iconf->ieee80211ax;
|
||||||
@@ -2516,7 +2522,7 @@ static int hostapd_owe_iface_iter2(struc
|
@@ -1843,7 +1856,7 @@ int hostapd_set_acl(struct hostapd_data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-static int hostapd_set_ctrl_sock_iface(struct hostapd_data *hapd)
|
||||||
|
+int hostapd_set_ctrl_sock_iface(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
int ret;
|
||||||
|
@@ -2516,7 +2529,7 @@ static int hostapd_owe_iface_iter2(struc
|
||||||
#endif /* CONFIG_OWE */
|
#endif /* CONFIG_OWE */
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -157,7 +215,7 @@ as adding/removing interfaces.
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_OWE
|
#ifdef CONFIG_OWE
|
||||||
/* Check whether the enabled BSS can complete OWE transition mode
|
/* Check whether the enabled BSS can complete OWE transition mode
|
||||||
@@ -2986,7 +2992,7 @@ hostapd_alloc_bss_data(struct hostapd_if
|
@@ -2986,7 +2999,7 @@ hostapd_alloc_bss_data(struct hostapd_if
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -166,7 +224,16 @@ as adding/removing interfaces.
|
||||||
{
|
{
|
||||||
if (!hapd)
|
if (!hapd)
|
||||||
return;
|
return;
|
||||||
@@ -4070,7 +4076,8 @@ int hostapd_remove_iface(struct hapd_int
|
@@ -3194,7 +3207,7 @@ fail:
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-static void hostapd_cleanup_unused_mlds(struct hapd_interfaces *interfaces)
|
||||||
|
+void hostapd_cleanup_unused_mlds(struct hapd_interfaces *interfaces)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
struct hostapd_mld *mld, **all_mld;
|
||||||
|
@@ -4074,7 +4087,8 @@ int hostapd_remove_iface(struct hapd_int
|
||||||
hapd_iface = interfaces->iface[i];
|
hapd_iface = interfaces->iface[i];
|
||||||
if (hapd_iface == NULL)
|
if (hapd_iface == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -213,16 +280,24 @@ as adding/removing interfaces.
|
||||||
void *owner;
|
void *owner;
|
||||||
char *config_fname;
|
char *config_fname;
|
||||||
struct hostapd_config *conf;
|
struct hostapd_config *conf;
|
||||||
@@ -787,6 +794,8 @@ struct hostapd_iface * hostapd_init(stru
|
@@ -787,11 +794,16 @@ struct hostapd_iface * hostapd_init(stru
|
||||||
struct hostapd_iface *
|
struct hostapd_iface *
|
||||||
hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
|
hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
|
||||||
const char *config_fname, int debug);
|
const char *config_fname, int debug);
|
||||||
|
+int hostapd_set_ctrl_sock_iface(struct hostapd_data *hapd);
|
||||||
+int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon);
|
+int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon);
|
||||||
|
+void hostapd_bss_link_deinit(struct hostapd_data *hapd);
|
||||||
+void hostapd_bss_deinit(struct hostapd_data *hapd);
|
+void hostapd_bss_deinit(struct hostapd_data *hapd);
|
||||||
void hostapd_bss_setup_multi_link(struct hostapd_data *hapd,
|
void hostapd_bss_setup_multi_link(struct hostapd_data *hapd,
|
||||||
struct hapd_interfaces *interfaces);
|
struct hapd_interfaces *interfaces);
|
||||||
void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
@@ -817,6 +826,7 @@ hostapd_switch_channel_fallback(struct h
|
int reassoc);
|
||||||
|
void hostapd_interface_deinit_free(struct hostapd_iface *iface);
|
||||||
|
+void hostapd_cleanup_unused_mlds(struct hapd_interfaces *interfaces);
|
||||||
|
int hostapd_enable_iface(struct hostapd_iface *hapd_iface);
|
||||||
|
int hostapd_reload_iface(struct hostapd_iface *hapd_iface);
|
||||||
|
int hostapd_reload_bss_only(struct hostapd_data *bss);
|
||||||
|
@@ -817,6 +829,7 @@ hostapd_switch_channel_fallback(struct h
|
||||||
void hostapd_cleanup_cs_params(struct hostapd_data *hapd);
|
void hostapd_cleanup_cs_params(struct hostapd_data *hapd);
|
||||||
void hostapd_periodic_iface(struct hostapd_iface *iface);
|
void hostapd_periodic_iface(struct hostapd_iface *iface);
|
||||||
int hostapd_owe_trans_get_info(struct hostapd_data *hapd);
|
int hostapd_owe_trans_get_info(struct hostapd_data *hapd);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ as adding/removing interfaces.
|
||||||
|
|
||||||
--- a/hostapd/config_file.c
|
--- a/hostapd/config_file.c
|
||||||
+++ b/hostapd/config_file.c
|
+++ b/hostapd/config_file.c
|
||||||
@@ -4981,7 +4981,14 @@ struct hostapd_config * hostapd_config_r
|
@@ -4983,7 +4983,14 @@ struct hostapd_config * hostapd_config_r
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
|
@ -58,7 +58,7 @@ as adding/removing interfaces.
|
||||||
return NULL;
|
return NULL;
|
||||||
--- a/src/ap/hostapd.c
|
--- a/src/ap/hostapd.c
|
||||||
+++ b/src/ap/hostapd.c
|
+++ b/src/ap/hostapd.c
|
||||||
@@ -3380,8 +3380,13 @@ hostapd_interface_init_bss(struct hapd_i
|
@@ -3400,8 +3400,13 @@ hostapd_interface_init_bss(struct hapd_i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ full device, e.g. in order to deal with hardware/driver limitations
|
||||||
} else if (os_strcmp(buf, "extended_key_id") == 0) {
|
} else if (os_strcmp(buf, "extended_key_id") == 0) {
|
||||||
--- a/src/ap/ap_config.h
|
--- a/src/ap/ap_config.h
|
||||||
+++ b/src/ap/ap_config.h
|
+++ b/src/ap/ap_config.h
|
||||||
@@ -1069,6 +1069,8 @@ struct hostapd_config {
|
@@ -1071,6 +1071,8 @@ struct hostapd_config {
|
||||||
unsigned int track_sta_max_num;
|
unsigned int track_sta_max_num;
|
||||||
unsigned int track_sta_max_age;
|
unsigned int track_sta_max_age;
|
||||||
|
|
||||||
|
|
@ -79,7 +79,7 @@ full device, e.g. in order to deal with hardware/driver limitations
|
||||||
{
|
{
|
||||||
--- a/src/ap/hostapd.h
|
--- a/src/ap/hostapd.h
|
||||||
+++ b/src/ap/hostapd.h
|
+++ b/src/ap/hostapd.h
|
||||||
@@ -828,6 +828,7 @@ void hostapd_periodic_iface(struct hosta
|
@@ -831,6 +831,7 @@ void hostapd_periodic_iface(struct hosta
|
||||||
int hostapd_owe_trans_get_info(struct hostapd_data *hapd);
|
int hostapd_owe_trans_get_info(struct hostapd_data *hapd);
|
||||||
void hostapd_owe_update_trans(struct hostapd_iface *iface);;
|
void hostapd_owe_update_trans(struct hostapd_iface *iface);;
|
||||||
void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx);
|
void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ handle reload.
|
||||||
|
|
||||||
#ifndef CONFIG_NO_HOSTAPD_LOGGER
|
#ifndef CONFIG_NO_HOSTAPD_LOGGER
|
||||||
static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
|
static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
|
||||||
@@ -834,6 +835,11 @@ int main(int argc, char *argv[])
|
@@ -838,6 +839,11 @@ int main(int argc, char *argv[])
|
||||||
if (os_program_init())
|
if (os_program_init())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ Hotfix-by: Sebastian Gottschall https://github.com/mirror/dd-wrt/commit/0c3001a6
|
||||||
|
|
||||||
--- a/hostapd/config_file.c
|
--- a/hostapd/config_file.c
|
||||||
+++ b/hostapd/config_file.c
|
+++ b/hostapd/config_file.c
|
||||||
@@ -4974,6 +4974,15 @@ static int hostapd_config_fill(struct ho
|
@@ -4976,6 +4976,15 @@ static int hostapd_config_fill(struct ho
|
||||||
bss->mld_indicate_disabled = atoi(pos);
|
bss->mld_indicate_disabled = atoi(pos);
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
#endif /* CONFIG_IEEE80211BE */
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
|
@ -71,7 +71,7 @@ Hotfix-by: Sebastian Gottschall https://github.com/mirror/dd-wrt/commit/0c3001a6
|
||||||
"Line %d: unknown configuration item '%s'",
|
"Line %d: unknown configuration item '%s'",
|
||||||
--- a/src/ap/ap_config.h
|
--- a/src/ap/ap_config.h
|
||||||
+++ b/src/ap/ap_config.h
|
+++ b/src/ap/ap_config.h
|
||||||
@@ -982,6 +982,35 @@ struct hostapd_bss_config {
|
@@ -984,6 +984,35 @@ struct hostapd_bss_config {
|
||||||
int mbssid_index;
|
int mbssid_index;
|
||||||
|
|
||||||
bool spp_amsdu;
|
bool spp_amsdu;
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,49 @@ bss_reload_vlans(struct hostapd_data *hapd, struct hostapd_bss_config *bss)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
__uc_hostapd_bss_stop(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
struct hostapd_iface *iface = hapd->iface;
|
||||||
|
|
||||||
|
if (!hapd->started)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hostapd_bss_deinit_no_free(hapd);
|
||||||
|
hostapd_drv_stop_ap(hapd);
|
||||||
|
hostapd_bss_link_deinit(hapd);
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
if (hapd == iface->bss[0])
|
||||||
|
hostapd_if_link_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface,
|
||||||
|
hapd->mld_link_id);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hostapd_free_hapd_data(hapd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
__uc_hostapd_bss_start(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
struct hostapd_iface *iface = hapd->iface;
|
||||||
|
bool first = hapd == iface->bss[0];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (hapd->started)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
if (hapd->conf->mld_ap)
|
||||||
|
first = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = hostapd_setup_bss(hapd, first, true);
|
||||||
|
hostapd_neighbor_set_own_report(hapd);
|
||||||
|
hostapd_owe_update_trans(iface);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static uc_value_t *
|
static uc_value_t *
|
||||||
uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs)
|
uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs)
|
||||||
{
|
{
|
||||||
|
|
@ -241,12 +284,10 @@ uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs)
|
||||||
|
|
||||||
swap_field(ssid.wpa_psk_file);
|
swap_field(ssid.wpa_psk_file);
|
||||||
ret = bss_reload_vlans(hapd, bss);
|
ret = bss_reload_vlans(hapd, bss);
|
||||||
goto done;
|
goto free;
|
||||||
}
|
}
|
||||||
|
|
||||||
hostapd_bss_deinit_no_free(hapd);
|
__uc_hostapd_bss_stop(hapd);
|
||||||
hostapd_drv_stop_ap(hapd);
|
|
||||||
hostapd_free_hapd_data(hapd);
|
|
||||||
|
|
||||||
old_bss = hapd->conf;
|
old_bss = hapd->conf;
|
||||||
for (i = 0; i < iface->conf->num_bss; i++)
|
for (i = 0; i < iface->conf->num_bss; i++)
|
||||||
|
|
@ -258,13 +299,9 @@ uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs)
|
||||||
if (hapd == iface->bss[0])
|
if (hapd == iface->bss[0])
|
||||||
memcpy(hapd->own_addr, hapd->conf->bssid, ETH_ALEN);
|
memcpy(hapd->own_addr, hapd->conf->bssid, ETH_ALEN);
|
||||||
|
|
||||||
hostapd_setup_bss(hapd, hapd == iface->bss[0], true);
|
ret = __uc_hostapd_bss_start(hapd);
|
||||||
hostapd_neighbor_set_own_report(hapd);
|
|
||||||
hostapd_ucode_update_interfaces();
|
hostapd_ucode_update_interfaces();
|
||||||
hostapd_owe_update_trans(iface);
|
|
||||||
|
|
||||||
done:
|
|
||||||
ret = 0;
|
|
||||||
free:
|
free:
|
||||||
hostapd_config_free(conf);
|
hostapd_config_free(conf);
|
||||||
out:
|
out:
|
||||||
|
|
@ -326,8 +363,13 @@ uc_hostapd_bss_delete(uc_vm_t *vm, size_t nargs)
|
||||||
hostapd_bss_deinit(hapd);
|
hostapd_bss_deinit(hapd);
|
||||||
hostapd_remove_iface_bss_conf(iface->conf, hapd->conf);
|
hostapd_remove_iface_bss_conf(iface->conf, hapd->conf);
|
||||||
hostapd_config_free_bss(hapd->conf);
|
hostapd_config_free_bss(hapd->conf);
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
if (hapd->mld)
|
||||||
|
hapd->mld->refcount--;
|
||||||
|
#endif
|
||||||
os_free(hapd);
|
os_free(hapd);
|
||||||
|
|
||||||
|
hostapd_cleanup_unused_mlds(iface->interfaces);
|
||||||
hostapd_ucode_update_interfaces();
|
hostapd_ucode_update_interfaces();
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -365,7 +407,12 @@ uc_hostapd_iface_add_bss(uc_vm_t *vm, size_t nargs)
|
||||||
#ifdef CONFIG_IEEE80211BE
|
#ifdef CONFIG_IEEE80211BE
|
||||||
os_strlcpy(hapd->ctrl_sock_iface, hapd->conf->iface,
|
os_strlcpy(hapd->ctrl_sock_iface, hapd->conf->iface,
|
||||||
sizeof(hapd->ctrl_sock_iface));
|
sizeof(hapd->ctrl_sock_iface));
|
||||||
|
if (hapd->conf->mld_ap) {
|
||||||
|
hostapd_bss_setup_multi_link(hapd, iface->interfaces);
|
||||||
|
hostapd_set_ctrl_sock_iface(hapd);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (interfaces->ctrl_iface_init &&
|
if (interfaces->ctrl_iface_init &&
|
||||||
interfaces->ctrl_iface_init(hapd) < 0)
|
interfaces->ctrl_iface_init(hapd) < 0)
|
||||||
goto free_hapd;
|
goto free_hapd;
|
||||||
|
|
@ -673,6 +720,7 @@ uc_hostapd_bss_rename(uc_vm_t *vm, size_t nargs)
|
||||||
{
|
{
|
||||||
struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss");
|
struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss");
|
||||||
uc_value_t *ifname_arg = uc_fn_arg(0);
|
uc_value_t *ifname_arg = uc_fn_arg(0);
|
||||||
|
uc_value_t *skip_rename = uc_fn_arg(1);
|
||||||
char prev_ifname[IFNAMSIZ + 1];
|
char prev_ifname[IFNAMSIZ + 1];
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
const char *ifname;
|
const char *ifname;
|
||||||
|
|
@ -688,9 +736,11 @@ uc_hostapd_bss_rename(uc_vm_t *vm, size_t nargs)
|
||||||
if (interfaces->ctrl_iface_deinit)
|
if (interfaces->ctrl_iface_deinit)
|
||||||
interfaces->ctrl_iface_deinit(hapd);
|
interfaces->ctrl_iface_deinit(hapd);
|
||||||
|
|
||||||
ret = hostapd_drv_if_rename(hapd, WPA_IF_AP_BSS, NULL, ifname);
|
if (!ucv_is_truish(skip_rename)) {
|
||||||
if (ret)
|
ret = hostapd_drv_if_rename(hapd, WPA_IF_AP_BSS, NULL, ifname);
|
||||||
goto out;
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
for (sta = hapd->sta_list; sta; sta = sta->next) {
|
for (sta = hapd->sta_list; sta; sta = sta->next) {
|
||||||
char cur_name[IFNAMSIZ + 1], new_name[IFNAMSIZ + 1];
|
char cur_name[IFNAMSIZ + 1], new_name[IFNAMSIZ + 1];
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue