master
go 97 lines 3.29 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package l2topology
4
5 import (
6 "sort"
7 "strings"
8 )
9
10 func (b *deviceInterfaceSummaryBuilder) buildSummaries() map[string]topologyDeviceInterfaceSummary {
11 out := make(map[string]topologyDeviceInterfaceSummary, len(b.collectors))
12 for deviceID, col := range b.collectors {
13 sort.Slice(col.portStatuses, func(i, j int) bool {
14 left, right := col.portStatuses[i], col.portStatuses[j]
15 if left.IfIndex != right.IfIndex {
16 return left.IfIndex < right.IfIndex
17 }
18 return left.IfName < right.IfName
19 })
20
21 modeCounts := make(map[string]int)
22 roleCounts := make(map[string]int)
23 deviceVLANIDs := make(map[string]struct{})
24 portsUp := 0
25 portsDown := 0
26 portsAdminDown := 0
27 totalBandwidthBps := int64(0)
28 fdbTotalMACs := 0
29 lldpNeighborCount := 0
30 cdpNeighborCount := 0
31 portStatuses := make([]map[string]any, 0, len(col.portStatuses))
32 for _, st := range col.portStatuses {
33 evidence := col.portEvidence[st.IfIndex]
34 mode, confidence, sources, vlans := classifyTopologyPortLinkMode(evidence)
35 role, roleConfidence, roleSources := classifyTopologyPortRole(evidence)
36 st.LinkMode = mode
37 st.ModeConfidence = confidence
38 st.ModeSources = sources
39 st.VLANIDs = vlans
40 st.TopologyRole = role
41 st.RoleConfidence = roleConfidence
42 st.RoleSources = roleSources
43 if evidence != nil {
44 st.FDBMACCount = len(evidence.fdbEndpointIDs)
45 st.STPState = summarizeTopologySTPState(evidence.stpStates)
46 st.VLANs = topologyPortVLANAttributes(st.VLANIDs, evidence.vlanNames, st.LinkMode)
47 st.Neighbors = sortedTopologyPortNeighbors(evidence.neighbors)
48 }
49
50 for _, vlanID := range st.VLANIDs {
51 deviceVLANIDs[vlanID] = struct{}{}
52 }
53 if strings.EqualFold(strings.TrimSpace(st.OperStatus), "up") {
54 portsUp++
55 totalBandwidthBps = safeTopologyInt64Add(totalBandwidthBps, st.SpeedBps)
56 } else if strings.EqualFold(strings.TrimSpace(st.OperStatus), "down") || strings.EqualFold(strings.TrimSpace(st.OperStatus), "lowerlayerdown") {
57 portsDown++
58 }
59 if strings.EqualFold(strings.TrimSpace(st.AdminStatus), "down") || strings.EqualFold(strings.TrimSpace(st.AdminStatus), "administrativelydown") {
60 portsAdminDown++
61 }
62 fdbTotalMACs += st.FDBMACCount
63 for _, neighbor := range st.Neighbors {
64 switch strings.ToLower(strings.TrimSpace(neighbor.Protocol)) {
65 case "lldp":
66 lldpNeighborCount++
67 case "cdp":
68 cdpNeighborCount++
69 }
70 }
71
72 modeCounts[mode]++
73 roleCounts[role]++
74 portStatuses = append(portStatuses, buildTopologyDevicePortStatusAttributes(st))
75 }
76
77 out[deviceID] = topologyDeviceInterfaceSummary{
78 portsTotal: len(col.ifIndexes),
79 ifIndexes: sortedTopologySet(col.ifIndexes),
80 ifNames: sortedTopologySet(col.ifNames),
81 adminStatusCount: intCountMapToAny(col.adminCounts),
82 operStatusCount: intCountMapToAny(col.operCounts),
83 linkModeCount: intCountMapToAny(modeCounts),
84 roleCount: intCountMapToAny(roleCounts),
85 portsUp: portsUp,
86 portsDown: portsDown,
87 portsAdminDown: portsAdminDown,
88 totalBandwidthBps: totalBandwidthBps,
89 fdbTotalMACs: fdbTotalMACs,
90 vlanCount: len(deviceVLANIDs),
91 lldpNeighborCount: lldpNeighborCount,
92 cdpNeighborCount: cdpNeighborCount,
93 portStatuses: portStatuses,
94 }
95 }
96 return out
97 }