Skip to content

Commit cbd0c8e

Browse files
Revert "Revert "[rfc1213] Interface MIB add l3 vlan interfaces & aggregate rif counters (sonic-net#169)" (sonic-net#191)"
This reverts commit dfde06e.
1 parent 183162f commit cbd0c8e

16 files changed

+1540
-45
lines changed

src/sonic_ax_impl/mibs/__init__.py

+76-5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,23 @@
2525
TABLE_NAME_SEPARATOR_COLON = ':'
2626
TABLE_NAME_SEPARATOR_VBAR = '|'
2727

28+
RIF_COUNTERS_AGGR_MAP = {
29+
"SAI_PORT_STAT_IF_IN_OCTETS": "SAI_ROUTER_INTERFACE_STAT_IN_OCTETS",
30+
"SAI_PORT_STAT_IF_IN_UCAST_PKTS": "SAI_ROUTER_INTERFACE_STAT_IN_PACKETS",
31+
"SAI_PORT_STAT_IF_IN_ERRORS": "SAI_ROUTER_INTERFACE_STAT_IN_ERROR_PACKETS",
32+
"SAI_PORT_STAT_IF_OUT_OCTETS": "SAI_ROUTER_INTERFACE_STAT_OUT_OCTETS",
33+
"SAI_PORT_STAT_IF_OUT_UCAST_PKTS": "SAI_ROUTER_INTERFACE_STAT_OUT_PACKETS",
34+
"SAI_PORT_STAT_IF_OUT_ERRORS": "SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS"
35+
}
36+
37+
RIF_DROPS_AGGR_MAP = {
38+
"SAI_PORT_STAT_IF_IN_ERRORS": "SAI_ROUTER_INTERFACE_STAT_IN_ERROR_PACKETS",
39+
"SAI_PORT_STAT_IF_OUT_ERRORS": "SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS"
40+
}
41+
42+
# IfIndex to OID multiplier for transceiver
43+
IFINDEX_SUB_ID_MULTIPLIER = 1000
44+
2845
redis_kwargs = {'unix_socket_path': '/var/run/redis/redis.sock'}
2946

3047

@@ -134,6 +151,14 @@ def if_entry_table(if_name):
134151
return 'PORT_TABLE:' + if_name
135152

136153

154+
def vlan_entry_table(if_name):
155+
"""
156+
:param if_name: given interface to cast.
157+
:return: VLAN_TABLE key.
158+
"""
159+
return 'VLAN_TABLE:' + if_name
160+
161+
137162
def lag_entry_table(lag_name):
138163
"""
139164
:param lag_name: given lag to cast.
@@ -290,6 +315,46 @@ def init_sync_d_interface_tables(db_conn):
290315

291316
return if_name_map, if_alias_map, if_id_map, oid_name_map
292317

318+
319+
def init_sync_d_rif_tables(db_conn):
320+
"""
321+
Initializes map of RIF SAI oids to port SAI oid.
322+
:return: dict
323+
"""
324+
rif_port_map = {get_sai_id_key(db_conn.namespace, rif): get_sai_id_key(db_conn.namespace, port)
325+
for rif, port in port_util.get_rif_port_map(db_conn).items()}
326+
port_rif_map = {port: rif for rif, port in rif_port_map.items()}
327+
logger.debug("Rif port map:\n" + pprint.pformat(rif_port_map, indent=2))
328+
329+
return rif_port_map, port_rif_map
330+
331+
332+
def init_sync_d_vlan_tables(db_conn):
333+
"""
334+
Initializes vlan interface maps for SyncD-connected MIB(s).
335+
:return: tuple(vlan_name_map, oid_sai_map, oid_name_map)
336+
"""
337+
338+
vlan_name_map = port_util.get_vlan_interface_oid_map(db_conn)
339+
340+
logger.debug("Vlan oid map:\n" + pprint.pformat(vlan_name_map, indent=2))
341+
342+
# { OID -> sai_id }
343+
oid_sai_map = {get_index_from_str(if_name): sai_id for sai_id, if_name in vlan_name_map.items()
344+
# only map the interface if it's a style understood to be a SONiC interface.
345+
if get_index_from_str(if_name) is not None}
346+
logger.debug("OID sai map:\n" + pprint.pformat(oid_sai_map, indent=2))
347+
348+
# { OID -> if_name (SONiC) }
349+
oid_name_map = {get_index_from_str(if_name): if_name for sai_id, if_name in vlan_name_map.items()
350+
# only map the interface if it's a style understood to be a SONiC interface.
351+
if get_index_from_str(if_name) is not None}
352+
353+
logger.debug("OID name map:\n" + pprint.pformat(oid_name_map, indent=2))
354+
355+
return vlan_name_map, oid_sai_map, oid_name_map
356+
357+
293358
def init_sync_d_lag_tables(db_conn):
294359
"""
295360
Helper method. Connects to and initializes LAG interface maps for SyncD-connected MIB(s).
@@ -304,13 +369,19 @@ def init_sync_d_lag_tables(db_conn):
304369
if_name_lag_name_map = {}
305370
# { OID -> lag_name (SONiC) }
306371
oid_lag_name_map = {}
372+
# { lag_name (SONiC) -> lag_oid (SAI) }
373+
lag_sai_map = {}
307374

308375
db_conn.connect(APPL_DB)
309376

310377
lag_entries = db_conn.keys(APPL_DB, "LAG_TABLE:*")
311378

312379
if not lag_entries:
313-
return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map
380+
return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map, lag_sai_map
381+
382+
db_conn.connect(COUNTERS_DB)
383+
lag_sai_map = db_conn.get_all(COUNTERS_DB, "COUNTERS_LAG_NAME_MAP")
384+
lag_sai_map = {name: get_sai_id_key(db_conn.namespace, sai_id.lstrip("oid:0x")) for name, sai_id in lag_sai_map.items()}
314385

315386
for lag_entry in lag_entries:
316387
lag_name = lag_entry[len("LAG_TABLE:"):]
@@ -332,7 +403,7 @@ def member_name_str(val, lag_name):
332403
if idx:
333404
oid_lag_name_map[idx] = if_name
334405

335-
return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map
406+
return lag_name_if_name_map, if_name_lag_name_map, oid_lag_name_map, lag_sai_map
336407

337408
def init_sync_d_queue_tables(db_conn):
338409
"""
@@ -347,7 +418,7 @@ def init_sync_d_queue_tables(db_conn):
347418

348419
# Parse the queue_name_map and create the following maps:
349420
# port_queues_map -> {"port_index : queue_index" : sai_oid}
350-
# queue_stat_map -> {"port_index : queue stat table name" : {counter name : value}}
421+
# queue_stat_map -> {"port_index : queue stat table name" : {counter name : value}}
351422
# port_queue_list_map -> {port_index: [sorted queue list]}
352423
port_queues_map = {}
353424
queue_stat_map = {}
@@ -411,7 +482,7 @@ class RedisOidTreeUpdater(MIBUpdater):
411482
def __init__(self, prefix_str):
412483
super().__init__()
413484

414-
self.db_conn = Namespace.init_namespace_dbs()
485+
self.db_conn = Namespace.init_namespace_dbs()
415486
if prefix_str.startswith('.'):
416487
prefix_str = prefix_str[1:]
417488
self.prefix_str = prefix_str
@@ -524,7 +595,7 @@ def dbs_get_all(dbs, db_name, _hash, *args, **kwargs):
524595
db get_all function executed on global and all namespace DBs.
525596
"""
526597
result = {}
527-
# If there are multiple namespaces, _hash might not be
598+
# If there are multiple namespaces, _hash might not be
528599
# present in all namespace, ignore if not present in a
529600
# specfic namespace.
530601
if len(dbs) > 1:

src/sonic_ax_impl/mibs/ietf/rfc1213.py

+86-10
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ class DbTables(int, Enum):
5050
class IfTypes(int, Enum):
5151
""" IANA ifTypes """
5252
ethernetCsmacd = 6
53-
ieee8023adLag = 161
53+
l3ipvlan = 136
54+
ieee8023adLag = 161
5455

5556
class ArpUpdater(MIBUpdater):
5657
def __init__(self):
@@ -192,8 +193,13 @@ def __init__(self):
192193
self.lag_name_if_name_map = {}
193194
self.if_name_lag_name_map = {}
194195
self.oid_lag_name_map = {}
196+
self.lag_sai_map = {}
195197
self.mgmt_oid_name_map = {}
196198
self.mgmt_alias_map = {}
199+
self.vlan_oid_name_map = {}
200+
self.vlan_name_map = {}
201+
self.rif_port_map = {}
202+
self.port_rif_map = {}
197203

198204
# cache of interface counters
199205
self.if_counters = {}
@@ -202,6 +208,8 @@ def __init__(self):
202208
self.if_alias_map = {}
203209
self.if_id_map = {}
204210
self.oid_name_map = {}
211+
self.rif_counters = {}
212+
205213
self.namespace_db_map = Namespace.get_namespace_db_map(self.db_conn)
206214

207215
def reinit_data(self):
@@ -220,26 +228,56 @@ def reinit_data(self):
220228
self.mgmt_oid_name_map, \
221229
self.mgmt_alias_map = mibs.init_mgmt_interface_tables(self.db_conn[0])
222230

231+
self.vlan_name_map, \
232+
self.vlan_oid_sai_map, \
233+
self.vlan_oid_name_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_vlan_tables, self.db_conn)
234+
235+
self.rif_port_map, \
236+
self.port_rif_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_rif_tables, self.db_conn)
237+
223238
def update_data(self):
224239
"""
225240
Update redis (caches config)
226241
Pulls the table references for each interface.
227242
"""
228-
for sai_id_key in self.if_id_map:
229-
namespace, sai_id = mibs.split_sai_id_key(sai_id_key)
230-
if_idx = mibs.get_index_from_str(self.if_id_map[sai_id_key])
231-
self.if_counters[if_idx] = self.namespace_db_map[namespace].get_all(mibs.COUNTERS_DB, \
232-
mibs.counter_table(sai_id), blocking=True)
243+
244+
self.update_if_counters()
245+
self.update_rif_counters()
246+
247+
self.aggregate_counters()
233248

234249
self.lag_name_if_name_map, \
235250
self.if_name_lag_name_map, \
236-
self.oid_lag_name_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn)
251+
self.oid_lag_name_map, \
252+
self.lag_sai_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn)
237253

238254
self.if_range = sorted(list(self.oid_name_map.keys()) +
239255
list(self.oid_lag_name_map.keys()) +
240-
list(self.mgmt_oid_name_map.keys()))
256+
list(self.mgmt_oid_name_map.keys()) +
257+
list(self.vlan_oid_name_map.keys()))
241258
self.if_range = [(i,) for i in self.if_range]
242259

260+
def update_if_counters(self):
261+
for sai_id_key in self.if_id_map:
262+
namespace, sai_id = mibs.split_sai_id_key(sai_id_key)
263+
if_idx = mibs.get_index_from_str(self.if_id_map[sai_id_key])
264+
counters_db_data = self.namespace_db_map[namespace].get_all(mibs.COUNTERS_DB,
265+
mibs.counter_table(sai_id),
266+
blocking=True)
267+
self.if_counters[if_idx] = {
268+
counter: int(value) for counter, value in counters_db_data.items()
269+
}
270+
271+
def update_rif_counters(self):
272+
rif_sai_ids = list(self.rif_port_map) + list(self.vlan_name_map)
273+
for sai_id in rif_sai_ids:
274+
counters_db_data = Namespace.dbs_get_all(self.db_conn, mibs.COUNTERS_DB,
275+
mibs.counter_table(mibs.split_sai_id_key(sai_id)[1]),
276+
blocking=False)
277+
self.rif_counters[sai_id] = {
278+
counter: int(value) for counter, value in counters_db_data.items()
279+
}
280+
243281
def get_next(self, sub_id):
244282
"""
245283
:param sub_id: The 1-based sub-identifier query.
@@ -281,6 +319,8 @@ def interface_description(self, sub_id):
281319
return self.oid_lag_name_map[oid]
282320
elif oid in self.mgmt_oid_name_map:
283321
return self.mgmt_alias_map[self.mgmt_oid_name_map[oid]]
322+
elif oid in self.vlan_oid_name_map:
323+
return self.vlan_oid_name_map[oid]
284324

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

@@ -296,13 +336,38 @@ def _get_counter(self, oid, table_name):
296336
try:
297337
counter_value = self.if_counters[oid][_table_name]
298338
# truncate to 32-bit counter (database implements 64-bit counters)
299-
counter_value = int(counter_value) & 0x00000000ffffffff
339+
counter_value = counter_value & 0x00000000ffffffff
300340
# done!
301341
return counter_value
302342
except KeyError as e:
303343
mibs.logger.warning("SyncD 'COUNTERS_DB' missing attribute '{}'.".format(e))
304344
return None
305345

346+
def aggregate_counters(self):
347+
"""
348+
For ports with l3 router interfaces l3 drops may be counted separately (RIF counters)
349+
add l3 drops to l2 drop counters cache according to mapping
350+
351+
For l3vlan map l3 counters to l2 counters
352+
"""
353+
for rif_sai_id, port_sai_id in self.rif_port_map.items():
354+
if port_sai_id in self.if_id_map:
355+
port_idx = mibs.get_index_from_str(self.if_id_map[port_sai_id])
356+
for port_counter_name, rif_counter_name in mibs.RIF_DROPS_AGGR_MAP.items():
357+
self.if_counters[port_idx][port_counter_name] = \
358+
self.if_counters[port_idx][port_counter_name] + \
359+
self.rif_counters[rif_sai_id][rif_counter_name]
360+
361+
for vlan_sai_id, vlan_name in self.vlan_name_map.items():
362+
for port_counter_name, rif_counter_name in mibs.RIF_COUNTERS_AGGR_MAP.items():
363+
vlan_idx = mibs.get_index_from_str(vlan_name)
364+
vlan_rif_counters = self.rif_counters[vlan_sai_id]
365+
if rif_counter_name in vlan_rif_counters:
366+
self.if_counters.setdefault(vlan_idx, {})
367+
self.if_counters[vlan_idx][port_counter_name] = \
368+
vlan_rif_counters[rif_counter_name]
369+
370+
306371
def get_counter(self, sub_id, table_name):
307372
"""
308373
:param sub_id: The 1-based sub-identifier query.
@@ -322,7 +387,13 @@ def get_counter(self, sub_id, table_name):
322387
counter_value = 0
323388
for lag_member in self.lag_name_if_name_map[self.oid_lag_name_map[oid]]:
324389
counter_value += self._get_counter(mibs.get_index_from_str(lag_member), table_name)
325-
390+
sai_lag_id = self.lag_sai_map[self.oid_lag_name_map[oid]]
391+
sai_lag_rif_id = self.port_rif_map[sai_lag_id]
392+
if sai_lag_rif_id in self.rif_port_map:
393+
table_name = getattr(table_name, 'name', table_name)
394+
if table_name in mibs.RIF_DROPS_AGGR_MAP:
395+
rif_table_name = mibs.RIF_DROPS_AGGR_MAP[table_name]
396+
counter_value += self.rif_counters[sai_lag_rif_id].get(rif_table_name, 0)
326397
# truncate to 32-bit counter
327398
return counter_value & 0x00000000ffffffff
328399
else:
@@ -352,6 +423,8 @@ def _get_if_entry(self, sub_id):
352423
elif oid in self.mgmt_oid_name_map:
353424
if_table = mibs.mgmt_if_entry_table(self.mgmt_oid_name_map[oid])
354425
db = mibs.CONFIG_DB
426+
elif oid in self.vlan_oid_name_map:
427+
if_table = mibs.vlan_entry_table(self.vlan_oid_name_map[oid])
355428
elif oid in self.oid_name_map:
356429
if_table = mibs.if_entry_table(self.oid_name_map[oid])
357430
else:
@@ -456,6 +529,7 @@ def get_if_type(self, sub_id):
456529
457530
ethernetCsmacd(6), -- for all ethernet-like interfaces,
458531
-- regardless of speed, as per RFC3635
532+
l3ipvlan(136) -- Layer 3 Virtual LAN using IP
459533
ieee8023adLag(161) -- IEEE 802.3ad Link Aggregate
460534
"""
461535
oid = self.get_oid(sub_id)
@@ -464,6 +538,8 @@ def get_if_type(self, sub_id):
464538

465539
if oid in self.oid_lag_name_map:
466540
return IfTypes.ieee8023adLag
541+
elif oid in self.vlan_oid_name_map:
542+
return IfTypes.l3ipvlan
467543
else:
468544
return IfTypes.ethernetCsmacd
469545

src/sonic_ax_impl/mibs/ietf/rfc2863.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def reinit_data(self):
7979

8080
self.lag_name_if_name_map, \
8181
self.if_name_lag_name_map, \
82-
self.oid_lag_name_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn)
82+
self.oid_lag_name_map, _ = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn)
8383
"""
8484
db_conn - will have db_conn to all namespace DBs and
8585
global db. First db in the list is global db.

src/sonic_ax_impl/mibs/vendor/cisco/ciscoPfcExtMIB.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def update_data(self):
5252

5353
self.lag_name_if_name_map, \
5454
self.if_name_lag_name_map, \
55-
self.oid_lag_name_map = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn)
55+
self.oid_lag_name_map, _ = Namespace.get_sync_d_from_all_namespace(mibs.init_sync_d_lag_tables, self.db_conn)
5656

5757
self.if_range = sorted(list(self.oid_name_map.keys()) + list(self.oid_lag_name_map.keys()))
5858
self.if_range = [(i,) for i in self.if_range]
@@ -94,7 +94,7 @@ def _get_counter(self, oid, counter_name):
9494
_counter_name = getattr(counter_name, 'name', counter_name)
9595

9696
try:
97-
counter_value = self.if_counters[oid][_counter_name]
97+
counter_value = self.if_counters[oid][_counter_name]
9898
counter_value = int(counter_value) & 0xffffffffffffffff
9999
# done!
100100
return counter_value

tests/mock_tables/asic0/asic_db.json

+7
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,12 @@
2323
"SAI_BRIDGE_PORT_ATTR_TYPE": "SAI_BRIDGE_PORT_TYPE_PORT",
2424
"SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x1000000000005",
2525
"SAI_BRIDGE_PORT_ATTR_ADMIN_STATE": "true"
26+
},
27+
"ASIC_STATE:SAI_OBJECT_TYPE_ROUTER_INTERFACE:oid:0x6000000000006": {
28+
"SAI_ROUTER_INTERFACE_ATTR_TYPE": "SAI_ROUTER_INTERFACE_TYPE_PORT",
29+
"SAI_ROUTER_INTERFACE_ATTR_PORT_ID": "oid:0x1000000000007"
30+
},
31+
"ASIC_STATE:SAI_OBJECT_TYPE_LAG:oid:0x1000000000007": {
32+
"NULL": "NULL"
2633
}
2734
}

0 commit comments

Comments
 (0)