fix(lldp): локальный порт из индекса OID + lldpLocPortDesc для таблицы связей

Made-with: Cursor
This commit is contained in:
Луценко Андрей Анатольевич
2026-04-10 14:56:43 +10:00
parent 66fc827f75
commit 1df5ddf67a
+66 -1
View File
@@ -259,6 +259,11 @@ func lldpRemRowsFromWalk(rows map[string]*lldpRemAggRow, pduName string, val any
case "9":
r.sysName = v
}
// Индекс lldpRemEntry: { timeMark, localPortNum, remIndex } — часть прошивок не отдаёт колонку 2, но порт есть в суффиксе OID.
idx := parts[1:]
if len(idx) >= 3 && strings.TrimSpace(r.localPort) == "" {
r.localPort = idx[1]
}
}
// probeLLDPViaRemTableWalk один раз обходит всю lldpRemTable (стандарт IEEE 802.1AB).
@@ -395,9 +400,13 @@ func probeLLDPViaColumnWalks(client *gosnmp.GoSNMP, ip string, checkedAt time.Ti
out := make([]LLDPResult, 0, len(keys))
for k := range keys {
lp := strings.TrimSpace(ports[k])
if lp == "" {
lp = lldpRemIndexLocalPortFromKey(k)
}
item := LLDPResult{
IP: ip,
LocalPortNum: ports[k],
LocalPortNum: lp,
RemoteChassisID: chassis[k],
RemotePortID: remotePorts[k],
RemoteSysName: sysNames[k],
@@ -419,9 +428,65 @@ func probeLLDP(client *gosnmp.GoSNMP, ip string, checkedAt time.Time) []LLDPResu
if len(out) == 0 {
out = probeLLDPViaGetNextRemTable(client, ip, checkedAt)
}
return enrichLLDPLocalPortLabels(client, out)
}
// lldpRemIndexLocalPortFromKey суффикс ключа walk: timeMark.localPortNum.remIndex (IEEE LLDP remTable).
func lldpRemIndexLocalPortFromKey(key string) string {
parts := strings.Split(key, ".")
if len(parts) >= 3 {
return parts[1]
}
return ""
}
// lldpLocPortDescOIDs — lldpLocPortDesc по номеру порта (RFC 4502 и встречающийся в поле вариант).
var lldpLocPortDescOIDs = []string{
".1.0.8802.1.1.2.1.2.1.7.1.3",
".1.0.8802.1.1.2.1.3.7.1.3",
}
func probeLLDPLocPortDescByPortNum(client *gosnmp.GoSNMP) map[string]string {
out := make(map[string]string)
for _, base := range lldpLocPortDescOIDs {
for k, v := range walkAsMap(client, base) {
v = strings.TrimSpace(v)
if v != "" {
out[k] = v
}
}
}
return out
}
func formatLocalPortLabel(portNum, ifDescr string) string {
portNum = strings.TrimSpace(portNum)
ifDescr = strings.TrimSpace(ifDescr)
if ifDescr != "" && portNum != "" && ifDescr != portNum {
return portNum + " — " + ifDescr
}
if ifDescr != "" {
return ifDescr
}
return portNum
}
// enrichLLDPLocalPortLabels подставляет lldpLocPortDesc (как в CLI) к номеру локального порта.
func enrichLLDPLocalPortLabels(client *gosnmp.GoSNMP, items []LLDPResult) []LLDPResult {
if len(items) == 0 {
return items
}
descByPort := probeLLDPLocPortDescByPortNum(client)
if len(descByPort) == 0 {
return items
}
for i := range items {
num := strings.TrimSpace(items[i].LocalPortNum)
items[i].LocalPortNum = formatLocalPortLabel(num, descByPort[num])
}
return items
}
func snmpOIDTrim(s string) string {
return strings.TrimPrefix(strings.TrimSpace(s), ".")
}