Skip to content

Commit ced0940

Browse files
authored
[dualtor_neighbor_check] Adjust zero-mac check condition (#3034)
* [dualtor_neighbor_check] Adjust zero-mac check condition
1 parent a4eeb69 commit ced0940

File tree

2 files changed

+75
-6
lines changed

2 files changed

+75
-6
lines changed

scripts/dualtor_neighbor_check.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@
155155

156156
DB_READ_SCRIPT_CONFIG_DB_KEY = "_DUALTOR_NEIGHBOR_CHECK_SCRIPT_SHA1"
157157
ZERO_MAC = "00:00:00:00:00:00"
158-
NEIGHBOR_ATTRIBUTES = ["NEIGHBOR", "MAC", "PORT", "MUX_STATE", "IN_MUX_TOGGLE", "NEIGHBOR_IN_ASIC", "TUNNERL_IN_ASIC", "HWSTATUS"]
158+
NEIGHBOR_ATTRIBUTES = ["NEIGHBOR", "MAC", "PORT", "MUX_STATE", "IN_MUX_TOGGLE", "NEIGHBOR_IN_ASIC", "TUNNEL_IN_ASIC", "HWSTATUS"]
159159
NOT_AVAILABLE = "N/A"
160160

161161

@@ -400,9 +400,12 @@ def check_neighbor_consistency(neighbors, mux_states, hw_mux_states, mac_to_port
400400
continue
401401

402402
check_result["NEIGHBOR_IN_ASIC"] = neighbor_ip in asic_neighs
403-
check_result["TUNNERL_IN_ASIC"] = neighbor_ip in asic_route_destinations
403+
check_result["TUNNEL_IN_ASIC"] = neighbor_ip in asic_route_destinations
404404
if is_zero_mac:
405-
check_result["HWSTATUS"] = ((not check_result["NEIGHBOR_IN_ASIC"]) and check_result["TUNNERL_IN_ASIC"])
405+
# NOTE: for zero-mac neighbors, two situations:
406+
# 1. new neighbor just learnt, no neighbor entry in ASIC, tunnel route present in ASIC.
407+
# 2. neighbor expired, neighbor entry still present in ASIC, no tunnel route in ASIC.
408+
check_result["HWSTATUS"] = check_result["NEIGHBOR_IN_ASIC"] or check_result["TUNNEL_IN_ASIC"]
406409
else:
407410
port_name = mac_to_port_name_map[mac]
408411
# NOTE: mux server ips are always fixed to the mux port
@@ -415,9 +418,9 @@ def check_neighbor_consistency(neighbors, mux_states, hw_mux_states, mac_to_port
415418
check_result["IN_MUX_TOGGLE"] = mux_state != hw_mux_state
416419

417420
if mux_state == "active":
418-
check_result["HWSTATUS"] = (check_result["NEIGHBOR_IN_ASIC"] and (not check_result["TUNNERL_IN_ASIC"]))
421+
check_result["HWSTATUS"] = (check_result["NEIGHBOR_IN_ASIC"] and (not check_result["TUNNEL_IN_ASIC"]))
419422
elif mux_state == "standby":
420-
check_result["HWSTATUS"] = ((not check_result["NEIGHBOR_IN_ASIC"]) and check_result["TUNNERL_IN_ASIC"])
423+
check_result["HWSTATUS"] = ((not check_result["NEIGHBOR_IN_ASIC"]) and check_result["TUNNEL_IN_ASIC"])
421424
else:
422425
# skip as unknown mux state
423426
continue
@@ -442,7 +445,7 @@ def parse_check_results(check_results):
442445
if not is_zero_mac:
443446
check_result["IN_MUX_TOGGLE"] = bool_to_yes_no[in_toggle]
444447
check_result["NEIGHBOR_IN_ASIC"] = bool_to_yes_no[check_result["NEIGHBOR_IN_ASIC"]]
445-
check_result["TUNNERL_IN_ASIC"] = bool_to_yes_no[check_result["TUNNERL_IN_ASIC"]]
448+
check_result["TUNNEL_IN_ASIC"] = bool_to_yes_no[check_result["TUNNEL_IN_ASIC"]]
446449
check_result["HWSTATUS"] = bool_to_consistency[hwstatus]
447450
if (not hwstatus):
448451
if is_zero_mac:

tests/dualtor_neighbor_check_test.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,3 +611,69 @@ def test_check_neighbor_consistency_zero_mac_neighbor(self, mock_log_functions):
611611
assert res is True
612612
mock_log_warn.assert_has_calls(expected_log_warn_calls)
613613
mock_log_error.assert_not_called()
614+
615+
def test_check_neighbor_consistency_zero_mac_expired_neighbor(self, mock_log_functions):
616+
mock_log_error, mock_log_warn, _, _ = mock_log_functions
617+
neighbors = {"192.168.0.102": "00:00:00:00:00:00"}
618+
mux_states = {"Ethernet4": "active"}
619+
hw_mux_states = {"Ethernet4": "active"}
620+
mac_to_port_name_map = {"ee:86:d8:46:7d:01": "Ethernet4"}
621+
asic_route_table = []
622+
asic_neigh_table = ["{\"ip\":\"192.168.0.102\",\"rif\":\"oid:0x6000000000671\",\"switch_id\":\"oid:0x21000000000000\"}"]
623+
mux_server_to_port_map = {"192.168.0.2": "Ethernet4"}
624+
expected_output = ["192.168.0.102", "00:00:00:00:00:00", "N/A", "N/A", "N/A", "yes", "no", "consistent"]
625+
expected_log_output = tabulate.tabulate(
626+
[expected_output],
627+
headers=dualtor_neighbor_check.NEIGHBOR_ATTRIBUTES,
628+
tablefmt="simple"
629+
).split("\n")
630+
expected_log_warn_calls = [call(line) for line in expected_log_output]
631+
632+
check_results = dualtor_neighbor_check.check_neighbor_consistency(
633+
neighbors,
634+
mux_states,
635+
hw_mux_states,
636+
mac_to_port_name_map,
637+
asic_route_table,
638+
asic_neigh_table,
639+
mux_server_to_port_map
640+
)
641+
res = dualtor_neighbor_check.parse_check_results(check_results)
642+
643+
assert res is True
644+
mock_log_warn.assert_has_calls(expected_log_warn_calls)
645+
mock_log_error.assert_not_called()
646+
647+
def test_check_neighbor_consistency_inconsistent_zero_mac_neighbor(self, mock_log_functions):
648+
mock_log_error, mock_log_warn, _, _ = mock_log_functions
649+
neighbors = {"192.168.0.102": "00:00:00:00:00:00"}
650+
mux_states = {"Ethernet4": "active"}
651+
hw_mux_states = {"Ethernet4": "active"}
652+
mac_to_port_name_map = {"ee:86:d8:46:7d:01": "Ethernet4"}
653+
asic_route_table = []
654+
asic_neigh_table = []
655+
mux_server_to_port_map = {"192.168.0.2": "Ethernet4"}
656+
expected_output = ["192.168.0.102", "00:00:00:00:00:00", "N/A", "N/A", "N/A", "no", "no", "inconsistent"]
657+
expected_log_output = tabulate.tabulate(
658+
[expected_output],
659+
headers=dualtor_neighbor_check.NEIGHBOR_ATTRIBUTES,
660+
tablefmt="simple"
661+
).split("\n")
662+
expected_log_warn_calls = [call(line) for line in expected_log_output]
663+
expected_log_error_calls = [call("Found neighbors that are inconsistent with mux states: %s", ["192.168.0.102"])]
664+
expected_log_error_calls.extend([call(line) for line in expected_log_output])
665+
666+
check_results = dualtor_neighbor_check.check_neighbor_consistency(
667+
neighbors,
668+
mux_states,
669+
hw_mux_states,
670+
mac_to_port_name_map,
671+
asic_route_table,
672+
asic_neigh_table,
673+
mux_server_to_port_map
674+
)
675+
res = dualtor_neighbor_check.parse_check_results(check_results)
676+
677+
assert res is False
678+
mock_log_warn.assert_has_calls(expected_log_warn_calls)
679+
mock_log_error.assert_has_calls(expected_log_error_calls)

0 commit comments

Comments
 (0)