ptf/sainexthopgroup.py (3,970 lines of code) (raw):

# Copyright 2021-present Intel Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Thrift SAI interface NextHopGroup tests """ import binascii import random from sai_thrift.sai_headers import * from sai_base_test import * TEST_ECMP_SEED = 0xabcdef TEST_LAG_SEED = 0xfedcba ROUTER_MAC = '00:77:66:55:44:00' MAX_ITRS = 160 def nhg_members_count(client, next_hop_group): """ Gets nexthop group members counter value Args: client (sai_thrift.sai_rpc.Client): RPC client next_hop_group (oid): next hop group object ID Returns: int: ngh members counter """ attr_list = sai_thrift_get_next_hop_group_attribute(client, next_hop_group, next_hop_count=True) next_hop_count = attr_list["SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_COUNT"] return next_hop_count def setup_hash(self): """ Creates hashes Returns: int: IPv4 hash ID int: IPv6 hash ID """ hash_fields_list = [SAI_NATIVE_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_DST_IP, SAI_NATIVE_HASH_FIELD_IP_PROTOCOL, SAI_NATIVE_HASH_FIELD_L4_DST_PORT, SAI_NATIVE_HASH_FIELD_L4_SRC_PORT] s32list = sai_thrift_s32_list_t( count=len(hash_fields_list), int32list=hash_fields_list) # create ECMP hashes ipv4_hash_id = sai_thrift_create_hash( self.client, native_hash_field_list=s32list) self.assertTrue(ipv4_hash_id != 0, "Failed to create IPv4 hash") ipv6_hash_id = sai_thrift_create_hash( self.client, native_hash_field_list=s32list) self.assertTrue(ipv6_hash_id != 0, "Failed to create IPv6 hash") # create Lag hashes self.lag_ipv4_hash_id = sai_thrift_create_hash( self.client, native_hash_field_list=s32list) self.assertTrue(self.lag_ipv4_hash_id != 0, "Failed to create LAG IPv4 hash") self.lag_ipv6_hash_id = sai_thrift_create_hash( self.client, native_hash_field_list=s32list) self.assertTrue(self.lag_ipv6_hash_id != 0, "Failed to create LAG IPv6 hash") sai_thrift_set_switch_attribute( self.client, ecmp_hash_ipv4=ipv4_hash_id) sai_thrift_set_switch_attribute( self.client, ecmp_hash_ipv6=ipv6_hash_id) sai_thrift_set_switch_attribute( self.client, lag_hash_ipv4=self.lag_ipv4_hash_id) sai_thrift_set_switch_attribute( self.client, lag_hash_ipv6=self.lag_ipv6_hash_id) return ipv4_hash_id, ipv6_hash_id def release_hash(self, ipv4_hash_id, ipv6_hash_id): """ Releases hashes Args: ipv4_hash_id (int): IPv4 hash ID ipv6_hash_id (int): IPv6 hash ID """ sai_thrift_set_switch_attribute(self.client, ecmp_hash_ipv4=0) sai_thrift_set_switch_attribute(self.client, ecmp_hash_ipv6=0) sai_thrift_set_switch_attribute(self.client, lag_hash_ipv4=0) sai_thrift_set_switch_attribute(self.client, lag_hash_ipv6=0) if self.lag_ipv6_hash_id != 0: sai_thrift_remove_hash(self.client, self.lag_ipv6_hash_id) self.lag_ipv6_hash_id = 0 if self.lag_ipv4_hash_id != 0: sai_thrift_remove_hash(self.client, self.lag_ipv4_hash_id) self.lag_ipv4_hash_id = 0 if ipv6_hash_id != 0: sai_thrift_remove_hash(self.client, ipv6_hash_id) ipv6_hash_id = 0 if ipv4_hash_id != 0: sai_thrift_remove_hash(self.client, ipv4_hash_id) ipv4_hash_id = 0 def print_number_of_available_nhg_resources(self): """ Prints the number of available ngh resources """ print("***** Number of available NHG resources") print("self.available_next_hop_group_entry=", self.available_next_hop_group_entry) print("self.available_next_hop_group_member_entry=", self.available_next_hop_group_member_entry) print("self.available_ipv4_nexthop_entry=", self.available_ipv4_nexthop_entry) print("self.available_ipv6_nexthop_entry=", self.available_ipv6_nexthop_entry) print("self.available_fdb_entry=", self.available_fdb_entry) print("self.available_ipv6_route_entry=", self.available_ipv6_route_entry) print("self.available_ipv4_route_entry=", self.available_ipv4_route_entry) def save_number_of_available_nhg_resources(self, debug=False): """ Saves number of available ngh resources Args: debug (boolean): debug option indicator """ attr_list = sai_thrift_get_switch_attribute( self.client, number_of_ecmp_groups=True, ecmp_members=True, available_next_hop_group_entry=True, available_next_hop_group_member_entry=True, available_ipv6_nexthop_entry=True, available_ipv4_nexthop_entry=True, available_fdb_entry=True, available_ipv6_route_entry=True, available_ipv4_route_entry=True) self.available_next_hop_group_entry = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_ENTRY"] self.available_next_hop_group_member_entry = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY"] self.available_ipv4_nexthop_entry = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_IPV4_NEXTHOP_ENTRY"] self.available_ipv6_nexthop_entry = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_IPV6_NEXTHOP_ENTRY"] self.available_fdb_entry = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_FDB_ENTRY"] self.available_ipv6_route_entry = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_IPV6_ROUTE_ENTRY"] self.available_ipv4_route_entry = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_IPV4_ROUTE_ENTRY"] if debug: print_number_of_available_nhg_resources(self) class L3IPv4EcmpHostHelper(PlatformSaiHelper): """ Base ECMP tests for IPv4 and ECMP members as regular L3 port RIFs """ def setUp(self): super(L3IPv4EcmpHostHelper, self).setUp() dmac1 = '00:11:22:33:44:55' dmac2 = '00:11:22:33:44:56' # save a number of available resources save_number_of_available_nhg_resources(self, False) # set switch src mac address sai_thrift_set_switch_attribute( self.client, src_mac_address=ROUTER_MAC) sai_thrift_set_switch_attribute( self.client, ecmp_default_hash_seed=TEST_ECMP_SEED) sai_thrift_set_switch_attribute( self.client, lag_default_hash_seed=TEST_LAG_SEED) # test neighbor creation self.neighbor_entry1 = sai_thrift_neighbor_entry_t( self.switch_id, self.port11_rif, sai_ipaddress('10.10.10.1')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry1, dst_mac_address=dmac1) self.neighbor_entry2 = sai_thrift_neighbor_entry_t( self.switch_id, self.port12_rif, sai_ipaddress('10.10.10.2')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry2, dst_mac_address=dmac2) self.nhop1 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port11_rif, ip=sai_ipaddress('10.10.10.1')) self.nhop2 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port12_rif, ip=sai_ipaddress('10.10.10.2')) self.nhop_group1 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) self.nh_group_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop1) self.nh_group_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop2) # create route entries self.route0 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix('10.10.0.0/16'), vr_id=self.default_vrf) status = sai_thrift_create_route_entry( self.client, self.route0, next_hop_id=self.nhop_group1) self.assertEqual(status, SAI_STATUS_SUCCESS) # define IPv4 IPv6 LagIPv4Hash and LagIPv6Hash self.ipv4_hash_id, self.ipv6_hash_id = setup_hash(self) def tearDown(self): try: sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry1) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry2) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group_member1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group_member2) self.assertEqual(nhg_members_count( self.client, self.nhop_group1), 0) sai_thrift_remove_route_entry(self.client, self.route0) sai_thrift_remove_next_hop_group(self.client, self.nhop_group1) sai_thrift_remove_next_hop(self.client, self.nhop1) sai_thrift_remove_next_hop(self.client, self.nhop2) self.switch_resources = self.saveNumberOfAvaiableResources(debug=True) resources_valid = self.verifyNumberOfAvaiableResources(self.switch_resources, debug=True) self.assertEqual(resources_valid, True) release_hash(self, self.ipv4_hash_id, self.ipv6_hash_id) finally: super(L3IPv4EcmpHostHelper, self).tearDown() class L3SaiNhgSetGetTest(L3IPv4EcmpHostHelper): """ Checks SAI switch ECMP attributes and validates get and set attributes """ def setUp(self): super(L3SaiNhgSetGetTest, self).setUp() def runTest(self): print("L3SaiNhgSetGetTest") try: # predefined NHG self.nhop_group1 with 2 members nhg1_size = 2 attr_list = sai_thrift_get_switch_attribute( self.client, number_of_ecmp_groups=True, ecmp_members=True, available_next_hop_group_entry=True, available_next_hop_group_member_entry=True, available_ipv6_nexthop_entry=True, available_ipv4_nexthop_entry=True) available_next_hop_group_entry = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_ENTRY"] available_next_hop_group_member_entry = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY"] available_ipv4_nexthop_entry = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_IPV4_NEXTHOP_ENTRY"] # Create new empty nhg and check the size of zero nhg_xx_size = 0 nhop_group_xx = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) self.assertEqual(nhg_members_count( self.client, nhop_group_xx), nhg_xx_size) attr_list = sai_thrift_get_switch_attribute( self.client, number_of_ecmp_groups=True, ecmp_members=True, available_next_hop_group_member_entry=True, available_next_hop_group_entry=True) available_next_hop_group_entry2 = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_ENTRY"] self.assertEqual( available_next_hop_group_entry2, (available_next_hop_group_entry - 1)) self.assertEqual(nhg_members_count( self.client, self.nhop_group1), nhg1_size) # Add new next hop group member nhop3 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port10_rif, ip=sai_ipaddress('10.10.10.10')) nh_group_member3 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=nhop3) nhg1_size += 1 attr_list = sai_thrift_get_switch_attribute( self.client, number_of_ecmp_groups=True, ecmp_members=True, available_next_hop_group_entry=True, available_next_hop_group_member_entry=True, available_ipv6_nexthop_entry=True, available_ipv4_nexthop_entry=True) available_next_hop_group_member_entry2 = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY"] available_ipv4_nexthop_entry2 = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_IPV4_NEXTHOP_ENTRY"] # The next_group and next_group member both decreases the # SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY self.assertEqual(available_next_hop_group_member_entry2, (available_next_hop_group_member_entry - 2)) self.assertEqual(available_ipv4_nexthop_entry2, (available_ipv4_nexthop_entry - 1)) self.assertEqual(nhg_members_count( self.client, self.nhop_group1), nhg1_size) sai_thrift_remove_next_hop_group_member( self.client, nh_group_member3) sai_thrift_remove_next_hop(self.client, nhop3) nhg1_size -= 1 self.assertEqual(nhg_members_count( self.client, self.nhop_group1), nhg1_size) finally: # Add new next hop group member to nhop_group_xx nhg_xx_nhop1 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port10_rif, ip=sai_ipaddress('10.10.10.10')) nh_group_xx_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=nhop_group_xx, next_hop_id=nhg_xx_nhop1) nhg_xx_size += 1 self.assertEqual(nhg_members_count( self.client, nhop_group_xx), nhg_xx_size) # Remove next hop group member sai_thrift_remove_next_hop_group_member( self.client, nh_group_xx_member1) nhg_xx_size -= 1 self.assertEqual(nhg_members_count( self.client, nhop_group_xx), nhg_xx_size) self.assertEqual(nhg_xx_size, 0) sai_thrift_remove_next_hop(self.client, nhg_xx_nhop1) # remove next hop group sai_thrift_remove_next_hop_group(self.client, nhop_group_xx) attr_list = sai_thrift_get_switch_attribute( self.client, available_next_hop_group_entry=True, available_next_hop_group_member_entry=True, available_ipv6_nexthop_entry=True, available_ipv4_nexthop_entry=True, number_of_ecmp_groups=True, ecmp_members=True) available_next_hop_group_entry2 = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_ENTRY"] available_next_hop_group_member_entry2 = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_NEXT_HOP_GROUP_MEMBER_ENTRY"] available_ipv4_nexthop_entry2 = attr_list[ "SAI_SWITCH_ATTR_AVAILABLE_IPV4_NEXTHOP_ENTRY"] self.assertEqual(available_next_hop_group_entry2, (available_next_hop_group_entry)) self.assertEqual(available_next_hop_group_member_entry2, (available_next_hop_group_member_entry)) self.assertEqual(available_ipv4_nexthop_entry2, (available_ipv4_nexthop_entry)) # check the Next hop group members attr_list = sai_thrift_get_next_hop_group_member_attribute( self.client, self.nh_group_member1, next_hop_group_id=True, next_hop_id=True) self.assertEqual( attr_list["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID"], self.nhop_group1) self.assertEqual( attr_list["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID"], self.nhop1) attr_list = sai_thrift_get_next_hop_group_member_attribute( self.client, self.nh_group_member2, next_hop_group_id=True, next_hop_id=True) self.assertEqual( attr_list["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID"], self.nhop_group1) self.assertEqual( attr_list["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID"], self.nhop2) def tearDown(self): super(L3SaiNhgSetGetTest, self).tearDown() class L3IPv4EcmpHostTest(L3IPv4EcmpHostHelper): """ IPv4 ECMP tests with all members which are port RIFs """ def setUp(self): super(L3IPv4EcmpHostTest, self).setUp() def runTest(self): print("L3IPv4EcmpHostTest") pkt1 = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src='00:22:22:22:22:22', ip_dst='10.10.10.1', ip_src='192.168.0.1', ip_id=106, ip_ttl=64) pkt2 = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src='00:22:22:22:22:22', ip_dst='10.10.10.2', ip_src='192.168.0.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:22:33:44:55', eth_src=ROUTER_MAC, ip_dst='10.10.10.1', ip_src='192.168.0.1', ip_id=106, # ip_tos=3, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:11:22:33:44:56', eth_src=ROUTER_MAC, ip_dst='10.10.10.2', ip_src='192.168.0.1', ip_id=106, # ip_tos=3, ip_ttl=63) print("Sending packet port %d -> port %d" "(192.168.0.1 -> 10.10.10.1 [id = 101])" % ( self.dev_port13, self.dev_port11)) send_packet(self, self.dev_port13, pkt1) verify_packet( self, exp_pkt1, self.dev_port11) print("Sending packet port %d -> port %d" "(192.168.0.1 -> 10.10.10.2 [id = 101])" % ( self.dev_port13, self.dev_port12)) send_packet(self, self.dev_port13, pkt2) verify_packet( self, exp_pkt2, self.dev_port12) pkt1 = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src='00:22:22:22:22:22', ip_dst='10.10.10.1', ip_src='192.168.100.3', ip_id=106, ip_ttl=64) pkt2 = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src='00:22:22:22:22:22', ip_dst='10.10.10.2', ip_src='192.168.100.3', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:22:33:44:55', eth_src=ROUTER_MAC, ip_dst='10.10.10.1', ip_src='192.168.100.3', ip_id=106, # ip_tos=3, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:11:22:33:44:56', eth_src=ROUTER_MAC, ip_dst='10.10.10.2', ip_src='192.168.100.3', ip_id=106, # ip_tos=3, ip_ttl=63) print("Sending packet port %d -> port %d" "(192.168.100.3 -> 10.10.10.1 [id = 101])" % ( self.dev_port13, self.dev_port11)) send_packet(self, self.dev_port13, pkt1) verify_packet( self, exp_pkt1, self.dev_port11) print("Sending packet port %d -> port %d" "(192.168.100.3 -> 10.10.10.2 [id = 101])" % ( self.dev_port13, self.dev_port12)) send_packet(self, self.dev_port13, pkt2) verify_packet( self, exp_pkt2, self.dev_port12) def tearDown(self): super(L3IPv4EcmpHostTest, self).tearDown() class L3IPv4EcmpRoutingTest(L3IPv4EcmpHostHelper): """ IPv4 ECMP routing test with random host """ def setUp(self): super(L3IPv4EcmpRoutingTest, self).setUp() def runTest(self): print("L3IPv4EcmpRoutingTest") for n_packet in range(4): host_ip = '10.10.{}.{}'.format(random.randint(2, 255), random.randint(3, 255)) pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src='00:22:22:22:22:22', ip_dst=host_ip, ip_src='192.168.0.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:22:33:44:55', eth_src=ROUTER_MAC, ip_dst=host_ip, ip_src='192.168.0.1', ip_id=106, # ip_tos=3, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:11:22:33:44:56', eth_src=ROUTER_MAC, ip_dst=host_ip, ip_src='192.168.0.1', ip_id=106, # ip_tos=3, ip_ttl=63) print("Sending packet port %d -> port [%d,%d]" "(192.168.0.1 -> %s [id = 101])" % ( self.dev_port13, self.dev_port11, self.dev_port12, host_ip)) send_packet(self, self.dev_port13, pkt) verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2], [self.dev_port11, self.dev_port12]) def tearDown(self): super(L3IPv4EcmpRoutingTest, self).tearDown() class L3IPv6EcmpHostHelper(PlatformSaiHelper): """ Basic ECMP tests for IPv6 and regular L3 port RIFs """ def setUp(self): super(L3IPv6EcmpHostHelper, self).setUp() ip_addr1 = '5000:1:1:0:0:0:0:1' ip_addr2 = '5000:1:1:0:0:0:0:2' dmac1 = '00:11:22:33:44:55' dmac2 = '00:11:22:33:44:56' # save a number of available resources save_number_of_available_nhg_resources(self, False) # set switch src mac address sai_thrift_set_switch_attribute( self.client, src_mac_address=ROUTER_MAC) sai_thrift_set_switch_attribute( self.client, ecmp_default_hash_seed=TEST_ECMP_SEED) sai_thrift_set_switch_attribute( self.client, lag_default_hash_seed=TEST_LAG_SEED) # test neighbor creation self.neighbor_entry1 = sai_thrift_neighbor_entry_t( self.switch_id, self.port11_rif, sai_ipaddress(ip_addr1)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry1, dst_mac_address=dmac1) self.neighbor_entry2 = sai_thrift_neighbor_entry_t( self.switch_id, self.port12_rif, sai_ipaddress(ip_addr2)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry2, dst_mac_address=dmac2) self.nhop1 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port11_rif, ip=sai_ipaddress(ip_addr1)) self.nhop2 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port12_rif, ip=sai_ipaddress(ip_addr2)) self.nhop_group1 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) self.nh_group_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop1) self.nh_group_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop2) # create route entries self.route0 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix(f'{ip_addr1}/64'), vr_id=self.default_vrf) status = sai_thrift_create_route_entry( self.client, self.route0, next_hop_id=self.nhop_group1) self.assertEqual(status, SAI_STATUS_SUCCESS) # define IPv4 IPv6 LagIPv4Hash and LagIPv6Hash self.ipv4_hash_id, self.ipv6_hash_id = setup_hash(self) def tearDown(self): sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry1) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry2) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group_member1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group_member2) sai_thrift_remove_route_entry(self.client, self.route0) self.assertEqual(nhg_members_count(self.client, self.nhop_group1), 0) sai_thrift_remove_next_hop_group(self.client, self.nhop_group1) sai_thrift_remove_next_hop(self.client, self.nhop1) sai_thrift_remove_next_hop(self.client, self.nhop2) self.switch_resources = self.saveNumberOfAvaiableResources(debug=True) self.assertEqual(True, self.verifyNumberOfAvaiableResources(self.switch_resources)) release_hash(self, self.ipv4_hash_id, self.ipv6_hash_id) super(L3IPv6EcmpHostHelper, self).tearDown() class L3IPv6EcmpHostTest(L3IPv6EcmpHostHelper): """ IPv6 ECMP tests with all members as regular L3 port RIFs """ def setUp(self): super(L3IPv6EcmpHostTest, self).setUp() def runTest(self): print("L3IPv6EcmpHostTest") # send the test packet(s) pkt1 = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src='00:22:22:22:22:22', ipv6_dst='5000:1:1:0:0:0:0:1', ipv6_src='2000:1:1:0:0:0:0:1', tcp_sport=0x1234, ipv6_hlim=64) pkt2 = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src='00:22:22:22:22:22', ipv6_dst='5000:1:1:0:0:0:0:2', ipv6_src='2000:1:1:0:0:0:0:1', tcp_sport=0x1234, ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:11:22:33:44:55', eth_src=ROUTER_MAC, ipv6_dst='5000:1:1:0:0:0:0:1', ipv6_src='2000:1:1:0:0:0:0:1', tcp_sport=0x1234, ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet(eth_dst='00:11:22:33:44:56', eth_src=ROUTER_MAC, ipv6_dst='5000:1:1:0:0:0:0:2', ipv6_src='2000:1:1:0:0:0:0:1', tcp_sport=0x1234, ipv6_hlim=63) send_packet(self, self.dev_port13, pkt1) verify_packet( self, exp_pkt1, self.dev_port11) send_packet(self, self.dev_port13, pkt2) verify_packet( self, exp_pkt2, self.dev_port12) pkt1 = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src='00:22:22:22:22:45', ipv6_dst='5000:1:1:0:0:0:0:1', ipv6_src='2000:1:1:0:0:0:0:1', tcp_sport=0x1248, ipv6_hlim=64) pkt2 = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src='00:22:22:22:22:45', ipv6_dst='5000:1:1:0:0:0:0:2', ipv6_src='2000:1:1:0:0:0:0:1', tcp_sport=0x1248, ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:11:22:33:44:55', eth_src=ROUTER_MAC, ipv6_dst='5000:1:1:0:0:0:0:1', ipv6_src='2000:1:1:0:0:0:0:1', tcp_sport=0x1248, ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet(eth_dst='00:11:22:33:44:56', eth_src=ROUTER_MAC, ipv6_dst='5000:1:1:0:0:0:0:2', ipv6_src='2000:1:1:0:0:0:0:1', tcp_sport=0x1248, ipv6_hlim=63) send_packet(self, self.dev_port13, pkt1) verify_packet( self, exp_pkt1, self.dev_port11) send_packet(self, self.dev_port13, pkt2) verify_packet( self, exp_pkt2, self.dev_port12) def tearDown(self): super(L3IPv6EcmpHostTest, self).tearDown() class L3IPv6EcmpRoutingTest(L3IPv6EcmpHostHelper): """ IPv6 ECMP routing test with random host """ def setUp(self): super(L3IPv6EcmpRoutingTest, self).setUp() def runTest(self): print("L3IPv6EcmpRoutingTest") for n_packet in range(4): host_ip = f'5000:1:1:0:0:0:0:{random.randint(3, 1000)}' pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src='00:22:22:22:22:22', ipv6_dst=host_ip, ipv6_src='2000:1:1:0:0:0:0:1', tcp_sport=0x1234, ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:11:22:33:44:55', eth_src=ROUTER_MAC, ipv6_dst=host_ip, ipv6_src='2000:1:1:0:0:0:0:1', tcp_sport=0x1234, ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet(eth_dst='00:11:22:33:44:56', eth_src=ROUTER_MAC, ipv6_dst=host_ip, ipv6_src='2000:1:1:0:0:0:0:1', tcp_sport=0x1234, ipv6_hlim=63) print("Sending packet port %d -> port [%d,%d]" "(2000:1:1:0:0:0:0:1 -> %s [id = 101])" % ( self.dev_port13, self.dev_port11, self.dev_port12, host_ip)) send_packet(self, self.dev_port13, pkt) verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2], [self.dev_port11, self.dev_port12]) def tearDown(self): super(L3IPv6EcmpRoutingTest, self).tearDown() class L3IPv4EcmpLpmTestHelper(PlatformSaiHelper): """ Base ECMP tests with LPM routes for IPv4 """ def setUp(self): super(L3IPv4EcmpLpmTestHelper, self).setUp() dmac1 = '00:11:22:33:44:55' dmac2 = '00:11:22:33:44:56' dmac3 = '00:11:22:33:44:57' dmac4 = '00:11:22:33:44:58' nhop_ip1 = '11.11.11.11' nhop_ip1_subnet = '11.11.11.0/16' nhop_ip2 = '22.22.22.22' nhop_ip2_subnet = '22.22.22.0/16' nhop_ip3 = '33.33.33.33' nhop_ip3_subnet = '33.33.33.0/16' nhop_ip4 = '44.44.44.44' # set switch src mac address sai_thrift_set_switch_attribute( self.client, src_mac_address=ROUTER_MAC) sai_thrift_set_switch_attribute( self.client, ecmp_default_hash_seed=TEST_ECMP_SEED) sai_thrift_set_switch_attribute( self.client, lag_default_hash_seed=TEST_LAG_SEED) self.port14_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_PORT, virtual_router_id=self.default_vrf, port_id=self.port14, admin_v4_state=True) self.port15_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_PORT, virtual_router_id=self.default_vrf, port_id=self.port15, admin_v4_state=True) # test neighbor creation self.neighbor_entry11 = sai_thrift_neighbor_entry_t( self.switch_id, self.port11_rif, sai_ipaddress(nhop_ip1)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry11, dst_mac_address=dmac1) self.neighbor_entry12 = sai_thrift_neighbor_entry_t( self.switch_id, self.port12_rif, sai_ipaddress(nhop_ip2)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry12, dst_mac_address=dmac2) self.neighbor_entry13 = sai_thrift_neighbor_entry_t( self.switch_id, self.port13_rif, sai_ipaddress(nhop_ip3)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry13, dst_mac_address=dmac3) self.neighbor_entry14 = sai_thrift_neighbor_entry_t( self.switch_id, self.port14_rif, sai_ipaddress(nhop_ip4)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry14, dst_mac_address=dmac4) self.nhop1 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port11_rif, ip=sai_ipaddress(nhop_ip1)) self.nhop2 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port12_rif, ip=sai_ipaddress(nhop_ip2)) self.nhop3 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port13_rif, ip=sai_ipaddress(nhop_ip3)) self.nhop_group1 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) self.nh_group_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop1) self.nh_group_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop2) self.nh_group_member3 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop3) # create route entries self.route0 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix('10.10.10.1/16'), vr_id=self.default_vrf) self.assertNotEqual(self.route0, 0) status = sai_thrift_create_route_entry( self.client, self.route0, next_hop_id=self.nhop_group1) self.assertEqual(status, SAI_STATUS_SUCCESS) self.route1 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix(nhop_ip1_subnet), vr_id=self.default_vrf) self.assertNotEqual(self.route1, 0) status = sai_thrift_create_route_entry( self.client, self.route1, next_hop_id=self.nhop1) self.assertEqual(status, SAI_STATUS_SUCCESS) self.route2 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix(nhop_ip2_subnet), vr_id=self.default_vrf) self.assertNotEqual(self.route2, 0) status = sai_thrift_create_route_entry( self.client, self.route2, next_hop_id=self.nhop2) self.assertEqual(status, SAI_STATUS_SUCCESS) self.route3 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix(nhop_ip3_subnet), vr_id=self.default_vrf) self.assertNotEqual(self.route3, 0) status = sai_thrift_create_route_entry( self.client, self.route3, next_hop_id=self.nhop3) self.assertEqual(status, SAI_STATUS_SUCCESS) # define IPv4 IPv6 LagIPv4Hash and LagIPv6Hash self.ipv4_hash_id, self.ipv6_hash_id = setup_hash(self) def tearDown(self): sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry11) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry12) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry13) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry14) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group_member1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group_member2) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group_member3) sai_thrift_remove_route_entry(self.client, self.route0) sai_thrift_remove_route_entry(self.client, self.route1) sai_thrift_remove_route_entry(self.client, self.route2) sai_thrift_remove_route_entry(self.client, self.route3) sai_thrift_remove_next_hop_group(self.client, self.nhop_group1) sai_thrift_remove_next_hop(self.client, self.nhop1) sai_thrift_remove_next_hop(self.client, self.nhop2) sai_thrift_remove_next_hop(self.client, self.nhop3) sai_thrift_remove_router_interface(self.client, self.port14_rif) sai_thrift_remove_router_interface(self.client, self.port15_rif) release_hash(self, self.ipv4_hash_id, self.ipv6_hash_id) super(L3IPv4EcmpLpmTestHelper, self).tearDown() class l3IPv4EcmpLpmTest(L3IPv4EcmpLpmTestHelper): """ Verifies ECMP load balancing with LPM routes configured """ def setUp(self): super(l3IPv4EcmpLpmTest, self).setUp() def runTest(self): print("l3IPv4EcmpLpmTest") count = [0, 0, 0] dst_ip = int(binascii.hexlify(socket.inet_aton('10.10.10.1')), 16) src_mac_start = '00:22:22:22:22:' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) src_mac = src_mac_start + str(i % 99).zfill(2) pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:22:33:44:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:11:22:33:44:56', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt3 = simple_tcp_packet(eth_dst='00:11:22:33:44:57', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) send_packet(self, self.dev_port14, pkt) rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3], [self.dev_port11, self.dev_port12, self.dev_port13]) count[rcv_idx] += 1 dst_ip += 1 for i in range(0, 3): self.assertTrue( (count[i] >= ((MAX_ITRS / 3) * 0.8)), "Not all paths are equally balanced, %s" % count) def tearDown(self): super(l3IPv4EcmpLpmTest, self).tearDown() class l3Ipv4EcmpLpmAddRemoveNhopTest(L3IPv4EcmpLpmTestHelper): # to be removed from here """ IPv4 ECMP rebalance test with removal of a nexthop member """ def setUp(self): super(l3Ipv4EcmpLpmAddRemoveNhopTest, self).setUp() def runTest(self): print("l3Ipv4EcmpLpmAddRemoveNhopTest") src_mac_start = '00:22:22:22:22:' nhop_ip4 = '44.44.44.44' # Case 1 ECMP 3 members # ECMP add new next hop nhop4 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port14_rif, ip=sai_ipaddress(nhop_ip4)) nh_group_member4 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=nhop4) status = sai_thrift_create_route_entry( self.client, self.route3, next_hop_id=nhop4) self.assertEqual(status, SAI_STATUS_SUCCESS) try: count = [0, 0, 0, 0] dst_ip = int(binascii.hexlify(socket.inet_aton('10.10.10.1')), 16) for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) src_mac = src_mac_start + str(i % 99).zfill(2) pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:22:33:44:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:11:22:33:44:56', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt3 = simple_tcp_packet(eth_dst='00:11:22:33:44:57', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt4 = simple_tcp_packet(eth_dst='00:11:22:33:44:58', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) send_packet(self, self.dev_port15, pkt) rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], [ self.dev_port11, self.dev_port12, self.dev_port13, self.dev_port14 ]) count[rcv_idx] += 1 dst_ip += 1 attr_list = sai_thrift_get_next_hop_group_attribute( self.client, self.nhop_group1, next_hop_count=True) nhg_size = attr_list["SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_COUNT"] self.assertEqual(nhg_size, 4) for i in range(0, 4): self.assertTrue( (count[i] >= ((MAX_ITRS / 4) * 0.5)), "Not all paths are equally balanced, %s" % count) # Case 3 Remove next_hop grpup member sai_thrift_remove_next_hop_group_member(self.client, nh_group_member4) for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) src_mac = src_mac_start + str(i % 99).zfill(2) pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:22:33:44:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:11:22:33:44:56', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt3 = simple_tcp_packet(eth_dst='00:11:22:33:44:57', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) send_packet(self, self.dev_port15, pkt) rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3], [self.dev_port11, self.dev_port12, self.dev_port13]) count[rcv_idx] += 1 dst_ip += 1 attr_list = sai_thrift_get_next_hop_group_attribute( self.client, self.nhop_group1, next_hop_count=True) nhg_size = attr_list["SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_COUNT"] self.assertEqual(nhg_size, 3) for i in range(0, nhg_size): self.assertTrue( (count[i] >= ((MAX_ITRS / nhg_size) * 0.8)), "Not all paths are equally balanced, %s" % count) finally: sai_thrift_remove_next_hop(self.client, nhop4) def tearDown(self): super(l3Ipv4EcmpLpmAddRemoveNhopTest, self).tearDown() def setupECMPHash(self, hash_fields_list): """ Setups ECMP hash Args: hash_fields_list (list): list of hash fields """ print("Setting the ECMP hash fields..") # Set ECMP HASH attr_list = sai_thrift_get_switch_attribute( self.client, ecmp_hash=True) hash_id = attr_list['SAI_SWITCH_ATTR_ECMP_HASH'] print("ECMP hash id =0x%x" % (hash_id)) hash_attr_list = [] s32list = sai_thrift_s32_list_t(count=100, int32list=hash_attr_list) hash_data = sai_thrift_get_hash_attribute( self.client, hash_id, native_hash_field_list=s32list) data_val = hash_data['native_hash_field_list'].int32list print('hash_data: ', hash_data) print('hash_val: ', data_val) hash_attr_list = hash_fields_list hash_field_list = sai_thrift_s32_list_t( count=len(hash_attr_list), int32list=hash_attr_list) status = sai_thrift_set_hash_attribute( self.client, hash_id, native_hash_field_list=hash_field_list) self.assertEqual(status, SAI_STATUS_SUCCESS) def l3IPv4EcmpHashSeedPortLag(self): """ Changes ECMP seed attribute and checks for rebalancing """ print("l3IPv4EcmpHashSeedPortLag") # setup the SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_SEED attr = sai_thrift_get_switch_attribute( self.client, ecmp_default_hash_seed=200) print(attr) ecmp_default_hash_seed = attr['ecmp_default_hash_seed'] status = sai_thrift_set_switch_attribute( self.client, ecmp_default_hash_seed=200) self.assertEqual(status, SAI_STATUS_SUCCESS) attr = sai_thrift_get_switch_attribute( self.client, ecmp_default_hash_seed=True) print(attr) self.assertEqual(attr['ecmp_default_hash_seed'], 200) try: count = [0, 0, 0, 0, 0, 0, 0, 0] dst_ip = int(binascii.hexlify(socket.inet_aton('10.10.10.1')), 16) for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) src_mac = '00:22:22:22:22:22' pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:11:11:11:11', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:22:22:22:22:22', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt3 = simple_tcp_packet(eth_dst='00:33:33:33:33:33', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt4 = simple_tcp_packet(eth_dst='00:44:44:44:44:44', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port11, self.dev_port12, self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) count[rcv_idx] += 1 dst_ip += 1 print("PORT lb counts:", count) ecmp_count = [ count[0], count[1], (count[2] + count[3] + count[4]), (count[5] + count[6] + count[7])] print("ECMP count:", ecmp_count) # Traffic should equally be ballanced, should apear on all port or # LAG for i in range(0, 4): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 4) * 0.5)), "Ecmp paths are not equally balanced") # reconfugure the default ECMP hash seed sai_thrift_set_switch_attribute( self.client, ecmp_default_hash_seed=400) self.assertEqual(attr['ecmp_default_hash_seed'], 400) count = [0, 0, 0, 0, 0, 0, 0, 0] dst_ip = int(binascii.hexlify(socket.inet_aton('10.10.10.1')), 16) for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) src_mac = '00:22:22:22:22:22' pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:11:11:11:11', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:22:22:22:22:22', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt3 = simple_tcp_packet(eth_dst='00:33:33:33:33:33', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt4 = simple_tcp_packet(eth_dst='00:44:44:44:44:44', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port11, self.dev_port12, self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) count[rcv_idx] += 1 dst_ip += 1 print("PORT lb counts:", count) ecmp_count = [ count[0], count[1], (count[2] + count[3] + count[4]), (count[5] + count[6] + count[7])] print("ECMP count:", ecmp_count) # Traffic should equally be ballanced, should apear on all port or # LAG for i in range(0, 4): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 4) * 0.75)), "Ecmp paths are not equally balanced") finally: sai_thrift_set_switch_attribute( self.client, ecmp_default_hash_seed=ecmp_default_hash_seed) class L3IPv6EcmpLagTestHelper(PlatformSaiHelper): """ Base ECMP tests with ECMP members as LAG RIFs """ def setUp(self): super(L3IPv6EcmpLagTestHelper, self).setUp() dmac1 = '00:11:11:11:11:11' dmac2 = '00:22:22:22:22:22' dmac3 = '00:33:33:33:33:33' dmac4 = '00:44:44:44:44:44' dmac5 = '00:55:55:55:55:55' dmac6 = '00:66:66:66:66:66' nhop_ip1 = '1000:1:1:0:0:0:0:1' nhop_ip2 = '2000:1:1:0:0:0:0:1' nhop_ip3 = '3000:1:1:0:0:0:0:1' nhop_ip4 = '4000:1:1:0:0:0:0:1' nhop_ip5 = '5000:1:1:0:0:0:0:1' nhop_ip6 = '6000:1:1:0:0:0:0:1' # set switch src mac address sai_thrift_set_switch_attribute( self.client, src_mac_address=ROUTER_MAC) status = sai_thrift_set_switch_attribute( self.client, ecmp_default_hash_seed=TEST_ECMP_SEED) status = sai_thrift_set_switch_attribute( self.client, lag_default_hash_seed=TEST_LAG_SEED) self.lag1_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_PORT, virtual_router_id=self.default_vrf, port_id=self.lag1, admin_v6_state=True) self.lag2_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_PORT, virtual_router_id=self.default_vrf, port_id=self.lag2, admin_v6_state=True) self.port15_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_PORT, virtual_router_id=self.default_vrf, port_id=self.port15, admin_v6_state=True) # test neighbor creation self.neighbor_entry11 = sai_thrift_neighbor_entry_t( self.switch_id, self.port11_rif, sai_ipaddress(nhop_ip1)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry11, dst_mac_address=dmac1, no_host_route=True) self.neighbor_entry12 = sai_thrift_neighbor_entry_t( self.switch_id, self.port12_rif, sai_ipaddress(nhop_ip2)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry12, dst_mac_address=dmac2, no_host_route=True) self.neighbor_entry13 = sai_thrift_neighbor_entry_t( self.switch_id, self.lag1_rif, sai_ipaddress(nhop_ip3)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry13, dst_mac_address=dmac3, no_host_route=True) self.neighbor_entry14 = sai_thrift_neighbor_entry_t( self.switch_id, self.lag2_rif, sai_ipaddress(nhop_ip4)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry14, dst_mac_address=dmac4, no_host_route=True) self.neighbor_entry15 = sai_thrift_neighbor_entry_t( self.switch_id, self.lag1_rif, sai_ipaddress(nhop_ip5)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry15, dst_mac_address=dmac5, no_host_route=True) self.neighbor_entry16 = sai_thrift_neighbor_entry_t( self.switch_id, self.lag2_rif, sai_ipaddress(nhop_ip6)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry16, dst_mac_address=dmac6, no_host_route=True) self.nhop1 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port11_rif, ip=sai_ipaddress(nhop_ip1)) self.nhop2 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port12_rif, ip=sai_ipaddress(nhop_ip2)) self.nhop3_lag1 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.lag1_rif, ip=sai_ipaddress(nhop_ip3)) self.nhop4_lag2 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.lag2_rif, ip=sai_ipaddress(nhop_ip4)) self.nhop5_lag1 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.lag1_rif, ip=sai_ipaddress(nhop_ip5)) self.nhop6_lag2 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.lag2_rif, ip=sai_ipaddress(nhop_ip6)) self.nhop_group1 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) self.nh_group1_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop1) self.nh_group1_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop2) self.nh_group1_member3 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop3_lag1) self.nh_group1_member4 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop4_lag2) self.nhop_group2 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) self.nh_group2_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group2, next_hop_id=self.nhop5_lag1) self.nh_group2_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group2, next_hop_id=self.nhop6_lag2) # create route entries self.route0 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix('1000:1:1:0:0:0:0:0/65'), vr_id=self.default_vrf) status = sai_thrift_create_route_entry( self.client, self.route0, next_hop_id=self.nhop_group1) self.assertEqual(status, SAI_STATUS_SUCCESS) self.route1 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix('5500:1:1:0:0:0:0:1/65'), vr_id=self.default_vrf) status = sai_thrift_create_route_entry( self.client, self.route1, next_hop_id=self.nhop_group2) self.assertEqual(status, SAI_STATUS_SUCCESS) # define IPv4 IPv6 LagIPv4Hash and LagIPv6Hash self.ipv4_hash_id, self.ipv6_hash_id = setup_hash(self) def tearDown(self): sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry11) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry12) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry13) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry14) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry15) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry16) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member2) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member3) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member4) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group2_member1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group2_member2) sai_thrift_remove_route_entry(self.client, self.route0) sai_thrift_remove_route_entry(self.client, self.route1) self.assertEqual(nhg_members_count(self.client, self.nhop_group1), 0) self.assertEqual(nhg_members_count(self.client, self.nhop_group2), 0) sai_thrift_remove_next_hop_group(self.client, self.nhop_group1) sai_thrift_remove_next_hop_group(self.client, self.nhop_group2) sai_thrift_remove_next_hop(self.client, self.nhop1) sai_thrift_remove_next_hop(self.client, self.nhop2) sai_thrift_remove_next_hop(self.client, self.nhop3_lag1) sai_thrift_remove_next_hop(self.client, self.nhop4_lag2) sai_thrift_remove_next_hop(self.client, self.nhop5_lag1) sai_thrift_remove_next_hop(self.client, self.nhop6_lag2) sai_thrift_remove_router_interface(self.client, self.lag1_rif) sai_thrift_remove_router_interface(self.client, self.lag2_rif) sai_thrift_remove_router_interface(self.client, self.port15_rif) release_hash(self, self.ipv4_hash_id, self.ipv6_hash_id) super(L3IPv6EcmpLagTestHelper, self).tearDown() def setupECMPIPv6Hash(self, hash_field_list=None): """ Setups ECMP IPv6 hash Args: hash_field_list (list): list of hash fields """ print("Setting the ECMP IPv6 hash fields..") if hash_field_list is None: hash_field_list = [ SAI_NATIVE_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_DST_IP, SAI_NATIVE_HASH_FIELD_IP_PROTOCOL, SAI_NATIVE_HASH_FIELD_L4_DST_PORT, SAI_NATIVE_HASH_FIELD_L4_SRC_PORT ] s32list = sai_thrift_s32_list_t( count=len(hash_field_list), int32list=hash_field_list) if self.ipv6_hash_id == 0: self.ipv6_hash_id = sai_thrift_create_hash( self.client, native_hash_field_list=s32list) self.assertTrue(self.ipv6_hash_id != 0, "Failed to create IPv6 hash") else: status = sai_thrift_set_hash_attribute( self.client, self.ipv6_hash_id, native_hash_field_list=s32list) self.assertEqual(status, SAI_STATUS_SUCCESS) class l3Ipv6EcmpLpmTest(L3IPv6EcmpLagTestHelper): """ Base ECMP tests with LPM routes for IPv6 """ def setUp(self): super(l3Ipv6EcmpLpmTest, self).setUp() def runTest(self): print("l3Ipv6EcmpLpmTest") dmac7 = '00:77:77:77:77:77' nhop_ip7 = '7000:1:1:0:0:0:0:1' try: # create the IPv6 LPM route entry neighbor_entry17 = sai_thrift_neighbor_entry_t( self.switch_id, self.lag2_rif, sai_ipaddress(nhop_ip7)) sai_thrift_create_neighbor_entry( self.client, neighbor_entry17, dst_mac_address=dmac7) nhop7 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.lag2_rif, ip=sai_ipaddress(nhop_ip7)) nhop_group3 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) nh_group3_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=nhop_group3, next_hop_id=nhop7) route3 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix('5500:1:1:0:0:0:0:1/70'), vr_id=self.default_vrf) status = sai_thrift_create_route_entry( self.client, route3, next_hop_id=nhop_group3) self.assertEqual(status, SAI_STATUS_SUCCESS) count = [0, 0, 0] dst_ip = socket.inet_pton(socket.AF_INET6, '5500:1:1:0:0:0:0:1') dst_ip_arr = list(dst_ip) src_mac_start = '00:22:22:22:22:22' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntop(socket.AF_INET6, dst_ip) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ipv6_dst=dst_ip_addr, ipv6_src='7000:1:1:0:0:0:0:1', ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:77:77:77:77:77', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='7000:1:1:0:0:0:0:1', ipv6_hlim=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1], ports_to_verify) count[rcv_idx] += 1 dst_ip_arr[15] = dst_ip_arr[15] + 1 dst_ip = bytearray(dst_ip_arr) print("PORT lb counts", count) ecmp_count = [(count[0] + count[1] + count[2])] print("ECMP count:", ecmp_count) for i in range(0, 3): self.assertTrue((count[i] >= ((MAX_ITRS / 3) * 0.75)), "Ecmp paths are not equally balanced") finally: sai_thrift_remove_neighbor_entry( self.client, neighbor_entry17) sai_thrift_remove_next_hop_group_member(self.client, nh_group3_member1) sai_thrift_remove_route_entry(self.client, route3) sai_thrift_remove_next_hop_group(self.client, nhop_group3) sai_thrift_remove_next_hop(self.client, nhop7) def tearDown(self): super(l3Ipv6EcmpLpmTest, self).tearDown() class l3IPv6EcmpHostTwoLagsTest(L3IPv6EcmpLagTestHelper): """ IPv6 ECMP tests with all members with RIF as LAG """ def setUp(self): super(l3IPv6EcmpHostTwoLagsTest, self).setUp() @warm_test(is_test_rebooting=True) def runTest(self): print("l3IPv6EcmpHostTwoLagsTest") count = [0, 0, 0, 0, 0, 0] dst_ip = socket.inet_pton(socket.AF_INET6, '5500:1:1:0:0:0:0:1') dst_ip_arr = list(dst_ip) src_mac_start = '00:22:22:22:22:22' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntop(socket.AF_INET6, dst_ip) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ipv6_dst=dst_ip_addr, ipv6_src='6000:1:1:0:0:0:0:1', ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:55:55:55:55:55', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='6000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet(eth_dst='00:66:66:66:66:66', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='6000:1:1:0:0:0:0:1', ipv6_hlim=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2], ports_to_verify) count[rcv_idx] += 1 dst_ip_arr[15] = dst_ip_arr[15] + 1 dst_ip = bytearray(dst_ip_arr) print("PORT lb counts", count) ecmp_count = [(count[0] + count[1] + count[2]), (count[3] + count[4] + count[5])] print("ECMP count:", ecmp_count) for i in range(0, 2): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 2) * 0.5)), "Ecmp paths are not equally balanced") def tearDown(self): super(l3IPv6EcmpHostTwoLagsTest, self).tearDown() class l3IPv6EcmpHostPortLagTest(L3IPv6EcmpLagTestHelper): """ IPv6 ECMP tests with members combination of port and LAG RIFs """ def setUp(self): super(l3IPv6EcmpHostPortLagTest, self).setUp() def runTest(self): print("l3IPv6EcmpHostPortLagTest") try: count = [0, 0, 0, 0, 0, 0, 0, 0] dst_ip = socket.inet_pton(socket.AF_INET6, '1000:1:1:0:0:0:0:1') dst_ip_arr = list(dst_ip) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntop(socket.AF_INET6, dst_ip) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:11:11:11:11:11', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet(eth_dst='00:22:22:22:22:22', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt3 = simple_tcpv6_packet(eth_dst='00:33:33:33:33:33', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt4 = simple_tcpv6_packet(eth_dst='00:44:44:44:44:44', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port11, self.dev_port12, self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) count[rcv_idx] += 1 dst_ip_arr[15] = dst_ip_arr[15] + 1 dst_ip = bytearray(dst_ip_arr) print("PORT lb counts", count) ecmp_count = [ count[0], count[1], (count[2] + count[3] + count[4]), (count[5] + count[6] + count[7])] print("ECMP counts", ecmp_count) for i in range(0, 4): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 4) * 0.5)), "Ecmp paths are not equally balanced") finally: pass def tearDown(self): super(l3IPv6EcmpHostPortLagTest, self).tearDown() class l3IPv6EcmpHashPortLagTest(L3IPv6EcmpLagTestHelper): """ IPv6 ECMP loads balance tests to check fair share on all members """ def setUp(self): super(l3IPv6EcmpHashPortLagTest, self).setUp() def runTest(self): print("l3IPv6EcmpHashPortLagTest") print("Limit ECMP IPv6 hash to SRC_IP only.") # for our test it will disable LB. self.setupECMPIPv6Hash([SAI_NATIVE_HASH_FIELD_SRC_IP]) try: count = [0, 0, 0, 0, 0, 0, 0, 0] dst_ip = socket.inet_pton(socket.AF_INET6, '1000:1:1:0:0:0:0:1') dst_ip_arr = list(dst_ip) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntop(socket.AF_INET6, dst_ip) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) src_mac = '00:22:22:22:22:22' pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:11:11:11:11:11', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet(eth_dst='00:22:22:22:22:22', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt3 = simple_tcpv6_packet(eth_dst='00:33:33:33:33:33', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt4 = simple_tcpv6_packet(eth_dst='00:44:44:44:44:44', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port11, self.dev_port12, self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) count[rcv_idx] += 1 dst_ip_arr[15] = dst_ip_arr[15] + 1 dst_ip = bytearray(dst_ip_arr) print("PORT lb counts:", count) ecmp_count = [ count[0], count[1], (count[2] + count[3] + count[4]), (count[5] + count[6] + count[7])] print("ECMP count:", ecmp_count) # Traffic should not be ballanced, should apear on single port or # LAG if ecmp_count[0] != 0: self.assertTrue( ecmp_count[0] == MAX_ITRS, "100 % traffic({}) expected on port: {}, but received only" "{} packets".format(MAX_ITRS, self.dev_port11, ecmp_count[0])) # port 11 self.assertTrue( ecmp_count[1] == 0, "No traffic expected on port:{}".format( self.dev_port12)) # port 12 self.assertTrue(ecmp_count[2] == 0, "No traffic expected on ports: {}" .format([self.dev_port4, self.dev_port5, self.dev_port6])) # LAG 1 self.assertTrue(ecmp_count[3] == 0, "No traffic expected on ports:{}" .format([self.dev_port7, self.dev_port8, self.dev_port9])) # LAG 2 elif ecmp_count[1] != 0: self.assertTrue( ecmp_count[0] == 0, "No traffic expected on port:{}" .format(self.dev_port11)) self.assertTrue( ecmp_count[1] == MAX_ITRS, "100 % traffic({}) expected on port: {}, but received" "only {} packets".format(MAX_ITRS, self.dev_port12, ecmp_count[1])) self.assertTrue(ecmp_count[2] == 0, "No traffic expected on ports:{}" .format([self.dev_port4, self.dev_port5, self.dev_port6])) self.assertTrue(ecmp_count[3] == 0, "No traffic expected on ports:{}" .format([self.dev_port7, self.dev_port8, self.dev_port9])) elif ecmp_count[2] != 0: self.assertTrue( ecmp_count[0] == 0, "No traffic expected on port:{}".format(self.dev_port11)) self.assertTrue( ecmp_count[1] == 0, "No traffic expected on port:{}".format(self.dev_port12)) self.assertTrue( ecmp_count[2] == MAX_ITRS, "100 % traffic({}) expected on ports: {}, but received" "only {} packets".format(MAX_ITRS, [self.dev_port4, self.dev_port5, self.dev_port6], ecmp_count[2])) self.assertTrue(ecmp_count[3] == 0, "No traffic expected on ports:{}" .format([self.dev_port7, self.dev_port8, self.dev_port9])) elif ecmp_count[3] != 0: self.assertTrue( ecmp_count[0] == 0, "No traffic expected on port:{}".format(self.dev_port11)) self.assertTrue( ecmp_count[1] == 0, "No traffic expected on port:{}".format(self.dev_port12)) self.assertTrue(ecmp_count[2] == 0, "No traffic expected on ports:{}" .format([self.dev_port4, self.dev_port5, self.dev_port6])) self.assertTrue( ecmp_count[3] == MAX_ITRS, "100 % traffic({}) expected on ports: {}, but received" "only {} pakets".format(MAX_ITRS, [self.dev_port7, self.dev_port8, self.dev_port9], ecmp_count[3])) # enable LB back to IPv4 full fields list print("Enable ECMP IPv6 LB") self.setupECMPIPv6Hash() count = [0, 0, 0, 0, 0, 0, 0, 0] dst_ip = socket.inet_pton(socket.AF_INET6, '1000:1:1:0:0:0:0:1') dst_ip_arr = list(dst_ip) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntop(socket.AF_INET6, dst_ip) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) src_mac = '00:22:22:22:22:22' pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:11:11:11:11:11', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet(eth_dst='00:22:22:22:22:22', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt3 = simple_tcpv6_packet(eth_dst='00:33:33:33:33:33', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt4 = simple_tcpv6_packet(eth_dst='00:44:44:44:44:44', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port11, self.dev_port12, self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) count[rcv_idx] += 1 dst_ip_arr[15] = dst_ip_arr[15] + 1 dst_ip = bytearray(dst_ip_arr) print("PORT lb counts:", count) ecmp_count = [ count[0], count[1], (count[2] + count[3] + count[4]), (count[5] + count[6] + count[7])] print("ECMP count:", ecmp_count) # Traffic should equally be ballanced, should apear on all port or # LAG for i in range(0, 4): print("ecmp_count=", ecmp_count, (MAX_ITRS / 4) * 0.5) self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 4) * 0.5)), "Ecmp paths are not equally balanced") finally: pass def tearDown(self): super(l3IPv6EcmpHashPortLagTest, self).tearDown() class l3IPv6EcmpHostTwoLagsDisabledLagMembersTest(L3IPv6EcmpLagTestHelper): """ IPv6 ECMP tests with LAG RIF and some LAG member in disable state """ def setUp(self): super(l3IPv6EcmpHostTwoLagsDisabledLagMembersTest, self).setUp() def runTest(self): print("l3IPv6EcmpHostTwoLagsDisabledLagMembersTest") print("Disable LAG1 member 4 and 5") print("Disable LAG2 member 7") status = sai_thrift_set_lag_member_attribute( self.client, self.lag1_member4, egress_disable=True) self.assertEqual(status, SAI_STATUS_SUCCESS) status = sai_thrift_set_lag_member_attribute( self.client, self.lag1_member5, egress_disable=True) self.assertEqual(status, SAI_STATUS_SUCCESS) status = sai_thrift_set_lag_member_attribute( self.client, self.lag2_member7, egress_disable=True) self.assertEqual(status, SAI_STATUS_SUCCESS) try: count = [0, 0, 0, 0, 0, 0] dst_ip = socket.inet_pton(socket.AF_INET6, '5500:1:1:0:0:0:0:1') dst_ip_arr = list(dst_ip) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntop(socket.AF_INET6, dst_ip) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ipv6_dst=dst_ip_addr, ipv6_src='6000:1:1:0:0:0:0:1', ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:55:55:55:55:55', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='6000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet(eth_dst='00:66:66:66:66:66', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='6000:1:1:0:0:0:0:1', ipv6_hlim=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port4, self.dev_port5, self.dev_port6, self.dev_port7, self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2], ports_to_verify) count[rcv_idx] += 1 dst_ip_arr[15] = dst_ip_arr[15] + 1 dst_ip = bytearray(dst_ip_arr) print("PORT lb counts:", count) ecmp_count = [(count[0] + count[1] + count[2]), (count[3] + count[4] + count[5])] print("ECMP count:", ecmp_count) # check LAG1 traffic self.assertEqual(count[0], 0) self.assertEqual(count[1], 0) self.assertTrue((count[2] >= ((MAX_ITRS / 2) * 0.7)), "Lag path1 is not equally balanced") # check LAG2 traffic self.assertEqual(count[3], 0) self.assertTrue((count[4] >= ((MAX_ITRS / 4) * 0.5)), "Lag path2 is not equally balanced") self.assertTrue((count[5] >= ((MAX_ITRS / 4) * 0.5)), "Lag path2 is not equally balanced") print(ecmp_count) for i in range(0, 2): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 2) * 0.5)), "Ecmp paths are not equally balanced") finally: print("Enable LAG1 member 4 and 5") print("Enable LAG2 member 7") status = sai_thrift_set_lag_member_attribute( self.client, self.lag1_member4, egress_disable=False) self.assertEqual(status, SAI_STATUS_SUCCESS) status = sai_thrift_set_lag_member_attribute( self.client, self.lag1_member5, egress_disable=False) self.assertEqual(status, SAI_STATUS_SUCCESS) status = sai_thrift_set_lag_member_attribute( self.client, self.lag2_member7, egress_disable=False) self.assertEqual(status, SAI_STATUS_SUCCESS) def tearDown(self): super(l3IPv6EcmpHostTwoLagsDisabledLagMembersTest, self).tearDown() class l3Ipv6EcmpAddRemoveNhopTest(L3IPv6EcmpLagTestHelper): """ IPv6 ECMP rebalance test with removal of a nexthop member """ def setUp(self): super(l3Ipv6EcmpAddRemoveNhopTest, self).setUp() def runTest(self): print("l3Ipv6EcmpAddRemoveNhopTest") print("Add new nhg member") dmac7 = '00:77:77:77:77:77' nhop_new_ip = '7000:1:1:0:0:0:0:1' neighbor_entry = sai_thrift_neighbor_entry_t( self.switch_id, self.port13_rif, sai_ipaddress(nhop_new_ip)) sai_thrift_create_neighbor_entry( self.client, neighbor_entry, dst_mac_address=dmac7) new_next_hop = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port13_rif, ip=sai_ipaddress(nhop_new_ip)) new_nhg1_member = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=new_next_hop) try: count = [0, 0, 0, 0, 0, 0, 0, 0, 0] dst_ip = socket.inet_pton(socket.AF_INET6, '1000:1:1:0:0:0:0:1') dst_ip_arr = list(dst_ip) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntop(socket.AF_INET6, dst_ip) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:11:11:11:11:11', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet(eth_dst='00:22:22:22:22:22', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt3 = simple_tcpv6_packet(eth_dst='00:33:33:33:33:33', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt4 = simple_tcpv6_packet(eth_dst='00:44:44:44:44:44', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt5 = simple_tcpv6_packet(eth_dst='00:77:77:77:77:77', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port11, self.dev_port12, self.dev_port4, self.dev_port5, self.dev_port6, self.dev_port7, self.dev_port8, self.dev_port9, self.dev_port13 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4, exp_pkt5], ports_to_verify) count[rcv_idx] += 1 dst_ip_arr[15] = dst_ip_arr[15] + 1 dst_ip = bytearray(dst_ip_arr) print("PORT lb counts:", count) ecmp_count = [ count[0], count[1], (count[2] + count[3] + count[4]), (count[5] + count[6] + count[7]), count[8]] print("ECMP count :", ecmp_count) for i in range(0, 5): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 5) * 0.5)), "Ecmp paths are not equally balanced") finally: print("Remove newly created nhg member") sai_thrift_remove_neighbor_entry(self.client, neighbor_entry) sai_thrift_remove_next_hop_group_member(self.client, new_nhg1_member) sai_thrift_remove_next_hop(self.client, new_next_hop) count = [0, 0, 0, 0, 0, 0, 0, 0, 0] dst_ip = socket.inet_pton(socket.AF_INET6, '1000:1:1:0:0:0:0:1') dst_ip_arr = list(dst_ip) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntop(socket.AF_INET6, dst_ip) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:11:11:11:11:11', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet(eth_dst='00:22:22:22:22:22', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt3 = simple_tcpv6_packet(eth_dst='00:33:33:33:33:33', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt4 = simple_tcpv6_packet(eth_dst='00:44:44:44:44:44', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port11, self.dev_port12, self.dev_port4, self.dev_port5, self.dev_port6, self.dev_port7, self.dev_port8, self.dev_port9, self.dev_port13 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) count[rcv_idx] += 1 dst_ip_arr[15] = dst_ip_arr[15] + 1 dst_ip = bytearray(dst_ip_arr) print("Port lb counts:", count) ecmp_count = [ count[0], count[1], (count[2] + count[3] + count[4]), (count[5] + count[6] + count[7]), count[8]] print("ECMP count :", ecmp_count) self.assertTrue(ecmp_count[4] == 0, "No traffic expected on removed nhg member") for i in range(0, 4): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 4) * 0.5)), "Ecmp paths are not equally balanced") def tearDown(self): super(l3Ipv6EcmpAddRemoveNhopTest, self).tearDown() class l3IPv6EcmpHostPortLagSharedMembersTest(L3IPv6EcmpLagTestHelper): """ IPv6 Multiple ECMP with shared nexthop members """ def setUp(self): super(l3IPv6EcmpHostPortLagSharedMembersTest, self).setUp() @warm_test(is_test_rebooting=True) def runTest(self): print("l3IPv6EcmpHostPortLagSharedMembersTest") try: count = [0, 0, 0, 0, 0, 0] dst_ip = socket.inet_pton(socket.AF_INET6, '5500:1:1:0:0:0:0:1') dst_ip_arr = list(dst_ip) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntop(socket.AF_INET6, dst_ip) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ipv6_dst=dst_ip_addr, ipv6_src='6000:1:1:0:0:0:0:1', ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:55:55:55:55:55', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='6000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet(eth_dst='00:66:66:66:66:66', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='6000:1:1:0:0:0:0:1', ipv6_hlim=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port4, self.dev_port5, self.dev_port6, self.dev_port7, self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2], ports_to_verify) count[rcv_idx] += 1 dst_ip_arr[15] = dst_ip_arr[15] + 1 dst_ip = bytearray(dst_ip_arr) print("PORT lb counts:", count) ecmp_count = [(count[0] + count[1] + count[2]), (count[3] + count[4] + count[5])] print("ECMP count:", ecmp_count) # check LAG1 traffic for i in range(0, 3): self.assertTrue((count[i] >= ((MAX_ITRS / 6) * 0.75)), "Lag path1 is not equally balanced") # check LAG2 traffic for i in range(3, 6): self.assertTrue((count[i] >= ((MAX_ITRS / 6) * 0.5)), "Lag path2 is not equally balanced") print(ecmp_count) for i in range(0, 2): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 2) * 0.5)), "Ecmp paths are not equally balanced") finally: count = [0, 0, 0, 0, 0, 0, 0, 0] dst_ip = socket.inet_pton(socket.AF_INET6, '1000:1:1:0:0:0:0:1') dst_ip_arr = list(dst_ip) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntop(socket.AF_INET6, dst_ip) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet(eth_dst='00:11:11:11:11:11', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet(eth_dst='00:22:22:22:22:22', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt3 = simple_tcpv6_packet(eth_dst='00:33:33:33:33:33', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt4 = simple_tcpv6_packet(eth_dst='00:44:44:44:44:44', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='5000:1:1:0:0:0:0:1', ipv6_hlim=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port11, self.dev_port12, self.dev_port4, self.dev_port5, self.dev_port6, self.dev_port7, self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) count[rcv_idx] += 1 dst_ip_arr[15] = dst_ip_arr[15] + 1 dst_ip = bytearray(dst_ip_arr) print("Port lb counts:", count) ecmp_count = [ count[0], count[1], (count[2] + count[3] + count[4]), (count[5] + count[6] + count[7])] print("ECMP count :", ecmp_count) for i in range(0, 4): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 4) * 0.5)), "Ecmp paths are not equally balanced") def tearDown(self): super(l3IPv6EcmpHostPortLagSharedMembersTest, self).tearDown() class L3IPv4SVIEcmpTestHelper(PlatformSaiHelper): """ Base ECMP tests for IPv4 and ECMP members as SVI RIFs """ def setUp(self): super(L3IPv4SVIEcmpTestHelper, self).setUp() self.vlan100_rif_counter_in = 0 self.vlan100_rif_counter_out = 0 self.vlan200_rif_counter_in = 0 self.vlan200_rif_counter_out = 0 self.vlan100_bcast_in = 0 self.vlan100_bcast_out = 0 self.vlan200_bcast_in = 0 self.vlan200_bcast_out = 0 # set switch src mac address sai_thrift_set_switch_attribute( self.client, src_mac_address=ROUTER_MAC) sai_thrift_set_switch_attribute( self.client, ecmp_default_hash_seed=TEST_ECMP_SEED) sai_thrift_set_switch_attribute( self.client, lag_default_hash_seed=TEST_LAG_SEED) self.port24_bp = sai_thrift_create_bridge_port( self.client, bridge_id=self.default_1q_bridge, port_id=self.port24, type=SAI_BRIDGE_PORT_TYPE_PORT) self.port25_bp = sai_thrift_create_bridge_port( self.client, bridge_id=self.default_1q_bridge, port_id=self.port25, type=SAI_BRIDGE_PORT_TYPE_PORT) self.port26_bp = sai_thrift_create_bridge_port( self.client, bridge_id=self.default_1q_bridge, port_id=self.port26, type=SAI_BRIDGE_PORT_TYPE_PORT) # vlan100 with members port24, port25 and port26 self.vlan100 = sai_thrift_create_vlan(self.client, vlan_id=100) self.vlan_member100 = sai_thrift_create_vlan_member( self.client, vlan_id=self.vlan100, bridge_port_id=self.port24_bp, vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) self.vlan_member101 = sai_thrift_create_vlan_member( self.client, vlan_id=self.vlan100, bridge_port_id=self.port25_bp, vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) self.vlan_member102 = sai_thrift_create_vlan_member( self.client, vlan_id=self.vlan100, bridge_port_id=self.port26_bp, vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) sai_thrift_set_port_attribute( self.client, self.port24, port_vlan_id=100) sai_thrift_set_port_attribute( self.client, self.port25, port_vlan_id=100) sai_thrift_set_port_attribute( self.client, self.port26, port_vlan_id=100) # create vlan100_rif self.vlan100_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_VLAN, virtual_router_id=self.default_vrf, vlan_id=self.vlan100) dmac1 = '00:11:22:33:44:55' dmac2 = '00:22:22:33:44:55' dmac3 = '00:33:22:33:44:55' dmac4 = '00:44:22:33:44:55' dmac5 = '00:11:33:33:44:55' dmac6 = '00:22:33:33:44:55' dmac7 = '00:44:33:33:44:55' # create nhop1, nhop2 & nhop3 on SVI self.neighbor_entry1 = sai_thrift_neighbor_entry_t( rif_id=self.vlan100_rif, ip_address=sai_ipaddress('10.10.0.1')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry1, dst_mac_address=dmac1) self.nhop1 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('10.10.0.1'), router_interface_id=self.vlan100_rif, type=SAI_NEXT_HOP_TYPE_IP) self.neighbor_entry2 = sai_thrift_neighbor_entry_t( rif_id=self.vlan100_rif, ip_address=sai_ipaddress('10.10.0.2')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry2, dst_mac_address=dmac2) self.nhop2 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('10.10.0.2'), router_interface_id=self.vlan100_rif, type=SAI_NEXT_HOP_TYPE_IP) self.neighbor_entry3 = sai_thrift_neighbor_entry_t( rif_id=self.vlan100_rif, ip_address=sai_ipaddress('10.10.0.3')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry3, dst_mac_address=dmac3) self.nhop3 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('10.10.0.3'), router_interface_id=self.vlan100_rif, type=SAI_NEXT_HOP_TYPE_IP) self.nhop_group1 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) self.nh_group1_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop1) self.nh_group1_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop2) self.nh_group1_member3 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop3) # create route entries self.route0 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix('10.20.30.1/16'), vr_id=self.default_vrf) status = sai_thrift_create_route_entry( self.client, self.route0, next_hop_id=self.nhop_group1) self.assertEqual(status, SAI_STATUS_SUCCESS) # create nhop and route to L2 intf self.neighbor_entry4 = sai_thrift_neighbor_entry_t( rif_id=self.port10_rif, ip_address=sai_ipaddress('11.11.0.2')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry4, dst_mac_address=dmac4) self.nhop4 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('11.11.0.2'), router_interface_id=self.port10_rif, type=SAI_NEXT_HOP_TYPE_IP) self.lag10 = sai_thrift_create_lag(self.client) self.lag10_bp = sai_thrift_create_bridge_port( self.client, bridge_id=self.default_1q_bridge, port_id=self.lag10, type=SAI_BRIDGE_PORT_TYPE_PORT) self.lag10_member30 = sai_thrift_create_lag_member( self.client, lag_id=self.lag10, port_id=self.port30) self.lag10_member31 = sai_thrift_create_lag_member( self.client, lag_id=self.lag10, port_id=self.port31) self.lag11 = sai_thrift_create_lag(self.client) self.lag11_bp = sai_thrift_create_bridge_port( self.client, bridge_id=self.default_1q_bridge, port_id=self.lag11, type=SAI_BRIDGE_PORT_TYPE_PORT) self.lag11_member28 = sai_thrift_create_lag_member( self.client, lag_id=self.lag11, port_id=self.port28) self.lag11_member29 = sai_thrift_create_lag_member( self.client, lag_id=self.lag11, port_id=self.port29) # create vlan200_rif self.vlan200 = sai_thrift_create_vlan(self.client, vlan_id=200) self.vlan_member200 = sai_thrift_create_vlan_member( self.client, vlan_id=self.vlan200, bridge_port_id=self.lag10_bp, vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) self.vlan_member201 = sai_thrift_create_vlan_member( self.client, vlan_id=self.vlan200, bridge_port_id=self.lag11_bp, vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) sai_thrift_set_lag_attribute(self.client, self.lag10, port_vlan_id=200) sai_thrift_set_lag_attribute(self.client, self.lag11, port_vlan_id=200) self.vlan200_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_VLAN, virtual_router_id=self.default_vrf, vlan_id=self.vlan200) # Create nhop5 and nhop6 on SVI self.neighbor_entry5 = sai_thrift_neighbor_entry_t( rif_id=self.vlan200_rif, ip_address=sai_ipaddress('20.10.0.1')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry5, dst_mac_address=dmac5) self.nhop5 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('20.10.0.1'), router_interface_id=self.vlan200_rif, type=SAI_NEXT_HOP_TYPE_IP) self.neighbor_entry6 = sai_thrift_neighbor_entry_t( rif_id=self.vlan200_rif, ip_address=sai_ipaddress('20.10.0.2')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry6, dst_mac_address=dmac6) self.nhop6 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('20.10.0.2'), router_interface_id=self.vlan200_rif, type=SAI_NEXT_HOP_TYPE_IP) self.neighbor_entry7 = sai_thrift_neighbor_entry_t( rif_id=self.port11_rif, ip_address=sai_ipaddress('21.11.0.2')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry7, dst_mac_address=dmac7) self.nhop7 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('21.11.0.2'), router_interface_id=self.port11_rif, type=SAI_NEXT_HOP_TYPE_IP) self.nhop_group2 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) self.nh_group2_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group2, next_hop_id=self.nhop4) self.nh_group2_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group2, next_hop_id=self.nhop5) self.nh_group2_member3 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group2, next_hop_id=self.nhop6) self.nh_group2_member4 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group2, next_hop_id=self.nhop7) self.route1 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix('10.40.40.1/16'), vr_id=self.default_vrf) status = sai_thrift_create_route_entry( self.client, self.route1, next_hop_id=self.nhop_group2) self.assertEqual(status, SAI_STATUS_SUCCESS) # define IPv4 IPv6 LagIPv4Hash and LagIPv6Hash self.ipv4_hash_id, self.ipv6_hash_id = setup_hash(self) def tearDown(self): sai_thrift_remove_route_entry(self.client, self.route1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group2_member1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group2_member2) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group2_member3) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group2_member4) self.assertEqual(nhg_members_count(self.client, self.nhop_group2), 0) sai_thrift_remove_next_hop_group(self.client, self.nhop_group2) sai_thrift_remove_next_hop(self.client, self.nhop4) sai_thrift_remove_next_hop(self.client, self.nhop5) sai_thrift_remove_next_hop(self.client, self.nhop6) sai_thrift_remove_next_hop(self.client, self.nhop7) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry4) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry5) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry6) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry7) sai_thrift_set_lag_attribute(self.client, self.lag10, port_vlan_id=0) sai_thrift_set_lag_attribute(self.client, self.lag11, port_vlan_id=0) sai_thrift_remove_router_interface(self.client, self.vlan200_rif) sai_thrift_remove_vlan_member(self.client, self.vlan_member200) sai_thrift_remove_vlan_member(self.client, self.vlan_member201) sai_thrift_remove_vlan(self.client, self.vlan200) sai_thrift_remove_lag_member(self.client, self.lag10_member30) sai_thrift_remove_lag_member(self.client, self.lag10_member31) sai_thrift_remove_lag_member(self.client, self.lag11_member28) sai_thrift_remove_lag_member(self.client, self.lag11_member29) sai_thrift_remove_bridge_port(self.client, self.lag10_bp) sai_thrift_remove_bridge_port(self.client, self.lag11_bp) sai_thrift_remove_lag(self.client, self.lag10) sai_thrift_remove_lag(self.client, self.lag11) sai_thrift_remove_route_entry(self.client, self.route0) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member2) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member3) sai_thrift_remove_next_hop_group(self.client, self.nhop_group1) sai_thrift_remove_next_hop(self.client, self.nhop1) sai_thrift_remove_next_hop(self.client, self.nhop2) sai_thrift_remove_next_hop(self.client, self.nhop3) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry1) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry2) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry3) sai_thrift_remove_router_interface(self.client, self.vlan100_rif) sai_thrift_set_port_attribute(self.client, self.port24, port_vlan_id=0) sai_thrift_set_port_attribute(self.client, self.port25, port_vlan_id=0) sai_thrift_set_port_attribute(self.client, self.port26, port_vlan_id=0) sai_thrift_remove_vlan_member(self.client, self.vlan_member100) sai_thrift_remove_vlan_member(self.client, self.vlan_member101) sai_thrift_remove_vlan_member(self.client, self.vlan_member102) sai_thrift_remove_vlan(self.client, self.vlan100) sai_thrift_remove_bridge_port(self.client, self.port24_bp) sai_thrift_remove_bridge_port(self.client, self.port25_bp) sai_thrift_remove_bridge_port(self.client, self.port26_bp) release_hash(self, self.ipv4_hash_id, self.ipv6_hash_id) super(L3IPv4SVIEcmpTestHelper, self).tearDown() class l3IPv4EcmpSVIHostTest(L3IPv4SVIEcmpTestHelper): """ IPv4 ECMP tests with SVI RIF as member """ def setUp(self): super(l3IPv4EcmpSVIHostTest, self).setUp() def runTest(self): print("l3IPv4EcmpSVIHostTest") mac_action = SAI_PACKET_ACTION_FORWARD fdb_entry1 = sai_thrift_fdb_entry_t( switch_id=self.switch_id, mac_address='00:11:22:33:44:55', bv_id=self.vlan100) sai_thrift_create_fdb_entry( self.client, fdb_entry1, type=SAI_FDB_ENTRY_TYPE_STATIC, bridge_port_id=self.port24_bp, packet_action=mac_action) fdb_entry2 = sai_thrift_fdb_entry_t( switch_id=self.switch_id, mac_address='00:22:22:33:44:55', bv_id=self.vlan100) sai_thrift_create_fdb_entry( self.client, fdb_entry2, type=SAI_FDB_ENTRY_TYPE_STATIC, bridge_port_id=self.port25_bp, packet_action=mac_action) fdb_entry3 = sai_thrift_fdb_entry_t( switch_id=self.switch_id, mac_address='00:33:22:33:44:55', bv_id=self.vlan100) sai_thrift_create_fdb_entry( self.client, fdb_entry3, type=SAI_FDB_ENTRY_TYPE_STATIC, bridge_port_id=self.port26_bp, packet_action=mac_action) try: count = [0, 0, 0] dst_ip = int(binascii.hexlify(socket.inet_aton('10.20.30.1')), 16) for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) pkt = simple_tcp_packet( eth_dst=ROUTER_MAC, eth_src='00:22:22:22:22:22', ip_dst=dst_ip_addr, ip_src='192.168.0.1', ip_id=105, ip_ttl=64) exp_pkt1 = simple_tcp_packet( eth_dst='00:11:22:33:44:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.0.1', ip_id=105, ip_ttl=63) exp_pkt2 = simple_tcp_packet( eth_dst='00:22:22:33:44:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.0.1', ip_id=105, ip_ttl=63) exp_pkt3 = simple_tcp_packet( eth_dst='00:33:22:33:44:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.0.1', ip_id=105, ip_ttl=63) send_packet(self, self.dev_port10, pkt) self.vlan100_rif_counter_out += 1 ports_to_verify = [ self.dev_port24, self.dev_port25, self.dev_port26 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3], ports_to_verify) count[rcv_idx] += 1 dst_ip += 1 print("Port LB counts:", count) for i in range(0, 3): self.assertTrue( (count[i] >= ((MAX_ITRS / 3) * 0.5)), "Not all paths are equally balanced, %s" % count) finally: sai_thrift_remove_fdb_entry(self.client, fdb_entry1) sai_thrift_remove_fdb_entry(self.client, fdb_entry2) sai_thrift_remove_fdb_entry(self.client, fdb_entry3) def tearDown(self): super(l3IPv4EcmpSVIHostTest, self).tearDown() class l3IPv4EcmpSVILagHostTest(L3IPv4SVIEcmpTestHelper): """ IPv4 ECMP tests with Port, LAG and SVI RIFs as nexthop members """ def setUp(self): super(l3IPv4EcmpSVILagHostTest, self).setUp() def runTest(self): print("l3IPv4EcmpSVILagHostTest") mac_action = SAI_PACKET_ACTION_FORWARD fdb_entry1 = sai_thrift_fdb_entry_t( switch_id=self.switch_id, mac_address='00:11:33:33:44:55', bv_id=self.vlan200) sai_thrift_create_fdb_entry( self.client, fdb_entry1, type=SAI_FDB_ENTRY_TYPE_STATIC, bridge_port_id=self.lag10_bp, packet_action=mac_action) fdb_entry2 = sai_thrift_fdb_entry_t( switch_id=self.switch_id, mac_address='00:22:33:33:44:55', bv_id=self.vlan200) sai_thrift_create_fdb_entry( self.client, fdb_entry2, type=SAI_FDB_ENTRY_TYPE_STATIC, bridge_port_id=self.lag11_bp, packet_action=mac_action) try: count = [0, 0, 0, 0, 0, 0] dst_ip = int(binascii.hexlify(socket.inet_aton('10.40.40.1')), 16) for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) pkt = simple_tcp_packet( eth_dst=ROUTER_MAC, eth_src='00:22:22:22:22:22', ip_dst=dst_ip_addr, ip_src='192.168.0.1', ip_id=105, ip_ttl=64) exp_pkt1 = simple_tcp_packet( eth_dst='00:44:22:33:44:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.0.1', ip_id=105, ip_ttl=63) exp_pkt2 = simple_tcp_packet( eth_dst='00:11:33:33:44:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.0.1', ip_id=105, ip_ttl=63) exp_pkt3 = simple_tcp_packet( eth_dst='00:22:33:33:44:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.0.1', ip_id=105, ip_ttl=63) exp_pkt4 = simple_tcp_packet( eth_dst='00:44:33:33:44:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.0.1', ip_id=105, ip_ttl=63) send_packet(self, self.dev_port10, pkt) ports_to_verify = [ self.dev_port10, self.dev_port11, self.dev_port28, self.dev_port29, self.dev_port30, self.dev_port31] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) count[rcv_idx] += 1 dst_ip += 1 ecmp_count = [ count[0], count[1], (count[2] + count[3]), (count[4] + count[5]) ] print("PORT lb counts", count) for i in range(0, 4): print("ECMP count LB[%d], %d, %d%%" % ( i, ecmp_count[i], ecmp_count[i] * 100 / MAX_ITRS)) for i in range(0, 4): self.assertTrue( (ecmp_count[i] >= ((MAX_ITRS / 4) * 0.5)), "Not all paths are equally balanced, %s" % count) finally: sai_thrift_remove_fdb_entry(self.client, fdb_entry1) sai_thrift_remove_fdb_entry(self.client, fdb_entry2) def tearDown(self): super(l3IPv4EcmpSVILagHostTest, self).tearDown() class L3IPv6SVIEcmpTestHelper(PlatformSaiHelper): """ Base ECMP tests for IPv6 and ECMP members as SVI RIFs """ def setUp(self): super(L3IPv6SVIEcmpTestHelper, self).setUp() self.vlan100_rif_counter_in = 0 self.vlan100_rif_counter_out = 0 self.vlan200_rif_counter_in = 0 self.vlan200_rif_counter_out = 0 self.vlan100_bcast_in = 0 self.vlan100_bcast_out = 0 self.vlan200_bcast_in = 0 self.vlan200_bcast_out = 0 # set switch src mac address sai_thrift_set_switch_attribute( self.client, src_mac_address=ROUTER_MAC) sai_thrift_set_switch_attribute( self.client, ecmp_default_hash_seed=TEST_ECMP_SEED) sai_thrift_set_switch_attribute( self.client, lag_default_hash_seed=TEST_LAG_SEED) self.port24_bp = sai_thrift_create_bridge_port( self.client, bridge_id=self.default_1q_bridge, port_id=self.port24, type=SAI_BRIDGE_PORT_TYPE_PORT) self.port25_bp = sai_thrift_create_bridge_port( self.client, bridge_id=self.default_1q_bridge, port_id=self.port25, type=SAI_BRIDGE_PORT_TYPE_PORT) self.port26_bp = sai_thrift_create_bridge_port( self.client, bridge_id=self.default_1q_bridge, port_id=self.port26, type=SAI_BRIDGE_PORT_TYPE_PORT) self.port10_bp = sai_thrift_create_bridge_port( self.client, bridge_id=self.default_1q_bridge, port_id=self.port10, type=SAI_BRIDGE_PORT_TYPE_PORT) self.port11_bp = sai_thrift_create_bridge_port( self.client, bridge_id=self.default_1q_bridge, port_id=self.port11, type=SAI_BRIDGE_PORT_TYPE_PORT) # vlan100 with members port24, port25 and port26 self.vlan100 = sai_thrift_create_vlan(self.client, vlan_id=100) self.vlan_member100 = sai_thrift_create_vlan_member( self.client, vlan_id=self.vlan100, bridge_port_id=self.port24_bp, vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) self.vlan_member101 = sai_thrift_create_vlan_member( self.client, vlan_id=self.vlan100, bridge_port_id=self.port25_bp, vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) self.vlan_member102 = sai_thrift_create_vlan_member( self.client, vlan_id=self.vlan100, bridge_port_id=self.port26_bp, vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) sai_thrift_set_port_attribute( self.client, self.port24, port_vlan_id=100) sai_thrift_set_port_attribute( self.client, self.port25, port_vlan_id=100) sai_thrift_set_port_attribute( self.client, self.port26, port_vlan_id=100) # create vlan100_rif self.vlan100_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_VLAN, virtual_router_id=self.default_vrf, vlan_id=self.vlan100, admin_v6_state=True) dmac1 = '00:11:22:33:44:55' dmac2 = '00:22:22:33:44:55' dmac3 = '00:33:22:33:44:55' dmac4 = '00:11:00:00:00:04' dmac5 = '00:11:00:00:00:05' dmac6 = '00:11:00:00:00:06' dmac7 = '00:11:00:00:00:07' # create nhop1, nhop2 & nhop3 on SVI self.neighbor_entry1 = sai_thrift_neighbor_entry_t( rif_id=self.vlan100_rif, ip_address=sai_ipaddress('1000:1:1:0:0:0:0:1')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry1, dst_mac_address=dmac1) self.nhop1 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('1000:1:1:0:0:0:0:1'), router_interface_id=self.vlan100_rif, type=SAI_NEXT_HOP_TYPE_IP) self.neighbor_entry2 = sai_thrift_neighbor_entry_t( rif_id=self.vlan100_rif, ip_address=sai_ipaddress('1000:1:1:0:0:0:0:2')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry2, dst_mac_address=dmac2) self.nhop2 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('1000:1:1:0:0:0:0:2'), router_interface_id=self.vlan100_rif, type=SAI_NEXT_HOP_TYPE_IP) self.neighbor_entry3 = sai_thrift_neighbor_entry_t( rif_id=self.vlan100_rif, ip_address=sai_ipaddress('1000:1:1:0:0:0:0:3')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry3, dst_mac_address=dmac3) self.nhop3 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('1000:1:1:0:0:0:0:3'), router_interface_id=self.vlan100_rif, type=SAI_NEXT_HOP_TYPE_IP) self.nhop_group1 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) self.nh_group1_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop1) self.nh_group1_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop2) self.nh_group1_member3 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop3) # create route entries self.route0 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix('4000:1:1:0:0:0:0:1/16'), vr_id=self.default_vrf) status = sai_thrift_create_route_entry( self.client, self.route0, next_hop_id=self.nhop_group1) self.assertEqual(status, SAI_STATUS_SUCCESS) # create nhop and route to L2 intf self.lag10 = sai_thrift_create_lag(self.client) self.lag10_bp = sai_thrift_create_bridge_port( self.client, bridge_id=self.default_1q_bridge, port_id=self.lag10, type=SAI_BRIDGE_PORT_TYPE_PORT) self.lag10_member30 = sai_thrift_create_lag_member( self.client, lag_id=self.lag10, port_id=self.port30) self.lag10_member31 = sai_thrift_create_lag_member( self.client, lag_id=self.lag10, port_id=self.port31) self.lag11 = sai_thrift_create_lag(self.client) self.lag11_bp = sai_thrift_create_bridge_port( self.client, bridge_id=self.default_1q_bridge, port_id=self.lag11, type=SAI_BRIDGE_PORT_TYPE_PORT) self.lag11_member28 = sai_thrift_create_lag_member( self.client, lag_id=self.lag11, port_id=self.port28) self.lag11_member29 = sai_thrift_create_lag_member( self.client, lag_id=self.lag11, port_id=self.port29) # create vlan200_rif self.vlan200 = sai_thrift_create_vlan(self.client, vlan_id=200) self.vlan_member200 = sai_thrift_create_vlan_member( self.client, vlan_id=self.vlan200, bridge_port_id=self.lag10_bp, vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) self.vlan_member201 = sai_thrift_create_vlan_member( self.client, vlan_id=self.vlan200, bridge_port_id=self.lag11_bp, vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) self.vlan_member202 = sai_thrift_create_vlan_member( self.client, vlan_id=self.vlan200, bridge_port_id=self.port10_bp, vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) self.vlan_member203 = sai_thrift_create_vlan_member( self.client, vlan_id=self.vlan200, bridge_port_id=self.port11_bp, vlan_tagging_mode=SAI_VLAN_TAGGING_MODE_UNTAGGED) sai_thrift_set_lag_attribute(self.client, self.lag10, port_vlan_id=200) sai_thrift_set_lag_attribute(self.client, self.lag11, port_vlan_id=200) sai_thrift_set_port_attribute( self.client, self.port10, port_vlan_id=200) sai_thrift_set_port_attribute( self.client, self.port11, port_vlan_id=200) self.vlan200_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_VLAN, virtual_router_id=self.default_vrf, vlan_id=self.vlan200, admin_v6_state=True) self.neighbor_entry4 = sai_thrift_neighbor_entry_t( rif_id=self.port10_rif, ip_address=sai_ipaddress('2010:1:1:0:0:0:0:1')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry4, dst_mac_address=dmac4) self.nhop4 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('2010:1:1:0:0:0:0:1'), router_interface_id=self.port10_rif, type=SAI_NEXT_HOP_TYPE_IP) # Create nhop5 and nhop6 on SVI self.neighbor_entry5 = sai_thrift_neighbor_entry_t( rif_id=self.vlan200_rif, ip_address=sai_ipaddress('2010:1:1:0:0:0:0:2')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry5, dst_mac_address=dmac5) self.nhop5 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('2010:1:1:0:0:0:0:2'), router_interface_id=self.vlan200_rif, type=SAI_NEXT_HOP_TYPE_IP) self.neighbor_entry6 = sai_thrift_neighbor_entry_t( rif_id=self.vlan200_rif, ip_address=sai_ipaddress('2010:1:1:0:0:0:0:3')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry6, dst_mac_address=dmac6) self.nhop6 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('2010:1:1:0:0:0:0:3'), router_interface_id=self.vlan200_rif, type=SAI_NEXT_HOP_TYPE_IP) self.neighbor_entry7 = sai_thrift_neighbor_entry_t( rif_id=self.port11_rif, ip_address=sai_ipaddress('2010:1:1:0:0:0:0:4')) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry7, dst_mac_address=dmac7) self.nhop7 = sai_thrift_create_next_hop( self.client, ip=sai_ipaddress('2010:1:1:0:0:0:0:4'), router_interface_id=self.port11_rif, type=SAI_NEXT_HOP_TYPE_IP) self.nhop_group2 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) self.nh_group2_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group2, next_hop_id=self.nhop4) self.nh_group2_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group2, next_hop_id=self.nhop5) self.nh_group2_member3 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group2, next_hop_id=self.nhop6) self.nh_group2_member4 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group2, next_hop_id=self.nhop7) self.route1 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix('5500:1:1:0:0:0:0:1/65'), vr_id=self.default_vrf) status = sai_thrift_create_route_entry( self.client, self.route1, next_hop_id=self.nhop_group2) self.assertEqual(status, SAI_STATUS_SUCCESS) # define IPv4 IPv6 LagIPv4Hash and LagIPv6Hash self.ipv4_hash_id, self.ipv6_hash_id = setup_hash(self) def tearDown(self): sai_thrift_remove_route_entry(self.client, self.route1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group2_member1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group2_member2) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group2_member3) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group2_member4) self.assertEqual(nhg_members_count(self.client, self.nhop_group2), 0) sai_thrift_remove_next_hop_group(self.client, self.nhop_group2) sai_thrift_remove_next_hop(self.client, self.nhop4) sai_thrift_remove_next_hop(self.client, self.nhop5) sai_thrift_remove_next_hop(self.client, self.nhop6) sai_thrift_remove_next_hop(self.client, self.nhop7) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry4) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry5) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry6) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry7) sai_thrift_set_lag_attribute(self.client, self.lag10, port_vlan_id=0) sai_thrift_set_lag_attribute(self.client, self.lag11, port_vlan_id=0) sai_thrift_set_port_attribute(self.client, self.port10, port_vlan_id=0) sai_thrift_set_port_attribute(self.client, self.port11, port_vlan_id=0) sai_thrift_remove_router_interface(self.client, self.vlan200_rif) sai_thrift_remove_vlan_member(self.client, self.vlan_member200) sai_thrift_remove_vlan_member(self.client, self.vlan_member201) sai_thrift_remove_vlan_member(self.client, self.vlan_member202) sai_thrift_remove_vlan_member(self.client, self.vlan_member203) sai_thrift_remove_vlan(self.client, self.vlan200) sai_thrift_remove_lag_member(self.client, self.lag10_member30) sai_thrift_remove_lag_member(self.client, self.lag10_member31) sai_thrift_remove_lag_member(self.client, self.lag11_member28) sai_thrift_remove_lag_member(self.client, self.lag11_member29) sai_thrift_remove_bridge_port(self.client, self.lag10_bp) sai_thrift_remove_bridge_port(self.client, self.lag11_bp) sai_thrift_remove_lag(self.client, self.lag10) sai_thrift_remove_lag(self.client, self.lag11) sai_thrift_remove_bridge_port(self.client, self.port10_bp) sai_thrift_remove_bridge_port(self.client, self.port11_bp) sai_thrift_remove_route_entry(self.client, self.route0) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member2) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member3) sai_thrift_remove_next_hop_group(self.client, self.nhop_group1) sai_thrift_remove_next_hop(self.client, self.nhop1) sai_thrift_remove_next_hop(self.client, self.nhop2) sai_thrift_remove_next_hop(self.client, self.nhop3) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry1) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry2) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry3) sai_thrift_remove_router_interface(self.client, self.vlan100_rif) sai_thrift_set_port_attribute(self.client, self.port24, port_vlan_id=0) sai_thrift_set_port_attribute(self.client, self.port25, port_vlan_id=0) sai_thrift_set_port_attribute(self.client, self.port26, port_vlan_id=0) sai_thrift_remove_vlan_member(self.client, self.vlan_member100) sai_thrift_remove_vlan_member(self.client, self.vlan_member101) sai_thrift_remove_vlan_member(self.client, self.vlan_member102) sai_thrift_remove_vlan(self.client, self.vlan100) sai_thrift_remove_bridge_port(self.client, self.port24_bp) sai_thrift_remove_bridge_port(self.client, self.port25_bp) sai_thrift_remove_bridge_port(self.client, self.port26_bp) release_hash(self, self.ipv4_hash_id, self.ipv6_hash_id) super(L3IPv6SVIEcmpTestHelper, self).tearDown() class l3IPv6EcmpSVIHostTest(L3IPv6SVIEcmpTestHelper): """ IPv6 ECMP tests with SVI RIF members """ def setUp(self): super(l3IPv6EcmpSVIHostTest, self).setUp() def runTest(self): print("l3IPv6EcmpSVIHostTest") mac_action = SAI_PACKET_ACTION_FORWARD fdb_entry1 = sai_thrift_fdb_entry_t( switch_id=self.switch_id, mac_address='00:11:22:33:44:55', bv_id=self.vlan100) sai_thrift_create_fdb_entry( self.client, fdb_entry1, type=SAI_FDB_ENTRY_TYPE_STATIC, bridge_port_id=self.port24_bp, packet_action=mac_action) fdb_entry2 = sai_thrift_fdb_entry_t( switch_id=self.switch_id, mac_address='00:22:22:33:44:55', bv_id=self.vlan100) sai_thrift_create_fdb_entry( self.client, fdb_entry2, type=SAI_FDB_ENTRY_TYPE_STATIC, bridge_port_id=self.port25_bp, packet_action=mac_action) fdb_entry3 = sai_thrift_fdb_entry_t( switch_id=self.switch_id, mac_address='00:33:22:33:44:55', bv_id=self.vlan100) sai_thrift_create_fdb_entry( self.client, fdb_entry3, type=SAI_FDB_ENTRY_TYPE_STATIC, bridge_port_id=self.port26_bp, packet_action=mac_action) try: count = [0, 0, 0] dst_ip = socket.inet_pton(socket.AF_INET6, '4000:1:1:0:0:0:0:1') dst_ip_arr = list(dst_ip) src_mac_start = '00:22:22:22:22:22' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntop(socket.AF_INET6, dst_ip) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ipv6_dst=dst_ip_addr, ipv6_src='7000:1:1:0:0:0:0:1', ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet( eth_dst='00:11:22:33:44:55', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='7000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet( eth_dst='00:22:22:33:44:55', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='7000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt3 = simple_tcpv6_packet( eth_dst='00:33:22:33:44:55', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='7000:1:1:0:0:0:0:1', ipv6_hlim=63) send_packet(self, self.dev_port10, pkt) self.vlan100_rif_counter_out += 1 ports_to_verify = [ self.dev_port24, self.dev_port25, self.dev_port26 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3], ports_to_verify) count[rcv_idx] += 1 dst_ip_arr[15] = dst_ip_arr[15] + 1 dst_ip = bytearray(dst_ip_arr) print("Port LB counts:", count) for i in range(0, 3): self.assertTrue( (count[i] >= ((MAX_ITRS / 3) * 0.6)), "Not all paths are equally balanced, %s" % count) finally: sai_thrift_remove_fdb_entry(self.client, fdb_entry1) sai_thrift_remove_fdb_entry(self.client, fdb_entry2) sai_thrift_remove_fdb_entry(self.client, fdb_entry3) def tearDown(self): super(l3IPv6EcmpSVIHostTest, self).tearDown() class l3IPv6EcmpSVIPortLagHostTest(L3IPv6SVIEcmpTestHelper): """ IPv6 ECMP tests with Port, LAG and SVI RIFs as ECMP members """ def setUp(self): super(l3IPv6EcmpSVIPortLagHostTest, self).setUp() def runTest(self): print("l3IPv6EcmpSVIPortLagHostTest") mac_action = SAI_PACKET_ACTION_FORWARD fdb_entry1 = sai_thrift_fdb_entry_t( switch_id=self.switch_id, mac_address='00:11:00:00:00:05', bv_id=self.vlan200) sai_thrift_create_fdb_entry( self.client, fdb_entry1, type=SAI_FDB_ENTRY_TYPE_STATIC, bridge_port_id=self.lag11_bp, packet_action=mac_action) fdb_entry2 = sai_thrift_fdb_entry_t( switch_id=self.switch_id, mac_address='00:11:00:00:00:06', bv_id=self.vlan200) sai_thrift_create_fdb_entry( self.client, fdb_entry2, type=SAI_FDB_ENTRY_TYPE_STATIC, bridge_port_id=self.lag10_bp, packet_action=mac_action) try: count = [0] * 6 dst_ip = socket.inet_pton(socket.AF_INET6, '5500:1:1:0:0:0:0:1') dst_ip_arr = list(dst_ip) src_mac_start = '00:22:22:22:22:22' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntop(socket.AF_INET6, dst_ip) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) pkt = simple_tcpv6_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ipv6_dst=dst_ip_addr, ipv6_src='7000:1:1:0:0:0:0:1', ipv6_hlim=64) exp_pkt1 = simple_tcpv6_packet( eth_dst='00:11:00:00:00:04', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='7000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt2 = simple_tcpv6_packet( eth_dst='00:11:00:00:00:05', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='7000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt3 = simple_tcpv6_packet( eth_dst='00:11:00:00:00:06', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='7000:1:1:0:0:0:0:1', ipv6_hlim=63) exp_pkt4 = simple_tcpv6_packet( eth_dst='00:11:00:00:00:07', eth_src=ROUTER_MAC, ipv6_dst=dst_ip_addr, ipv6_src='7000:1:1:0:0:0:0:1', ipv6_hlim=63) send_packet(self, self.dev_port10, pkt) ports_to_verify = [ self.dev_port10, self.dev_port28, self.dev_port29, # Lag11 self.dev_port30, self.dev_port31, # Lag10 self.dev_port11] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) count[rcv_idx] += 1 dst_ip_arr[15] = dst_ip_arr[15] + 1 dst_ip = bytearray(dst_ip_arr) ecmp_count = [count[0], count[1] + count[2], count[3] + count[4], count[5]] print("Port ECMP counts:", ecmp_count) for i in range(0, 4): self.assertTrue( (ecmp_count[i] >= ((MAX_ITRS / 4) * 0.5)), "Not all paths are equally balanced, %s" % ecmp_count) finally: sai_thrift_remove_fdb_entry(self.client, fdb_entry1) sai_thrift_remove_fdb_entry(self.client, fdb_entry2) def tearDown(self): super(l3IPv6EcmpSVIPortLagHostTest, self).tearDown() class L3IPv4EcmpLagTestHelper(PlatformSaiHelper): """ Base ECMP tests common setup and teardown with lag for IPv4 """ def setUp(self): super(L3IPv4EcmpLagTestHelper, self).setUp() dmac1 = '00:11:11:11:11:11' dmac2 = '00:22:22:22:22:22' dmac3 = '00:33:33:33:33:33' dmac4 = '00:44:44:44:44:44' dmac5 = '00:55:55:55:55:55' dmac6 = '00:66:66:66:66:66' nhop_ip1 = '11.11.11.11' nhop_ip2 = '22.22.22.22' nhop_ip3 = '33.33.33.33' nhop_ip4 = '44.44.44.44' nhop_ip5 = '44.55.55.55' nhop_ip6 = '44.66.66.66' # set switch src mac address sai_thrift_set_switch_attribute( self.client, src_mac_address=ROUTER_MAC) sai_thrift_set_switch_attribute( self.client, ecmp_default_hash_seed=TEST_ECMP_SEED) sai_thrift_set_switch_attribute( self.client, lag_default_hash_seed=TEST_LAG_SEED) self.lag1_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_PORT, virtual_router_id=self.default_vrf, port_id=self.lag1, admin_v4_state=True) self.lag2_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_PORT, virtual_router_id=self.default_vrf, port_id=self.lag2, admin_v4_state=True) self.port15_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_PORT, virtual_router_id=self.default_vrf, port_id=self.port15, admin_v4_state=True) # test neighbor creation self.neighbor_entry11 = sai_thrift_neighbor_entry_t( self.switch_id, self.port11_rif, sai_ipaddress(nhop_ip1)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry11, dst_mac_address=dmac1) self.neighbor_entry12 = sai_thrift_neighbor_entry_t( self.switch_id, self.port12_rif, sai_ipaddress(nhop_ip2)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry12, dst_mac_address=dmac2) self.neighbor_entry13 = sai_thrift_neighbor_entry_t( self.switch_id, self.lag1_rif, sai_ipaddress(nhop_ip3)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry13, dst_mac_address=dmac3) self.neighbor_entry14 = sai_thrift_neighbor_entry_t( self.switch_id, self.lag2_rif, sai_ipaddress(nhop_ip4)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry14, dst_mac_address=dmac4) self.neighbor_entry15 = sai_thrift_neighbor_entry_t( self.switch_id, self.lag1_rif, sai_ipaddress(nhop_ip5)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry15, dst_mac_address=dmac5) self.neighbor_entry16 = sai_thrift_neighbor_entry_t( self.switch_id, self.lag2_rif, sai_ipaddress(nhop_ip6)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry16, dst_mac_address=dmac6) self.nhop1 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port11_rif, ip=sai_ipaddress(nhop_ip1)) self.nhop2 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port12_rif, ip=sai_ipaddress(nhop_ip2)) self.nhop3_lag1 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.lag1_rif, ip=sai_ipaddress(nhop_ip3)) self.nhop4_lag2 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.lag2_rif, ip=sai_ipaddress(nhop_ip4)) self.nhop5_lag1 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.lag1_rif, ip=sai_ipaddress(nhop_ip5)) self.nhop6_lag2 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.lag2_rif, ip=sai_ipaddress(nhop_ip6)) self.nhop_group1 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) self.nh_group1_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop1) self.nh_group1_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop2) self.nh_group1_member3 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop3_lag1) self.nh_group1_member4 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop4_lag2) self.nhop_group2 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_ECMP) self.nh_group2_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group2, next_hop_id=self.nhop5_lag1) self.nh_group2_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group2, next_hop_id=self.nhop6_lag2) # create route entries self.route0 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix('10.10.10.1/16'), vr_id=self.default_vrf) status = sai_thrift_create_route_entry( self.client, self.route0, next_hop_id=self.nhop_group1) self.assertEqual(status, SAI_STATUS_SUCCESS) self.route1 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix('20.20.20.1/16'), vr_id=self.default_vrf) status = sai_thrift_create_route_entry( self.client, self.route1, next_hop_id=self.nhop_group2) self.assertEqual(status, SAI_STATUS_SUCCESS) # define IPv4 IPv6 LagIPv4Hash and LagIPv6Hash self.ipv4_hash_id, self.ipv6_hash_id = setup_hash(self) def tearDown(self): sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member2) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member3) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group1_member4) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group2_member1) sai_thrift_remove_next_hop_group_member(self.client, self.nh_group2_member2) self.assertEqual(nhg_members_count(self.client, self.nhop_group1), 0) self.assertEqual(nhg_members_count(self.client, self.nhop_group2), 0) sai_thrift_remove_route_entry(self.client, self.route0) sai_thrift_remove_route_entry(self.client, self.route1) sai_thrift_remove_next_hop_group(self.client, self.nhop_group1) sai_thrift_remove_next_hop_group(self.client, self.nhop_group2) sai_thrift_remove_next_hop(self.client, self.nhop1) sai_thrift_remove_next_hop(self.client, self.nhop2) sai_thrift_remove_next_hop(self.client, self.nhop3_lag1) sai_thrift_remove_next_hop(self.client, self.nhop4_lag2) sai_thrift_remove_next_hop(self.client, self.nhop5_lag1) sai_thrift_remove_next_hop(self.client, self.nhop6_lag2) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry11) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry12) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry13) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry14) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry15) sai_thrift_remove_neighbor_entry(self.client, self.neighbor_entry16) sai_thrift_remove_router_interface(self.client, self.lag1_rif) sai_thrift_remove_router_interface(self.client, self.lag2_rif) sai_thrift_remove_router_interface(self.client, self.port15_rif) release_hash(self, self.ipv4_hash_id, self.ipv6_hash_id) super(L3IPv4EcmpLagTestHelper, self).tearDown() class L3IPv4EcmpHostTwoLagsTest(L3IPv4EcmpLagTestHelper): """ IPv4 ECMP tests with all LAG RIFs members """ def setUp(self): super(L3IPv4EcmpHostTwoLagsTest, self).setUp() def runTest(self): print("l3IPv4EcmpHostTwoLagsTest") count = [0, 0, 0, 0, 0, 0] dst_ip = int(binascii.hexlify(socket.inet_aton('20.20.20.1')), 16) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:55:55:55:55:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:66:66:66:66:66', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2], ports_to_verify) count[rcv_idx] += 1 dst_ip += 1 print("PORT lb counts", count) ecmp_count = [(count[0] + count[1] + count[2]), (count[3] + count[4] + count[5])] print("ECMP count:", ecmp_count) for i in range(0, 2): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 2) * 0.7)), "Ecmp paths are not equally balanced") for i in range(0, 3): self.assertTrue((count[i] >= ((MAX_ITRS / 6) * 0.6)), "Lag path1 is not equally balanced") for i in range(3, 6): self.assertTrue((count[i] >= ((MAX_ITRS / 6) * 0.6)), "Lag path2 is not equally balanced") print("\nVerification done") def tearDown(self): super(L3IPv4EcmpHostTwoLagsTest, self).tearDown() class L3IPv4EcmpHostPortLagSharedMembersTest(L3IPv4EcmpLagTestHelper): """ IPv4 multiples ECMP with shared nexthop members """ def setUp(self): super(L3IPv4EcmpHostPortLagSharedMembersTest, self).setUp() def runTest(self): print("l3IPv4EcmpHostPortLagSharedMembersTest") src_mac = '00:01:01:01:01:01' # verify NG1 route pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst='10.10.10.1', ip_src='192.168.8.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:11:11:11:11', eth_src=ROUTER_MAC, ip_dst='10.10.10.1', ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:22:22:22:22:22', eth_src=ROUTER_MAC, ip_dst='10.10.10.1', ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt3 = simple_tcp_packet(eth_dst='00:33:33:33:33:33', eth_src=ROUTER_MAC, ip_dst='10.10.10.1', ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt4 = simple_tcp_packet(eth_dst='00:44:44:44:44:44', eth_src=ROUTER_MAC, ip_dst='10.10.10.1', ip_src='192.168.8.1', ip_id=106, ip_ttl=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port11, self.dev_port12, self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] verify_any_packet_any_port(self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) # verify NG2 traffic dst_ip = "20.20.1.21" pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst=dst_ip, ip_src='192.168.1.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:55:55:55:55:55', eth_src=ROUTER_MAC, ip_dst=dst_ip, ip_src='192.168.1.1', ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:66:66:66:66:66', eth_src=ROUTER_MAC, ip_dst=dst_ip, ip_src='192.168.1.1', ip_id=106, ip_ttl=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] verify_any_packet_any_port(self, [exp_pkt1, exp_pkt2], ports_to_verify) print("\nVerification done") def tearDown(self): super(L3IPv4EcmpHostPortLagSharedMembersTest, self).tearDown() class L3IPv4EcmpHostTwoLagsDisabledLagMembersTest(L3IPv4EcmpLagTestHelper): """ IPv4 ECMP tests with LAG RIF and some LAG member in disable state """ def setUp(self): super(L3IPv4EcmpHostTwoLagsDisabledLagMembersTest, self).setUp() def runTest(self): print("l3IPv4EcmpHostTwoLagsDisabledLagMembersTest") print("Disable LAG1 member 4 and 5") status = sai_thrift_set_lag_member_attribute( self.client, self.lag1_member4, egress_disable=True) self.assertEqual(status, SAI_STATUS_SUCCESS) status = sai_thrift_set_lag_member_attribute( self.client, self.lag1_member5, egress_disable=True) self.assertEqual(status, SAI_STATUS_SUCCESS) try: count = [0, 0, 0, 0, 0, 0] dst_ip = int(binascii.hexlify(socket.inet_aton('20.20.20.1')), 16) src_ip = int(binascii.hexlify(socket.inet_aton('192.168.8.1')), 16) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) src_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(src_ip)[2:].zfill(8))) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst=dst_ip_addr, ip_src=src_ip_addr, ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:55:55:55:55:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src=src_ip_addr, ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:66:66:66:66:66', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src=src_ip_addr, ip_id=106, ip_ttl=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2], ports_to_verify) count[rcv_idx] += 1 dst_ip += 1 src_ip += 1 print("PORT lb counts", count) ecmp_count = [(count[0] + count[1] + count[2]), (count[3] + count[4] + count[5])] # check LAG1 traffic self.assertTrue(count[0] == 0) # LAG1 member 1 port4 disabled self.assertTrue(count[1] == 0) # LAG1 member 2 port5 disabled self.assertTrue((count[2] >= ((MAX_ITRS / 2) * 0.6)), "Lag path1 is not equally balanced") print("ECMP count:", ecmp_count) for i in range(0, 2): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 2) * 0.75)), "Ecmp paths are not equally balanced") # check LAG2 traffic for i in range(3, 6): self.assertTrue((count[i] >= ((MAX_ITRS / 6) * 0.6)), "Lag path2 is not equally balanced") finally: print("Enable LAG1 member 4 and 5") status = sai_thrift_set_lag_member_attribute( self.client, self.lag1_member4, egress_disable=False) self.assertEqual(status, SAI_STATUS_SUCCESS) status = sai_thrift_set_lag_member_attribute( self.client, self.lag1_member5, egress_disable=False) self.assertEqual(status, SAI_STATUS_SUCCESS) def tearDown(self): super(L3IPv4EcmpHostTwoLagsDisabledLagMembersTest, self).tearDown() class L3IPv4EcmpHostPortLagTest(L3IPv4EcmpLagTestHelper): """ IPv4 ECMP load balance tests to check fair share on all members """ def setUp(self): super(L3IPv4EcmpHostPortLagTest, self).setUp() def runTest(self): print("l3IPv4EcmpHostPortLagTest") try: count = [0, 0, 0, 0, 0, 0, 0, 0] dst_ip = int(binascii.hexlify(socket.inet_aton('10.10.10.1')), 16) src_ip = int(binascii.hexlify(socket.inet_aton('192.168.8.1')), 16) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) src_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(src_ip)[2:].zfill(8))) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) src_mac = '00:22:22:22:00:00' pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst=dst_ip_addr, ip_src=src_ip_addr, ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:11:11:11:11', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src=src_ip_addr, ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:22:22:22:22:22', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src=src_ip_addr, ip_id=106, ip_ttl=63) exp_pkt3 = simple_tcp_packet(eth_dst='00:33:33:33:33:33', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src=src_ip_addr, ip_id=106, ip_ttl=63) exp_pkt4 = simple_tcp_packet(eth_dst='00:44:44:44:44:44', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src=src_ip_addr, ip_id=106, ip_ttl=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port11, self.dev_port12, self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) count[rcv_idx] += 1 dst_ip += 1 src_ip += 1 print("PORT lb counts", count) ecmp_count = [ count[0], count[1], (count[2] + count[3] + count[4]), (count[5] + count[6] + count[7])] print("ECMP count:", ecmp_count) for i in range(0, 4): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 4) * 0.5)), "Ecmp paths are not equally balanced") for i in range(2, 5): self.assertTrue((count[i] >= ((MAX_ITRS / 12) * 0.5)), "Lag path1 is not equally balanced") for i in range(5, 8): self.assertTrue((count[i] >= ((MAX_ITRS / 12) * 0.5)), "Lag path2 is not equally balanced") finally: pass def tearDown(self): super(L3IPv4EcmpHostPortLagTest, self).tearDown() class L3IPv4EcmpHashPortLagTest(L3IPv4EcmpLagTestHelper): """ Creates hash object and sends multiple packets Validates that there is no load balancing with various fields in ECMP hash """ def setUp(self): super(L3IPv4EcmpHashPortLagTest, self).setUp() def runTest(self): print("l3IPv4EcmpHashPortLagTest") # setup the ECMP hash to SRC IP print("Limit ECMP IPv4 hash to SRC_IP only.") # for our test it will disable LB. self.setupECMPIPv4Hash([SAI_NATIVE_HASH_FIELD_SRC_IP]) try: count = [0, 0, 0, 0, 0, 0, 0, 0] dst_ip = int(binascii.hexlify(socket.inet_aton('10.10.10.1')), 16) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) src_mac = '00:22:22:22:22:22' pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:11:11:11:11', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:22:22:22:22:22', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt3 = simple_tcp_packet(eth_dst='00:33:33:33:33:33', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt4 = simple_tcp_packet(eth_dst='00:44:44:44:44:44', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port11, self.dev_port12, self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) count[rcv_idx] += 1 dst_ip += 1 print("PORT lb counts:", count) ecmp_count = [ count[0], count[1], (count[2] + count[3] + count[4]), (count[5] + count[6] + count[7])] print("ECMP count:", ecmp_count) # Traffic should not be ballanced, should apear on single port or # LAG if ecmp_count[0] != 0: self.assertTrue(ecmp_count[0] == MAX_ITRS, "100% expected on this port") self.assertTrue(ecmp_count[1] == 0, "No traffic expected on this port") self.assertTrue(ecmp_count[2] == 0, "No traffic expected on this port") self.assertTrue(ecmp_count[3] == 0, "No traffic expected on this port") elif ecmp_count[1] != 0: self.assertTrue(ecmp_count[0] == 0, "No traffic expected on this port") self.assertTrue(ecmp_count[1] == MAX_ITRS, "100% expected on this port") self.assertTrue(ecmp_count[2] == 0, "No traffic expected on this port") self.assertTrue(ecmp_count[3] == 0, "No traffic expected on this port") elif ecmp_count[2] != 0: self.assertTrue(ecmp_count[0] == 0, "No traffic expected on this port") self.assertTrue(ecmp_count[1] == 0, "No traffic expected on this port") self.assertTrue(ecmp_count[2] == MAX_ITRS, "100% expected on this port") self.assertTrue(ecmp_count[3] == 0, "No traffic expected on this port") elif ecmp_count[3] != 0: self.assertTrue(ecmp_count[0] == 0, "No traffic expected on this port") self.assertTrue(ecmp_count[1] == 0, "No traffic expected on this port") self.assertTrue(ecmp_count[2] == 0, "No traffic expected on this port") self.assertTrue(ecmp_count[3] == MAX_ITRS, "100% expected on this port") # enable LB back to IPv4 full fields list print("Enable ECMP IPv4 LB") self.setupECMPIPv4Hash() count = [0, 0, 0, 0, 0, 0, 0, 0] dst_ip = int(binascii.hexlify(socket.inet_aton('10.10.10.1')), 16) src_mac_start = '00:22:22:22:{0}:{1}' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) src_mac = src_mac_start.format( str(i).zfill(4)[:2], str(i).zfill(4)[2:]) src_mac = '00:22:22:22:22:22' pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:11:11:11:11', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:22:22:22:22:22', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt3 = simple_tcp_packet(eth_dst='00:33:33:33:33:33', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt4 = simple_tcp_packet(eth_dst='00:44:44:44:44:44', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) send_packet(self, self.dev_port15, pkt) ports_to_verify = [ self.dev_port11, self.dev_port12, self.dev_port4, # LAG1 ports self.dev_port5, self.dev_port6, self.dev_port7, # LAG2 ports self.dev_port8, self.dev_port9 ] rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3, exp_pkt4], ports_to_verify) count[rcv_idx] += 1 dst_ip += 1 print("PORT lb counts:", count) ecmp_count = [ count[0], count[1], (count[2] + count[3] + count[4]), (count[5] + count[6] + count[7])] print("ECMP count:", ecmp_count) # Traffic should equally be ballanced, should apear on all port or # LAG for i in range(0, 4): self.assertTrue((ecmp_count[i] >= ((MAX_ITRS / 4) * 0.5)), "Ecmp paths are not equally balanced") finally: pass def tearDown(self): super(L3IPv4EcmpHashPortLagTest, self).tearDown() def setupECMPIPv4Hash(self, hash_field_list=None): """ Setups ECMP IPv4 hash Args: hash_field_list (list): list of hash fields """ print("Setting the ECMP IPv4 hash fields..") if hash_field_list is None: hash_field_list = [ SAI_NATIVE_HASH_FIELD_SRC_IP, SAI_NATIVE_HASH_FIELD_DST_IP, SAI_NATIVE_HASH_FIELD_IP_PROTOCOL, SAI_NATIVE_HASH_FIELD_L4_DST_PORT, SAI_NATIVE_HASH_FIELD_L4_SRC_PORT ] s32list = sai_thrift_s32_list_t( count=len(hash_field_list), int32list=hash_field_list) if self.ipv4_hash_id == 0: self.ipv4_hash_id = sai_thrift_create_hash( self.client, native_hash_field_list=s32list) else: status = sai_thrift_set_hash_attribute( self.client, self.ipv4_hash_id, native_hash_field_list=s32list) self.assertEqual(status, SAI_STATUS_SUCCESS) class EcmpFGTestHelper(PlatformSaiHelper): ''' ECMP Fine Grain Test cases ''' def setUp(self): super(EcmpFGTestHelper, self).setUp() print('') nhop_ip1 = '11.11.11.11' nhop_ip2 = '22.22.22.22' nhop_ip3 = '33.33.33.33' dmac1 = '00:11:22:33:44:55' dmac2 = '00:11:22:33:44:56' dmac3 = '00:11:22:33:44:57' # set switch src mac address sai_thrift_set_switch_attribute( self.client, src_mac_address=ROUTER_MAC) self.port14_rif = sai_thrift_create_router_interface( self.client, type=SAI_ROUTER_INTERFACE_TYPE_PORT, virtual_router_id=self.default_vrf, port_id=self.port14, admin_v4_state=True) # neighbor creation self.neighbor_entry11 = sai_thrift_neighbor_entry_t( self.switch_id, self.port11_rif, sai_ipaddress(nhop_ip1)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry11, dst_mac_address=dmac1) self.neighbor_entry12 = sai_thrift_neighbor_entry_t( self.switch_id, self.port12_rif, sai_ipaddress(nhop_ip2)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry12, dst_mac_address=dmac2) self.neighbor_entry13 = sai_thrift_neighbor_entry_t( self.switch_id, self.port13_rif, sai_ipaddress(nhop_ip3)) sai_thrift_create_neighbor_entry( self.client, self.neighbor_entry13, dst_mac_address=dmac3) # NH creation self.nhop1 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port11_rif, ip=sai_ipaddress(nhop_ip1)) self.nhop2 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port12_rif, ip=sai_ipaddress(nhop_ip2)) self.nhop3 = sai_thrift_create_next_hop( self.client, type=SAI_NEXT_HOP_TYPE_IP, router_interface_id=self.port13_rif, ip=sai_ipaddress(nhop_ip3)) # Create Fine Grained ECMP group self.nhop_group1 = sai_thrift_create_next_hop_group( self.client, type=SAI_NEXT_HOP_GROUP_TYPE_FINE_GRAIN_ECMP, configured_size=50) # Add members with index to FG Ecmp group self.nh_group_member1 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop1, index=0) self.nh_group_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop2, index=1) self.nh_group_member3 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop3, index=2) self.ecmp_members = [self.nh_group_member1, self.nh_group_member2, self.nh_group_member3] # create route entries self.route0 = sai_thrift_route_entry_t( switch_id=self.switch_id, destination=sai_ipprefix('10.10.10.1/16'), vr_id=self.default_vrf) self.assertTrue(self.route0 != 0) status = sai_thrift_create_route_entry( self.client, self.route0, next_hop_id=self.nhop_group1) self.assertEqual(status, SAI_STATUS_SUCCESS) def tearDown(self): sai_thrift_remove_next_hop_group_member( self.client, self.nh_group_member1) sai_thrift_remove_next_hop_group_member( self.client, self.nh_group_member2) sai_thrift_remove_next_hop_group_member( self.client, self.nh_group_member3) sai_thrift_remove_route_entry(self.client, self.route0) sai_thrift_remove_next_hop_group(self.client, self.nhop_group1) sai_thrift_remove_next_hop(self.client, self.nhop1) sai_thrift_remove_next_hop(self.client, self.nhop2) sai_thrift_remove_next_hop(self.client, self.nhop3) sai_thrift_remove_neighbor_entry( self.client, self.neighbor_entry11) sai_thrift_remove_neighbor_entry( self.client, self.neighbor_entry12) sai_thrift_remove_neighbor_entry( self.client, self.neighbor_entry13) sai_thrift_remove_router_interface(self.client, self.port14_rif) super(EcmpFGTestHelper, self).tearDown() def packetTest(self): ''' For sending traffic Returns: int: pkts count ''' print('Sending Traffic') count = [0, 0, 0] try: dst_ip = int(binascii.hexlify(socket.inet_aton('10.10.10.1')), 16) src_mac_start = '00:22:22:22:22:' for i in range(0, MAX_ITRS): dst_ip_addr = socket.inet_ntoa( binascii.unhexlify(hex(dst_ip)[2:].zfill(8))) src_mac = src_mac_start + str(i % 99).zfill(2) pkt = simple_tcp_packet(eth_dst=ROUTER_MAC, eth_src=src_mac, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=64) exp_pkt1 = simple_tcp_packet(eth_dst='00:11:22:33:44:55', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt2 = simple_tcp_packet(eth_dst='00:11:22:33:44:56', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) exp_pkt3 = simple_tcp_packet(eth_dst='00:11:22:33:44:57', eth_src=ROUTER_MAC, ip_dst=dst_ip_addr, ip_src='192.168.8.1', ip_id=106, ip_ttl=63) send_packet(self, self.dev_port14, pkt) rcv_idx = verify_any_packet_any_port( self, [exp_pkt1, exp_pkt2, exp_pkt3], [self.dev_port11, self.dev_port12, self.dev_port13]) count[rcv_idx] += 1 dst_ip += 1 return count finally: pass class ecmpFGBasicTest(EcmpFGTestHelper): ''' Ecmp FG Basic TCs ''' def setUp(self): super(ecmpFGBasicTest, self).setUp() @warm_test(is_test_rebooting=True) def runTest(self): print('ecmpFGBasicTest1') attr = sai_thrift_get_next_hop_group_attribute(self.client, self.nhop_group1, configured_size=True) nhop_grp_conf_size = attr["SAI_NEXT_HOP_GROUP_ATTR_CONFIGURED_SIZE"] print('FG ECMP group --> Configured Size: %u' % nhop_grp_conf_size) self.assertTrue((nhop_grp_conf_size == 50), 'Configured size is %u, expected size should be 50' % nhop_grp_conf_size) attr = sai_thrift_get_next_hop_group_attribute(self.client, self.nhop_group1, real_size=True) nhop_grp_real_size = attr["SAI_NEXT_HOP_GROUP_ATTR_REAL_SIZE"] print('FG ECMP group --> Real Size: %u' % nhop_grp_real_size) self.assertTrue((nhop_grp_real_size > 0), 'Real size is %u, expected size should be > 0' % nhop_grp_real_size) try: count = self.packetTest() print('Traffic distribution [port11, port12, port13] --> %s' % count) for i in range(0, 3): self.assertTrue((count[i] >= ((MAX_ITRS / 3) * 0.8)), 'Not all paths are equally balanced, %s' % count) finally: pass def tearDown(self): super(ecmpFGBasicTest, self).tearDown() class ecmpFGAddDelMemTest(EcmpFGTestHelper): ''' Ecmp FG Add & Del member TCs ''' def setUp(self): super(ecmpFGAddDelMemTest, self).setUp() @warm_test(is_test_rebooting=True) def runTest(self): print('ecmpFGAddDelMemTest') try: count = self.packetTest() print('Traffic distribution [port11, port12, port13] --> %s' % count) print('Removing nexthop2 at Member Index 1, port12') sai_thrift_remove_next_hop_group_member(self.client, self.nh_group_member2) count = self.packetTest() print('Traffic dist after change [port11, port12, port13] -> %s' % count) self.assertTrue((count[1] == 0), 'Pkts are still fwds to port12,%s' % count) print('Re-Inserting member nexthop2 back at Member Index 1') self.nh_group_member2 = sai_thrift_create_next_hop_group_member( self.client, next_hop_group_id=self.nhop_group1, next_hop_id=self.nhop2, index=1) count = self.packetTest() print('Traffic distribution now [port11, port12, port13] --> %s' % count) finally: pass def tearDown(self): super(ecmpFGAddDelMemTest, self).tearDown() class ecmpFGGrpMemAttrTest(EcmpFGTestHelper): ''' Ecmp FG Member Attribure TCs ''' def setUp(self): super(ecmpFGGrpMemAttrTest, self).setUp() def runTest(self): print('ecmpFGGrpMemAttrTest') try: print('Assigning Nexthop2 to an Ecmp Grp Member') sai_thrift_set_next_hop_group_member_attribute( self.client, self.nhop_group1, next_hop_id=self.nhop2) attr_list = sai_thrift_get_next_hop_group_member_attribute( self.client, self.nh_group_member2, next_hop_group_id=True, next_hop_id=True, index=True) self.assertEqual( attr_list["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID"], self.nhop_group1) self.assertEqual( attr_list["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID"], self.nhop2) self.assertEqual( attr_list["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_INDEX"], 1) count = self.packetTest() print('Traffic flow - [port11, port12, port13] --> %s' % count) print('Assigning Nexthop1 to an Ecmp Grp Member') sai_thrift_set_next_hop_group_member_attribute( self.client, self.nhop_group1, next_hop_id=self.nhop1) attr_list = sai_thrift_get_next_hop_group_member_attribute( self.client, self.nh_group_member1, next_hop_group_id=True, next_hop_id=True, index=True) self.assertEqual( attr_list["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID"], self.nhop_group1) self.assertEqual( attr_list["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID"], self.nhop1) self.assertEqual( attr_list["SAI_NEXT_HOP_GROUP_MEMBER_ATTR_INDEX"], 0) count = self.packetTest() print('Traffic flow - [port11, port12, port13] --> %s' % count) finally: pass def tearDown(self): super(ecmpFGGrpMemAttrTest, self).tearDown()