travelmate: configured uplink MAC address is dropped and permanently deleted after a failed connection attempt
### Package Name
travelmate (2.4.6-r2)
### Maintainer
@dibdot
### OpenWrt Version
SNAPSHOT (r35533-3b2bc55dcb)
### OpenWrt Target/Subtarget
mediatek/filogic
### Steps to Reproduce
1. Add a `config uplink` section with `option macaddr` set to a fixed address, and keep `trm_randomize=0`.
2. Make the first connection attempt to that uplink fail. A weak signal, a busy AP, or a briefly wrong key all work.
3. Let a later retry succeed.
4. Read the log line for the successful attempt, then check `/etc/config/wireless`.
### Actual Behaviour
The configured MAC address is used on the first attempt only. If that attempt fails and a later retry succeeds, travelmate connects with the driver's own MAC instead, and commits the removal of `macaddr` from the wireless section to `/etc/config/wireless`.
Nothing reports an error. The uplink connects, so the only visible sign is the log line showing an empty MAC:
```
connected to uplink '<radio>/<essid>/<bssid>' with mac '-' (2/3)
```
To be precise about what is and is not lost, since the two are easy to confuse:
- `travelmate.@uplink[N].macaddr` — the configured value — is **not** touched.
- `wireless.<section>.macaddr` — the value `f_mac` derives from it — is removed and committed.
The station then runs with the factory MAC. Measured on the affected router by reproducing the end state: with the wireless option removed, the interface came up as `cc:d8:43:...`, the vendor OUI, instead of the configured locally-administered address.
It does not repair itself while the uplink keeps working. `f_mac "set"` is only reached on the scan/connect path, so travelmate leaves the wireless section alone for as long as the station stays associated — restarting the service is not enough. Measured: after `/etc/init.d/travelmate restart` the uplink came back up and the option was still absent.
Because the removal is committed, it also survives a reboot as an absence. On an open network the station simply associates at boot with the factory MAC, and travelmate never enters the connect path that would restore the value.
#### Root cause
All line numbers are from `net/travelmate/files/travelmate-functions.sh` at 2.4.6.
1. Line 1485 resolves the uplink section into `trm_uplinkcfg`, once, just before the retry loop starts.
2. Inside the loop, line 1488 calls `f_mac "set"`. That function reads the configured address through `f_getval "macaddr"` (line 547), which returns nothing when `trm_uplinkcfg` is empty.
3. When an attempt fails, line 1499 calls:
```sh
f_check "rev" "false"
```
`f_check` takes the radio, ESSID and BSSID as its third, fourth and fifth arguments. They are not passed here, so inside the function they are empty strings.
4. `f_check` then calls `f_getcfg "" "" ""`. `f_getcfg` begins by clearing the variable (line 529):
```sh
trm_uplinkcfg=""
```
and its matching loop requires a non-empty radio and ESSID, so it never matches. `trm_uplinkcfg` is left empty for the rest of the retry loop.
5. On the next iteration, `f_mac "set"` finds no configured address. With `trm_randomize=0` it falls through to the last branch (line 381):
```sh
uci_remove "wireless" "${section}" "macaddr" 2>/dev/null
```
6. If that attempt succeeds, line 1493 commits the pending wireless changes:
```sh
[ -n "$(uci -q changes "wireless")" ] && uci_commit "wireless"
```
The removal is part of those changes, so it is written to `/etc/config/wireless`.
In short: the uplink section is resolved once before the loop, but the failure path clears it, and the loop body assumes it is still set.
#### Suggested fix
Resolve the uplink section at the start of every iteration rather than only before the loop:
```diff
while [ "${trm_maxretry}" = "0" ] || [ "${retrycnt}" -le "${trm_maxretry}" ]; do
+ f_getcfg "${sta_radio}" "${sta_essid}" "${sta_bssid}"
sta_mac="$(f_mac "set" "${section}")"
```
Another option is to pass the station details to `f_check` in the `"rev"` call so it does not clear the variable, but re-resolving in the loop is the smaller change and keeps `f_check` untouched.
I have been running the one-line version above for several days. Forcing three consecutive failed attempts now keeps the configured MAC on every retry, and the setting survives a reboot.
#### Why it matters
A fixed per-uplink MAC address is normally set for a reason: keeping a captive portal session valid across reconnects, matching an address that has been allowed on the network, or simply not presenting the factory vendor prefix. Losing it silently defeats all three.
The trigger is ordinary. One failed first attempt is common on a busy public access point, which is exactly where a travel router spends its time, and exactly where the factory MAC is the thing you least want on air.
### Confirmation Checklist
- [X] The package is maintained in this repository.
- [X] I understand that issues related to [the base OpenWrt repository](https://github.com/openwrt/openwrt/issues) or [LuCI repository](https://github.com/openwrt/luci/issues) will be closed.
- [X] I am reporting an issue for OpenWrt, not an unsupported fork.
关闭于 27 天前 1 条评论