Skip to content

Commit

Permalink
Merge ef2d5a7 into 27a387c
Browse files Browse the repository at this point in the history
  • Loading branch information
shastrinator committed Nov 2, 2023
2 parents 27a387c + ef2d5a7 commit 32c49ed
Show file tree
Hide file tree
Showing 5 changed files with 330 additions and 48 deletions.
3 changes: 3 additions & 0 deletions cmd/opflexagentcni/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ func cmdAdd(args *skel.CmdArgs) error {
Name: result2.Interfaces[idx].Name,
Sandbox: result2.Interfaces[idx].Sandbox,
}
if idx >= 1 {
ifaceMd.HostVethName = result2.Interfaces[idx-1].Name
}
ifaceMds = append(ifaceMds, ifaceMd)
ifaceFound = true
ifaceResultIdx = idx
Expand Down
207 changes: 198 additions & 9 deletions pkg/hostagent/fabricdiscovery_lldpnmstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ type FabricDiscoveryAgentLLDPNMState struct {
collectTrigger chan bool
LLDPIntfMap map[string]*LLDPInterfaceState
LLDPNeighborMap map[string]map[string][]FabricAttachmentData
port2BridgeMap map[string]string
bridge2PortsMap map[string]map[string]bool
port2BondMap map[string]string
bond2PortsMap map[string]map[string]bool
}

func (agent *FabricDiscoveryAgentLLDPNMState) RunCommand(cmd string, cmdArgs ...string) ([]byte, error) {
Expand All @@ -36,6 +40,10 @@ func (agent *FabricDiscoveryAgentLLDPNMState) Init(ha *HostAgent) error {
agent.collectTrigger = make(chan bool)
agent.LLDPIntfMap = make(map[string]*LLDPInterfaceState)
agent.LLDPNeighborMap = make(map[string]map[string][]FabricAttachmentData)
agent.port2BridgeMap = make(map[string]string)
agent.bridge2PortsMap = make(map[string]map[string]bool)
agent.port2BondMap = make(map[string]string)
agent.bond2PortsMap = make(map[string]map[string]bool)
if ha.integ_test == nil {
_, err := agent.RunCommand("nmstatectl", "show")
return err
Expand All @@ -61,6 +69,50 @@ func (agent *FabricDiscoveryAgentLLDPNMState) TriggerCollectionDiscoveryData() {
agent.collectTrigger <- true
}

func (agent *FabricDiscoveryAgentLLDPNMState) getBondAdjacencyLocked(bond string, adj []*FabricAttachmentData) []*FabricAttachmentData {
for port := range agent.bond2PortsMap[bond] {
for sys := range agent.LLDPNeighborMap[port] {
for link := range agent.LLDPNeighborMap[port][sys] {
adj = append(adj, &agent.LLDPNeighborMap[port][sys][link])
}
}
}
return adj
}

func (agent *FabricDiscoveryAgentLLDPNMState) notifyBridge(bridge string) {
adj := []*FabricAttachmentData{}
agent.indexMutex.Lock()
for port := range agent.bridge2PortsMap[bridge] {
if _, ok := agent.bond2PortsMap[port]; ok {
adj = agent.getBondAdjacencyLocked(port, adj)
continue
}
for sys := range agent.LLDPNeighborMap[port] {
for link := range agent.LLDPNeighborMap[port][sys] {
adj = append(adj, &agent.LLDPNeighborMap[port][sys][link])
}
}
}
agent.indexMutex.Unlock()
agent.hostAgent.log.Infof("Collecting for bridge: %s", bridge)
agent.hostAgent.NotifyFabricAdjacency(bridge, adj)
}

func (agent *FabricDiscoveryAgentLLDPNMState) notifyBond(bond string) {
adj := []*FabricAttachmentData{}
agent.indexMutex.Lock()
if bridge, ok := agent.port2BridgeMap[bond]; ok {
agent.indexMutex.Unlock()
agent.notifyBridge(bridge)
return
}
adj = agent.getBondAdjacencyLocked(bond, adj)
agent.indexMutex.Unlock()
agent.hostAgent.log.Infof("Collecting for bond: %s", bond)
agent.hostAgent.NotifyFabricAdjacency(bond, adj)
}

func (agent *FabricDiscoveryAgentLLDPNMState) CollectDiscoveryData(stopCh <-chan struct{}) {
if agent.hostAgent.integ_test != nil {
return
Expand Down Expand Up @@ -89,6 +141,7 @@ func (agent *FabricDiscoveryAgentLLDPNMState) CollectDiscoveryData(stopCh <-chan
agent.hostAgent.log.Errorf("unmarshaling %v", err)
continue
}
visited := map[string]bool{}
nmOut := base.(map[string]interface{})
nmOutInterfaces := nmOut["interfaces"].([]interface{})
for _, intf := range nmOutInterfaces {
Expand All @@ -99,14 +152,86 @@ func (agent *FabricDiscoveryAgentLLDPNMState) CollectDiscoveryData(stopCh <-chan
lldpEnabled = lldpData["enabled"].(bool)
}
iface := intfData["name"].(string)
visited[iface] = true
agent.indexMutex.Lock()
agent.LLDPIntfMap[iface] = &LLDPInterfaceState{
Enabled: lldpEnabled,
InterfaceType: intfData["type"].(string),
AdminState: intfData["state"].(string),
}
bridgeNotify := false
bondNotify := false
isCompositeIf := false
var bridge, ifaceStr, bond string
if agent.LLDPIntfMap[iface].InterfaceType == "linux-bridge" {
if bridgeData, ok := intfData["bridge"].(map[string]interface{}); ok {
if bridgePorts, ok := bridgeData["port"].([]interface{}); ok {
bridgeMbrs := make(map[string]bool)
for _, bridgePortData := range bridgePorts {
bridgePort := bridgePortData.(map[string]interface{})
if port, ok := bridgePort["name"].(string); ok {
agent.port2BridgeMap[port] = iface
bridgeMbrs[port] = true
if _, ok := agent.bridge2PortsMap[iface]; !ok {
bridgeNotify = true
} else if _, ok := agent.bridge2PortsMap[iface][port]; !ok {
bridgeNotify = true
}
}
}
for currPort := range agent.bridge2PortsMap[iface] {
if _, ok := bridgeMbrs[currPort]; !ok {
delete(agent.port2BridgeMap, currPort)
bridgeNotify = true
}
}
agent.bridge2PortsMap[iface] = bridgeMbrs
}
}
bridge = iface
isCompositeIf = true
} else if agent.LLDPIntfMap[iface].InterfaceType == "bond" {

if aggData, ok := intfData["link-aggregation"].(map[string]interface{}); ok {
if portList, ok := aggData["port"].([]interface{}); ok {
portMap := make(map[string]bool)
for _, portData := range portList {
if port, ok := portData.(string); ok {
portMap[port] = true
agent.port2BondMap[port] = iface
if _, ok := agent.bond2PortsMap[iface]; !ok {
bondNotify = true
} else if _, ok := agent.bond2PortsMap[iface][port]; !ok {
bondNotify = true
}
}
}
for currPort := range agent.bond2PortsMap[iface] {
if _, ok := portMap[currPort]; !ok {
delete(agent.port2BondMap, currPort)
bondNotify = true
}
}
agent.bond2PortsMap[iface] = portMap
}
}
bond = iface
isCompositeIf = true
} else {
if bridge, ok = agent.port2BridgeMap[iface]; !ok {
bridge = "default"
}
if bridge != "default" {
ifaceStr = "bridge " + bridge + "iface " + iface
} else {
ifaceStr = "iface " + iface
}
if bond, ok = agent.port2BondMap[iface]; !ok {
bond = ""
}
}
agent.indexMutex.Unlock()
if lldpEnabled {
if lldpEnabled && !isCompositeIf {
needNotify := false
nbrList, ok := lldpData["neighbors"].([]interface{})
if !ok {
Expand Down Expand Up @@ -138,7 +263,6 @@ func (agent *FabricDiscoveryAgentLLDPNMState) CollectDiscoveryData(stopCh <-chan
agent.indexMutex.Lock()
existingNeighbors, ok := agent.LLDPNeighborMap[iface]
if ok {

if existingNeighbor, ok := existingNeighbors[fabricAtt.SystemName]; ok {
existingLink := false
for _, currLink := range existingNeighbor {
Expand All @@ -149,43 +273,108 @@ func (agent *FabricDiscoveryAgentLLDPNMState) CollectDiscoveryData(stopCh <-chan
}
if !existingLink {
agent.LLDPNeighborMap[iface][fabricAtt.SystemName] = append(agent.LLDPNeighborMap[iface][fabricAtt.SystemName], fabricAtt)
agent.hostAgent.log.Infof("LLDP Adjacency updated for iface %s: %s", iface, fabricAtt.StaticPath)
agent.hostAgent.log.Infof("LLDP Adjacency updated for %s: %s", ifaceStr, fabricAtt.StaticPath)
needNotify = true
}
} else {

agent.LLDPNeighborMap[iface][fabricAtt.SystemName] = append(agent.LLDPNeighborMap[iface][fabricAtt.SystemName], fabricAtt)
agent.hostAgent.log.Infof("LLDP Adjacency discovered for iface %s: %s", iface, fabricAtt.StaticPath)
agent.hostAgent.log.Infof("LLDP Adjacency discovered for %s: %s", ifaceStr, fabricAtt.StaticPath)
needNotify = true
}
} else {
agent.LLDPNeighborMap[iface] = make(map[string][]FabricAttachmentData)
agent.LLDPNeighborMap[iface][fabricAtt.SystemName] = append(agent.LLDPNeighborMap[iface][fabricAtt.SystemName], fabricAtt)
agent.hostAgent.log.Infof("LLDP Adjacency discovered for iface %s: %s", iface, fabricAtt.StaticPath)
agent.hostAgent.log.Infof("LLDP Adjacency discovered for %s: %s", ifaceStr, fabricAtt.StaticPath)
needNotify = true
}
agent.indexMutex.Unlock()
}
if needNotify {
adj := []*FabricAttachmentData{}
agent.indexMutex.Lock()
for sys := range agent.LLDPNeighborMap[iface] {
for link := range agent.LLDPNeighborMap[iface][sys] {
adj = append(adj, &agent.LLDPNeighborMap[iface][sys][link])
if bridge == "default" {
for sys := range agent.LLDPNeighborMap[iface] {
for link := range agent.LLDPNeighborMap[iface][sys] {
adj = append(adj, &agent.LLDPNeighborMap[iface][sys][link])
}
}
}
agent.indexMutex.Unlock()
agent.hostAgent.NotifyFabricAdjacency(iface, adj)
if bridge != "default" {
agent.notifyBridge(bridge)
} else if bond != "" {
agent.notifyBond(bond)
} else {
agent.hostAgent.NotifyFabricAdjacency(iface, adj)
}
}
}
if bridgeNotify {
agent.notifyBridge(bridge)
}
if bondNotify {
agent.notifyBond(bond)
}
}
deletedIfaces := []string{}
agent.indexMutex.Lock()
for iface := range agent.LLDPIntfMap {
if _, ok := visited[iface]; !ok {
delete(agent.LLDPIntfMap, iface)
// if port is part of a bridge/bond, then bridge/bond output will indicate missing port.
// skip notifying adjacency loss in this case
if _, ok := agent.port2BridgeMap[iface]; !ok {
if _, ok := agent.port2BondMap[iface]; !ok {
deletedIfaces = append(deletedIfaces, iface)
}
}
}
}
agent.indexMutex.Unlock()
adj := []*FabricAttachmentData{}
for _, iface := range deletedIfaces {
agent.hostAgent.NotifyFabricAdjacency(iface, adj)
}
}
}
}()
}

func (agent *FabricDiscoveryAgentLLDPNMState) GetNeighborData(iface string) ([]*FabricAttachmentData, error) {
fabAttData := []*FabricAttachmentData{}
agent.indexMutex.Lock()
defer agent.indexMutex.Unlock()
if _, ok := agent.bridge2PortsMap[iface]; ok {
for port := range agent.bridge2PortsMap[iface] {
if _, ok := agent.bond2PortsMap[port]; ok {
fabAttData = agent.getBondAdjacencyLocked(port, fabAttData)
continue
}
for sys := range agent.LLDPNeighborMap[port] {
for link := range agent.LLDPNeighborMap[port][sys] {
fabAttData = append(fabAttData, &agent.LLDPNeighborMap[port][sys][link])
}
}
}
if len(fabAttData) == 0 {
return nil, fmt.Errorf("LLDP Neighbor Data from NMState is not available yet for %s", iface)
}
return fabAttData, nil
}
if _, ok := agent.bond2PortsMap[iface]; ok {
for port := range agent.bond2PortsMap[iface] {
for sys := range agent.LLDPNeighborMap[port] {
for link := range agent.LLDPNeighborMap[port][sys] {
fabAttData = append(fabAttData, &agent.LLDPNeighborMap[port][sys][link])
}
}
}
if len(fabAttData) == 0 {
return nil, fmt.Errorf("LLDP Neighbor Data from NMState is not available yet for %s", iface)
}
return fabAttData, nil
}
fabAttMap, ok := agent.LLDPNeighborMap[iface]
if !ok {
return nil, fmt.Errorf("LLDP Neighbor Data from NMState is not available yet for %s", iface)
Expand Down

0 comments on commit 32c49ed

Please sign in to comment.