master
go 148 lines 4.36 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package l2topology
4
5 import "strings"
6
7 func (s *l2BuildState) applyLLDP(observations []L2Observation) {
8 lldpLinks := buildLLDPMatchLinks(observations)
9 annotateLLDPLinkMatchIdentities(lldpLinks, s.hostToID, s.chassisToID, s.ipToID)
10 lldpPairs := matchLLDPLinksEnlinkdPassOrder(lldpLinks)
11 lldpTargetOverrides := buildLLDPTargetOverrides(lldpLinks, lldpPairs)
12 lldpPairMetadata := buildLLDPPairMetadata(lldpLinks, lldpPairs)
13
14 for _, link := range lldpLinks {
15 targetID := strings.TrimSpace(lldpTargetOverrides[link.index])
16 if targetID == "" {
17 targetID = s.resolveRemote(link.remoteSysName, link.remoteChassisID, link.remoteManagement, link.remoteFallbackID)
18 }
19
20 adj := Adjacency{
21 Protocol: "lldp",
22 SourceID: link.sourceDeviceID,
23 SourcePort: link.sourcePort,
24 TargetID: targetID,
25 TargetPort: link.targetPort,
26 }
27 applyAdjacencyPairMetadata(&adj, lldpPairMetadata[link.index])
28 if addAdjacency(s.adjacencies, adj) {
29 s.linksLLDP++
30 }
31 }
32 }
33
34 func (s *l2BuildState) applyCDP(observations []L2Observation) {
35 cdpLinks := buildCDPMatchLinks(observations)
36 cdpPairs := matchCDPLinksEnlinkdPassOrder(cdpLinks)
37 cdpTargetOverrides := buildCDPTargetOverrides(cdpLinks, cdpPairs)
38 cdpPairMetadata := buildCDPPairMetadata(cdpLinks, cdpPairs)
39
40 for _, link := range cdpLinks {
41 rawAddress := strings.TrimSpace(link.remoteAddressRaw)
42 targetID := strings.TrimSpace(cdpTargetOverrides[link.index])
43 if targetID == "" {
44 targetIP := canonicalIP(rawAddress)
45 targetID = s.resolveRemoteEnforcingHostnameMACGuard(link.remoteHost, link.remoteDeviceID, targetIP, link.remoteDeviceID)
46 }
47
48 adj := Adjacency{
49 Protocol: "cdp",
50 SourceID: link.sourceDeviceID,
51 SourcePort: link.localInterfaceName,
52 TargetID: targetID,
53 TargetPort: link.remoteDevicePort,
54 }
55 if rawAddress != "" {
56 adj.Labels = map[string]string{
57 "remote_address_raw": strings.ToLower(rawAddress),
58 }
59 }
60 applyAdjacencyPairMetadata(&adj, cdpPairMetadata[link.index])
61 if addAdjacency(s.adjacencies, adj) {
62 s.linksCDP++
63 }
64 }
65 }
66
67 func (s *l2BuildState) applySTP(observations []L2Observation) {
68 for _, obs := range observations {
69 sourceID := strings.TrimSpace(obs.DeviceID)
70 if sourceID == "" {
71 continue
72 }
73
74 localBridgeAddr := canonicalBridgeAddr(obs.BaseBridgeAddress, obs.ChassisID)
75 bridgePortToIfIndex := make(map[string]int, len(obs.BridgePorts))
76 for _, bridgePort := range sortedBridgePorts(obs.BridgePorts) {
77 basePort := strings.TrimSpace(bridgePort.BasePort)
78 if basePort == "" || bridgePort.IfIndex <= 0 {
79 continue
80 }
81 bridgePortToIfIndex[basePort] = bridgePort.IfIndex
82 }
83
84 for _, entry := range sortedSTPPortEntries(obs.STPPorts) {
85 remoteBridgeAddr := canonicalBridgeAddr(entry.DesignatedBridge, "")
86 if remoteBridgeAddr == "" {
87 continue
88 }
89 if localBridgeAddr != "" && localBridgeAddr == remoteBridgeAddr {
90 continue
91 }
92
93 targetID := strings.TrimSpace(s.bridgeAddrToID[remoteBridgeAddr])
94 if targetID == "" || targetID == sourceID {
95 continue
96 }
97
98 ifIndex := entry.IfIndex
99 if ifIndex <= 0 {
100 ifIndex = bridgePortToIfIndex[strings.TrimSpace(entry.Port)]
101 }
102 sourcePort := strings.TrimSpace(entry.IfName)
103 if sourcePort == "" && ifIndex > 0 {
104 sourcePort = strings.TrimSpace(s.ifNameByDeviceIfIndex[deviceIfIndexKey(sourceID, ifIndex)])
105 }
106 if sourcePort == "" {
107 sourcePort = strings.TrimSpace(entry.Port)
108 }
109
110 adj := Adjacency{
111 Protocol: "stp",
112 SourceID: sourceID,
113 SourcePort: sourcePort,
114 TargetID: targetID,
115 TargetPort: strings.TrimSpace(entry.DesignatedPort),
116 }
117 labels := make(map[string]string)
118 if v := strings.TrimSpace(entry.Port); v != "" {
119 labels["stp_port"] = v
120 }
121 if v := strings.TrimSpace(entry.State); v != "" {
122 labels["stp_state"] = v
123 }
124 if v := strings.TrimSpace(entry.Enable); v != "" {
125 labels["stp_enable"] = v
126 }
127 if v := strings.TrimSpace(entry.PathCost); v != "" {
128 labels["stp_path_cost"] = v
129 }
130 if v := strings.TrimSpace(entry.DesignatedRoot); v != "" {
131 labels["stp_designated_root"] = v
132 }
133 if v := strings.TrimSpace(entry.VLANID); v != "" {
134 labels["vlan_id"] = v
135 labels["vlan"] = v
136 }
137 if v := strings.TrimSpace(entry.VLANName); v != "" {
138 labels["vlan_name"] = v
139 }
140 if len(labels) > 0 {
141 adj.Labels = labels
142 }
143 if addAdjacency(s.adjacencies, adj) {
144 s.linksSTP++
145 }
146 }
147 }
148 }