fix(lldp): parse the v7 neighbour table, which uses a different command
get_lldp_neighbors() existed but spoke to the older CLI generation: it ran
`show lldp remote-device all` and expected FASTPATH-style `0/1` ports in
whitespace-separated columns. v7 firmware answers `Unknown command` — as it
does for `show lldp remote-device`, a bare `show lldp`, and the plural
`show lldp neighbors`. Only the singular works, though `show ?` lists `lldp`
plainly enough:
Port | Device ID | Port ID | SysName | ...
---- + ----------------- + ---------------- + ----------------- + ...
g9 | 10:01:02:44:37:26 |10:01:02:44:37:28 | pve-eze.eze.local | ...
Ports are named g9, and the columns are separated by `|` with irregular
padding, so splitting on whitespace tears the values apart. The port ID is
not always a port name either — a neighbour may identify its port by MAC.
_get_lldp_table() now branches on _detect_cli_v7() into a second parser, the
same shape get_mac_address_table() already uses for this divergence.
get_lldp_neighbors() itself is untouched.
Confirmed against a GS110TPv3 on 7.1.1.17: _detect_cli_v7() returns True
there, and the switch reports two neighbours it had never surfaced. Without
them NetOrk's map had nothing to draw for the site this switch serves, so
four APs and a firewall behind it stood unconnected.
This commit is contained in:
@@ -1052,7 +1052,9 @@ class NetgearSmartDriver(ConfigLifecycleMixin, SwitchDriver):
|
||||
return neighbors
|
||||
|
||||
def _get_lldp_table(self) -> List[Dict]:
|
||||
"""Parse ``show lldp remote-device all`` into a list of row dicts."""
|
||||
"""Parse the LLDP neighbour table into a list of row dicts."""
|
||||
if self._detect_cli_v7():
|
||||
return self._get_lldp_table_v7()
|
||||
output = self._send_command("show lldp remote-device all")
|
||||
rows: List[Dict] = []
|
||||
in_table = False
|
||||
@@ -1086,6 +1088,50 @@ class NetgearSmartDriver(ConfigLifecycleMixin, SwitchDriver):
|
||||
|
||||
return rows
|
||||
|
||||
def _get_lldp_table_v7(self) -> List[Dict]:
|
||||
"""Parse ``show lldp neighbor`` on v7 firmware.
|
||||
|
||||
The v7 CLI has neither ``show lldp remote-device all`` nor a bare
|
||||
``show lldp`` — both answer "Unknown command". Only the singular
|
||||
``neighbor`` works, and it lays the table out differently::
|
||||
|
||||
Port | Device ID | Port ID | SysName | Capabilities | TTL
|
||||
---- + ----------------- + ---------------- + ----------------- + -------------- + -----
|
||||
g9 | 10:01:02:44:37:26 |10:01:02:44:37:28 | pve-eze.eze.local | Bridge | 97
|
||||
|
||||
Ports are named ``g9`` rather than ``0/1``, and the columns are
|
||||
separated by ``|`` with irregular padding — splitting on whitespace
|
||||
would tear the values apart. The port ID is not always a port name; a
|
||||
neighbour may identify its port by MAC.
|
||||
"""
|
||||
try:
|
||||
output = self._send_paged_command("show lldp neighbor")
|
||||
except Exception: # pragma: no cover - transport failure
|
||||
return []
|
||||
|
||||
rows: List[Dict] = []
|
||||
for line in output.splitlines():
|
||||
if "|" not in line:
|
||||
continue
|
||||
cols = [c.strip() for c in line.split("|")]
|
||||
if len(cols) < 4:
|
||||
continue
|
||||
port, chassis_id, remote_port, sysname = cols[0], cols[1], cols[2], cols[3]
|
||||
if not port or port.lower() == "port" or set(port) <= set("-+ "):
|
||||
continue
|
||||
if not sysname and not remote_port:
|
||||
continue
|
||||
rows.append(
|
||||
{
|
||||
"local_port": port,
|
||||
"remote_id": "",
|
||||
"remote_chassis_id": chassis_id,
|
||||
"port_id": remote_port,
|
||||
"system_name": sysname,
|
||||
}
|
||||
)
|
||||
return rows
|
||||
|
||||
def get_lldp_neighbors_detail(self, interface: str = "") -> Dict[str, List[Dict]]:
|
||||
"""Return detailed LLDP neighbor information.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user