597a59fa3995d46193cbe88c51d6ac2bb8381d66
fix_snmp reported success on APs where the rule never reached nftables. Five defects stacked up: 1. Zone detection required ".src=" and "ssh" in the same `uci show` line. UCI prints one option per line, so anonymous rules never matched and every device fell through to the hardcoded "lan" fallback. 2. That fallback was never checked against the zones that actually exist. On an AP whose zone section has no `option name`, fw4 skips the section, so `src='lan'` referenced a zone that was not there and the rule was dropped with it. 3. The "already present" guard was a substring test, so a rule written by an earlier broken run was skipped forever instead of repaired. 4. Stale-rule deletion never committed — the only `uci commit firewall` sat in the add branch that the guard had just skipped. 5. `fw4 reload` errors were swallowed by `|| true`, and with no local snmpget the action hardcoded success = True. Now: the management address comes from $SSH_CONNECTION and is mapped to its network section (via ipaddr, or via `ip -o -4 addr` -> device when the interface is DHCP-addressed) and from there to the owning zone. A zone section without a name aborts the action with the repair command rather than writing a dead rule — naming it is left to the operator, since an inert zone becoming active changes what the AP filters. Rules are written in full every run, stale ones are deleted highest anonymous index first (uci renumbers @rule[n] on delete) and committed, reload output is no longer truncated or ignored, and success is verified on the device via `ss -lun` and a udp/161 lookup in the live ruleset.
napalm-openwrt
NAPALM community driver for OpenWrt routers and access-points.
Communicates over SSH using Netmiko (linux device type).
Requires OpenWrt 19.07 or newer.
Tested devices
| Model | OpenWrt version | Tested |
|---|---|---|
| TP-Link TL-WR1043N/ND v5 | 23.05.3 | ✅ |
Contributions for additional devices and firmware versions are welcome.
Requirements
| Dependency | Minimum version |
|---|---|
| Python | 3.8 |
| NAPALM | 4.0 |
| Netmiko | 4.0 |
Installation
From source:
git clone https://github.com/napalm-automation-community/napalm-openwrt
cd napalm-openwrt
pip install -e .
Quick start
from napalm import get_network_driver
driver = get_network_driver("openwrt")
device = driver("192.168.1.1", "root", "")
device.open()
facts = device.get_facts()
print(facts)
interfaces = device.get_interfaces()
print(interfaces)
device.close()
Supported NAPALM getters
| Getter | Supported | Notes |
|---|---|---|
get_facts |
✅ | Uses /etc/openwrt_release, /tmp/sysinfo/model, /proc/uptime |
get_interfaces |
✅ | Uses ip link show |
get_interfaces_ip |
✅ | Uses ip addr show |
get_interfaces_counters |
✅ | Uses /proc/net/dev |
get_arp_table |
✅ | Uses ip neigh show |
get_mac_address_table |
✅ | Uses bridge fdb show |
get_config |
✅ | Uses uci export |
get_environment |
✅ | CPU from /proc/stat, memory from /proc/meminfo |
get_lldp_neighbors |
✅ | Requires lldpd package installed on device |
get_lldp_neighbors_detail |
✅ | Requires lldpd package installed on device |
Configuration management
Configuration is managed via UCI (Unified Configuration Interface).
Merge candidate
device.load_merge_candidate(config="""
uci set system.@system[0].hostname='my-router'
uci set network.lan.ipaddr='10.0.0.1'
""")
print(device.compare_config())
device.commit_config()
Replace candidate
with open("full-config.uci") as f:
device.load_replace_candidate(config=f.read())
print(device.compare_config())
device.commit_config()
Rollback
# Reverts to the config state before the last commit_config call
device.rollback()
Development
# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Lint
ruff check napalm_openwrt/
Languages
Python
100%