mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 15:32:33 +00:00
a6bb1df40b
When an IBBS interface is configured for IBSS legacy mode, wdev.htmode is empty. This is empty string results in an empty positional argument to the "ibbs join" command, for example: iw dev phy0-ibss0 ibss join crymesh 2412 '' fixed-freq beacon-interval 100 This empty argument is interpreted as an invalid HT mode by 'iw', causing the entire command to fail and print a "usage" message: daemon.notice netifd: radio0 (4527): Usage: iw [options] \ dev <devname> ibss join <SSID> <freq in MHz> ... Although nobody will ever need more than 640K of IBSS, explicitly use "NOHT" if an HT mode is not given. This fixes the problem. Fixes:e56c5f7b27
("hostapd: add ucode support, use ucode for the main ubus object") Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Signed-off-by: Felix Fietkau <nbd@nbd.name> [extend to cover more cases] (cherry picked from commitcee9fcdb73
)
187 lines
4.1 KiB
Ucode
187 lines
4.1 KiB
Ucode
#!/usr/bin/env ucode
|
|
'use strict';
|
|
import { vlist_new, is_equal, wdev_create, wdev_set_mesh_params, wdev_remove, wdev_set_up, 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 command = shift(ARGV);
|
|
let phydev;
|
|
|
|
function iface_stop(wdev)
|
|
{
|
|
if (keep_devices[wdev.ifname])
|
|
return;
|
|
|
|
wdev_remove(wdev.ifname);
|
|
}
|
|
|
|
function iface_start(wdev)
|
|
{
|
|
let ifname = wdev.ifname;
|
|
|
|
if (readfile(`/sys/class/net/${ifname}/ifindex`)) {
|
|
wdev_set_up(ifname, false);
|
|
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_config);
|
|
wdev_set_up(ifname, true);
|
|
let htmode = wdev.htmode || "NOHT";
|
|
if (wdev.freq)
|
|
system(`iw dev ${ifname} set freq ${wdev.freq} ${htmode}`);
|
|
if (wdev.mode == "adhoc") {
|
|
let cmd = ["iw", "dev", ifname, "ibss", "join", wdev.ssid, wdev.freq, htmode, "fixed-freq" ];
|
|
if (wdev.bssid)
|
|
push(cmd, wdev.bssid);
|
|
for (let key in [ "beacon-interval", "basic-rates", "mcast-rate", "keys" ])
|
|
if (wdev[key])
|
|
push(cmd, key, wdev[key]);
|
|
system(cmd);
|
|
} else if (wdev.mode == "mesh") {
|
|
let cmd = [ "iw", "dev", ifname, "mesh", "join", wdev.ssid, "freq", wdev.freq, htmode ];
|
|
for (let key in [ "mcast-rate", "beacon-interval" ])
|
|
if (wdev[key])
|
|
push(cmd, key, wdev[key]);
|
|
system(cmd);
|
|
|
|
wdev_set_mesh_params(ifname, wdev);
|
|
}
|
|
}
|
|
|
|
function iface_cb(new_if, old_if)
|
|
{
|
|
if (old_if && new_if && is_equal(old_if, new_if))
|
|
return;
|
|
|
|
if (old_if)
|
|
iface_stop(old_if);
|
|
if (new_if)
|
|
iface_start(new_if);
|
|
}
|
|
|
|
function drop_inactive(config)
|
|
{
|
|
for (let key in config) {
|
|
if (!readfile(`/sys/class/net/${key}/ifindex`))
|
|
delete config[key];
|
|
}
|
|
}
|
|
|
|
function add_ifname(config)
|
|
{
|
|
for (let key in config)
|
|
config[key].ifname = key;
|
|
}
|
|
|
|
function delete_ifname(config)
|
|
{
|
|
for (let key in config)
|
|
delete config[key].ifname;
|
|
}
|
|
|
|
function add_existing(phy, config)
|
|
{
|
|
let wdevs = glob(`/sys/class/ieee80211/${phy}/device/net/*`);
|
|
wdevs = map(wdevs, (arg) => basename(arg));
|
|
for (let wdev in wdevs) {
|
|
if (config[wdev])
|
|
continue;
|
|
|
|
if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != phy)
|
|
continue;
|
|
|
|
if (trim(readfile(`/sys/class/net/${wdev}/operstate`)) == "down")
|
|
config[wdev] = {};
|
|
}
|
|
}
|
|
|
|
function usage()
|
|
{
|
|
warn(`Usage: ${basename(sourcepath())} <phy> <command> [<arguments>]
|
|
|
|
Commands:
|
|
set_config <config> [<device]...] - set phy configuration
|
|
get_macaddr <id> - get phy MAC address for vif index <id>
|
|
`);
|
|
exit(1);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
commands[command](ARGV);
|