Skip to content

Commit

Permalink
[lldp] LLDP-MIB indexes according to specification (sonic-net#78)
Browse files Browse the repository at this point in the history
* 802.1ab update indexes according to specification
* review coments - no global vars, logging, etc
  • Loading branch information
mykolaf authored and qiluo-msft committed Aug 14, 2018
1 parent fd9ac3e commit b180f44
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 52 deletions.
107 changes: 69 additions & 38 deletions src/sonic_ax_impl/mibs/ieee802_1ab.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,15 @@ def port_table_lookup(self, sub_id, table_name):
logger.warning(" 0 - b'PORT_TABLE' missing attribute '{}'.".format(e))
return None

def port_id_subtype(self, sub_id):
"""
return port_id_subtype 7(local)
for every port
"""
if len(sub_id) == 0:
return None
return 7


class LLDPLocManAddrUpdater(MIBUpdater):
def __init__(self):
Expand All @@ -274,10 +283,14 @@ def reinit_data(self):
self.mgmt_ip_str = mgmt_ip_bytes.decode()
logger.debug("Got mgmt ip from db : {}".format(self.mgmt_ip_str))
try:
mgmt_ip_sub_oid = tuple([int(i) for i in self.mgmt_ip_str.split('.')])
addr_subtype_sub_oid = 4
mgmt_ip_sub_oid = (addr_subtype_sub_oid, *[int(i) for i in self.mgmt_ip_str.split('.')])
except ValueError:
logger.error("Invalid local mgmt IP {}".format(self.mgmt_ip_str))
self.man_addr_list.append(mgmt_ip_sub_oid)
return
sub_oid = (ManAddrConst.man_addr_subtype_ipv4,
*mgmt_ip_sub_oid)
self.man_addr_list.append(sub_oid)

def update_data(self):
"""
Expand Down Expand Up @@ -370,22 +383,32 @@ def update_data(self):
lldp_kvs = self.db_conn.get_all(mibs.APPL_DB, mibs.lldp_entry_table(if_name))
if not lldp_kvs:
continue
self.if_range.append((if_oid, ))
self.lldp_counters.update({if_name: lldp_kvs})
try:
time_mark = int(lldp_kvs[b'lldp_rem_time_mark'])
remote_index = int(lldp_kvs[b'lldp_rem_index'])
self.if_range.append((time_mark,
if_oid,
remote_index))

self.lldp_counters.update({if_name: lldp_kvs})
except (KeyError, AttributeError) as e:
logger.warning("Exception when updating lldpRemTable: {}".format(e))
continue

self.if_range.sort()

def local_port_num(self, sub_id):
if len(sub_id) == 0:
return None
sub_id = sub_id[0]
sub_id = sub_id[1]
if sub_id not in self.oid_name_map:
return None
return int(sub_id)

def lldp_table_lookup(self, sub_id, table_name):
if len(sub_id) == 0:
return None
sub_id = sub_id[0]
sub_id = sub_id[1]
if sub_id not in self.oid_name_map:
return None
if_name = self.oid_name_map[sub_id]
Expand Down Expand Up @@ -424,25 +447,37 @@ def __init__(self):
self.pubsub = None

def update_rem_if_mgmt(self, if_oid, if_name):
mgmt_ip_bytes = self.db_conn.get(mibs.APPL_DB, mibs.lldp_entry_table(if_name),
b'lldp_rem_man_addr')
if not mgmt_ip_bytes:
lldp_kvs = self.db_conn.get_all(mibs.APPL_DB, mibs.lldp_entry_table(if_name))
if not lldp_kvs or b'lldp_rem_man_addr' not in lldp_kvs:
# this interfaces doesn't have remote lldp data, or the peer doesn't advertise his mgmt address
return
mgmt_ip_str = mgmt_ip_bytes.decode()
subtype = self.get_subtype(mgmt_ip_str)
ip_hex = self.get_ip_hex(mgmt_ip_str, subtype)
mgmt_ip_sub_oid = None
if subtype == ManAddrConst.man_addr_subtype_ipv4:
mgmt_ip_sub_oid = tuple(int(i) for i in mgmt_ip_str.split('.'))
elif subtype == ManAddrConst.man_addr_subtype_ipv6:
mgmt_ip_sub_oid = tuple(int(i, 16) if i else 0 for i in mgmt_ip_str.split(':'))
else:
logger.warning("Ivalid management IP {}".format(mgmt_ip_str))
try:
mgmt_ip_str = lldp_kvs[b'lldp_rem_man_addr'].decode()
time_mark = int(lldp_kvs[b'lldp_rem_time_mark'])
remote_index = int(lldp_kvs[b'lldp_rem_index'])
subtype = self.get_subtype(mgmt_ip_str)
ip_hex = self.get_ip_hex(mgmt_ip_str, subtype)
if subtype == ManAddrConst.man_addr_subtype_ipv4:
addr_subtype_sub_oid = 4
mgmt_ip_sub_oid = (addr_subtype_sub_oid, *[int(i) for i in mgmt_ip_str.split('.')])
elif subtype == ManAddrConst.man_addr_subtype_ipv6:
addr_subtype_sub_oid = 6
mgmt_ip_sub_oid = (addr_subtype_sub_oid, *[int(i, 16) if i else 0 for i in mgmt_ip_str.split(':')])
else:
logger.warning("Invalid management IP {}".format(mgmt_ip_str))
return
self.if_range.append((time_mark,
if_oid,
remote_index,
subtype,
*mgmt_ip_sub_oid))

self.mgmt_ips.update({if_name: {"ip_str": mgmt_ip_str,
"addr_subtype": subtype,
"addr_hex": ip_hex}})
except (KeyError, AttributeError) as e:
logger.warning("Error updating remote mgmt addr: {}".format(e))
return
self.if_range.append((if_oid, *mgmt_ip_sub_oid))
self.mgmt_ips.update({if_name: {"ip_str": mgmt_ip_str,
"addr_subtype": subtype,
"addr_hex": ip_hex}})
self.if_range.sort()

def update_data(self):
Expand Down Expand Up @@ -490,7 +525,7 @@ def get_next(self, sub_id):
def lookup(self, sub_id, callable):
if len(sub_id) == 0:
return None
sub_id = sub_id[0]
sub_id = sub_id[1]
if sub_id not in self.oid_name_map:
return None
if_name = self.oid_name_map[sub_id]
Expand Down Expand Up @@ -543,21 +578,15 @@ def man_addr_if_id(sub_id, _): return ManAddrConst.man_addr_if_id
def man_addr_OID(sub_id, _): return ManAddrConst.man_addr_oid


_lldp_updater = LLDPRemTableUpdater()
_port_updater = LocPortUpdater()
_chassis_updater = LLDPLocalSystemDataUpdater()
_loc_man_addr_updater = LLDPLocManAddrUpdater()
_rem_man_addr_updater = LLDPRemManAddrUpdater()


class LLDPLocalSystemData(metaclass=MIBMeta, prefix='.1.0.8802.1.1.2.1.3'):
"""
lldpLocalSystemData OBJECT IDENTIFIER
::= { lldpObjects 3 }
"""
chassis_updater = _chassis_updater
chassis_updater = LLDPLocalSystemDataUpdater()

lldpLocChassisIdSubtype = MIBEntry('1', ValueType.INTEGER, chassis_updater.table_lookup_integer, LLDPLocalChassis(1))
lldpLocChassisIdSubtype = MIBEntry('1', ValueType.INTEGER, chassis_updater.table_lookup_integer,
LLDPLocalChassis(1))

lldpLocChassisId = MIBEntry('2', ValueType.OCTET_STRING, chassis_updater.table_lookup, LLDPLocalChassis(2))

Expand Down Expand Up @@ -588,14 +617,14 @@ class LLDPLocPortTable(metaclass=MIBMeta, prefix='.1.0.8802.1.1.2.1.3.7'):
}
"""
port_updater = _port_updater
port_updater = LocPortUpdater()

# lldpLocPortEntry = '1'

lldpLocPortNum = SubtreeMIBEntry('1.1', port_updater, ValueType.INTEGER, port_updater.local_port_num)

# We're using locally assigned name, so according to textual convention, the subtype is 7
lldpLocPortIdSubtype = SubtreeMIBEntry('1.2', port_updater, ValueType.INTEGER, lambda _: 7)
lldpLocPortIdSubtype = SubtreeMIBEntry('1.2', port_updater, ValueType.INTEGER, port_updater.port_id_subtype)

lldpLocPortId = SubtreeMIBEntry('1.3', port_updater, ValueType.OCTET_STRING, port_updater.local_port_id)

Expand All @@ -613,7 +642,8 @@ class LLDPLocManAddrTable(metaclass=MIBMeta, prefix='.1.0.8802.1.1.2.1.3.8'):
local system known to this agent."
::= { lldpLocalSystemData 8 }
"""
updater = _loc_man_addr_updater
updater = LLDPLocManAddrUpdater()

lldpLocManAddrSubtype = SubtreeMIBEntry('1.1', updater, ValueType.INTEGER,
updater.lookup, updater.man_addr_subtype)

Expand Down Expand Up @@ -721,7 +751,7 @@ class LLDPRemTable(metaclass=MIBMeta, prefix='.1.0.8802.1.1.2.1.4.1'):
lldpRemSysCapEnabled LldpSystemCapabilitiesMap
}
"""
lldp_updater = _lldp_updater
lldp_updater = LLDPRemTableUpdater()

lldpRemTimeMark = \
SubtreeMIBEntry('1.1', lldp_updater, ValueType.TIME_TICKS, lldp_updater.lldp_table_lookup_integer,
Expand Down Expand Up @@ -783,7 +813,8 @@ class LLDPRemManAddrTable(metaclass=MIBMeta, prefix='.1.0.8802.1.1.2.1.4.2'):
contained in the local chassis known to this agent."
::= { lldpRemoteSystemsData 2 }
"""
updater = _rem_man_addr_updater
updater = LLDPRemManAddrUpdater()

lldpRemManAddrSubtype = SubtreeMIBEntry('1.1', updater, ValueType.INTEGER,
updater.lookup, updater.man_addr_subtype)

Expand Down
26 changes: 12 additions & 14 deletions tests/test_lldp.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class LLDPMIB(ieee802_1ab.LLDPLocalSystemData,
updater.update_data()

def test_getnextpdu_eth1(self):
oid = ObjectIdentifier(12, 0, 1, 0, (1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, 7, 1))
oid = ObjectIdentifier(12, 0, 1, 0, (1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, 7, 1, 1))
get_pdu = GetNextPDU(
header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0),
oids=[oid]
Expand All @@ -46,12 +46,12 @@ def test_getnextpdu_eth1(self):
value0 = response.values[0]
self.assertEqual(value0.type_, ValueType.OCTET_STRING)
print("test_getnextpdu_exactmatch: ", str(oid))
self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, 7, 1))))
self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, 7, 1, 1))))
self.assertEqual(str(value0.data), "Ethernet1")

def test_getnextpdu_eth2(self):
# oid.include = 1
oid = ObjectIdentifier(12, 0, 1, 0, (1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, 7, 5))
oid = ObjectIdentifier(12, 0, 1, 0, (1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, 7, 1, 5))
get_pdu = GetNextPDU(
header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0),
oids=[oid]
Expand All @@ -64,13 +64,13 @@ def test_getnextpdu_eth2(self):
value0 = response.values[0]
self.assertEqual(value0.type_, ValueType.OCTET_STRING)
print("test_getnextpdu_exactmatch: ", str(oid))
self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, 7, 5))))
self.assertEqual(str(value0.name), str(ObjectIdentifier(11, 0, 1, 0, (1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, 7, 1, 5))))
self.assertEqual(str(value0.data), "Ethernet2")

def test_subtype_lldp_rem_table(self):
for entry in range(2, 13):
mib_entry = self.lut[(1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, entry)]
ret = mib_entry(sub_id=(1,))
ret = mib_entry(sub_id=(1, 1))
self.assertIsNotNone(ret)
print(ret)

Expand Down Expand Up @@ -98,20 +98,20 @@ def test_subtype_lldp_loc_man_addr_table(self):
def test_subtype_lldp_rem_man_addr_table(self):
for entry in range(1, 6):
mib_entry = self.lut[(1, 0, 8802, 1, 1, 2, 1, 4, 2, 1, entry)]
ret = mib_entry(sub_id=(1,))
ret = mib_entry(sub_id=(1, 1))
self.assertIsNotNone(ret)
print(ret)

def test_ipv4_rem_man_addr(self):
# ethernet0 has IPv4 remote management address
interface_number = 1
mib_entry = self.lut[(1, 0, 8802, 1, 1, 2, 1, 4, 2, 1, 2)]
ret = mib_entry(sub_id=(interface_number,))
ret = mib_entry(sub_id=(1, interface_number,))
self.assertEquals(ret, "0A E0 19 64")
print(ret)
# test remManAddrSubtype
mib_entry = self.lut[(1, 0, 8802, 1, 1, 2, 1, 4, 2, 1, 1)]
ret = mib_entry(sub_id=(interface_number,))
ret = mib_entry(sub_id=(1, interface_number,))
# subtype 1 means IPv4
self.assertEquals(ret, 1)
print(ret)
Expand All @@ -120,12 +120,12 @@ def test_ipv6_rem_man_addr(self):
# ethernet4 has IPv6 remote management address
interface_number = 5
mib_entry = self.lut[(1, 0, 8802, 1, 1, 2, 1, 4, 2, 1, 2)]
ret = mib_entry(sub_id=(interface_number,))
ret = mib_entry(sub_id=(1, interface_number,))
self.assertEquals(ret, "fe80 0 268a 7ff fe3f 834c")
print(ret)
# test remManAddrSubtype
mib_entry = self.lut[(1, 0, 8802, 1, 1, 2, 1, 4, 2, 1, 1)]
ret = mib_entry(sub_id=(interface_number,))
ret = mib_entry(sub_id=(1, interface_number,))
# subtype 2 means IPv6
self.assertEquals(ret, 2)
print(ret)
Expand All @@ -139,7 +139,7 @@ def test_local_port_identification(self):
def test_local_port_num(self):
mib_entry = self.lut[(1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, 2)]
for num in range(1, 126, 4):
ret = mib_entry(sub_id=(num,))
ret = mib_entry(sub_id=(1, num,))
self.assertEqual(ret, num)

def test_getnextpdu_local_port_identification(self):
Expand Down Expand Up @@ -177,10 +177,9 @@ def test_lab_breaks(self):
resp = pdu.make_response(self.lut)
print(resp)


def test_getnextpdu_noeth(self):
# oid.include = 1
oid = ObjectIdentifier(12, 0, 1, 0, (1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, 7, 126))
oid = ObjectIdentifier(12, 0, 1, 0, (1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, 7, 18545, 126, 1))
get_pdu = GetNextPDU(
header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0),
oids=[oid]
Expand All @@ -192,4 +191,3 @@ def test_getnextpdu_noeth(self):
print(response)
value0 = response.values[0]
self.assertEqual(value0.type_, ValueType.END_OF_MIB_VIEW)

0 comments on commit b180f44

Please sign in to comment.