-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vlan snmp #2
Vlan snmp #2
Changes from all commits
c467dc8
4e16579
21678dd
c9f495c
c2375ab
cc61819
15cd0f2
aa0d150
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,7 +50,8 @@ class DbTables(int, Enum): | |
class IfTypes(int, Enum): | ||
""" IANA ifTypes """ | ||
ethernetCsmacd = 6 | ||
ieee8023adLag = 161 | ||
l3ipvlan = 136 | ||
ieee8023adLag = 161 | ||
|
||
class ArpUpdater(MIBUpdater): | ||
def __init__(self): | ||
|
@@ -192,8 +193,13 @@ def __init__(self): | |
self.lag_name_if_name_map = {} | ||
self.if_name_lag_name_map = {} | ||
self.oid_lag_name_map = {} | ||
self.lag_sai_map = {} | ||
self.mgmt_oid_name_map = {} | ||
self.mgmt_alias_map = {} | ||
self.vlan_oid_name_map = {} | ||
self.vlan_name_map = {} | ||
self.rif_port_map = {} | ||
self.port_rif_map = {} | ||
|
||
# cache of interface counters | ||
self.if_counters = {} | ||
|
@@ -202,6 +208,8 @@ def __init__(self): | |
self.if_alias_map = {} | ||
self.if_id_map = {} | ||
self.oid_name_map = {} | ||
self.rif_counters = {} | ||
|
||
self.namespace_db_map = Namespace.get_namespace_db_map(self.db_conn) | ||
|
||
def reinit_data(self): | ||
|
@@ -220,26 +228,56 @@ def reinit_data(self): | |
self.mgmt_oid_name_map, \ | ||
self.mgmt_alias_map = mibs.init_mgmt_interface_tables(self.db_conn[0]) | ||
|
||
self.vlan_name_map, \ | ||
self.vlan_oid_sai_map, \ | ||
self.vlan_oid_name_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_vlan_tables, self.db_conn) | ||
|
||
self.rif_port_map, \ | ||
self.port_rif_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_rif_tables, self.db_conn) | ||
|
||
def update_data(self): | ||
""" | ||
Update redis (caches config) | ||
Pulls the table references for each interface. | ||
""" | ||
for sai_id_key in self.if_id_map: | ||
namespace, sai_id = mibs.split_sai_id_key(sai_id_key) | ||
if_idx = mibs.get_index_from_str(self.if_id_map[sai_id_key]) | ||
self.if_counters[if_idx] = self.namespace_db_map[namespace].get_all(mibs.COUNTERS_DB, \ | ||
mibs.counter_table(sai_id), blocking=True) | ||
|
||
self.update_if_counters() | ||
self.update_rif_counters() | ||
|
||
self.aggregate_counters() | ||
|
||
self.lag_name_if_name_map, \ | ||
self.if_name_lag_name_map, \ | ||
self.oid_lag_name_map, _ = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn) | ||
self.oid_lag_name_map, \ | ||
self.lag_sai_map, self.sai_lag_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn) | ||
|
||
self.if_range = sorted(list(self.oid_name_map.keys()) + | ||
list(self.oid_lag_name_map.keys()) + | ||
list(self.mgmt_oid_name_map.keys())) | ||
list(self.mgmt_oid_name_map.keys()) + | ||
list(self.vlan_oid_name_map.keys())) | ||
self.if_range = [(i,) for i in self.if_range] | ||
|
||
def update_if_counters(self): | ||
for sai_id_key in self.if_id_map: | ||
namespace, sai_id = mibs.split_sai_id_key(sai_id_key) | ||
if_idx = mibs.get_index_from_str(self.if_id_map[sai_id_key]) | ||
counters_db_data = self.namespace_db_map[namespace].get_all(mibs.COUNTERS_DB, | ||
mibs.counter_table(sai_id), | ||
blocking=True) | ||
self.if_counters[if_idx] = { | ||
counter: int(value) for counter, value in counters_db_data.items() | ||
} | ||
|
||
def update_rif_counters(self): | ||
rif_sai_ids = list(self.rif_port_map) + list(self.vlan_name_map) | ||
for sai_id in rif_sai_ids: | ||
counters_db_data = Namespace.dbs_get_all(self.db_conn, mibs.COUNTERS_DB, | ||
mibs.counter_table(mibs.split_sai_id_key(sai_id)[1]), | ||
blocking=False) | ||
self.rif_counters[sai_id] = { | ||
counter: int(value) for counter, value in counters_db_data.items() | ||
} | ||
|
||
def get_next(self, sub_id): | ||
""" | ||
:param sub_id: The 1-based sub-identifier query. | ||
|
@@ -281,6 +319,8 @@ def interface_description(self, sub_id): | |
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]] | ||
elif oid in self.vlan_oid_name_map: | ||
return self.vlan_oid_name_map[oid] | ||
|
||
return self.if_alias_map[self.oid_name_map[oid]] | ||
|
||
|
@@ -291,18 +331,46 @@ def _get_counter(self, oid, table_name): | |
:return: the counter for the respective sub_id/table. | ||
""" | ||
# Enum.name or table_name = 'name_of_the_table' | ||
# Example: | ||
# table_name = <DbTables.SAI_PORT_STAT_IF_OUT_ERRORS: 20> | ||
# _table_name = 'SAI_PORT_STAT_IF_OUT_ERRORS' | ||
_table_name = getattr(table_name, 'name', table_name) | ||
|
||
try: | ||
counter_value = self.if_counters[oid][_table_name] | ||
# truncate to 32-bit counter (database implements 64-bit counters) | ||
counter_value = int(counter_value) & 0x00000000ffffffff | ||
counter_value = counter_value & 0x00000000ffffffff | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it safe to remove int() There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to Stepan, yes. Originally, the int() was used to convert from string to int, but now self.if_counters contains integers. |
||
# done! | ||
return counter_value | ||
except KeyError as e: | ||
mibs.logger.warning("SyncD 'COUNTERS_DB' missing attribute '{}'.".format(e)) | ||
return None | ||
|
||
def aggregate_counters(self): | ||
""" | ||
For ports with l3 router interfaces l3 drops may be counted separately (RIF counters) | ||
add l3 drops to l2 drop counters cache according to mapping | ||
|
||
For l3vlan map l3 counters to l2 counters | ||
""" | ||
for rif_sai_id, port_sai_id in self.rif_port_map.items(): | ||
if port_sai_id in self.if_id_map: | ||
port_idx = mibs.get_index_from_str(self.if_id_map[port_sai_id]) | ||
for port_counter_name, rif_counter_name in mibs.RIF_DROPS_AGGR_MAP.items(): | ||
self.if_counters[port_idx][port_counter_name] = \ | ||
self.if_counters[port_idx][port_counter_name] + \ | ||
self.rif_counters[rif_sai_id][rif_counter_name] | ||
|
||
for vlan_sai_id, vlan_name in self.vlan_name_map.items(): | ||
for port_counter_name, rif_counter_name in mibs.RIF_COUNTERS_AGGR_MAP.items(): | ||
vlan_idx = mibs.get_index_from_str(vlan_name) | ||
vlan_rif_counters = self.rif_counters[vlan_sai_id] | ||
if rif_counter_name in vlan_rif_counters: | ||
self.if_counters.setdefault(vlan_idx, {}) | ||
self.if_counters[vlan_idx][port_counter_name] = \ | ||
vlan_rif_counters[rif_counter_name] | ||
|
||
|
||
def get_counter(self, sub_id, table_name): | ||
""" | ||
:param sub_id: The 1-based sub-identifier query. | ||
|
@@ -320,9 +388,40 @@ def get_counter(self, sub_id, table_name): | |
return 0 | ||
elif oid in self.oid_lag_name_map: | ||
counter_value = 0 | ||
# Sum the values of this counter for all ports in the LAG. | ||
# Example: | ||
# table_name = <DbTables.SAI_PORT_STAT_IF_OUT_ERRORS: 20> | ||
# oid = 1001 | ||
# self.oid_lag_name_map = {1001: 'PortChannel01', 1002: 'PortChannel02', 1003: 'PortChannel03'} | ||
# self.oid_lag_name_map[oid] = 'PortChannel01' | ||
# self.lag_name_if_name_map = {'PortChannel01': ['Ethernet112'], 'PortChannel02': ['Ethernet116'], 'PortChannel03': ['Ethernet120']} | ||
# self.lag_name_if_name_map['PortChannel01'] = ['Ethernet112'] | ||
# mibs.get_index_from_str('Ethernet112') = 113 (because Ethernet N = N + 1) | ||
# self._get_counter retrieves the counter per oid and table. | ||
for lag_member in self.lag_name_if_name_map[self.oid_lag_name_map[oid]]: | ||
counter_value += self._get_counter(mibs.get_index_from_str(lag_member), table_name) | ||
|
||
# Check if we need to add a router interface count. | ||
# Example: | ||
# self.lag_sai_map = {'PortChannel01': '2000000000006', 'PortChannel02': '2000000000005', 'PortChannel03': '2000000000004'} | ||
# self.port_rif_map = {'2000000000006': '6000000000006', '2000000000005': '6000000000005', '2000000000004': '6000000000004'} | ||
# self.rif_port_map = {'6000000000006': '2000000000006', '6000000000005': '2000000000005', '6000000000004': '2000000000004'} | ||
# self.lag_sai_map['PortChannel01'] = '2000000000006' | ||
# self.port_rif_map['2000000000006'] = '6000000000006' | ||
sai_lag_id = self.lag_sai_map[self.oid_lag_name_map[oid]] | ||
sai_lag_rif_id = self.port_rif_map[sai_lag_id] | ||
if sai_lag_rif_id in self.rif_port_map: | ||
# Extract the 'name' part of 'table_name'. | ||
# Example: | ||
# table_name = <DbTables.SAI_PORT_STAT_IF_OUT_ERRORS: 20> | ||
# _table_name = 'SAI_PORT_STAT_IF_OUT_ERRORS' | ||
table_name = getattr(table_name, 'name', table_name) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why we need getattr here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stepan said the purpose is to return the entry in table_name corresponding to 'name', but if there is no 'name' attribute, return table_name. There are other ways of doing it, but this is the most concise. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks strange, could you add some comment here? I suppose table_name should be a str which has no 'name' attribute, could you please explain the situation that table_name would have a 'name' attribute? |
||
# Find rif counter table if applicable and add the count for this table. | ||
# Example: | ||
# mibs.RIF_DROPS_AGGR_MAP = {'SAI_PORT_STAT_IF_IN_ERRORS': 'SAI_ROUTER_INTERFACE_STAT_IN_ERROR_PACKETS', 'SAI_PORT_STAT_IF_OUT_ERRORS': 'SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS'} | ||
# self.rif_counters['6000000000006'] = {'SAI_ROUTER_INTERFACE_STAT_IN_PACKETS': 6, ... 'SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS': 6, ...} | ||
if table_name in mibs.RIF_DROPS_AGGR_MAP: | ||
rif_table_name = mibs.RIF_DROPS_AGGR_MAP[table_name] | ||
counter_value += self.rif_counters[sai_lag_rif_id].get(rif_table_name, 0) | ||
# truncate to 32-bit counter | ||
return counter_value & 0x00000000ffffffff | ||
else: | ||
|
@@ -352,6 +451,8 @@ def _get_if_entry(self, sub_id): | |
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.vlan_oid_name_map: | ||
if_table = mibs.vlan_entry_table(self.vlan_oid_name_map[oid]) | ||
elif oid in self.oid_name_map: | ||
if_table = mibs.if_entry_table(self.oid_name_map[oid]) | ||
else: | ||
|
@@ -456,6 +557,7 @@ def get_if_type(self, sub_id): | |
|
||
ethernetCsmacd(6), -- for all ethernet-like interfaces, | ||
-- regardless of speed, as per RFC3635 | ||
l3ipvlan(136) -- Layer 3 Virtual LAN using IP | ||
ieee8023adLag(161) -- IEEE 802.3ad Link Aggregate | ||
""" | ||
oid = self.get_oid(sub_id) | ||
|
@@ -464,6 +566,8 @@ def get_if_type(self, sub_id): | |
|
||
if oid in self.oid_lag_name_map: | ||
return IfTypes.ieee8023adLag | ||
elif oid in self.vlan_oid_name_map: | ||
return IfTypes.l3ipvlan | ||
else: | ||
return IfTypes.ethernetCsmacd | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we move the map to the file which use it? i see it is only used in one place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don’t think so, as it seems to be the convention to define variables in init.py, even if they are only used in one other file. For example, Qi Luo recently added HOST_NAMESPACE_DB_IDX which you see above, defined in init.py and used only in rfc3433.py.