@@ -49,7 +49,8 @@ class DbTables(int, Enum):
4949class IfTypes (int , Enum ):
5050 """ IANA ifTypes """
5151 ethernetCsmacd = 6
52- ieee8023adLag = 161
52+ l3ipvlan = 136
53+ ieee8023adLag = 161
5354
5455class ArpUpdater (MIBUpdater ):
5556 def __init__ (self ):
@@ -191,8 +192,13 @@ def __init__(self):
191192 self .lag_name_if_name_map = {}
192193 self .if_name_lag_name_map = {}
193194 self .oid_lag_name_map = {}
195+ self .lag_sai_map = {}
194196 self .mgmt_oid_name_map = {}
195197 self .mgmt_alias_map = {}
198+ self .vlan_oid_name_map = {}
199+ self .vlan_name_map = {}
200+ self .rif_port_map = {}
201+ self .port_rif_map = {}
196202
197203 # cache of interface counters
198204 self .if_counters = {}
@@ -201,6 +207,8 @@ def __init__(self):
201207 self .if_alias_map = {}
202208 self .if_id_map = {}
203209 self .oid_name_map = {}
210+ self .rif_counters = {}
211+
204212 self .namespace_db_map = Namespace .get_namespace_db_map (self .db_conn )
205213
206214 def reinit_data (self ):
@@ -219,26 +227,50 @@ def reinit_data(self):
219227 self .mgmt_oid_name_map , \
220228 self .mgmt_alias_map = mibs .init_mgmt_interface_tables (self .db_conn [0 ])
221229
230+ self .vlan_name_map , \
231+ self .vlan_oid_sai_map , \
232+ self .vlan_oid_name_map = Namespace .get_sync_d_from_all_namespace (mibs .init_sync_d_vlan_tables , self .db_conn )
233+
234+ self .rif_port_map , \
235+ self .port_rif_map = Namespace .get_sync_d_from_all_namespace (mibs .init_sync_d_rif_tables , self .db_conn )
236+
222237 def update_data (self ):
223238 """
224239 Update redis (caches config)
225240 Pulls the table references for each interface.
226241 """
227- for sai_id_key in self . if_id_map :
228- namespace , sai_id = mibs . split_sai_id_key ( sai_id_key )
229- if_idx = mibs . get_index_from_str ( self .if_id_map [ sai_id_key ] )
230- self . if_counters [ if_idx ] = self . namespace_db_map [ namespace ]. get_all ( mibs . COUNTERS_DB , \
231- mibs . counter_table ( sai_id ), blocking = True )
242+
243+ self . update_if_counters ( )
244+ self .update_rif_counters ( )
245+
246+ self . aggregate_counters ( )
232247
233248 self .lag_name_if_name_map , \
234249 self .if_name_lag_name_map , \
235- self .oid_lag_name_map = Namespace .get_sync_d_from_all_namespace (mibs .init_sync_d_lag_tables , self .db_conn )
250+ self .oid_lag_name_map , \
251+ self .lag_sai_map = Namespace .get_sync_d_from_all_namespace (mibs .init_sync_d_lag_tables , self .db_conn )
236252
237253 self .if_range = sorted (list (self .oid_name_map .keys ()) +
238254 list (self .oid_lag_name_map .keys ()) +
239- list (self .mgmt_oid_name_map .keys ()))
255+ list (self .mgmt_oid_name_map .keys ()) +
256+ list (self .vlan_oid_name_map .keys ()))
240257 self .if_range = [(i ,) for i in self .if_range ]
241258
259+ def update_if_counters (self ):
260+ for sai_id_key in self .if_id_map :
261+ namespace , sai_id = mibs .split_sai_id_key (sai_id_key )
262+ if_idx = mibs .get_index_from_str (self .if_id_map [sai_id_key ])
263+ self .if_counters [if_idx ] = self .namespace_db_map [namespace ].get_all (mibs .COUNTERS_DB , \
264+ mibs .counter_table (sai_id ), blocking = True )
265+
266+ def update_rif_counters (self ):
267+ rif_sai_ids = list (self .rif_port_map ) + list (self .vlan_name_map )
268+ self .rif_counters = \
269+ {sai_id : Namespace .dbs_get_all (self .db_conn , mibs .COUNTERS_DB ,
270+ mibs .counter_table (mibs .split_sai_id_key (sai_id )[1 ]),
271+ blocking = False )
272+ for sai_id in rif_sai_ids }
273+
242274 def get_next (self , sub_id ):
243275 """
244276 :param sub_id: The 1-based sub-identifier query.
@@ -280,6 +312,8 @@ def interface_description(self, sub_id):
280312 return self .oid_lag_name_map [oid ]
281313 elif oid in self .mgmt_oid_name_map :
282314 return self .mgmt_alias_map [self .mgmt_oid_name_map [oid ]]
315+ elif oid in self .vlan_oid_name_map :
316+ return self .vlan_oid_name_map [oid ]
283317
284318 return self .if_alias_map [self .oid_name_map [oid ]]
285319
@@ -302,6 +336,31 @@ def _get_counter(self, oid, table_name):
302336 mibs .logger .warning ("SyncD 'COUNTERS_DB' missing attribute '{}'." .format (e ))
303337 return None
304338
339+ def aggregate_counters (self ):
340+ """
341+ For ports with l3 router interfaces l3 drops may be counted separately (RIF counters)
342+ add l3 drops to l2 drop counters cache according to mapping
343+
344+ For l3vlan map l3 counters to l2 counters
345+ """
346+ for rif_sai_id , port_sai_id in self .rif_port_map .items ():
347+ if port_sai_id in self .if_id_map :
348+ port_idx = mibs .get_index_from_str (self .if_id_map [port_sai_id ])
349+ for port_counter_name , rif_counter_name in mibs .RIF_DROPS_AGGR_MAP .items ():
350+ self .if_counters [port_idx ][port_counter_name ] = \
351+ int (self .if_counters [port_idx ][port_counter_name ]) + \
352+ int (self .rif_counters [rif_sai_id ][rif_counter_name ])
353+
354+ for vlan_sai_id , vlan_name in self .vlan_name_map .items ():
355+ for port_counter_name , rif_counter_name in mibs .RIF_COUNTERS_AGGR_MAP .items ():
356+ vlan_idx = mibs .get_index_from_str (vlan_name )
357+ vlan_rif_counters = self .rif_counters [vlan_sai_id ]
358+ if rif_counter_name in vlan_rif_counters :
359+ self .if_counters .setdefault (vlan_idx , {})
360+ self .if_counters [vlan_idx ][port_counter_name ] = \
361+ int (vlan_rif_counters [rif_counter_name ])
362+
363+
305364 def get_counter (self , sub_id , table_name ):
306365 """
307366 :param sub_id: The 1-based sub-identifier query.
@@ -321,7 +380,13 @@ def get_counter(self, sub_id, table_name):
321380 counter_value = 0
322381 for lag_member in self .lag_name_if_name_map [self .oid_lag_name_map [oid ]]:
323382 counter_value += self ._get_counter (mibs .get_index_from_str (lag_member ), table_name )
324-
383+ sai_lag_id = self .lag_sai_map [self .oid_lag_name_map [oid ]]
384+ sai_lag_rif_id = self .port_rif_map [sai_lag_id ]
385+ if sai_lag_rif_id in self .rif_port_map :
386+ table_name = getattr (table_name , 'name' , table_name )
387+ if table_name in mibs .RIF_DROPS_AGGR_MAP :
388+ rif_table_name = mibs .RIF_DROPS_AGGR_MAP [table_name ]
389+ counter_value += int (self .rif_counters [sai_lag_rif_id ].get (rif_table_name , 0 ))
325390 # truncate to 32-bit counter
326391 return counter_value & 0x00000000ffffffff
327392 else :
@@ -351,6 +416,8 @@ def _get_if_entry(self, sub_id):
351416 elif oid in self .mgmt_oid_name_map :
352417 if_table = mibs .mgmt_if_entry_table (self .mgmt_oid_name_map [oid ])
353418 db = mibs .CONFIG_DB
419+ elif oid in self .vlan_oid_name_map :
420+ if_table = mibs .vlan_entry_table (self .vlan_oid_name_map [oid ])
354421 elif oid in self .oid_name_map :
355422 if_table = mibs .if_entry_table (self .oid_name_map [oid ])
356423 else :
@@ -455,6 +522,7 @@ def get_if_type(self, sub_id):
455522
456523 ethernetCsmacd(6), -- for all ethernet-like interfaces,
457524 -- regardless of speed, as per RFC3635
525+ l3ipvlan(136) -- Layer 3 Virtual LAN using IP
458526 ieee8023adLag(161) -- IEEE 802.3ad Link Aggregate
459527 """
460528 oid = self .get_oid (sub_id )
@@ -463,6 +531,8 @@ def get_if_type(self, sub_id):
463531
464532 if oid in self .oid_lag_name_map :
465533 return IfTypes .ieee8023adLag
534+ elif oid in self .vlan_oid_name_map :
535+ return IfTypes .l3ipvlan
466536 else :
467537 return IfTypes .ethernetCsmacd
468538
0 commit comments