Skip to content

Commit afa6c14

Browse files
authored
Skip checking offload flags for static routes/sids in route check and add check_sids (#187)
<!-- Please make sure you've read and understood our contributing guidelines: https://github.com/Azure/SONiC/blob/gh-pages/CONTRIBUTING.md failure_prs.log skip_prs.log Make sure all your commits include a signature generated with `git commit -s` ** If this is a bug fix, make sure your description includes "closes #xxxx", "fixes #xxxx" or "resolves #xxxx" so that GitHub automatically closes the related issue when the PR is merged. If you are adding/modifying/removing any command or utility script, please also make sure to add/modify/remove any unit tests from the tests directory as appropriate. If you are modifying or removing an existing 'show', 'config' or 'sonic-clear' subcommand, or you are adding a new subcommand, please make sure you also update the Command Line Reference Guide (doc/Command-Reference.md) to reflect your changes. Please provide the following information: --> #### What I did 1. Skip checking offload flags for static routes and static SIDs in FRR in check_frr_pending_routes. 2. Add check_sids to check consistency between MY_SID tables of ASIC_DB and APPL_DB #### How I did it #### How to verify it Run on a device supporting SRv6 #### Previous command output (if the output of a command-line utility has changed) #### New command output (if the output of a command-line utility has changed)
1 parent 09597f2 commit afa6c14

2 files changed

Lines changed: 511 additions & 197 deletions

File tree

scripts/route_check.py

Lines changed: 130 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,52 @@ def get_asicdb_routes(namespace):
328328
return (selector, subs, sorted(rt))
329329

330330

331+
def get_appdb_sids(namespace):
332+
"""
333+
helper to read SIDs table from APPL-DB.
334+
:return list of sorted SIDs with prefix ensured
335+
"""
336+
db = swsscommon.DBConnector(APPL_DB_NAME, REDIS_TIMEOUT_MSECS, True, namespace)
337+
print_message(syslog.LOG_DEBUG, "APPL DB connected for sids")
338+
tbl = swsscommon.Table(db, 'SRV6_MY_SID_TABLE')
339+
keys = tbl.getKeys()
340+
341+
sids = sorted(keys)
342+
print_message(syslog.LOG_DEBUG, json.dumps({"APPL_MY_SID_TABLE": sids}, indent=4))
343+
return sids
344+
345+
346+
def get_asicdb_sids(namespace):
347+
"""
348+
helper to read SIDs table from APPL-DB.
349+
:return list of sorted SIDs with prefix ensured
350+
"""
351+
db = swsscommon.DBConnector(ASIC_DB_NAME, REDIS_TIMEOUT_MSECS, True, namespace)
352+
print_message(syslog.LOG_DEBUG, "ASIC DB connected for sids")
353+
tbl = swsscommon.Table(db, ASIC_TABLE_NAME)
354+
keys = tbl.getKeys()
355+
356+
sids = []
357+
for k in keys:
358+
content = k.split(":", 1)
359+
if content[0] != 'SAI_OBJECT_TYPE_MY_SID_ENTRY':
360+
continue
361+
sid_info = json.loads(content[1])
362+
sid_entry = ":".join([
363+
sid_info.get("locator_block_len", "0"),
364+
sid_info.get("locator_node_len", "0"),
365+
sid_info.get("function_len", "0"),
366+
sid_info.get("args_len", "0"),
367+
sid_info.get("sid")
368+
])
369+
370+
sids.append(sid_entry)
371+
372+
sids = sorted(sids)
373+
print_message(syslog.LOG_DEBUG, json.dumps({"ASIC_MY_SID_TABLE": sids}, indent=4))
374+
return sids
375+
376+
331377
def is_suppress_fib_pending_enabled(namespace):
332378
"""
333379
Returns True if FIB suppression is enabled, False otherwise
@@ -560,7 +606,7 @@ def check_frr_pending_routes(namespace):
560606

561607
for _, entries in frr_routes.items():
562608
for entry in entries:
563-
if entry['protocol'] in ('connected', 'kernel'):
609+
if entry['protocol'] in ('connected', 'kernel', 'static'):
564610
continue
565611

566612
# TODO: Also handle VRF routes. Currently this script does not check for VRF routes so it would be incorrect for us
@@ -804,6 +850,74 @@ def check_routes(namespace):
804850
print_message(syslog.LOG_INFO, "All good!")
805851
return 0, None
806852

853+
854+
def check_sids_for_namespace(namespace):
855+
"""
856+
Process a Single Namespace for SIDs consistency check:
857+
Read APPL-DB & ASIC-DB, the relevant tables for SID checking.
858+
Checkout SIDs in ASIC-DB to match APPL-DB. Compared to check_routes,
859+
this function does not wait for subscriber updates, as SIDs are not
860+
expected to change frequently.
861+
862+
:return (0, None) on sucess, else (-1, results) where results holds
863+
the unjustifiable entries.
864+
"""
865+
866+
results = {}
867+
sid_appl_miss = []
868+
sid_asic_miss = []
869+
870+
sids_asic = get_asicdb_sids(namespace)
871+
872+
sids_appl = get_appdb_sids(namespace)
873+
874+
# Diff APPL-DB SIDs & ASIC-DB SIDs
875+
sid_appl_miss, sid_asic_miss = diff_sorted_lists(sids_appl, sids_asic)
876+
877+
if sid_appl_miss:
878+
results["missed_APPL_MY_SID_TABLE_entries"] = sid_appl_miss
879+
880+
if sid_asic_miss:
881+
results["missed_ASIC_MY_SID_TABLE_entries"] = sid_asic_miss
882+
883+
return results
884+
885+
886+
def check_sids(namespace):
887+
"""
888+
Main function to parallelize SID checks across all namespaces.
889+
"""
890+
namespace_list = []
891+
if namespace is not multi_asic.DEFAULT_NAMESPACE and namespace in multi_asic.get_namespace_list():
892+
namespace_list.append(namespace)
893+
else:
894+
namespace_list = multi_asic.get_namespace_list()
895+
print_message(syslog.LOG_INFO, "Checking SIDs for namespaces: ", namespace_list)
896+
897+
results = {}
898+
899+
# Use ThreadPoolExecutor to parallelize the check for each namespace
900+
with concurrent.futures.ThreadPoolExecutor() as executor:
901+
futures = {executor.submit(check_sids_for_namespace, ns): ns for ns in namespace_list}
902+
903+
for future in concurrent.futures.as_completed(futures):
904+
ns = futures[future]
905+
try:
906+
result = future.result()
907+
if result:
908+
results[ns] = result
909+
except Exception as e:
910+
print_message(syslog.LOG_ERR, "Error processing namespace {}: {}".format(ns, e))
911+
return -1, results
912+
913+
if results:
914+
print_message(syslog.LOG_WARNING, "SIDs Check Failure results: {", json.dumps(results, indent=4), "}")
915+
return -1, results
916+
else:
917+
print_message(syslog.LOG_INFO, "All good!")
918+
return 0, None
919+
920+
807921
def main():
808922
"""
809923
main entry point, which mainly parses the args and call check_routes
@@ -849,9 +963,22 @@ def main():
849963

850964
while True:
851965
signal.alarm(TIMEOUT_SECONDS)
852-
ret, res= check_routes(namespace)
853-
print_message(syslog.LOG_DEBUG, "ret={}, res={}".format(ret, res))
966+
ret1, res1 = check_routes(namespace)
967+
print_message(syslog.LOG_DEBUG, "check_routes: ret={}, res={}".format(ret1, res1))
968+
ret2, res2 = check_sids(namespace)
969+
print_message(syslog.LOG_DEBUG, "check_sids: ret={}, res={}".format(ret2, res2))
854970
signal.alarm(0)
971+
if ret1 < 0 or ret2 < 0:
972+
ret = -1
973+
else:
974+
ret = 0
975+
976+
if res1 is not None or res2 is not None:
977+
res = dict()
978+
res.update(res1 if res1 else {})
979+
res.update(res2 if res2 else {})
980+
else:
981+
res = None
855982

856983
if interval:
857984
time.sleep(interval)

0 commit comments

Comments
 (0)