master
go 84 lines 2.23 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package l2topology
4
5 import (
6 "fmt"
7 "strconv"
8 "strings"
9 )
10
11 // keySep separates delimiter-based identifiers that some topology paths still split later.
12 // Opaque keys built from observation data should use opaqueCompositeKey() instead.
13 const keySep = "\x00"
14
15 func opaqueCompositeKey(parts ...string) string {
16 if len(parts) == 0 {
17 return ""
18 }
19
20 var b strings.Builder
21 for _, part := range parts {
22 b.WriteString(strconv.Itoa(len(part)))
23 b.WriteByte(':')
24 b.WriteString(part)
25 }
26 return b.String()
27 }
28
29 func topologyMatchCompositeKey(parts ...string) string {
30 return opaqueCompositeKey(parts...)
31 }
32
33 func adjacencyKey(adj Adjacency) string {
34 protocol := strings.ToLower(strings.TrimSpace(adj.Protocol))
35 sourceID := strings.TrimSpace(adj.SourceID)
36 sourcePort := strings.TrimSpace(adj.SourcePort)
37 targetID := strings.TrimSpace(adj.TargetID)
38 targetPort := strings.TrimSpace(adj.TargetPort)
39
40 return opaqueCompositeKey(protocol, sourceID, sourcePort, targetID, targetPort)
41 }
42
43 func attachmentKey(attachment Attachment) string {
44 deviceID := strings.TrimSpace(attachment.DeviceID)
45 endpointID := strings.TrimSpace(attachment.EndpointID)
46 method := strings.ToLower(strings.TrimSpace(attachment.Method))
47 vlanID := ""
48 if len(attachment.Labels) > 0 {
49 vlanID = strings.TrimSpace(attachment.Labels["vlan_id"])
50 if vlanID == "" {
51 vlanID = strings.TrimSpace(attachment.Labels["vlan"])
52 }
53 }
54 return opaqueCompositeKey(
55 deviceID,
56 strconv.Itoa(attachment.IfIndex),
57 endpointID,
58 method,
59 strings.ToLower(vlanID),
60 )
61 }
62
63 func ifaceKey(iface Interface) string {
64 return opaqueCompositeKey(iface.DeviceID, strconv.Itoa(iface.IfIndex), iface.IfName)
65 }
66
67 func deviceIfIndexKey(deviceID string, ifIndex int) string {
68 return opaqueCompositeKey(deviceID, strconv.Itoa(ifIndex))
69 }
70
71 func deriveBridgeDomainFromIfIndex(deviceID string, ifIndex int) string {
72 return fmt.Sprintf("bridge-domain:%s:if:%d", deviceID, ifIndex)
73 }
74
75 func deriveBridgeDomainFromBridgePort(deviceID, bridgePort string) string {
76 return fmt.Sprintf("bridge-domain:%s:bp:%s", deviceID, bridgePort)
77 }
78
79 func attachmentDomain(attachment Attachment) string {
80 if len(attachment.Labels) == 0 {
81 return ""
82 }
83 return strings.TrimSpace(attachment.Labels["bridge_domain"])
84 }