Add VPP API support to retrieve mtu/ifspeed/operstatus/adminstatus/mac

This commit is contained in:
Pim van Pelt
2021-09-05 19:39:20 +00:00
parent 238471d25f
commit e1cddc8c26
2 changed files with 210 additions and 11 deletions

View File

@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
from vppstats import VPPStats
import vppapi
import time
import pyagentx
import logging
@ -13,7 +14,7 @@ class NullHandler(logging.Handler):
pass
logger = logging.getLogger('pyagentx.vpp')
logger = logging.getLogger('pyagentx.vppstats')
logger.addHandler(NullHandler())
@ -47,6 +48,105 @@ class ifType(pyagentx.Updater):
self.set_INTEGER(str(i + 1), t)
class ifMtu(pyagentx.Updater):
def update(self):
global vppstat, vpp
vppstat.connect()
ifaces = vppapi.get_ifaces(vpp)
for i in range(len(vppstat['/if/names'])):
ifname = vppstat['/if/names'][i]
mtu = 0
if not ifname in ifaces:
logger.warning("Could not get MTU for interface %s", ifname)
else:
mtu = ifaces[ifname].mtu[0]
self.set_INTEGER(str(i + 1), mtu)
class ifSpeed(pyagentx.Updater):
def update(self):
global vppstat, vpp
vppstat.connect()
ifaces = vppapi.get_ifaces(vpp)
for i in range(len(vppstat['/if/names'])):
ifname = vppstat['/if/names'][i]
speed = 0
if ifname.startswith("loop") or ifname.startswith("tap"):
speed = 1000000000
elif not ifname in ifaces:
logger.warning("Could not get link speed for interface %s",
ifname)
else:
speed = ifaces[ifname].link_speed * 1000
if speed >= 2**32:
speed = 2**32 - 1
self.set_GAUGE32(str(i + 1), speed)
class ifAdminStatus(pyagentx.Updater):
def update(self):
global vppstat, vpp
vppstat.connect()
ifaces = vppapi.get_ifaces(vpp)
for i in range(len(vppstat['/if/names'])):
ifname = vppstat['/if/names'][i]
state = 3 # testing
if not ifname in ifaces:
logger.warning("Could not get AdminStatus for interface %s",
ifname)
else:
if int(ifaces[ifname].flags) & 2:
state = 1 # up
else:
state = 2 # down
self.set_INTEGER(str(i + 1), state)
class ifOperStatus(pyagentx.Updater):
def update(self):
global vppstat, vpp
vppstat.connect()
ifaces = vppapi.get_ifaces(vpp)
for i in range(len(vppstat['/if/names'])):
ifname = vppstat['/if/names'][i]
state = 3 # testing
if not ifname in ifaces:
logger.warning("Could not get OperStatus for interface %s",
ifname)
else:
if int(ifaces[ifname].flags) & 1:
state = 1 # up
else:
state = 2 # down
self.set_INTEGER(str(i + 1), state)
class ifPhysAddress(pyagentx.Updater):
def update(self):
global vppstat, vpp
vppstat.connect()
ifaces = vppapi.get_ifaces(vpp)
for i in range(len(vppstat['/if/names'])):
ifname = vppstat['/if/names'][i]
mac = "00:00:00:00:00:00"
if not ifname in ifaces:
logger.warning("Could not get PhysAddress for interface %s",
ifname)
else:
mac = str(ifaces[ifname].l2_address)
self.set_OCTETSTRING(str(i + 1), mac)
class ifAlias(pyagentx.Updater):
def update(self):
global vppstat
@ -178,11 +278,22 @@ class ifHCOutBroadcastPkts(pyagentx.Updater):
class ifHighSpeed(pyagentx.Updater):
def update(self):
global vppstat
global vppstat, vpp
vppstat.connect()
ifaces = vppapi.get_ifaces(vpp)
for i in range(len(vppstat['/if/names'])):
self.set_GAUGE32(str(i + 1), 1000)
ifname = vppstat['/if/names'][i]
speed = 0
if ifname.startswith("loop") or ifname.startswith("tap"):
speed = 1000
elif not ifname in ifaces:
logger.warning("Could not get link speed for interface %s",
ifname)
else:
speed = int(ifaces[ifname].link_speed / 1000)
self.set_GAUGE32(str(i + 1), speed)
class ifPromiscuousMode(pyagentx.Updater):
@ -319,6 +430,11 @@ class MyAgent(pyagentx.Agent):
self.register('1.3.6.1.2.1.2.2.1.1', ifIndex)
self.register('1.3.6.1.2.1.2.2.1.2', ifName)
self.register('1.3.6.1.2.1.2.2.1.3', ifType)
self.register('1.3.6.1.2.1.2.2.1.4', ifMtu)
self.register('1.3.6.1.2.1.2.2.1.5', ifSpeed)
self.register('1.3.6.1.2.1.2.2.1.6', ifPhysAddress)
self.register('1.3.6.1.2.1.2.2.1.7', ifAdminStatus)
self.register('1.3.6.1.2.1.2.2.1.8', ifOperStatus)
self.register('1.3.6.1.2.1.2.2.1.9', ifCounterDiscontinuityTime)
self.register('1.3.6.1.2.1.2.2.1.10', ifInOctets)
self.register('1.3.6.1.2.1.2.2.1.11', ifInUcastPkts)
@ -332,13 +448,6 @@ class MyAgent(pyagentx.Agent):
self.register('1.3.6.1.2.1.2.2.1.19', ifOutDiscards)
self.register('1.3.6.1.2.1.2.2.1.20', ifOutErrors)
# TODO(pim) -- these require VPP API calls
#4 .iso.org.dod.internet.mgmt.mib_2.interfaces.ifTable.ifEntry.ifMtu.132 = INTEGER: 1500
#5 .iso.org.dod.internet.mgmt.mib_2.interfaces.ifTable.ifEntry.ifSpeed.132 = Gauge32: 10000000
#6 .iso.org.dod.internet.mgmt.mib_2.interfaces.ifTable.ifEntry.ifPhysAddress.132 = Hex-STRING: 68 05 CA 32 46 15
#7 .iso.org.dod.internet.mgmt.mib_2.interfaces.ifTable.ifEntry.ifAdminStatus.132 = INTEGER: 1
#8 .iso.org.dod.internet.mgmt.mib_2.interfaces.ifTable.ifEntry.ifOperStatus.132 = INTEGER: 1
# iso.org.dod.internet.mgmt.mib_2.ifMIB.ifMIBObjects.ifXTable.ifXEntry
self.register('1.3.6.1.2.1.31.1.1.1.1', ifName)
self.register('1.3.6.1.2.1.31.1.1.1.2', ifInMulticastPkts)
@ -364,13 +473,18 @@ class MyAgent(pyagentx.Agent):
def main():
global vppstat
global vppstat, vpp, logger
pyagentx.setup_logging(debug=False)
vppstat = VPPStats(socketname='/run/vpp/stats.sock', timeout=2)
vppstat.connect()
vpp = vppapi.vpp_connect()
if not vpp:
logger.error("Can't connect to VPP API, bailing")
return
try:
a = MyAgent()
a.start()