From b5323cdf181532cc192aff053fd391731d62e269 Mon Sep 17 00:00:00 2001 From: Yaroslav Kholod Date: Fri, 20 Dec 2024 16:41:06 +0200 Subject: [PATCH] CLI: Added line permutation check for file loaded config Sometimes instructions in the loaded config does not match the same instructions in the running config. In this case frr-reload.py removes the line. For example: pppoe-server(config-vrf)# ip route 10.0.0.0/8 blackhole tag 220 250 pppoe-server(config-vrf)# ip route 10.0.0.0/8 blackhole 250 tag 220 This leads to config loss and unpredictable FRR functionality. Signed-off-by: Yaroslav Kholod --- tools/frr-reload.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 2bb364f32b00..66aa10dabc2b 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -1701,6 +1701,26 @@ def ignore_unconfigurable_lines(lines_to_add, lines_to_del): return (lines_to_add, lines_to_del) +def is_line_permutated(test_line, conf): + """ + Verify if test_line permutations are present in conf + """ + + for conf_line in conf: + # If length of both strings is not same, + # then they cannot be Permutation + # Look for the lines with the same length! + if (len(test_line) == len(conf_line)): + # Sort both lines + test_line_sorted = sorted(test_line) # This is not the fastest code, however, this is a rare action :) + conf_line_sorted = sorted(conf_line) + # Compare sorted lines + if (test_line_sorted == conf_line_sorted): + log.info("Skip line %s, because it is a permutation of configuration line %s.", line, conf_line) + return True + + return False + def compare_context_objects(newconf, running): """ Create a context diff for the two specified contexts @@ -1934,7 +1954,8 @@ def compare_context_objects(newconf, running): for line in running_ctx.lines: if line not in newconf_ctx.dlines: - lines_to_del.append((newconf_ctx_keys, line)) + if (not is_line_permutated(line, newconf_ctx.dlines)): + lines_to_del.append((newconf_ctx_keys, line)) for newconf_ctx_keys, newconf_ctx in iteritems(newconf.contexts): if newconf_ctx_keys not in running.contexts: