netgear_smart: get_lldp_neighbors() nutzt ein Kommando, das v7-Firmware nicht kennt #3

Closed
opened 2026-08-18 04:16:51 +00:00 by christianmanivong · 1 comment
Owner

Problem

netgear_smart implementiert get_lldp_neighbors() nicht. Nur netgear_plus hat eine Implementierung:

napalm_netgear/netgear_plus.py:410:    def get_lldp_neighbors(self) -> dict[str, Any]:
napalm_netgear/netgear_smart.py:      (keine)

Damit fällt der Aufruf auf die NAPALM-Basisklasse zurück und liefert nichts.

Auswirkung

NetOrk baut seine Netzwerkkarte aus LLDP-Nachbarschaften. swt-eze-core (GS110TPv3) ist der Kern-Switch des Standorts Eze; ohne Nachbarn erscheinen er und alles daran Hängende als isolierte Knoten. Vier APs, eine Firewall und ein Proxmox-Host sind betroffen.

Die MAC-Adresstabelle liefert der Treiber (29 Einträge), die Verbindung zum Gerät funktioniert also.

Zu klären

Ob die Smart-Managed-Firmware LLDP-Nachbarn über show lldp remote-device oder eine vergleichbare Ausgabe bereitstellt, ist noch nicht geprüft. netgear_plus löst es über HTTP, netgear_smart spricht CLI — die Implementierung wäre also eine eigene, keine Übernahme.

Zusammenhang: christianmanivong/netork#81

## Problem `netgear_smart` implementiert `get_lldp_neighbors()` nicht. Nur `netgear_plus` hat eine Implementierung: ``` napalm_netgear/netgear_plus.py:410: def get_lldp_neighbors(self) -> dict[str, Any]: napalm_netgear/netgear_smart.py: (keine) ``` Damit fällt der Aufruf auf die NAPALM-Basisklasse zurück und liefert nichts. ## Auswirkung NetOrk baut seine Netzwerkkarte aus LLDP-Nachbarschaften. `swt-eze-core` (GS110TPv3) ist der Kern-Switch des Standorts Eze; ohne Nachbarn erscheinen er und alles daran Hängende als isolierte Knoten. Vier APs, eine Firewall und ein Proxmox-Host sind betroffen. Die MAC-Adresstabelle liefert der Treiber (29 Einträge), die Verbindung zum Gerät funktioniert also. ## Zu klären Ob die Smart-Managed-Firmware LLDP-Nachbarn über `show lldp remote-device` oder eine vergleichbare Ausgabe bereitstellt, ist noch nicht geprüft. `netgear_plus` löst es über HTTP, `netgear_smart` spricht CLI — die Implementierung wäre also eine eigene, keine Übernahme. Zusammenhang: christianmanivong/netork#81
Author
Owner

Korrektur des Befunds — und behoben

Der Titel dieses Issues ist falsch. netgear_smart hat ein get_lldp_neighbors(). Mein grep lief mit head -1 und zeigte nur den ersten Treffer über beide Treiberdateien; da netgear_plus.py alphabetisch vorne steht, blieb netgear_smart.py unsichtbar. Ich habe daraus eine fehlende Implementierung geschlossen, die es nie war.

Was tatsächlich kaputt war

Die vorhandene Implementierung spricht eine andere CLI-Generation an:

output = self._send_command("show lldp remote-device all")
...
if not re.match(r"^\d+/\d+$", parts[0]):   # Ports wie 0/1

Auf v7-Firmware (GS110TPv3, 7.1.1.17) antwortet das Gerät darauf Unknown command. Am Gerät geprüft:

show lldp remote-device all   -> Unknown command
show lldp remote-device       -> Unknown command
show lldp                     -> Unknown command
show lldp neighbors           -> Unknown command
show lldp neighbor            -> funktioniert

Nur der Singular geht. show ? listet lldp sehr wohl auf — das Kommando war also da, nur unter anderem Namen. Und das Ausgabeformat weicht ab:

 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
  g10 | 10:01:02:44:37:26 |10:01:02:44:37:26 | pve-eze.eze.local |         Bridge |    97

Ports heissen g9 statt 0/1, und die Spalten sind durch | getrennt statt durch Leerraum — ein Split auf Whitespace zerreisst die Werte. Die Port-ID ist ausserdem nicht immer ein Portname, sondern oft die MAC des Nachbarn.

Umsetzung

_get_lldp_table() verzweigt jetzt über _detect_cli_v7() auf einen zweiten Parser, genau wie get_mac_address_table() es bereits tut. get_lldp_neighbors() selbst bleibt unverändert.

Am Gerät bestätigt: _detect_cli_v7() liefert für diesen Switch True, der neue Pfad greift also.

Tests: TestGetLldpNeighbors (7) gegen die wörtlich übernommene Geräteausgabe — Zuordnung pro lokalem Port, SysName als Hostname, Port-ID verbatim auch wenn sie eine MAC ist, Header- und Prompt-Zeilen werden nicht als Nachbarn gelesen, leere Tabelle und Unknown command ergeben ein leeres Mapping statt einer Exception. Suite: 77 passed.

Anmerkung: die neuen Signaturen verwenden Dict/List wie der Rest der Datei, was ruff 6 zusätzliche FA100 meldet — dieselbe Klasse wie die 209 bereits vorhandenen. Ein from __future__ import annotations wäre eine dateiweite Umstellung und gehört nicht in diesen Fix.

## Korrektur des Befunds — und behoben Der Titel dieses Issues ist falsch. `netgear_smart` **hat** ein `get_lldp_neighbors()`. Mein `grep` lief mit `head -1` und zeigte nur den ersten Treffer über beide Treiberdateien; da `netgear_plus.py` alphabetisch vorne steht, blieb `netgear_smart.py` unsichtbar. Ich habe daraus eine fehlende Implementierung geschlossen, die es nie war. ## Was tatsächlich kaputt war Die vorhandene Implementierung spricht eine andere CLI-Generation an: ```python output = self._send_command("show lldp remote-device all") ... if not re.match(r"^\d+/\d+$", parts[0]): # Ports wie 0/1 ``` Auf v7-Firmware (GS110TPv3, 7.1.1.17) antwortet das Gerät darauf `Unknown command`. Am Gerät geprüft: ``` show lldp remote-device all -> Unknown command show lldp remote-device -> Unknown command show lldp -> Unknown command show lldp neighbors -> Unknown command show lldp neighbor -> funktioniert ``` Nur der Singular geht. `show ?` listet `lldp` sehr wohl auf — das Kommando war also da, nur unter anderem Namen. Und das Ausgabeformat weicht ab: ``` 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 g10 | 10:01:02:44:37:26 |10:01:02:44:37:26 | pve-eze.eze.local | Bridge | 97 ``` Ports heissen `g9` statt `0/1`, und die Spalten sind durch `|` getrennt statt durch Leerraum — ein Split auf Whitespace zerreisst die Werte. Die Port-ID ist ausserdem nicht immer ein Portname, sondern oft die MAC des Nachbarn. ## Umsetzung `_get_lldp_table()` verzweigt jetzt über `_detect_cli_v7()` auf einen zweiten Parser, genau wie `get_mac_address_table()` es bereits tut. `get_lldp_neighbors()` selbst bleibt unverändert. Am Gerät bestätigt: `_detect_cli_v7()` liefert für diesen Switch `True`, der neue Pfad greift also. Tests: `TestGetLldpNeighbors` (7) gegen die wörtlich übernommene Geräteausgabe — Zuordnung pro lokalem Port, SysName als Hostname, Port-ID verbatim auch wenn sie eine MAC ist, Header- und Prompt-Zeilen werden nicht als Nachbarn gelesen, leere Tabelle und `Unknown command` ergeben ein leeres Mapping statt einer Exception. Suite: 77 passed. Anmerkung: die neuen Signaturen verwenden `Dict`/`List` wie der Rest der Datei, was ruff 6 zusätzliche `FA100` meldet — dieselbe Klasse wie die 209 bereits vorhandenen. Ein `from __future__ import annotations` wäre eine dateiweite Umstellung und gehört nicht in diesen Fix.
christianmanivong changed title from netgear_smart: get_lldp_neighbors() fehlt (nur netgear_plus hat es) to netgear_smart: get_lldp_neighbors() nutzt ein Kommando, das v7-Firmware nicht kennt 2026-08-18 08:18:40 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: NAPALM/napalm-netgear#3