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>
monitor: nl80211.const.NL80211_IFTYPE_MONITOR,
};
+const mesh_params = {
+ mesh_retry_timeout: "retry_timeout",
+ mesh_confirm_timeout: "confirm_timeout",
+ mesh_holding_timeout: "holding_timeout",
+ mesh_max_peer_links: "max_peer_links",
+ mesh_max_retries: "max_retries",
+ mesh_ttl: "ttl",
+ mesh_element_ttl: "element_ttl",
+ mesh_auto_open_plinks: "auto_open_plinks",
+ mesh_hwmp_max_preq_retries: "hwmp_max_preq_retries",
+ mesh_path_refresh_time: "path_refresh_time",
+ mesh_min_discovery_timeout: "min_discovery_timeout",
+ mesh_hwmp_active_path_timeout: "hwmp_active_path_timeout",
+ mesh_hwmp_preq_min_interval: "hwmp_preq_min_interval",
+ mesh_hwmp_net_diameter_traversal_time: "hwmp_net_diam_trvs_time",
+ mesh_hwmp_rootmode: "hwmp_rootmode",
+ mesh_hwmp_rann_interval: "hwmp_rann_interval",
+ mesh_gate_announcements: "gate_announcements",
+ mesh_sync_offset_max_neighor: "sync_offset_max_neighbor",
+ mesh_rssi_threshold: "rssi_threshold",
+ mesh_hwmp_active_path_to_root_timeout: "hwmp_path_to_root_timeout",
+ mesh_hwmp_root_interval: "hwmp_root_interval",
+ mesh_hwmp_confirmation_interval: "hwmp_confirmation_interval",
+ mesh_awake_window: "awake_window",
+ mesh_plink_timeout: "plink_timeout",
+ mesh_fwding: "forwarding",
+ mesh_power_mode: "power_mode",
+ mesh_nolearn: "nolearn"
+};
+
function wdev_remove(name)
{
nl80211.request(nl80211.const.NL80211_CMD_DEL_INTERFACE, 0, { dev: name });
return null;
}
+function wdev_set_mesh_params(name, data)
+{
+ let mesh_cfg = {};
+
+ for (let key in mesh_params) {
+ let val = data[key];
+ if (val == null)
+ continue;
+ mesh_cfg[mesh_params[key]] = int(val);
+ }
+
+ if (!length(mesh_cfg))
+ return null;
+
+ nl80211.request(nl80211.const.NL80211_CMD_SET_MESH_CONFIG, 0,
+ { dev: name, mesh_params: mesh_cfg });
+
+ return nl80211.error();
+}
+
function phy_sysfs_file(phy, name)
{
return trim(readfile(`/sys/class/ieee80211/${phy}/${name}`));
}, vlist_proto);
}
-export { wdev_remove, wdev_create, is_equal, vlist_new, phy_is_fullmac, phy_open };
+export { wdev_remove, wdev_create, wdev_set_mesh_params, is_equal, vlist_new, phy_is_fullmac, phy_open };
#!/usr/bin/env ucode
'use strict';
-import { vlist_new, is_equal, wdev_create, wdev_remove, phy_open } from "/usr/share/hostap/common.uc";
+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 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",
- "mesh_path_refresh_time", "mesh_min_discovery_timeout", "mesh_hwmp_active_path_timeout",
- "mesh_hwmp_preq_min_interval", "mesh_hwmp_net_diameter_traversal_time", "mesh_hwmp_rootmode",
- "mesh_hwmp_rann_interval", "mesh_gate_announcements", "mesh_sync_offset_max_neighor",
- "mesh_rssi_threshold", "mesh_hwmp_active_path_to_root_timeout", "mesh_hwmp_root_interval",
- "mesh_hwmp_confirmation_interval", "mesh_awake_window", "mesh_plink_timeout",
- "mesh_auto_open_plinks", "mesh_fwding", "mesh_power_mode"
-];
-
function iface_stop(wdev)
{
if (keep_devices[wdev.ifname])
push(cmd, key, wdev[key]);
system(cmd);
- cmd = ["iw", "dev", ifname, "set", "mesh_param" ];
- let len = length(cmd);
-
- for (let param in mesh_params)
- if (wdev[param])
- push(cmd, param, wdev[param]);
-
- if (len == length(cmd))
- return;
-
- system(cmd);
+ wdev_set_mesh_params(ifname, wdev);
}
-
}
function iface_cb(new_if, old_if)
let libubus = require("ubus");
import { open, readfile } from "fs";
-import { wdev_create, wdev_remove, is_equal, vlist_new, phy_open } from "common";
+import { wdev_create, wdev_set_mesh_params, wdev_remove, is_equal, vlist_new, phy_open } from "common";
let ubus = libubus.connect();
}
iface_hostapd_notify(phy, ifname, iface, state);
+
+ if (state != "COMPLETED")
+ return;
+
+ let phy_data = wpas.data.config[phy];
+ if (!phy_data)
+ return;
+
+ let iface_data = phy_data.data[ifname];
+ if (!iface_data)
+ return;
+
+ let wdev_config = iface_data.config;
+ if (!wdev_config || wdev_config.mode != "mesh")
+ return;
+
+ wdev_set_mesh_params(ifname, wdev_config);
},
event: function(ifname, iface, ev, info) {
let phy = wpas.data.iface_phy[ifname];