85041c13bbeee274aa89d0a16b95a9236d6aa5f8
Added _lldpd_fix_interface() helper that detects the management interface via the default route and strips any .VID suffix (e.g. br-ap.10 → br-ap). LLDP is L2 and must run on the bridge itself — sending on a VLAN subinterface produces tagged frames the switch won't recognize as LLDP. The helper runs every poll so existing wrong configs (e.g. eth0 from the original install action) are corrected automatically on the next poll. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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%