Use interface details to populate the ifmib, on startup and after each event

This commit is contained in:
Pim van Pelt
2025-06-23 19:11:28 +02:00
parent 35165b0464
commit 4f368e625d
4 changed files with 165 additions and 21 deletions

View File

@@ -7,11 +7,73 @@ import (
"go.fd.io/govpp/api"
interfaces "go.fd.io/govpp/binapi/interface"
"go.fd.io/govpp/binapi/interface_types"
"govpp-snmp-agentx/logger"
)
func WatchInterfaceEvents(ch api.Channel) error {
// InterfaceDetails holds detailed information about a VPP interface
type InterfaceDetails struct {
SwIfIndex interface_types.InterfaceIndex
InterfaceName string
MacAddress []byte
Speed uint64
AdminStatus bool
OperStatus bool
MTU uint32
}
// InterfaceEventCallback is called when interface events occur
type InterfaceEventCallback func(details []InterfaceDetails)
// GetAllInterfaceDetails retrieves detailed information for all interfaces
func GetAllInterfaceDetails(ch api.Channel) ([]InterfaceDetails, error) {
logger.Debugf("Retrieving all interface details from VPP")
// Get all interfaces
reqCtx := ch.SendMultiRequest(&interfaces.SwInterfaceDump{
SwIfIndex: ^interface_types.InterfaceIndex(0), // All interfaces
})
var details []InterfaceDetails
for {
iface := &interfaces.SwInterfaceDetails{}
stop, err := reqCtx.ReceiveReply(iface)
if stop {
break
}
if err != nil {
logger.Debugf("Error retrieving interface details: %v", err)
return nil, err
}
// Convert VPP interface flags to admin/oper status
adminUp := (iface.Flags & interface_types.IF_STATUS_API_FLAG_ADMIN_UP) != 0
operUp := (iface.Flags & interface_types.IF_STATUS_API_FLAG_LINK_UP) != 0
detail := InterfaceDetails{
SwIfIndex: iface.SwIfIndex,
InterfaceName: string(iface.InterfaceName),
MacAddress: iface.L2Address[:],
Speed: uint64(iface.LinkSpeed) * 1000, // Convert Kbps to bps
AdminStatus: adminUp,
OperStatus: operUp,
MTU: uint32(iface.LinkMtu),
}
details = append(details, detail)
logger.Debugf("Interface %d (%s): MAC=%x, Speed=%d, Admin=%t, Oper=%t, MTU=%d",
detail.SwIfIndex, detail.InterfaceName, detail.MacAddress,
detail.Speed, detail.AdminStatus, detail.OperStatus, detail.MTU)
}
logger.Debugf("Retrieved details for %d interfaces", len(details))
return details, nil
}
func WatchInterfaceEvents(ch api.Channel, callback InterfaceEventCallback) error {
logger.Debugf("WatchInterfaceEvents() called - starting interface event monitoring")
notifChan := make(chan api.Message, 100)
@@ -64,6 +126,17 @@ func WatchInterfaceEvents(ch api.Channel) error {
e := notif.(*interfaces.SwInterfaceEvent)
logger.Debugf("interface event: SwIfIndex=%d, Flags=%d, Deleted=%t",
e.SwIfIndex, e.Flags, e.Deleted)
// When an interface event occurs, retrieve all interface details and call callback
if callback != nil {
details, err := GetAllInterfaceDetails(ch)
if err != nil {
logger.Debugf("Failed to retrieve interface details after event: %v", err)
} else {
logger.Debugf("Calling interface event callback with %d interfaces", len(details))
callback(details)
}
}
}
logger.Debugf("Interface event listener goroutine ended")
}()