diff --git a/scripts/vnet_route_check.py b/scripts/vnet_route_check.py index db50503cd9..886875f66f 100755 --- a/scripts/vnet_route_check.py +++ b/scripts/vnet_route_check.py @@ -47,7 +47,7 @@ RC_OK = 0 RC_ERR = -1 - +default_vrf_oid = "" report_level = syslog.LOG_ERR write_to_syslog = True @@ -211,7 +211,7 @@ def get_vnet_routes_from_app_db(): vnet_routes = {} for vnet_route_db_key in vnet_routes_db_keys: - vnet_route_list = vnet_route_db_key.split(':') + vnet_route_list = vnet_route_db_key.split(':',1) vnet_name = vnet_route_list[0] vnet_route = vnet_route_list[1] @@ -219,8 +219,22 @@ def get_vnet_routes_from_app_db(): vnet_routes[vnet_name] = {} vnet_routes[vnet_name]['routes'] = [] - intf = vnet_intfs[vnet_name][0] - vnet_routes[vnet_name]['vrf_oid'] = vnet_vrfs.get(intf, 'None') + if vnet_name not in vnet_intfs: + # this route has no vnet_intf and may be part of default VRF. + vnet_table = swsscommon.Table(db, 'VNET_TABLE') + scope_value = "" + # "Vnet_v4_in_v4-0": [("vxlan_tunnel", "tunnel_v4"), ("scope", "default"), ("vni", "10000"), ("peer_list", "")] + for key,value in vnet_table.get(vnet_name)[1]: + if key == "scope": + scope_value = value + break + if scope_value == 'default': + vnet_routes[vnet_name]['vrf_oid'] = default_vrf_oid + else: + assert "Non-default VRF route present without vnet interface." + else: + intf = vnet_intfs[vnet_name][0] + vnet_routes[vnet_name]['vrf_oid'] = vnet_vrfs.get(intf, 'None') vnet_routes[vnet_name]['routes'].append(vnet_route) @@ -237,10 +251,12 @@ def get_vnet_routes_from_asic_db(): vnet_vrfs = get_vrf_entries() vnet_vrfs_oids = [vnet_vrfs[k] for k in vnet_vrfs] + vnet_vrfs_oids.append(default_vrf_oid) vnet_intfs = get_vnet_intfs() vrf_oid_to_vnet_map = {} + vrf_oid_to_vnet_map[default_vrf_oid] = 'default_VRF' for vnet_name, vnet_rifs in vnet_intfs.items(): for vnet_rif, vrf_oid in vnet_vrfs.items(): @@ -276,7 +292,22 @@ def get_vnet_routes_from_asic_db(): return vnet_routes -def get_vnet_routes_diff(routes_1, routes_2): +def check_routes_with_default_vrf(vnet_name, vnet_attrs, routes_1, routes): + for vnet_route in vnet_attrs['routes']: + ispresent = False + for vnet_name_other, vnet_attrs_other in routes_1.items(): + if vnet_route in vnet_attrs_other['routes']: + ispresent = True + if not ispresent: + if vnet_name not in routes: + routes[vnet_name] = {} + routes[vnet_name]['routes'] = [] + routes[vnet_name]['routes'].append(vnet_route) + + return + + +def get_vnet_routes_diff(routes_1, routes_2, verify_default_vrf_routes = False): ''' Returns all routes present in routes_2 dictionary but missed in routes_1 Format: { : { 'routes': [ ] } } ''' @@ -284,15 +315,21 @@ def get_vnet_routes_diff(routes_1, routes_2): routes = {} for vnet_name, vnet_attrs in routes_2.items(): - if vnet_name not in routes_1: - routes[vnet_name] = routes + if vnet_attrs['vrf_oid'] == default_vrf_oid: + if verify_default_vrf_routes: + check_routes_with_default_vrf(vnet_name, vnet_attrs, routes_1, routes) + else: + continue else: - for vnet_route in vnet_attrs['routes']: - if vnet_route not in routes_1[vnet_name]['routes']: - if vnet_name not in routes: - routes[vnet_name] = {} - routes[vnet_name]['routes'] = [] - routes[vnet_name]['routes'].append(vnet_route) + if vnet_name not in routes_1: + routes[vnet_name] = vnet_attrs['routes'].copy() + else: + for vnet_route in vnet_attrs['routes']: + if vnet_route not in routes_1[vnet_name]['routes']: + if vnet_name not in routes: + routes[vnet_name] = {} + routes[vnet_name]['routes'] = [] + routes[vnet_name]['routes'].append(vnet_route) return routes @@ -326,11 +363,16 @@ def main(): # Don't run VNET routes consistancy logic if there is no VNET configuration if not check_vnet_cfg(): return rc + asic_db = swsscommon.DBConnector('ASIC_DB', 0) + virtual_router = swsscommon.Table(asic_db, 'ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER') + if virtual_router.getKeys() != []: + global default_vrf_oid + default_vrf_oid = virtual_router.getKeys()[0] app_db_vnet_routes = get_vnet_routes_from_app_db() asic_db_vnet_routes = get_vnet_routes_from_asic_db() - missed_in_asic_db_routes = get_vnet_routes_diff(asic_db_vnet_routes, app_db_vnet_routes) + missed_in_asic_db_routes = get_vnet_routes_diff(asic_db_vnet_routes, app_db_vnet_routes,True) missed_in_app_db_routes = get_vnet_routes_diff(app_db_vnet_routes, asic_db_vnet_routes) missed_in_sdk_routes = get_sdk_vnet_routes_diff(asic_db_vnet_routes) diff --git a/tests/vnet_route_check_test.py b/tests/vnet_route_check_test.py index c06ea10ea3..2596b28e20 100644 --- a/tests/vnet_route_check_test.py +++ b/tests/vnet_route_check_test.py @@ -27,7 +27,7 @@ VNET_ROUTE_TABLE = "VNET_ROUTE_TABLE" INTF_TABLE = "INTF_TABLE" ASIC_STATE = "ASIC_STATE" - +VNET_ROUTE_TUNNEL_TABLE = "VNET_ROUTE_TUNNEL_TABLE" RT_ENTRY_KEY_PREFIX = 'SAI_OBJECT_TYPE_ROUTE_ENTRY:{\"dest":\"' RT_ENTRY_KEY_SUFFIX = '\",\"switch_id\":\"oid:0x21000000000000\",\"vr\":\"oid:0x3000000000d4b\"}' @@ -223,6 +223,76 @@ } } } + }, + "4": { + DESCR: "All tunnel routes are configured in both APP and ASIC DB", + ARGS: "vnet_route_check", + PRE: { + APPL_DB: { + VXLAN_TUNNEL_TABLE: { + "tunnel_v4": { "src_ip": "10.1.0.32" }, + "tunnel_v6": { "src_ip": "3001:2000::1" } + }, + VNET_TABLE: { + "Vnet_v4_in_v4-0": [("vxlan_tunnel", "tunnel_v4"), ("scope", "default"), ("vni", "10000"), ("peer_list", "")], + "Vnet_v6_in_v6-0": [("vxlan_tunnel", "tunnel_v6"), ("scope", "default"), ("vni", "10002"), ("peer_list", "")] + + }, + VNET_ROUTE_TUNNEL_TABLE: { + "Vnet_v4_in_v4-0:150.62.191.1/32" : { "endpoint" : "100.251.7.1,100.251.7.2" }, + "Vnet_v6_in_v6-0:fd01:fc00::1/128" : { "endpoint" : "fc02:1000::1,fc02:1000::2" } + + } + }, + ASIC_DB: { + "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER": { + "oid:0x3000000000d4b" : { "":"" } + }, + ASIC_STATE: { + RT_ENTRY_KEY_PREFIX + "150.62.191.1/32" + RT_ENTRY_KEY_SUFFIX: {}, + RT_ENTRY_KEY_PREFIX + "fd01:fc00::1/128" + RT_ENTRY_KEY_SUFFIX: {} + } + } + }, + RESULT: { + "results": {} + } + }, + "5": { + DESCR: "Tunnel route present in APP DB but mssing in ASIC DB", + ARGS: "vnet_route_check", + RET: -1, + PRE: { + APPL_DB: { + VXLAN_TUNNEL_TABLE: { + "tunnel_v4": { "src_ip": "10.1.0.32" } + }, + VNET_TABLE: { + "Vnet_v4_in_v4-0": [("vxlan_tunnel", "tunnel_v4"), ("scope", "default"), ("vni", "10000"), ("peer_list", "")] + }, + VNET_ROUTE_TUNNEL_TABLE: { + "Vnet_v4_in_v4-0:150.62.191.1/32" : { "endpoint" : "100.251.7.1,100.251.7.2" } + } + }, + ASIC_DB: { + "ASIC_STATE:SAI_OBJECT_TYPE_VIRTUAL_ROUTER": { + "oid:0x3000000000d4b" : { "":"" } + }, + ASIC_STATE: { + } + } + }, + RESULT: { + "results": { + "missed_in_asic_db_routes": { + "Vnet_v4_in_v4-0": { + "routes": [ + "150.62.191.1/32" + ] + } + } + } + } } }