Skip to content

Commit f0ce586

Browse files
[route_check]: Ignore standalone tunnel routes (sonic-net#2325)
When checking for route entry mismatches, ignore mismatched routes where an APPL_DB neighbor entry with a zero MAC is present. These routes are introduced by this change in SWSS and are expected: sonic-net/sonic-swss#2137 Signed-off-by: Lawrence Lee <[email protected]>
1 parent 3af8ba4 commit f0ce586

File tree

5 files changed

+92
-15
lines changed

5 files changed

+92
-15
lines changed

scripts/route_check.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,45 @@ def filter_out_vnet_routes(routes):
450450
return updated_routes
451451

452452

453+
def filter_out_standalone_tunnel_routes(routes):
454+
config_db = swsscommon.ConfigDBConnector()
455+
config_db.connect()
456+
device_metadata = config_db.get_table('DEVICE_METADATA')
457+
subtype = device_metadata['localhost'].get('subtype', '')
458+
459+
if subtype.lower() != 'dualtor':
460+
return routes
461+
462+
app_db = swsscommon.DBConnector('APPL_DB', 0)
463+
neigh_table = swsscommon.Table(app_db, 'NEIGH_TABLE')
464+
neigh_keys = neigh_table.getKeys()
465+
standalone_tunnel_route_ips = []
466+
updated_routes = []
467+
468+
for neigh in neigh_keys:
469+
_, mac = neigh_table.hget(neigh, 'neigh')
470+
if mac == '00:00:00:00:00:00':
471+
# remove preceding 'VlanXXXX' to get just the neighbor IP
472+
neigh_ip = ':'.join(neigh.split(':')[1:])
473+
standalone_tunnel_route_ips.append(neigh_ip)
474+
475+
if not standalone_tunnel_route_ips:
476+
return routes
477+
478+
for route in routes:
479+
ip, subnet = route.split('/')
480+
ip_version = ipaddress.ip_address(ip).version
481+
482+
# we want to keep the route if it is not a standalone tunnel route.
483+
# if the route subnet contains more than one address, it is not a
484+
# standalone tunnel route
485+
if (ip not in standalone_tunnel_route_ips) or \
486+
((ip_version == 6 and subnet != '128') or (ip_version == 4 and subnet != '32')):
487+
updated_routes.append(route)
488+
489+
return updated_routes
490+
491+
453492
def check_routes():
454493
"""
455494
The heart of this script which runs the checks.
@@ -486,6 +525,7 @@ def check_routes():
486525
_, rt_asic_miss = diff_sorted_lists(intf_appl, rt_asic_miss)
487526
rt_asic_miss = filter_out_default_routes(rt_asic_miss)
488527
rt_asic_miss = filter_out_vnet_routes(rt_asic_miss)
528+
rt_asic_miss = filter_out_standalone_tunnel_routes(rt_asic_miss)
489529

490530
# Check APPL-DB INTF_TABLE with ASIC table route entries
491531
intf_appl_miss, _ = diff_sorted_lists(intf_appl, rt_asic)

scripts/route_check_test.sh

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,36 @@
22

33
# add a route, interface & route-entry to simulate error
44
#
5-
sonic-db-cli APPL_DB hmset "ROUTE_TABLE:20c0:d9b8:99:80::/64" "nexthop" "fc00::72,fc00::76,fc00::7a,fc00::7e" "ifname" "PortChannel01,PortChannel02,PortChannel03,PortChannel04"
5+
sonic-db-cli APPL_DB hmset "ROUTE_TABLE:20c0:d9b8:99:80::/64" "nexthop" "fc00::72,fc00::76,fc00::7a,fc00::7e" "ifname" "PortChannel01,PortChannel02,PortChannel03,PortChannel04" > /dev/null
6+
sonic-db-cli ASIC_DB hmset "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY:{\"dest\":\"192.193.120.255/25\",\"switch_id\":\"oid:0x21000000000000\",\"vr\":\"oid:0x3000000000022\"}" "SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID" "oid:0x5000000000614" > /dev/null
7+
sonic-db-cli APPL_DB hmset "INTF_TABLE:PortChannel01:10.0.0.99/31" "scope" "global" "family" "IPv4" > /dev/null
68

9+
echo "------"
10+
echo "expect errors!"
11+
echo "Running Route Check..."
12+
./route_check.py
13+
echo "return value: $?"
714

8-
sonic-db-cli ASIC_DB hmset "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY:{\"dest\":\"192.193.120.255/25\",\"switch_id\":\"oid:0x21000000000000\",\"vr\":\"oid:0x3000000000022\"}" "SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID" "oid:0x5000000000614"
15+
sonic-db-cli APPL_DB del "ROUTE_TABLE:20c0:d9b8:99:80::/64" > /dev/null
16+
sonic-db-cli ASIC_DB del "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY:{\"dest\":\"192.193.120.255/25\",\"switch_id\":\"oid:0x21000000000000\",\"vr\":\"oid:0x3000000000022\"}" > /dev/null
17+
sonic-db-cli APPL_DB del "INTF_TABLE:PortChannel01:10.0.0.99/31" > /dev/null
918

10-
sonic-db-cli APPL_DB hmset "INTF_TABLE:PortChannel01:10.0.0.99/31" "scope" "global" "family" "IPv4"
19+
# add standalone tunnel route to simulate unreachable neighbor scenario on dual ToR
20+
# in this scenario, we expect the route mismatch to be ignored
21+
sonic-db-cli APPL_DB hmset "NEIGH_TABLE:Vlan1000:fc02:1000::99" "neigh" "00:00:00:00:00:00" "family" "IPv6" > /dev/null
22+
sonic-db-cli ASIC_DB hmset 'ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY:{"dest":"fc02:1000::99/128","switch_id":"oid:0x21000000000000","vr":"oid:0x300000000007c"}' "SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID" "oid:0x400000000167d" "SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION" "SAI_PACKET_ACTION_FORWARD" > /dev/null
1123

12-
echo "expect errors!\n------\nRunning Route Check...\n"
24+
echo "------"
25+
echo "expect success on dualtor, expect error on all other devices!"
26+
echo "Running Route Check..."
1327
./route_check.py
1428
echo "return value: $?"
1529

16-
sonic-db-cli APPL_DB del "ROUTE_TABLE:20c0:d9b8:99:80::/64"
17-
sonic-db-cli ASIC_DB del "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY:{\"dest\":\"192.193.120.255/25\",\"switch_id\":\"oid:0x21000000000000\",\"vr\":\"oid:0x3000000000022\"}"
18-
sonic-db-cli APPL_DB del "INTF_TABLE:PortChannel01:10.0.0.99/31"
19-
30+
sonic-db-cli APPL_DB del "NEIGH_TABLE:Vlan1000:fc02:1000::99" > /dev/null
31+
sonic-db-cli ASIC_DB del 'ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY:{"dest":"fc02:1000::99/128","switch_id":"oid:0x21000000000000","vr":"oid:0x300000000007c"}' > /dev/null
2032

21-
echo "expect success!\n------\nRunning Route Check...\n"
33+
echo "------"
34+
echo "expect success!"
35+
echo "Running Route Check..."
2236
./route_check.py
2337
echo "return value: $?"

tests/config_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def test_config_reload(self, get_cmd_module, setup_single_broadcom_asic):
222222
obj = {'config_db': db.cfgdb}
223223

224224
# simulate 'config reload' to provoke load_sys_info option
225-
result = runner.invoke(config.config.commands["reload"], ["-l", "-n", "-y"], obj=obj)
225+
result = runner.invoke(config.config.commands["reload"], ["-l", "-n", "-y", "--disable_arp_cache"], obj=obj)
226226

227227
print(result.exit_code)
228228
print(result.output)
@@ -484,7 +484,7 @@ def test_reload_config(self, get_cmd_module, setup_single_broadcom_asic):
484484

485485
result = runner.invoke(
486486
config.config.commands["reload"],
487-
[self.dummy_cfg_file, '-y', '-f'])
487+
[self.dummy_cfg_file, '-y', '-f', "--disable_arp_cache"])
488488

489489
print(result.exit_code)
490490
print(result.output)
@@ -501,7 +501,7 @@ def test_config_reload_disabled_service(self, get_cmd_module, setup_single_broad
501501
(config, show) = get_cmd_module
502502

503503
runner = CliRunner()
504-
result = runner.invoke(config.config.commands["reload"], [self.dummy_cfg_file, "-y"])
504+
result = runner.invoke(config.config.commands["reload"], [self.dummy_cfg_file, "-y", "--disable_arp_cache"])
505505

506506
print(result.exit_code)
507507
print(result.output)
@@ -526,7 +526,7 @@ def test_reload_config_masic(self, get_cmd_module, setup_multi_broadcom_masic):
526526
self.dummy_cfg_file)
527527
result = runner.invoke(
528528
config.config.commands["reload"],
529-
[cfg_files, '-y', '-f'])
529+
[cfg_files, '-y', '-f', "--disable_arp_cache"])
530530

531531
print(result.exit_code)
532532
print(result.output)
@@ -545,7 +545,7 @@ def test_reload_yang_config(self, get_cmd_module,
545545
runner = CliRunner()
546546

547547
result = runner.invoke(config.config.commands["reload"],
548-
[self.dummy_cfg_file, '-y','-f' ,'-t', 'config_yang'])
548+
[self.dummy_cfg_file, "--disable_arp_cache", '-y', '-f', '-t', 'config_yang'])
549549

550550
print(result.exit_code)
551551
print(result.output)

tests/mock_tables/config_db.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,8 @@
828828
"mac": "1d:34:db:16:a6:00",
829829
"platform": "x86_64-mlnx_msn3800-r0",
830830
"peer_switch": "sonic-switch",
831-
"type": "ToRRouter"
831+
"type": "ToRRouter",
832+
"subtype": "DualToR"
832833
},
833834
"SNMP_COMMUNITY|msft": {
834835
"TYPE": "RO"

tests/route_check_test.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
OP_SET = "SET"
2525
OP_DEL = "DEL"
2626

27+
NEIGH_TABLE = 'NEIGH_TABLE'
2728
ROUTE_TABLE = 'ROUTE_TABLE'
2829
VNET_ROUTE_TABLE = 'VNET_ROUTE_TABLE'
2930
INTF_TABLE = 'INTF_TABLE'
@@ -295,6 +296,22 @@
295296
}
296297
},
297298
"7": {
299+
DESCR: "dualtor standalone tunnel route case",
300+
ARGS: "route_check",
301+
PRE: {
302+
APPL_DB: {
303+
NEIGH_TABLE: {
304+
"Vlan1000:fc02:1000::99": { "neigh": "00:00:00:00:00:00", "family": "IPv6"}
305+
}
306+
},
307+
ASIC_DB: {
308+
RT_ENTRY_TABLE: {
309+
RT_ENTRY_KEY_PREFIX + "fc02:1000::99/128" + RT_ENTRY_KEY_SUFFIX: {},
310+
}
311+
}
312+
}
313+
},
314+
"8": {
298315
DESCR: "Good one with VRF routes",
299316
ARGS: "route_check",
300317
PRE: {
@@ -403,6 +420,11 @@ def get(self, key):
403420
return (True, ret)
404421

405422

423+
def hget(self, key, field):
424+
ret = copy.deepcopy(self.data.get(key, {}).get(field, {}))
425+
return True, ret
426+
427+
406428
db_conns = {"APPL_DB": APPL_DB, "ASIC_DB": ASIC_DB}
407429
def conn_side_effect(arg, _):
408430
return db_conns[arg]

0 commit comments

Comments
 (0)