3 Commits

Author SHA1 Message Date
Pim van Pelt
cdc8765a9e Cut release 1.2.1-1 2025-11-22 06:26:55 +01:00
Pim van Pelt
9596e16887 A few cosmetic changes in session handling 2025-11-22 06:18:01 +01:00
Pim van Pelt
4935f5a8ef Refactor code: clear old OIDs in the Session before updating them 2025-11-22 06:17:23 +01:00
4 changed files with 76 additions and 35 deletions

11
debian/changelog vendored
View File

@@ -1,3 +1,14 @@
govpp-snmp-agentx (1.2.1-1) bookworm; urgency=medium
* Fix OID visibility bug after go-agentx 0.3.0 upgrade
* Use reflection to clear handler contents instead of creating new handlers
* Simplify AgentX session creation and registration logic
* Add proper session cleanup method (Close())
* Improve error handling in AgentX interactions
* Code cleanup and maintainability improvements
-- Pim van Pelt <pim@ipng.ch> Fri, 22 Nov 2024 00:00:00 +0000
govpp-snmp-agentx (1.2.0-1) bookworm; urgency=medium
* Update go-agentx dependency from 0.2.1 to 0.3.0 to fix compilation issues

View File

@@ -20,18 +20,15 @@ var (
// StartAgentXRoutine initializes the AgentX client and registers the interface MIB
func StartAgentXRoutine(interfaceMIB *ifmib.InterfaceMIB) error {
var network, address string
// Determine network type based on address format
network := "tcp"
if strings.HasPrefix(*AgentXAddr, "/") {
network = "unix"
address = *AgentXAddr
} else {
network = "tcp"
address = *AgentXAddr
}
logger.Debugf("Connecting to AgentX at %s://%s", network, address)
logger.Debugf("Connecting to AgentX at %s://%s", network, *AgentXAddr)
client, err := agentx.Dial(network, address,
client, err := agentx.Dial(network, *AgentXAddr,
agentx.WithTimeout(1*time.Minute),
agentx.WithReconnectInterval(1*time.Second),
)
@@ -44,6 +41,6 @@ func StartAgentXRoutine(interfaceMIB *ifmib.InterfaceMIB) error {
return err
}
logger.Printf("Successfully registered with AgentX at %s://%s", network, address)
logger.Printf("Successfully registered with AgentX at %s://%s", network, *AgentXAddr)
return nil
}

View File

@@ -5,6 +5,7 @@ package ifmib
import (
"fmt"
"os"
"reflect"
"sync"
"time"
@@ -161,14 +162,32 @@ func (m *InterfaceMIB) UpdateInterfaceDetails(details []vpp.InterfaceDetails) {
logger.Debugf("Interface details updated for %d interfaces", len(details))
}
func (m *InterfaceMIB) clearHandler() {
// Use reflection to access and clear the private fields of ListHandler
// since it doesn't have a Clear() method
handlerValue := reflect.ValueOf(m.handler).Elem()
oidsField := handlerValue.FieldByName("oids")
itemsField := handlerValue.FieldByName("items")
if oidsField.IsValid() && oidsField.CanSet() {
oidsField.Set(reflect.Zero(oidsField.Type()))
}
if itemsField.IsValid() && itemsField.CanSet() {
itemsField.Set(reflect.Zero(itemsField.Type()))
}
}
func (m *InterfaceMIB) UpdateStats(interfaceStats *api.InterfaceStats) {
m.mutex.Lock()
defer m.mutex.Unlock()
logger.Debugf("Updating IF-MIB with %d interfaces", len(interfaceStats.Interfaces))
// Clear existing entries
m.handler = &agentx.ListHandler{}
// Clear existing entries while preserving the handler reference
// Since go-agentx 0.3.0 binds handlers to sessions at creation time
m.clearHandler()
m.stats = make(map[uint32]*api.InterfaceCounters)
// Add new entries
@@ -178,11 +197,7 @@ func (m *InterfaceMIB) UpdateStats(interfaceStats *api.InterfaceStats) {
m.addInterfaceToMIB(&iface)
}
// Note: With go-agentx 0.3.0, handlers are set during session creation and cannot be changed
if m.ifXTableSession != nil {
logger.Printf("Updated IF-MIB data for %d interfaces", len(m.stats))
}
logger.Debugf("IF-MIB now contains %d interfaces", len(m.stats))
}
@@ -452,37 +467,55 @@ func (m *InterfaceMIB) addIfXTable(iface *api.InterfaceCounters, idx int) {
}
}
func (m *InterfaceMIB) createAndRegisterSession(client *agentx.Client, oid, name string) (*agentx.Session, error) {
session, err := client.Session(value.MustParseOID(oid), name, m.handler)
if err != nil {
return nil, fmt.Errorf("failed to create %s session: %v", name, err)
}
err = session.Register(127, value.MustParseOID(oid))
if err != nil {
session.Close()
return nil, fmt.Errorf("failed to register %s: %v", name, err)
}
return session, nil
}
func (m *InterfaceMIB) RegisterWithClient(client *agentx.Client) error {
m.mutex.Lock()
defer m.mutex.Unlock()
// Create separate sessions for each MIB with the handler
ifEntrySession, err := client.Session(value.MustParseOID(ifEntryOID), "ifEntry", m.handler)
// Create and register sessions
ifEntrySession, err := m.createAndRegisterSession(client, ifEntryOID, "ifEntry")
if err != nil {
return fmt.Errorf("failed to create ifEntry session: %v", err)
return err
}
ifXTableSession, err := client.Session(value.MustParseOID(ifXTableOID), "ifXTable", m.handler)
ifXTableSession, err := m.createAndRegisterSession(client, ifXTableOID, "ifXTable")
if err != nil {
return fmt.Errorf("failed to create ifXTable session: %v", err)
ifEntrySession.Close()
return err
}
m.ifEntrySession = ifEntrySession
m.ifXTableSession = ifXTableSession
// Register the classic ifEntry
err = ifEntrySession.Register(127, value.MustParseOID(ifEntryOID))
if err != nil {
return fmt.Errorf("failed to register ifEntry: %v", err)
}
// Register the extended ifXTable
err = ifXTableSession.Register(127, value.MustParseOID(ifXTableOID))
if err != nil {
return fmt.Errorf("failed to register ifXTable: %v", err)
}
logger.Debugf("Registered IF-MIB ifEntry at OID %s", ifEntryOID)
logger.Debugf("Registered IF-MIB ifXTable at OID %s", ifXTableOID)
logger.Debugf("Registered IF-MIB sessions: ifEntry (%s) and ifXTable (%s)", ifEntryOID, ifXTableOID)
return nil
}
// Close cleans up AgentX sessions
func (m *InterfaceMIB) Close() {
m.mutex.Lock()
defer m.mutex.Unlock()
if m.ifEntrySession != nil {
m.ifEntrySession.Close()
m.ifEntrySession = nil
}
if m.ifXTableSession != nil {
m.ifXTableSession.Close()
m.ifXTableSession = nil
}
}

View File

@@ -16,7 +16,7 @@ import (
"govpp-snmp-agentx/vpp"
)
const Version = "1.2.0-1"
const Version = "1.2.1-1"
func main() {
debug := flag.Bool("debug", false, "Enable debug logging")