Skip to content

Commit 4fc6f42

Browse files
committed
1 parent f500d7b commit 4fc6f42

File tree

2 files changed

+130
-3
lines changed

2 files changed

+130
-3
lines changed

tests/test_vnet.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3275,6 +3275,65 @@ def test_vnet_orch_32(self, dvs, testlog):
32753275
self.remove_ip_address("Ethernet12", "9.1.0.4/32")
32763276
self.set_admin_status("Ethernet12", "down")
32773277

3278+
'''
3279+
Test 33 - Test for vnet tunnel routes with fine-grained ECMP using consistent_hashing_buckets
3280+
'''
3281+
def test_vnet_orch_33(self, dvs, testlog):
3282+
vnet_obj = self.get_vnet_obj()
3283+
3284+
self.setup_db(dvs)
3285+
3286+
tunnel_name = 'tunnel_33'
3287+
vnet_name = 'Vnet33'
3288+
3289+
vnet_obj.fetch_exist_entries(dvs)
3290+
3291+
# Create VxLAN tunnel
3292+
create_vxlan_tunnel(dvs, tunnel_name, '10.10.10.10')
3293+
create_vnet_entry(dvs, vnet_name, tunnel_name, '10033', "")
3294+
3295+
vnet_obj.check_vnet_entry(dvs, vnet_name)
3296+
vnet_obj.check_vxlan_tunnel_entry(dvs, tunnel_name, vnet_name, '10033')
3297+
vnet_obj.check_vxlan_tunnel(dvs, tunnel_name, '10.10.10.10')
3298+
3299+
vnet_obj.fetch_exist_entries(dvs)
3300+
3301+
# Create VNET route with consistent_hashing_buckets for fine-grained ECMP
3302+
bucket_size = 120
3303+
create_vnet_routes(dvs, "100.100.33.0/24", vnet_name, '33.0.0.1,33.0.0.2,33.0.0.3',
3304+
consistent_hashing_buckets=bucket_size)
3305+
3306+
# Verify the route is created with fine-grained ECMP
3307+
route, nhgid = vnet_obj.check_vnet_fine_grained_ecmp_routes(dvs, vnet_name,
3308+
['33.0.0.1', '33.0.0.2', '33.0.0.3'],
3309+
tunnel_name, bucket_size)
3310+
3311+
check_state_db_routes(dvs, vnet_name, "100.100.33.0/24", ['33.0.0.1', '33.0.0.2', '33.0.0.3'])
3312+
check_remove_routes_advertisement(dvs, "100.100.33.0/24")
3313+
3314+
# Update route with different endpoints while keeping fine-grained ECMP
3315+
vnet_obj.fetch_exist_entries(dvs)
3316+
set_vnet_routes(dvs, "100.100.33.0/24", vnet_name, '33.0.0.1,33.0.0.2,33.0.0.3,33.0.0.4',
3317+
consistent_hashing_buckets=bucket_size)
3318+
3319+
route, nhgid = vnet_obj.check_vnet_fine_grained_ecmp_routes(dvs, vnet_name,
3320+
['33.0.0.1', '33.0.0.2', '33.0.0.3', '33.0.0.4'],
3321+
tunnel_name, bucket_size, route_ids=route)
3322+
3323+
check_state_db_routes(dvs, vnet_name, "100.100.33.0/24", ['33.0.0.1', '33.0.0.2', '33.0.0.3', '33.0.0.4'])
3324+
check_remove_routes_advertisement(dvs, "100.100.33.0/24")
3325+
3326+
# Clean up
3327+
vnet_obj.fetch_exist_entries(dvs)
3328+
delete_vnet_routes(dvs, "100.100.33.0/24", vnet_name)
3329+
vnet_obj.check_del_vnet_routes(dvs, vnet_name, ["100.100.33.0/24"])
3330+
check_remove_state_db_routes(dvs, vnet_name, "100.100.33.0/24")
3331+
check_remove_routes_advertisement(dvs, "100.100.33.0/24")
3332+
3333+
delete_vnet_entry(dvs, vnet_name)
3334+
vnet_obj.check_del_vnet_entry(dvs, vnet_name)
3335+
delete_vxlan_tunnel(dvs, tunnel_name)
3336+
32783337
# Add Dummy always-pass test at end as workaroud
32793338
# for issue when Flaky fail on final test it invokes module tear-down before retrying
32803339
def test_nonflaky_dummy():

tests/vnet_lib.py

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@ def delete_vnet_local_routes(dvs, prefix, vnet_name):
140140
time.sleep(2)
141141

142142

143-
def create_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile="", primary="", monitoring="", rx_monitor_timer=-1, tx_monitor_timer=-1, adv_prefix="", check_directly_connected=False):
144-
set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac=mac, vni=vni, ep_monitor=ep_monitor, profile=profile, primary=primary, monitoring=monitoring, rx_monitor_timer=rx_monitor_timer, tx_monitor_timer=tx_monitor_timer, adv_prefix=adv_prefix, check_directly_connected=check_directly_connected)
143+
def create_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile="", primary="", monitoring="", rx_monitor_timer=-1, tx_monitor_timer=-1, adv_prefix="", check_directly_connected=False, consistent_hashing_buckets=0):
144+
set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac=mac, vni=vni, ep_monitor=ep_monitor, profile=profile, primary=primary, monitoring=monitoring, rx_monitor_timer=rx_monitor_timer, tx_monitor_timer=tx_monitor_timer, adv_prefix=adv_prefix, check_directly_connected=check_directly_connected, consistent_hashing_buckets=consistent_hashing_buckets)
145145

146146

147-
def set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile="", primary="", monitoring="", rx_monitor_timer=-1, tx_monitor_timer=-1, adv_prefix="", check_directly_connected=False):
147+
def set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor="", profile="", primary="", monitoring="", rx_monitor_timer=-1, tx_monitor_timer=-1, adv_prefix="", check_directly_connected=False, consistent_hashing_buckets=0):
148148
conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0)
149149

150150
attrs = [
@@ -181,6 +181,9 @@ def set_vnet_routes(dvs, prefix, vnet_name, endpoint, mac="", vni=0, ep_monitor=
181181
if tx_monitor_timer != -1:
182182
attrs.append(('tx_monitor_timer', str(tx_monitor_timer)))
183183

184+
if consistent_hashing_buckets > 0:
185+
attrs.append(('consistent_hashing_buckets', str(consistent_hashing_buckets)))
186+
184187
tbl = swsscommon.Table(conf_db, "VNET_ROUTE_TUNNEL")
185188
fvs = swsscommon.FieldValuePairs(attrs)
186189
tbl.set("%s|%s" % (vnet_name, prefix), fvs)
@@ -1222,6 +1225,71 @@ def check_vnet_ecmp_routes(self, dvs, name, endpoints, tunnel, mac=[], vni=[], r
12221225

12231226
return new_route, new_nhg
12241227

1228+
def check_vnet_fine_grained_ecmp_routes(self, dvs, name, endpoints, tunnel, bucket_size, route_ids=[], mac=[], vni=[]):
1229+
asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0)
1230+
1231+
vr_ids = self.vnet_route_ids(dvs, name)
1232+
count = len(vr_ids)
1233+
1234+
# Validate that next hop group is of type FINE_GRAIN_ECMP
1235+
if route_ids:
1236+
new_route = route_ids
1237+
else:
1238+
new_route = get_created_entries(asic_db, self.ASIC_ROUTE_ENTRY, self.routes, count)
1239+
1240+
# Get the next hop group ID from the route
1241+
fvs = asic_db.get_entry(self.ASIC_ROUTE_ENTRY, new_route[0])
1242+
nhgid = fvs.get("SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID")
1243+
assert nhgid, "Next hop group ID not found"
1244+
1245+
# Check that the next hop group is of type FINE_GRAIN_ECMP
1246+
nhg_fvs = asic_db.get_entry(self.ASIC_NEXT_HOP_GROUP, nhgid)
1247+
nhg_type = nhg_fvs.get("SAI_NEXT_HOP_GROUP_ATTR_TYPE")
1248+
assert nhg_type == "SAI_NEXT_HOP_GROUP_TYPE_FINE_GRAIN_ECMP", f"Expected FINE_GRAIN_ECMP, got {nhg_type}"
1249+
1250+
# Check that configured size matches bucket_size
1251+
nhg_cfg_size = nhg_fvs.get("SAI_NEXT_HOP_GROUP_ATTR_CONFIGURED_SIZE")
1252+
assert int(nhg_cfg_size) == bucket_size, f"Expected bucket size {bucket_size}, got {nhg_cfg_size}"
1253+
1254+
# Check that next hop group members exist and match bucket size
1255+
nhg_members = asic_db.get_keys(self.ASIC_NEXT_HOP_GROUP_MEMBER)
1256+
member_count = 0
1257+
for member in nhg_members:
1258+
fvs = asic_db.get_entry(self.ASIC_NEXT_HOP_GROUP_MEMBER, member)
1259+
if fvs.get("SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID") == nhgid:
1260+
member_count += 1
1261+
1262+
assert member_count == bucket_size, f"Expected {bucket_size} members, found {member_count}"
1263+
1264+
# Verify endpoints are properly configured
1265+
expected_attrs = {}
1266+
for idx, endpoint in enumerate(endpoints):
1267+
expected_attr = {
1268+
"SAI_NEXT_HOP_ATTR_TYPE": "SAI_NEXT_HOP_TYPE_TUNNEL_ENCAP",
1269+
"SAI_NEXT_HOP_ATTR_IP": endpoint,
1270+
"SAI_NEXT_HOP_ATTR_TUNNEL_ID": self.tunnel[tunnel],
1271+
}
1272+
if vni and vni[idx]:
1273+
expected_attr.update({'SAI_NEXT_HOP_ATTR_TUNNEL_VNI': vni[idx]})
1274+
if mac and mac[idx]:
1275+
expected_attr.update({'SAI_NEXT_HOP_ATTR_TUNNEL_MAC': mac[idx]})
1276+
expected_attrs[endpoint] = expected_attr
1277+
1278+
# Verify routes are in correct VRF
1279+
asic_vrs = set()
1280+
for idx in range(count):
1281+
check_object(asic_db, self.ASIC_ROUTE_ENTRY, new_route[idx],
1282+
{
1283+
"SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID": nhgid,
1284+
})
1285+
rt_key = json.loads(new_route[idx])
1286+
asic_vrs.add(rt_key['vr'])
1287+
1288+
assert asic_vrs == vr_ids
1289+
self.routes.update(new_route)
1290+
1291+
return new_route, nhgid
1292+
12251293
def check_priority_vnet_ecmp_routes(self, dvs, name, endpoints_primary, tunnel, mac=[], vni=[], route_ids=[], count =1, prefix =""):
12261294
asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0)
12271295
endpoint_str_primary = name + "|" + self.serialize_endpoint_group(endpoints_primary)

0 commit comments

Comments
 (0)