Add -vppcfg flag to set ifAlias from the 'description' fields in vppcfg.yaml

This commit is contained in:
Pim van Pelt
2025-06-09 19:12:05 +02:00
parent 069b1b6fc2
commit 458168e308
6 changed files with 136 additions and 2 deletions

View File

@ -2,6 +2,7 @@ package ifmib
import (
"fmt"
"io/ioutil"
"sync"
"time"
@ -9,6 +10,7 @@ import (
"github.com/posteo/go-agentx/pdu"
"github.com/posteo/go-agentx/value"
"go.fd.io/govpp/api"
"gopkg.in/yaml.v3"
"govpp-snmp-example/logger"
"govpp-snmp-example/vppstats"
@ -56,22 +58,36 @@ import (
// ifHCOutUcastPkts .11 - Counter64
// ifHCOutMulticastPkts .12 - Counter64
// ifHCOutBroadcastPkts .13 - Counter64
// ifAlias .18 - DisplayString
const ifEntryOID = "1.3.6.1.2.1.2.2.1"
const ifXTableOID = "1.3.6.1.2.1.31.1.1.1"
// VPP Config YAML structures
type VPPConfig struct {
Interfaces map[string]VPPInterface `yaml:"interfaces"`
Loopbacks map[string]VPPInterface `yaml:"loopbacks"`
}
type VPPInterface struct {
Description string `yaml:"description"`
SubInterfaces map[string]VPPInterface `yaml:"sub-interfaces"`
}
type InterfaceMIB struct {
mutex sync.RWMutex
handler *agentx.ListHandler
ifEntrySession *agentx.Session
ifXTableSession *agentx.Session
stats map[uint32]*api.InterfaceCounters // indexed by interface index
descriptions map[string]string // interface name -> description mapping
}
func NewInterfaceMIB() *InterfaceMIB {
return &InterfaceMIB{
handler: &agentx.ListHandler{},
stats: make(map[uint32]*api.InterfaceCounters),
handler: &agentx.ListHandler{},
stats: make(map[uint32]*api.InterfaceCounters),
descriptions: make(map[string]string),
}
}
@ -79,6 +95,51 @@ func (m *InterfaceMIB) GetHandler() *agentx.ListHandler {
return m.handler
}
func (m *InterfaceMIB) LoadVPPConfig(configPath string) error {
m.mutex.Lock()
defer m.mutex.Unlock()
// Read YAML file
data, err := ioutil.ReadFile(configPath)
if err != nil {
return fmt.Errorf("failed to read VPP config file: %v", err)
}
// Parse YAML
var config VPPConfig
if err := yaml.Unmarshal(data, &config); err != nil {
return fmt.Errorf("failed to parse VPP config YAML: %v", err)
}
// Extract interface descriptions
for ifName, ifConfig := range config.Interfaces {
if ifConfig.Description != "" {
m.descriptions[ifName] = ifConfig.Description
logger.Debugf("Loaded description for interface %s: %s", ifName, ifConfig.Description)
}
// Process sub-interfaces
for subID, subConfig := range ifConfig.SubInterfaces {
if subConfig.Description != "" {
subIfName := fmt.Sprintf("%s.%s", ifName, subID)
m.descriptions[subIfName] = subConfig.Description
logger.Debugf("Loaded description for sub-interface %s: %s", subIfName, subConfig.Description)
}
}
}
// Extract loopback descriptions
for ifName, ifConfig := range config.Loopbacks {
if ifConfig.Description != "" {
m.descriptions[ifName] = ifConfig.Description
logger.Debugf("Loaded description for loopback %s: %s", ifName, ifConfig.Description)
}
}
logger.Printf("Loaded %d interface descriptions from VPP config", len(m.descriptions))
return nil
}
func (m *InterfaceMIB) UpdateStats(interfaceStats *api.InterfaceStats) {
m.mutex.Lock()
defer m.mutex.Unlock()
@ -298,6 +359,16 @@ func (m *InterfaceMIB) addIfXTable(iface *api.InterfaceCounters, idx int) {
item = m.handler.Add(fmt.Sprintf("%s.13.%d", ifXTableOID, idx))
item.Type = pdu.VariableTypeCounter64
item.Value = iface.TxBroadcast.Packets
// ifAlias (.18) - Interface description/alias
item = m.handler.Add(fmt.Sprintf("%s.18.%d", ifXTableOID, idx))
item.Type = pdu.VariableTypeOctetString
// Use description from VPP config if available, otherwise use interface name
if desc, exists := m.descriptions[iface.InterfaceName]; exists {
item.Value = desc
} else {
item.Value = iface.InterfaceName
}
}
func (m *InterfaceMIB) RegisterWithClient(client *agentx.Client) error {