Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
d448ee8
gitignore: Ignore __pycache__ directories
mattiaswal Oct 7, 2026
4289bf2
test: Regenerate the OSPF BFD specifications
mattiaswal Oct 7, 2026
1d37330
board: bpi-r3: Move ramdisk above the MT7986 WiFi reserved memory
mattiaswal Oct 2, 2026
aa5e053
confd: wifi: Create a hostapd control socket for every BSS
mattiaswal Oct 2, 2026
82f3427
hostapd: Allow binding WDS stations to preconfigured interfaces
mattiaswal Oct 2, 2026
c8cbab6
confd: wifi: Add 4-address WDS link and station modes
mattiaswal Oct 2, 2026
e8501ec
statd: wifi: Report wds-link state in operational data and CLI
mattiaswal Oct 2, 2026
11e0c96
webui: Show wds-link WiFi interfaces
mattiaswal Oct 2, 2026
e9a14d5
test: Add WiFi WDS link and repeater tests
mattiaswal Oct 2, 2026
895094c
doc: Document WDS backhaul and repeaters
mattiaswal Oct 2, 2026
75e3b51
test: wifimedium: Raise the carrier MTU and drop oversized frames
mattiaswal Oct 3, 2026
bcce0b6
confd: wifi: Detach a WiFi interface from hostapd before deleting it
mattiaswal Oct 2, 2026
14dc663
confd: wifi: Apply station and mesh changes on commit
mattiaswal Oct 2, 2026
4304599
confd: wifi: Collect the channel survey on request
mattiaswal Oct 5, 2026
1fd8576
cli: Add show hardware <radio> survey
mattiaswal Oct 5, 2026
3bfc7d3
webui: Scan channels on request from the WiFi page
mattiaswal Oct 5, 2026
aaa00f3
doc: Document the WiFi channel survey
mattiaswal Oct 5, 2026
68ccbaa
test: Add WiFi channel survey test
mattiaswal Oct 5, 2026
b9e0d4a
yang: Limit WiFi country codes to the regulatory database
mattiaswal Oct 6, 2026
04abc29
confd: wifi: Move the country code to a box-wide setting
mattiaswal Oct 6, 2026
0124b95
webui: Use the box-wide WiFi country code
mattiaswal Oct 6, 2026
0dd2d70
confd: wifi: Enable management frame protection on stations
mattiaswal Oct 6, 2026
587fd1f
statd: wifi: Tell WPA3-only networks apart in scan results
mattiaswal Oct 6, 2026
90e5ae5
webui: Click the survey chart to open it in an overlay
mattiaswal Oct 6, 2026
8d3403a
webui: Survive a broken YANG schema cache
mattiaswal Oct 7, 2026
0a6bbd7
confd: Run the hardware handler after the interfaces
mattiaswal Oct 7, 2026
7dfd698
hostapd: Add ft_iface for the 802.11r key holder exchange
mattiaswal Oct 7, 2026
a4e4711
confd: wifi: Exchange 802.11r keys between access points
mattiaswal Oct 7, 2026
52a2041
confd: wifi: Hand clients over before hostapd stops
mattiaswal Oct 7, 2026
5b099c6
confd: wifi: Steer dual-band clients to the higher band
mattiaswal Oct 7, 2026
23831d0
confd: wifi: Tell the other nodes about our access points
mattiaswal Oct 7, 2026
3a5ed05
patches: linux: Map the WED firmware regions without requesting them
mattiaswal Oct 2, 2026
79cbcad
patches: linux: Fix WED attach panic on non-DBDC MT7986
mattiaswal Oct 2, 2026
51301b8
patches: linux: Fix WED on the single-band MT7986 radio
mattiaswal Oct 8, 2026
f7624e1
board: bpi-r3: Enable WED in mt7915e
mattiaswal Oct 2, 2026
2f44733
onieprom: Fix encoding JSON to a TLV
mattiaswal Oct 9, 2026
c6c54e6
probe: Read the product VPD from a factory partition
mattiaswal Oct 9, 2026
a4f0057
bpi-r3: Give ports a chassis-derived address at boot
mattiaswal Oct 9, 2026
af66b33
confd: wifi: Derive VIF addresses from the chassis MAC
mattiaswal Oct 9, 2026
1f23c49
hostapd: Push PMK-R1 to the R1KHs added by RELOAD_RXKHS
mattiaswal Oct 9, 2026
d73690b
confd: wifi: Push the 802.11r keys to the other nodes' access points
mattiaswal Oct 9, 2026
8d6f687
bpi-r3: dts: Drop the ethernet aliases
mattiaswal Oct 10, 2026
447088c
webui: Add the 802.11r key holder secret to the interface editor
mattiaswal Oct 11, 2026
69704a3
hostapd: Cancel the key holder timers before RELOAD_RXKHS frees them
mattiaswal Oct 11, 2026
9cfe39e
confd: firewall: Re-apply dynamic address-set entries after reload
mattiaswal Oct 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ AGENTS.md
/test/.log
/local.mk
/test/spec/Readme.adoc
__pycache__/
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"name": "radio0",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "2.4GHz",
"channel": "auto"
}
Expand All @@ -31,7 +30,6 @@
"name": "radio1",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "6GHz",
"channel": "auto"
}
Expand All @@ -40,12 +38,14 @@
"name": "radio2",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "5GHz",
"channel": "auto"
}
}
]
],
"infix-hardware:wifi": {
"country-code": "DE"
}
},
"ietf-interfaces:interfaces": {
"interface": [
Expand Down Expand Up @@ -457,7 +457,7 @@
]
},
"infix-meta:meta": {
"version": "1.10"
"version": "1.11"
},
"infix-services:mdns": {
"enabled": true
Expand Down
30 changes: 30 additions & 0 deletions board/aarch64/bananapi-bpi-r3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,36 @@ sync
2. Set boot switches to eMMC mode (see image above)
3. Power on

## Giving the Board a Permanent MAC Address

The BPI-R3 family has no EEPROM with a factory-programmed MAC address.
Out of the box every Ethernet port therefore gets a random address on
each boot, and the hostname, which is derived from the base address,
changes with it. Worse, both WiFi radios carry the same MediaTek
default address on every board, so two boards cannot even connect to
each other over WiFi: a client refuses to authenticate to an access
point that has its own address.

The eMMC image carries an empty `factory` partition for this purpose.
Write a product record to it once, from the Infix shell, and the board
keeps that identity across reboots and upgrades:

```
echo '{"mac-address":"02:00:00:ba:01:00","serial-number":"banana1","vendor":"Bananapi","product-name":"BPI-R3"}' \
| onieprom -e | dd of=/dev/disk/by-partlabel/factory
```

Give each board its own base address and serial number, then reboot.
The base address becomes the hostname suffix, the wired ports get base
+ 1, base + 2, and so on in name order, and the WiFi interfaces get
addresses derived from the base. With the record above the board is
named `bpi-ba-01-00`, `lan1` is `02:00:00:ba:01:02` and `wifi0` is
`06:00:00:ba:01:00`.

A locally administered address like `02:xx:xx:xx:xx:xx` is fine for a
lab. For boards that will share a network with other equipment, use a
range you own. See [Vital Product Data](../../../doc/vpd.md#factory-partition)
for the record format and what else it can carry.

## Troubleshooting

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
/ {
/*
* U-Boot writes its ethaddr, which it generates at random on
* every boot, into the node behind the ethernet0 alias. The
* kernel then reports that port, and every switch port that
* inherits from it, as having a permanent hardware address.
* Drop the aliases so the ports come up with a random address
* instead, which init.d/22-macaddr replaces with a chassis-
* derived one when a product VPD is present.
*/
aliases {
/delete-property/ ethernet0;
/delete-property/ ethernet1;
};

chosen {
infix {
/* Default admin user password: 'admin' */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Wireless Ethernet Dispatch, the WiFi hardware offload path
options mt7915e wed_enable=1
86 changes: 86 additions & 0 deletions board/aarch64/bananapi-bpi-r3/rootfs/usr/libexec/bpi-r3/macaddr
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env python3
"""Give ports without a hardware MAC address a chassis-derived one.

The BPI-R3 family has no MAC EEPROM, so every port boots with a random
address, and the switch ports inherit that from their conduit. When
the product VPD provides a base MAC, hand each such port a stable
address derived from it: base + 1, base + 2, ... in interface name
order. This mirrors what products with real hardware addresses get
from their device tree. Ports with a permanent address are left alone.

Runs from /etc/product/init.d, before the DSA conduit is renamed, so
it sorts as eth0 and takes base + 1.
"""
import json
import os
import subprocess
import sys

SYSTEM_JSON = "/run/system.json"
NET = "/sys/class/net"
NET_ADDR_PERM = 0


def log(msg):
subprocess.run(["logger", "-k", "-p", "user.notice", "-t", "macaddr", msg],
check=False)


def vpd_base_mac():
try:
with open(SYSTEM_JSON, encoding="ascii") as f:
system = json.load(f)
except (OSError, ValueError):
return None

product = system.get("vpd", {}).get("product", {})
return product.get("data", {}).get("mac-address")


def mac_add(mac, offset):
num = int(mac.replace(":", ""), 16) + offset
num %= 1 << 48
return ":".join(f"{(num >> 8 * i) & 0xff:02x}" for i in range(5, -1, -1))


def read(path):
with open(path, encoding="ascii") as f:
return f.read().strip()


def ports():
"""Wired ports whose address the kernel did not get from hardware."""
for name in sorted(os.listdir(NET)):
path = os.path.join(NET, name)
if not os.path.exists(os.path.join(path, "device")):
continue
if os.path.exists(os.path.join(path, "phy80211")):
continue
try:
if int(read(os.path.join(path, "addr_assign_type"))) == NET_ADDR_PERM:
continue
except (OSError, ValueError):
continue

yield name


def main():
base = vpd_base_mac()
if not base:
return 0

for offset, name in enumerate(ports(), start=1):
mac = mac_add(base, offset)
rc = subprocess.run(["ip", "link", "set", "dev", name, "address", mac],
check=False)
if rc.returncode:
log(f"failed setting {name} address {mac}")
continue
log(f"{name}: {mac} (chassis + {offset})")

return 0


if __name__ == "__main__":
sys.exit(main())
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"name": "radio0",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "2.4GHz",
"channel": "auto"
}
Expand All @@ -31,12 +30,14 @@
"name": "radio1",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "5GHz",
"channel": "auto"
}
}
]
],
"infix-hardware:wifi": {
"country-code": "DE"
}
},
"ietf-interfaces:interfaces": {
"interface": [
Expand Down Expand Up @@ -450,7 +451,7 @@
]
},
"infix-meta:meta": {
"version": "1.10"
"version": "1.11"
},
"infix-services:mdns": {
"enabled": true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"name": "radio0",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "2.4GHz",
"channel": "auto"
}
Expand All @@ -31,12 +30,14 @@
"name": "radio1",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "5GHz",
"channel": "auto"
}
}
]
],
"infix-hardware:wifi": {
"country-code": "DE"
}
},
"ietf-interfaces:interfaces": {
"interface": [
Expand Down Expand Up @@ -416,7 +417,7 @@
]
},
"infix-meta:meta": {
"version": "1.10"
"version": "1.11"
},
"infix-services:mdns": {
"enabled": true
Expand Down
2 changes: 1 addition & 1 deletion board/aarch64/bananapi-bpi-r3/uboot/mt7986-env.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
fdt_addr_r = "0x43f00000";
kernel_addr_r = "0x44000000";
scriptaddr = "0x48000000";
ramdisk_addr_r = "0x4A000000";
ramdisk_addr_r = "0x50000000";

en8811h_fw_part = "0#en8811h_fw";
en8811h_fw_dm_dir = "EthMD32.dm.bin";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@
]
},
"infix-meta:meta": {
"version": "1.10"
"version": "1.11"
},
"infix-services:mdns": {
"enabled": true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@
]
},
"infix-meta:meta": {
"version": "1.10"
"version": "1.11"
},
"infix-services:mdns": {
"enabled": true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
"name": "radio0",
"class": "infix-hardware:wifi",
"infix-hardware:wifi-radio": {
"country-code": "DE",
"band": "2.4GHz",
"channel": "auto"
}
}
]
],
"infix-hardware:wifi": {
"country-code": "DE"
}
},
"ietf-interfaces:interfaces": {
"interface": [
Expand Down Expand Up @@ -408,7 +410,7 @@
]
},
"infix-meta:meta": {
"version": "1.10"
"version": "1.11"
},
"infix-services:mdns": {
"enabled": true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@
]
},
"infix-meta:meta": {
"version": "1.10"
"version": "1.11"
},
"infix-services:mdns": {
"enabled": true
Expand Down
10 changes: 5 additions & 5 deletions board/aarch64/raspberrypi-rpi64/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,19 +118,19 @@ Then configure the WiFi interface using the keystore reference:

```
admin@infix:/> configure
admin@infix:/config/> set hardware wifi country-code US
admin@infix:/config/> edit interface wifi0
admin@infix:/config/interface/wifi0/> set ipv4 dhcp-client
admin@infix:/config/interface/wifi0/> set wifi ssid YourNetworkName
admin@infix:/config/interface/wifi0/> set wifi secret mywifi
admin@infix:/config/interface/wifi0/> set wifi country-code US
admin@infix:/config/interface/wifi0/> set wifi station ssid YourNetworkName
admin@infix:/config/interface/wifi0/> set wifi station security secret mywifi
admin@infix:/config/interface/wifi0/> leave
```

> [!NOTE]
> The WiFi password (8-63 characters) is stored securely in the keystore as
> `mywifi` (or any name you choose), which is then referenced in the WiFi
> configuration. The country-code must match your location for regulatory
> compliance (e.g., US, SE, DE, JP).
> configuration. The country code is one setting for all radios and must
> match your location for regulatory compliance (e.g., US, SE, DE, JP).

### Touch Screen Support

Expand Down
Loading
Loading