Exception in lan backend when dhcp config contains host entries with a list of MAC addresses
reForis version: 1.0.8
Turris OS version: 5.2.2
When trying to open the reForis Network Settings - LAN
page, the following error was shown under the page header: 'An unknown API error occurred'. When I checked the page in the Firefox debugger, I got some more details:
500 - Server error
Error:
Remote Exception: Internal error 'list' object has no attribute 'strip'('<class 'AttributeError'>')
Extra:
{"module": "lan", "action": "get_settings", "kind": "request"}
Trace:
Traceback (most recent call last): File "/usr/lib/python3.7/site-packages/foris_controller/message_router.py", line 117, in process_message File "/usr/lib/python3.7/site-packages/foris_controller/module_base.py", line 61, in perform_action File "/usr/lib/python3.7/site-packages/foris_controller_modules/lan/__init__.py", line 35, in action_get_settings File "/usr/lib/python3.7/site-packages/foris_controller/utils.py", line 111, in inner File "/usr/lib/python3.7/site-packages/foris_controller_modules/lan/handlers/openwrt.py", line 41, in get_settings File "/usr/lib/python3.7/site-packages/foris_controller_backends/lan/__init__.py", line 169, in get_settings File "/usr/lib/python3.7/site-packages/foris_controller_backends/lan/__init__.py", line 89, in get_client_list AttributeError: 'list' object has no attribute 'strip'
After some debugging I found that the lan backend of foris-controller has a problem with dhcp host entries (aka static leases) which contain a list of MAC addresses.
Example: A host entry in /etc/config/dhcp
looking like
config host
list mac 'A4:34:D9:ED:8B:6D'
list mac '50:7B:9D:D5:A9:65'
option name 'moka'
option ip '172.30.42.200'
causes an exception in foris_controller_backends.lan.LanUci.get_client_list(..)
The problem is the following line in get_client_list(..)
:
record["data"]["mac"] = record["data"]["mac"].strip().upper()
which doesn't expect record["data"]["mac"]
to contain a list. The problem can be fixed using the following change:
for record in uci_data:
if "mac" in record["data"]:
- record["data"]["mac"] = record["data"]["mac"].strip().upper()
+ # handle a simple string or a list of MAC addresses
+ if isinstance(record["data"]["mac"], str):
+ record["data"]["mac"] = [record["data"]["mac"]]
+ record["data"]["mac"] = " ".join([e.strip().upper() for e in record["data"]["mac"]])
uci_map = {
e["data"]["mac"]: e["data"]
Note: There is an inconsistency in OpenWRT regarding the definition of dhcp host entries. The documentation (https://openwrt.org/docs/guide-user/base-system/dhcp) claims that multiple MAC addresses can be configured by separating them with spaces (e.g. option mac 11:22:33:44:55:66 21:22:23:24:25:26
). And this is still the only way to enter multiple MAC addresses via the Web UI. However, when such a configuration gets saved, the Web UI gets confused and doesn't display such entries properly (instead of the MAC addresses, luci just displays none
). This can be fixed by manually updating the config file and create list entries instead. Such entries are then properly displayed in the Web UI (and they also work internally - the resulting dnsmasq config is identical). So the situation is a bit messy. Maybe this is an issue which should be fixed in OpenWRT first. However, the local fix (or workaround?) in reForis shown above seems to be simple enough (and would support both options)?