4
4
from bisect import bisect_right
5
5
6
6
from sonic_ax_impl import mibs
7
+ from sonic_ax_impl import logger
7
8
from sonic_ax_impl .mibs import Namespace
8
9
from ax_interface .mib import MIBMeta , ValueType , MIBUpdater , MIBEntry , SubtreeMIBEntry , OverlayAdpaterMIBEntry , OidMIBEntry
9
10
from ax_interface .encodings import ObjectIdentifier
@@ -49,7 +50,8 @@ class DbTables(int, Enum):
49
50
class IfTypes (int , Enum ):
50
51
""" IANA ifTypes """
51
52
ethernetCsmacd = 6
52
- ieee8023adLag = 161
53
+ l3ipvlan = 136
54
+ ieee8023adLag = 161
53
55
54
56
class ArpUpdater (MIBUpdater ):
55
57
def __init__ (self ):
@@ -157,8 +159,13 @@ def __init__(self):
157
159
self .lag_name_if_name_map = {}
158
160
self .if_name_lag_name_map = {}
159
161
self .oid_lag_name_map = {}
162
+ self .lag_sai_map = {}
160
163
self .mgmt_oid_name_map = {}
161
164
self .mgmt_alias_map = {}
165
+ self .vlan_oid_name_map = {}
166
+ self .vlan_name_map = {}
167
+ self .rif_port_map = {}
168
+ self .port_rif_map = {}
162
169
163
170
# cache of interface counters
164
171
self .if_counters = {}
@@ -168,6 +175,7 @@ def __init__(self):
168
175
self .if_id_map = {}
169
176
self .oid_sai_map = {}
170
177
self .oid_name_map = {}
178
+ self .rif_counters = {}
171
179
172
180
def reinit_data (self ):
173
181
"""
@@ -186,6 +194,13 @@ def reinit_data(self):
186
194
self .mgmt_oid_name_map , \
187
195
self .mgmt_alias_map = mibs .init_mgmt_interface_tables (self .db_conn [0 ])
188
196
197
+ self .vlan_name_map , \
198
+ self .vlan_oid_sai_map , \
199
+ self .vlan_oid_name_map = Namespace .init_namespace_sync_d_vlan_tables (self .db_conn )
200
+
201
+ self .rif_port_map , \
202
+ self .port_rif_map = Namespace .init_namespace_sync_d_rif_tables (self .db_conn )
203
+
189
204
def update_data (self ):
190
205
"""
191
206
Update redis (caches config)
@@ -195,13 +210,24 @@ def update_data(self):
195
210
{sai_id : Namespace .dbs_get_all (self .db_conn , mibs .COUNTERS_DB , mibs .counter_table (sai_id ), blocking = True )
196
211
for sai_id in self .if_id_map }
197
212
213
+ rif_sai_ids = list (self .rif_port_map ) + list (self .vlan_name_map )
214
+
215
+ self .rif_counters = \
216
+ {sai_id : Namespace .dbs_get_all (self .db_conn , mibs .COUNTERS_DB , mibs .counter_table (sai_id ), blocking = True )
217
+ for sai_id in rif_sai_ids }
218
+
219
+ if self .rif_counters :
220
+ self .aggregate_counters ()
221
+
198
222
self .lag_name_if_name_map , \
199
223
self .if_name_lag_name_map , \
200
- self .oid_lag_name_map = Namespace .init_namespace_sync_d_lag_tables (self .db_conn )
224
+ self .oid_lag_name_map , \
225
+ self .lag_sai_map = Namespace .init_namespace_sync_d_lag_tables (self .db_conn )
201
226
202
227
self .if_range = sorted (list (self .oid_sai_map .keys ()) +
203
228
list (self .oid_lag_name_map .keys ()) +
204
- list (self .mgmt_oid_name_map .keys ()))
229
+ list (self .mgmt_oid_name_map .keys ()) +
230
+ list (self .vlan_oid_name_map .keys ()))
205
231
self .if_range = [(i ,) for i in self .if_range ]
206
232
207
233
def get_next (self , sub_id ):
@@ -245,6 +271,8 @@ def interface_description(self, sub_id):
245
271
return self .oid_lag_name_map [oid ]
246
272
elif oid in self .mgmt_oid_name_map :
247
273
return self .mgmt_alias_map [self .mgmt_oid_name_map [oid ]]
274
+ elif oid in self .vlan_oid_name_map :
275
+ return self .vlan_oid_name_map [oid ]
248
276
249
277
return self .if_alias_map [self .oid_name_map [oid ]]
250
278
@@ -254,7 +282,13 @@ def _get_counter(self, oid, table_name):
254
282
:param table_name: the redis table (either IntEnum or string literal) to query.
255
283
:return: the counter for the respective sub_id/table.
256
284
"""
257
- sai_id = self .oid_sai_map [oid ]
285
+ sai_id = ''
286
+ if oid in self .oid_sai_map :
287
+ sai_id = self .oid_sai_map [oid ]
288
+ elif oid in self .vlan_oid_sai_map :
289
+ sai_id = self .vlan_oid_sai_map [oid ]
290
+ else :
291
+ logger .warning ("Unexpected oid {}" .format (oid ))
258
292
# Enum.name or table_name = 'name_of_the_table'
259
293
_table_name = bytes (getattr (table_name , 'name' , table_name ), 'utf-8' )
260
294
@@ -268,6 +302,29 @@ def _get_counter(self, oid, table_name):
268
302
mibs .logger .warning ("SyncD 'COUNTERS_DB' missing attribute '{}'." .format (e ))
269
303
return None
270
304
305
+ def aggregate_counters (self ):
306
+ """
307
+ For ports with l3 router interfaces l3 drops may be counted separately (RIF counters)
308
+ add l3 drops to l2 drop counters cache according to mapping
309
+
310
+ For l3vlan map l3 counters to l2 counters
311
+ """
312
+ for rif_sai_id , port_sai_id in self .rif_port_map .items ():
313
+ if port_sai_id in self .if_id_map :
314
+ for port_counter_name , rif_counter_name in mibs .RIF_DROPS_AGGR_MAP .items ():
315
+ self .if_counters [port_sai_id ][port_counter_name ] = \
316
+ int (self .if_counters [port_sai_id ][port_counter_name ]) + \
317
+ int (self .rif_counters [rif_sai_id ][rif_counter_name ])
318
+
319
+ for vlan_sai_id in self .vlan_name_map :
320
+ for port_counter_name , rif_counter_name in mibs .RIF_COUNTERS_AGGR_MAP .items ():
321
+ try :
322
+ self .if_counters .setdefault (vlan_sai_id , {})
323
+ self .if_counters [vlan_sai_id ][port_counter_name ] = \
324
+ int (self .rif_counters [vlan_sai_id ][rif_counter_name ])
325
+ except KeyError as e :
326
+ logger .warning ("Not able to aggregate counters for {}: {}\n {}" .format (vlan_sai_id , rif_counter_name , e ))
327
+
271
328
def get_counter (self , sub_id , table_name ):
272
329
"""
273
330
:param sub_id: The 1-based sub-identifier query.
@@ -287,7 +344,13 @@ def get_counter(self, sub_id, table_name):
287
344
counter_value = 0
288
345
for lag_member in self .lag_name_if_name_map [self .oid_lag_name_map [oid ]]:
289
346
counter_value += self ._get_counter (mibs .get_index (lag_member ), table_name )
290
-
347
+ sai_lag_id = self .lag_sai_map [self .oid_lag_name_map [oid ]]
348
+ sai_lag_rif_id = self .port_rif_map [sai_lag_id ]
349
+ if sai_lag_rif_id in self .rif_port_map :
350
+ table_name = bytes (getattr (table_name , 'name' , table_name ), 'utf-8' )
351
+ if table_name in mibs .RIF_DROPS_AGGR_MAP :
352
+ rif_table_name = mibs .RIF_DROPS_AGGR_MAP [table_name ]
353
+ counter_value += int (self .rif_counters [sai_lag_rif_id ][rif_table_name ])
291
354
# truncate to 32-bit counter
292
355
return counter_value & 0x00000000ffffffff
293
356
else :
@@ -317,6 +380,8 @@ def _get_if_entry(self, sub_id):
317
380
elif oid in self .mgmt_oid_name_map :
318
381
if_table = mibs .mgmt_if_entry_table (self .mgmt_oid_name_map [oid ])
319
382
db = mibs .CONFIG_DB
383
+ elif oid in self .vlan_oid_name_map :
384
+ if_table = mibs .vlan_entry_table (self .vlan_oid_name_map [oid ])
320
385
elif oid in self .oid_name_map :
321
386
if_table = mibs .if_entry_table (self .oid_name_map [oid ])
322
387
else :
@@ -421,6 +486,7 @@ def get_if_type(self, sub_id):
421
486
422
487
ethernetCsmacd(6), -- for all ethernet-like interfaces,
423
488
-- regardless of speed, as per RFC3635
489
+ l3ipvlan(136) -- Layer 3 Virtual LAN using IP
424
490
ieee8023adLag(161) -- IEEE 802.3ad Link Aggregate
425
491
"""
426
492
oid = self .get_oid (sub_id )
@@ -429,6 +495,8 @@ def get_if_type(self, sub_id):
429
495
430
496
if oid in self .oid_lag_name_map :
431
497
return IfTypes .ieee8023adLag
498
+ elif oid in self .vlan_oid_name_map :
499
+ return IfTypes .l3ipvlan
432
500
else :
433
501
return IfTypes .ethernetCsmacd
434
502
0 commit comments