wifi-scripts: add macaddr_base wifi-device option
authorFelix Fietkau <nbd@nbd.name>
Mon, 9 Dec 2024 19:09:15 +0000 (20:09 +0100)
committerFelix Fietkau <nbd@nbd.name>
Thu, 12 Dec 2024 18:19:05 +0000 (19:19 +0100)
This can be used to configure the base mac address from which all
interface mac addresses are derived

Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/network/config/wifi-scripts/files-ucode/lib/netifd/wireless/mac80211.sh
package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-device.json
package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/hostapd.uc
package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/iface.uc
package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/supplicant.uc
package/network/config/wifi-scripts/files/lib/netifd/wireless/mac80211.sh
package/network/config/wifi-scripts/files/usr/share/hostap/common.uc
package/network/services/hostapd/files/hostapd.uc
package/network/services/hostapd/files/wpa_supplicant.uc

index cfd74240611fc040e9b3f0e792b5f92f1b30b67e..93ab404d57cf12f851bed5146633dd9d3bd9e80b 100755 (executable)
@@ -302,7 +302,7 @@ function setup() {
                        if (mode != "ap")
                                data.config.noscan = true;
                        validate('iface', v.config);
-                       iface.prepare(v.config, data.phy + data.phy_suffix, data.config.num_global_macaddr);
+                       iface.prepare(v.config, data.phy + data.phy_suffix, data.config.num_global_macaddr, data.config.macaddr_base);
                        netifd.set_vif(k, v.config.ifname);
                        break;
                }
index 77b7adada891eaf85540586dc92016a8fe877443..4354b4f816a6d61c8a38f20be4d8314be1d82bfd 100644 (file)
                        "type": "alias",
                        "default": "bssid"
                },
+               "macaddr_base": {
+                       "type": "string",
+                       "description": "Base MAC address used for deriving interface MAC addresses"
+               },
                "max_amsdu": {
                        "description": "Maximum A-MSDU length of 7935 octects (3839 octets if option set to 0)",
                        "type": "boolean",
index c7baa8d85bd2b5fb69632723f5bd8fc213281b0e..f95f01e846807981f3877c4533098c489ff350f4 100644 (file)
@@ -544,6 +544,8 @@ export function setup(data) {
 
        if (data.config.num_global_macaddr)
                append('\n#num_global_macaddr', data.config.num_global_macaddr);
+       if (data.config.macaddr_base)
+               append('\n#macaddr_base', data.config.macaddr_base);
 
        for (let k, interface in data.interfaces) {
                if (interface.config.mode != 'ap')
index daddb801ef9bc7ccf9ce8f597af951cd158e5110..ed9b2625bb0f0524d99699d34b5358f3b7460b03 100644 (file)
@@ -178,9 +178,9 @@ function macaddr_random() {
 }
 
 let mac_idx = 0;
-export function prepare(data, phy, num_global_macaddr) {
+export function prepare(data, phy, num_global_macaddr, macaddr_base) {
        if (!data.macaddr) {
-               let pipe = fs.popen(`ucode /usr/share/hostap/wdev.uc ${phy} get_macaddr id=${mac_idx} num_global=${num_global_macaddr} mbssid=${data.mbssid ?? 0}`);
+               let pipe = fs.popen(`ucode /usr/share/hostap/wdev.uc ${phy} get_macaddr id=${mac_idx} num_global=${num_global_macaddr} mbssid=${data.mbssid ?? 0} macaddr_base=${macaddr_base}`);
 
                data.macaddr = trim(pipe.read("all"), '\n');
                pipe.close();
index 0519e5817770160cf6a6b8a8e4589b47d04b57b8..c7bfeb6b9a63a6425b61a3c0a7e110edd958a137 100644 (file)
@@ -221,6 +221,7 @@ export function setup(config, data) {
                config,
                defer: true,
                num_global_macaddr: data.config.num_global_macaddr,
+               macaddr_base: data.config.macaddr_base,
        });
 
        if (ret)
@@ -235,5 +236,6 @@ export function start(data) {
                phy: data.phy,
                radio: data.config.radio,
                num_global_macaddr: data.config.num_global_macaddr,
+               macaddr_base: data.config.macaddr_base,
        });
 };
index 1fb3edf0558d303453ad42c2d26bb2b705ab3bbe..5d9bf8ee09eb80520087a1481b4a5efb556fc994 100755 (executable)
@@ -30,6 +30,7 @@ drv_mac80211_init_device_config() {
        config_add_string tx_burst
        config_add_string distance
        config_add_string ifname_prefix
+       config_add_string macaddr_base
        config_add_int radio beacon_int chanbw frag rts
        config_add_int rxantenna txantenna txpower min_tx_power
        config_add_int num_global_macaddr multiple_bssid
@@ -530,6 +531,7 @@ ${hostapd_noscan:+noscan=1}
 ${tx_burst:+tx_queue_data2_burst=$tx_burst}
 ${multiple_bssid:+mbssid=$multiple_bssid}
 #num_global_macaddr=$num_global_macaddr
+#macaddr_base=$macaddr_base
 $base_cfg
 
 EOF
@@ -577,7 +579,7 @@ mac80211_generate_mac() {
        local phy="$1"
        local id="${macidx:-0}"
 
-       wdev_tool "$phy$phy_suffix" get_macaddr id=$id num_global=$num_global_macaddr mbssid=${multiple_bssid:-0}
+       wdev_tool "$phy$phy_suffix" get_macaddr id=$id num_global=$num_global_macaddr mbssid=${multiple_bssid:-0} macaddr_base=${macaddr_base}
 }
 
 get_board_phy_name() (
@@ -939,6 +941,7 @@ wpa_supplicant_set_config() {
        json_add_string phy "$phy"
        json_add_int radio "$radio"
        json_add_int num_global_macaddr "$num_global_macaddr"
+       json_add_string macaddr_base "$macaddr_base"
        json_add_boolean defer 1
        local data="$(json_dump)"
 
@@ -985,7 +988,7 @@ wpa_supplicant_start() {
 
        [ -n "$wpa_supp_init" ] || return 0
 
-       ubus_call wpa_supplicant config_set '{ "phy": "'"$phy"'", "radio": '"$radio"', "num_global_macaddr": '"$num_global_macaddr"' }' > /dev/null
+       ubus_call wpa_supplicant config_set '{ "phy": "'"$phy"'", "radio": '"$radio"', "num_global_macaddr": '"$num_global_macaddr"', "macaddr_base": "'"$macaddr_base"'" }' > /dev/null
 }
 
 mac80211_setup_supplicant() {
@@ -1112,7 +1115,7 @@ drv_mac80211_setup() {
                rxantenna txantenna \
                frag rts beacon_int:100 htmode \
                num_global_macaddr:1 multiple_bssid \
-               ifname_prefix
+               ifname_prefix macaddr_base
        json_get_values basic_rate_list basic_rate
        json_get_values scan_list scan_list
        json_select ..
index c6bfb62ef3c5d096d1713451568d4f734506902d..fd28b664725dc2ff97304d0d342c6549e8a0fe5b 100644 (file)
@@ -213,7 +213,9 @@ const phy_proto = {
                if (!base_mask)
                        return null;
 
-               if (base_mask == "00:00:00:00:00:00" &&
+               if (data.macaddr_base)
+                       base_addr = data.macaddr_base;
+               else if (base_mask == "00:00:00:00:00:00" &&
                    (radio_idx > 0 || idx >= num_global)) {
                        let addrs = split(phy_sysfs_file(phy, "addresses"), "\n");
 
index 1593feef6bc7469245be01f77230ef319e1013ae..053f08cb96b5206b4dbe71d534cd927e71d9a2c6 100644 (file)
@@ -280,6 +280,7 @@ function iface_macaddr_init(phydev, config, macaddr_list)
 {
        let macaddr_data = {
                num_global: config.num_global_macaddr ?? 1,
+               macaddr_base: config.macaddr_base,
                mbssid: config.mbssid ?? 0,
        };
 
@@ -750,6 +751,8 @@ function iface_load_config(phy, radio, filename)
 
                if (val[0] == "#num_global_macaddr")
                        config[substr(val[0], 1)] = int(val[1]);
+               else if (val[0] == "#macaddr_base")
+                       config[substr(val[0], 1)] = val[1];
                else if (val[0] == "mbssid")
                        config[val[0]] = int(val[1]);
 
index fbea27628e341d2f1a27b76a5e80ab0fc9f70ad2..f288121e9d4b034d051df2334056f7df52795ec9 100644 (file)
@@ -68,7 +68,7 @@ function prepare_config(config, radio)
        return { config };
 }
 
-function set_config(config_name, phy_name, radio, num_global_macaddr, config_list)
+function set_config(config_name, phy_name, radio, num_global_macaddr, macaddr_base, config_list)
 {
        let phy = wpas.data.config[config_name];
 
@@ -83,6 +83,7 @@ function set_config(config_name, phy_name, radio, num_global_macaddr, config_lis
 
        phy.radio = radio;
        phy.num_global_macaddr = num_global_macaddr;
+       phy.macaddr_base = macaddr_base;
 
        let values = [];
        for (let config in config_list)
@@ -106,7 +107,10 @@ function start_pending(phy_name)
        }
 
        let macaddr_list = wpas.data.macaddr_list[phy_name];
-       phydev.macaddr_init(macaddr_list, { num_global: phy.num_global_macaddr });
+       phydev.macaddr_init(macaddr_list, {
+               num_global: phy.num_global_macaddr,
+               macaddr_base: phy.macaddr_base,
+       });
 
        for (let ifname in phy.data)
                iface_start(phydev, phy.data[ifname]);
@@ -210,6 +214,7 @@ let main_obj = {
                        phy: "",
                        radio: 0,
                        num_global_macaddr: 0,
+                       macaddr_base: "",
                        config: [],
                        defer: true,
                },
@@ -221,7 +226,7 @@ let main_obj = {
                        wpas.printf(`Set new config for phy ${phy}`);
                        try {
                                if (req.args.config)
-                                       set_config(phy, req.args.phy, req.args.radio, req.args.num_global_macaddr, req.args.config);
+                                       set_config(phy, req.args.phy, req.args.radio, req.args.num_global_macaddr, req.args.macaddr_base, req.args.config);
 
                                if (!req.args.defer)
                                        start_pending(phy);