From 3e28dfce7566e5678f11d6d48f1b4ca655e2d54d 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 | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 2bb364f32b00..21d3b84edbf1 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -1701,6 +1701,33 @@ 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 +1961,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: