Skip to content

Commit

Permalink
Add managment port support to RFC1213, RFC2863, IEEE802.1ab MIBs (son…
Browse files Browse the repository at this point in the history
…ic-net#88)

* Add managment port support to RFC1213, RFC2863, IEEE802.1ab MIBs
* Get mgmt ports from CONFIG DB, add oper status test
* Add comments to the code
* Add management port admin status unit test
* Add unit test for mgmt port alias
  • Loading branch information
stepanblyschak authored and qiluo-msft committed Oct 2, 2018
1 parent 8a628a5 commit c675724
Show file tree
Hide file tree
Showing 11 changed files with 336 additions and 18 deletions.
50 changes: 50 additions & 0 deletions src/sonic_ax_impl/mibs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
APPL_DB = 'APPL_DB'
ASIC_DB = 'ASIC_DB'
COUNTERS_DB = 'COUNTERS_DB'
CONFIG_DB = 'CONFIG_DB'
STATE_DB = 'STATE_DB'

TABLE_NAME_SEPARATOR_COLON = ':'
TABLE_NAME_SEPARATOR_VBAR = '|'
Expand Down Expand Up @@ -98,6 +100,24 @@ def lag_entry_table(lag_name):
return b'LAG_TABLE:' + lag_name


def mgmt_if_entry_table(if_name):
"""
:param if_name: given interface to cast
:return: MGMT_PORT_TABLE key
"""

return b'MGMT_PORT|' + if_name


def mgmt_if_entry_table_state_db(if_name):
"""
:param if_name: given interface to cast
:return: MGMT_PORT_TABLE key
"""

return b'MGMT_PORT_TABLE|' + if_name


def config(**kwargs):
global redis_kwargs
redis_kwargs = {k:v for (k,v) in kwargs.items() if k in ['unix_socket_path', 'host', 'port']}
Expand All @@ -113,6 +133,36 @@ def init_db():

return db_conn

def init_mgmt_interface_tables(db_conn):
"""
Initializes interface maps for mgmt ports
:param db_conn: db connector
:return: tuple of mgmt name to oid map and mgmt name to alias map
"""

db_conn.connect(CONFIG_DB)
db_conn.connect(STATE_DB)

mgmt_ports_keys = db_conn.keys(CONFIG_DB, mgmt_if_entry_table(b'*'))

if not mgmt_ports_keys:
logger.warning('No managment ports found in {}'.format(mgmt_if_entry_table(b'')))
return {}, {}

mgmt_ports = [key.split(mgmt_if_entry_table(b''))[-1] for key in mgmt_ports_keys]
oid_name_map = {get_index(mgmt_name): mgmt_name for mgmt_name in mgmt_ports}
logger.debug('Managment port map:\n' + pprint.pformat(oid_name_map, indent=2))

if_alias_map = dict()

for if_name in oid_name_map.values():
if_entry = db_conn.get_all(CONFIG_DB, mgmt_if_entry_table(if_name), blocking=True)
if_alias_map[if_name] = if_entry.get(b'alias', if_name)

logger.debug("Management alias map:\n" + pprint.pformat(if_alias_map, indent=2))

return oid_name_map, if_alias_map


def init_sync_d_interface_tables(db_conn):
"""
Expand Down
46 changes: 42 additions & 4 deletions src/sonic_ax_impl/mibs/ieee802_1ab.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,6 @@ def poll_lldp_entry_updates(pubsub):
"The error seems to be: {}".format(msg, e))
return ret

if interface == 'eth0':
return ret

# get interface from interface name
if_index = port_util.get_index_from_str(interface)

Expand Down Expand Up @@ -147,6 +144,10 @@ def __init__(self):
self.if_id_map = {}
self.oid_sai_map = {}
self.oid_name_map = {}

self.mgmt_oid_name_map = {}
self.mgmt_alias_map = {}

self.if_range = []

# cache of port data
Expand All @@ -164,6 +165,13 @@ def reinit_data(self):
self.oid_sai_map, \
self.oid_name_map = mibs.init_sync_d_interface_tables(self.db_conn)

self.mgmt_oid_name_map, \
self.mgmt_alias_map = mibs.init_mgmt_interface_tables(self.db_conn)

# merge dataplane and mgmt ports
self.oid_name_map.update(self.mgmt_oid_name_map)
self.if_alias_map.update(self.mgmt_alias_map)

self.if_range = []
# get local port kvs from APP_BD's PORT_TABLE
self.loc_port_data = {}
Expand All @@ -174,11 +182,28 @@ def reinit_data(self):
if not self.loc_port_data:
logger.warning("0 - b'PORT_TABLE' is empty. No local port information could be retrieved.")

def _get_if_entry(self, if_name):
if_table = ""

# Once PORT_TABLE will be moved to CONFIG DB
# we will get entry from CONFIG_DB for all cases
db = mibs.APPL_DB
if if_name in self.if_name_map:
if_table = mibs.if_entry_table(if_name)
elif if_name in self.mgmt_oid_name_map.values():
if_table = mibs.mgmt_if_entry_table(if_name)
db = mibs.CONFIG_DB
else:
return None

return self.db_conn.get_all(db, if_table, blocking=True)

def update_interface_data(self, if_name):
"""
Update data from the DB for a single interface
"""
loc_port_kvs = self.db_conn.get_all(mibs.APPL_DB, mibs.if_entry_table(if_name))

loc_port_kvs = self._get_if_entry(if_name)
if not loc_port_kvs:
return
self.loc_port_data.update({if_name: loc_port_kvs})
Expand Down Expand Up @@ -344,6 +369,9 @@ def __init__(self):
self.if_id_map = {}
self.oid_sai_map = {}
self.oid_name_map = {}

self.mgmt_oid_name_map = {}

self.if_range = []

# cache of interface counters
Expand All @@ -360,6 +388,10 @@ def reinit_data(self):
self.oid_sai_map, \
self.oid_name_map = mibs.init_sync_d_interface_tables(self.db_conn)

self.mgmt_oid_name_map, _ = mibs.init_mgmt_interface_tables(self.db_conn)

self.oid_name_map.update(self.mgmt_oid_name_map)

def get_next(self, sub_id):
"""
:param sub_id: The 1-based sub-identifier query.
Expand Down Expand Up @@ -443,6 +475,7 @@ def __init__(self):
self.if_range = []
self.mgmt_ips = {}
self.oid_name_map = {}
self.mgmt_oid_name_map = {}
self.mgmt_ip_str = None
self.pubsub = None

Expand Down Expand Up @@ -508,6 +541,11 @@ def reinit_data(self):
Subclass reinit data routine.
"""
_, _, _, _, self.oid_name_map = mibs.init_sync_d_interface_tables(self.db_conn)

self.mgmt_oid_name_map, _ = mibs.init_mgmt_interface_tables(self.db_conn)

self.oid_name_map.update(self.mgmt_oid_name_map)

# establish connection to application database.
self.db_conn.connect(mibs.APPL_DB)

Expand Down
70 changes: 59 additions & 11 deletions src/sonic_ax_impl/mibs/ietf/rfc1213.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import python_arptable
from enum import unique, Enum
from bisect import bisect_right
from swsssdk.port_util import BaseIdx

from sonic_ax_impl import mibs
from ax_interface import MIBMeta, ValueType, MIBUpdater, MIBEntry, SubtreeMIBEntry
Expand Down Expand Up @@ -159,6 +158,8 @@ def __init__(self):
self.lag_name_if_name_map = {}
self.if_name_lag_name_map = {}
self.oid_lag_name_map = {}
self.mgmt_oid_name_map = {}
self.mgmt_alias_map = {}

# cache of interface counters
self.if_counters = {}
Expand All @@ -179,6 +180,9 @@ def reinit_data(self):
self.oid_sai_map, \
self.oid_name_map = mibs.init_sync_d_interface_tables(self.db_conn)

self.mgmt_oid_name_map, \
self.mgmt_alias_map = mibs.init_mgmt_interface_tables(self.db_conn)

def update_data(self):
"""
Update redis (caches config)
Expand All @@ -192,7 +196,9 @@ def update_data(self):
self.if_name_lag_name_map, \
self.oid_lag_name_map = mibs.init_sync_d_lag_tables(self.db_conn)

self.if_range = sorted(list(self.oid_sai_map.keys()) + list(self.oid_lag_name_map.keys()))
self.if_range = sorted(list(self.oid_sai_map.keys()) +
list(self.oid_lag_name_map.keys()) +
list(self.mgmt_oid_name_map.keys()))
self.if_range = [(i,) for i in self.if_range]

def get_next(self, sub_id):
Expand Down Expand Up @@ -234,6 +240,8 @@ def interface_description(self, sub_id):

if oid in self.oid_lag_name_map:
return self.oid_lag_name_map[oid]
elif oid in self.mgmt_oid_name_map:
return self.mgmt_alias_map[self.mgmt_oid_name_map[oid]]

return self.if_alias_map[self.oid_name_map[oid]]

Expand Down Expand Up @@ -267,7 +275,12 @@ def get_counter(self, sub_id, table_name):
if not oid:
return

if oid in self.oid_lag_name_map:
if oid in self.mgmt_oid_name_map:
# TODO: mgmt counters not available through SNMP right now
# COUNTERS DB does not have suppot for generic linux (mgmt) interface counters
mibs.logger.warning('management interface counters not available through SNMP right now')
return 0
elif oid in self.oid_lag_name_map:
counter_value = 0
for lag_member in self.lag_name_if_name_map[self.oid_lag_name_map[oid]]:
counter_value += self._get_counter(mibs.get_index(lag_member), table_name)
Expand All @@ -293,12 +306,39 @@ def _get_if_entry(self, sub_id):
return

if_table = ""
# Once PORT_TABLE will be moved to CONFIG DB
# we will get entry from CONFIG_DB for all cases
db = mibs.APPL_DB
if oid in self.oid_lag_name_map:
if_table = mibs.lag_entry_table(self.oid_lag_name_map[oid])
else:
elif oid in self.mgmt_oid_name_map:
if_table = mibs.mgmt_if_entry_table(self.mgmt_oid_name_map[oid])
db = mibs.CONFIG_DB
elif oid in self.oid_name_map:
if_table = mibs.if_entry_table(self.oid_name_map[oid])
else:
return None

return self.db_conn.get_all(db, if_table, blocking=True)

return self.db_conn.get_all(mibs.APPL_DB, if_table, blocking=True)
def _get_if_entry_state_db(self, sub_id):
"""
:param oid: The 1-based sub-identifier query.
:return: the DB entry for the respective sub_id.
"""
oid = self.get_oid(sub_id)
if not oid:
return

if_table = ""
db = mibs.STATE_DB
if oid in self.mgmt_oid_name_map:
mgmt_if_name = self.mgmt_oid_name_map[oid]
if_table = mibs.mgmt_if_entry_table_state_db(mgmt_if_name)
else:
return None

return self.db_conn.get_all(db, if_table, blocking=True)

def _get_status(self, sub_id, key):
"""
Expand All @@ -311,7 +351,13 @@ def _get_status(self, sub_id, key):
b"down": 2
}

entry = self._get_if_entry(sub_id)
# Once PORT_TABLE will be moved to CONFIG DB
# we will get rid of this if-else
# and read oper status from STATE_DB
if self.get_oid(sub_id) in self.mgmt_oid_name_map and key == b"oper_status":
entry = self._get_if_entry_state_db(sub_id)
else:
entry = self._get_if_entry(sub_id)
if not entry:
return

Expand Down Expand Up @@ -369,11 +415,13 @@ def get_if_type(self, sub_id):
ieee8023adLag(161) -- IEEE 802.3ad Link Aggregate
"""
oid = self.get_oid(sub_id)
if oid:
if oid < BaseIdx.portchannel_base_idx:
return IfTypes.ethernetCsmacd
else:
return IfTypes.ieee8023adLag
if not oid:
return

if oid in self.oid_lag_name_map:
return IfTypes.ieee8023adLag
else:
return IfTypes.ethernetCsmacd


class InterfacesMIB(metaclass=MIBMeta, prefix='.1.3.6.1.2.1.2'):
Expand Down
30 changes: 27 additions & 3 deletions src/sonic_ax_impl/mibs/ietf/rfc2863.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ def __init__(self):
self.lag_name_if_name_map = {}
self.if_name_lag_name_map = {}
self.oid_lag_name_map = {}
self.mgmt_oid_name_map = {}
self.mgmt_alias_map = {}

self.if_counters = {}
self.if_range = []
Expand All @@ -79,7 +81,12 @@ def reinit_data(self):
self.if_name_lag_name_map, \
self.oid_lag_name_map = mibs.init_sync_d_lag_tables(self.db_conn)

self.if_range = sorted(list(self.oid_sai_map.keys()) + list(self.oid_lag_name_map.keys()))
self.mgmt_oid_name_map, \
self.mgmt_alias_map = mibs.init_mgmt_interface_tables(self.db_conn)

self.if_range = sorted(list(self.oid_sai_map.keys()) +
list(self.oid_lag_name_map.keys()) +
list(self.mgmt_oid_name_map.keys()))
self.if_range = [(i,) for i in self.if_range]

def update_data(self):
Expand Down Expand Up @@ -123,6 +130,8 @@ def interface_name(self, sub_id):

if oid in self.oid_lag_name_map:
return self.oid_lag_name_map[oid]
elif oid in self.mgmt_oid_name_map:
return self.mgmt_alias_map[self.mgmt_oid_name_map[oid]]

return self.if_alias_map[self.oid_name_map[oid]]

Expand Down Expand Up @@ -160,6 +169,13 @@ def _get_counter(self, oid, table_name, mask):
:param mask: mask to apply to counter
:return: the counter for the respective sub_id/table.
"""

if oid in self.mgmt_oid_name_map:
# TODO: mgmt counters not available through SNMP right now
# COUNTERS DB does not have suppot for generic linux (mgmt) interface counters
mibs.logger.warning('management interface counters not available through SNMP right now')
return 0

if oid in self.oid_lag_name_map:
counter_value = 0
for lag_member in self.lag_name_if_name_map[self.oid_lag_name_map[oid]]:
Expand Down Expand Up @@ -190,12 +206,20 @@ def _get_if_entry(self, sub_id):
return

if_table = ""
# Once PORT_TABLE will be moved to CONFIG DB
# we will get entry from CONFIG_DB for all cases
db = mibs.APPL_DB
if oid in self.oid_lag_name_map:
if_table = mibs.lag_entry_table(self.oid_lag_name_map[oid])
else:
elif oid in self.mgmt_oid_name_map:
if_table = mibs.mgmt_if_entry_table(self.mgmt_oid_name_map[oid])
db = mibs.CONFIG_DB
elif oid in self.oid_name_map:
if_table = mibs.if_entry_table(self.oid_name_map[oid])
else:
return None

return self.db_conn.get_all(mibs.APPL_DB, if_table, blocking=True)
return self.db_conn.get_all(db, if_table, blocking=True)

def get_high_speed(self, sub_id):
"""
Expand Down
Loading

0 comments on commit c675724

Please sign in to comment.