mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-24 07:46:48 +00:00
bbfb920e99
Apply them directly using nl80211 after setting up the interface.
Use the same method in wdev.uc as well
Signed-off-by: Felix Fietkau <nbd@nbd.name>
(cherry picked from commit 531314260d
)
186 lines
4.1 KiB
Ucode
186 lines
4.1 KiB
Ucode
#!/usr/bin/env ucode
|
|
'use strict';
|
|
import { vlist_new, is_equal, wdev_create, wdev_set_mesh_params, 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 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`)) {
|
|
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_config);
|
|
system([ "ip", "link", "set", "dev", ifname, "up" ]);
|
|
if (wdev.freq)
|
|
system(`iw dev ${ifname} set freq ${wdev.freq} ${wdev.htmode}`);
|
|
if (wdev.mode == "adhoc") {
|
|
let cmd = ["iw", "dev", ifname, "ibss", "join", wdev.ssid, wdev.freq, wdev.htmode, "fixed-freq" ];
|
|
if (wdev.bssid)
|
|
push(cmd, wdev.bssid);
|
|
for (let key in [ "beacon-interval", "basic-rates", "mcast-rate", "keys" ])
|
|
if (wdev[key])
|
|
push(cmd, key, wdev[key]);
|
|
system(cmd);
|
|
} else if (wdev.mode == "mesh") {
|
|
let cmd = [ "iw", "dev", ifname, "mesh", "join", wdev.ssid, "freq", wdev.freq, wdev.htmode ];
|
|
for (let key in [ "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);
|