def do_task(ctl, hosts, ifaces, aliases): m1, sw, m2 = hosts m1_if1, sw_if1, sw_if2, sw_if3, m2_if1, m2_if2, m2_if3, m3_if1 = ifaces ecmp_sw_ifaces = [sw_if2, sw_if3] ecmp_m_ifaces = [m2_if1, m2_if2] m2.config("/proc/sys/net/ipv4/ip_forward", "1") m2.config("/proc/sys/net/ipv6/conf/all/forwarding", "1") ecmp_common.create_topology(m1_if1, sw_if1, ecmp_sw_ifaces, ecmp_m_ifaces, m2_if3, m3_if1, num_nexthops=MAX_NEXTHOPS) tl = TestLib(ctl, aliases) tl.wait_for_if(ifaces) tl.ping_simple(m1_if1, m3_if1) tl.netperf_udp(m1_if1, m3_if1) ecmp_common.test_traffic(tl, m1_if1, m3_if1, sw_if1, ecmp_sw_ifaces) routes_filter = "to match %s" % m3_if1.get_ip() dc_routes, nh_routes = sw.get_routes(routes_filter=routes_filter) if len(nh_routes) != 1: tl.custom(sw, "route", "could not find the ecmp route") for nh in nh_routes[0]["nexthops"]: if "offload" not in nh["flags"]: tl.custom(sw, "route", "ecmp route is not offloaded")
def do_task(ctl, hosts, ifaces, aliases): """ This test deffines MAX_ROUTES number of routes on the switch with different 32bit prefixes in the range 192.168.[10..].[1..254] and redirects them to a nexthop on machine2. The test than checks that: - All routes has the offloaded flag - Traffic destined to each of the route prefixes did end up on machine2, as the route specifies """ m1, sw, m2 = hosts m1_if1, sw_if1, sw_if2, m2_if1 = ifaces m1_if1.reset(ip=test_ip(1, 1)) sw_if1.reset(ip=test_ip(1, 2)) sw_if2.reset(ip=test_ip(2, 2)) m2_if1.reset(ip=test_ip(2, 3)) for route_index in range(ROUTES_COUNT): route_major = get_route_major(route_index) route_minor = get_route_minor(route_index) sw_if1.add_nhs_route(ipv4(test_ip(route_major, route_minor, [])), [ipv4(test_ip(2, 3, []))]) sleep(30) tl = TestLib(ctl, aliases) # check that there are ROUTES_COUNT offloaded routes dc_routes, nh_routes = sw.get_routes() offloaded_routes_num = 0 for nh_route in nh_routes: if "offload" in nh_route["flags"]: offloaded_routes_num += 1 if offloaded_routes_num < ROUTES_COUNT: tl.custom( sw, "route", "Only %d out of %d routes offloaded" % (offloaded_routes_num, ROUTES_COUNT)) # run traffic, and validate that each route will be hit sleep(2) before_stats = m2_if1.link_stats()["rx_packets"] total_sent = 0 for major in get_all_route_majors(): total_sent += traffic_route_major(tl, major, m1_if1, m2_if1, sw_if1) sleep(2) after_stats = m2_if1.link_stats()["rx_packets"] recieved = after_stats - before_stats # validate that all traffic went according to the routes thresh = total_sent * 0.95 if recieved < thresh: tl.custom(sw, "route", "Recieved %d out of %d packets" % (recieved, thresh))
def do_task(ctl, hosts, ifaces, aliases): """ This test deffines MAX_ROUTES number of routes on the switch with different 32bit prefixes in the range 192.168.[10..].[1..254] and redirects them to a nexthop on machine2. The test than checks that: - All routes has the offloaded flag - Traffic destined to each of the route prefixes did end up on machine2, as the route specifies """ m1, sw, m2 = hosts m1_if1, sw_if1, sw_if2, m2_if1 = ifaces m1_if1.reset(ip=test_ip(1, 1)) sw_if1.reset(ip=test_ip(1, 2)) sw_if2.reset(ip=test_ip(2, 2)) m2_if1.reset(ip=test_ip(2, 3)) for route_index in range(ROUTES_COUNT): route_major = get_route_major(route_index) route_minor = get_route_minor(route_index) sw_if1.add_nhs_route(ipv4(test_ip(route_major, route_minor, [])), [ipv4(test_ip(2, 3, []))]) sleep(30) tl = TestLib(ctl, aliases) # check that there are ROUTES_COUNT offloaded routes dc_routes, nh_routes = sw.get_routes() offloaded_routes_num = 0 for nh_route in nh_routes: if "offload" in nh_route["nexthops"][0]["flags"]: offloaded_routes_num += 1 if offloaded_routes_num < ROUTES_COUNT: tl.custom(sw, "route", "Only %d out of %d routes offloaded" % (offloaded_routes_num, ROUTES_COUNT)) # run traffic, and validate that each route will be hit sleep(2) before_stats = m2_if1.link_stats()["rx_packets"] total_sent = 0 for major in get_all_route_majors(): total_sent += traffic_route_major(tl, major, m1_if1, m2_if1, sw_if1) sleep(2) after_stats = m2_if1.link_stats()["rx_packets"] recieved = after_stats - before_stats # validate that all traffic went according to the routes thresh = total_sent * 0.95 if recieved < thresh: tl.custom(sw, "route", "Recieved %d out of %d packets" % (recieved, thresh))
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces tl = TestLib(ctl, aliases) red_test = RedTestLib(tl, sw, {sw_if1: m1_if1, sw_if2: m2_if1}) red_test.create_bottleneck(aliases) sleep(30) try: run_actual_test(red_test) except Exception as e: logging.error("Test run failed") tl.custom(sw, "Basic RED test", "Failed because of %s" % e)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces vrf_None = None tl = TestLib(ctl, aliases) # Test that offloaded routes do have "offload" flag. with dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d: with gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_None, 2, g, ip=ipv4), \ encap_route(sw, vrf_None, 2, g, ip=ipv6): sleep(15) ulip = test_ip(2, 0, [24, 64]) (r4,), _ = sw.get_routes("table 0 %s" % ipv4(ulip)) if "offload" not in r4["flags"]: tl.custom(sw, "ipip", "IPv4 encap route not offloaded") (r6,), _ = sw.get_routes("table 0 %s" % ipv6(ulip)) if "offload" not in r6["flags"]: tl.custom(sw, "ipip", "IPv6 encap route not offloaded") (dcr4,), _ = sw.get_routes("table local 1.2.3.4") if "offload" not in dcr4["flags"]: tl.custom(sw, "ipip", "IPv4 decap route not offloaded") sleep(5) (dcr4,), _ = sw.get_routes("table local 1.2.3.4") if "offload" in dcr4["flags"]: tl.custom(sw, "ipip", "IPv4 decap still flagged offloaded")
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces vrf_None = None tl = TestLib(ctl, aliases) # Test that offloaded routes do have "offload" flag. with dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d: with gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_None, 2, g, ip=ipv4), \ encap_route(sw, vrf_None, 2, g, ip=ipv6): sleep(30) ulip = onet2_ip(ctl, 0, [24, 64]) (r4,), _ = sw.get_routes("table 0 %s" % ipv4(ulip)) if "offload" not in r4["flags"]: tl.custom(sw, "ipip", "IPv4 encap route not offloaded") (r6,), _ = sw.get_routes("table 0 %s" % ipv6(ulip)) if "offload" not in r6["flags"]: tl.custom(sw, "ipip", "IPv6 encap route not offloaded") (dcr4,), _ = sw.get_routes("table local 1.2.3.4") if "offload" not in dcr4["flags"]: tl.custom(sw, "ipip", "IPv4 decap route not offloaded") sleep(5) (dcr4,), _ = sw.get_routes("table local 1.2.3.4") if "offload" in dcr4["flags"]: tl.custom(sw, "ipip", "IPv4 decap still flagged offloaded")
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces m1_if1.add_nhs_route(ipv4(test_ip(2, 0)), [ipv4(test_ip(1, 1, []))]) m2_if1.add_nhs_route("1.2.3.4/32", [ipv4(test_ip(99, 1, []))]) vrf_None = None tl = TestLib(ctl, aliases) sw_if1.reset(ip=test_ip(1, 2)) sw_if2.reset(ip=test_ip(99, 1)) # Test that non-IPIP traffic gets to slow path. with dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d, \ gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_None, 2, g, ip=ipv4): sleep(15) ping_test(tl, m2, sw, "1.2.3.4", m2_if1, g, count=20) # Configure the wrong interface on M2 to test that the traffic gets trapped # to CPU. with encap_route(m2, vrf_None, 1, "gre3"): add_forward_route(sw, vrf_None, "1.2.3.5") with dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d, \ gre(sw, None, vrf_None, local_ip="1.2.3.4", remote_ip="1.2.3.5") as g: sleep(15) before_stats = sw_if2.link_stats()["rx_packets"] ping_test(tl, m2, sw, ipv4(test_ip(1, 33, [])), m2_if1, g, count=20, fail_expected=True) after_stats = sw_if2.link_stats()["rx_packets"] delta = after_stats - before_stats if delta < 15: tl.custom(sw, "ipip", "Too few packets (%d) observed in slow path" % delta)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces m1_if1.reset(ip=["192.168.101.10/24", "2002::1/64"]) m2_if1.reset(ip=["192.168.101.11/24", "2002::2/64"]) tl = TestLib(ctl, aliases) red_test = RedTestLib(tl, sw, {sw_if1: m1_if1, sw_if2: m2_if1}) red_test.create_bottleneck(aliases) sleep(30) try: run_actual_test(red_test) except Exception as e: logging.error("Test run failed") tl.custom(sw, "Basic RED-ECN test", "Failed because of %s" % e)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces m1_if1.add_nhs_route(ipv4(test_ip(2, 0)), [ipv4(test_ip(1, 1, []))]) m2_if1.add_nhs_route("1.2.3.4/32", [ipv4(test_ip(99, 1, []))]) vrf_None = None tl = TestLib(ctl, aliases) # Test that non-IPIP traffic gets to slow path. with dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d, \ gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_None, 2, g, ip=ipv4): sleep(15) ping_test(tl, m2, sw, "1.2.3.4", m2_if1, g, count=20) # Configure the wrong interface on M2 to test that the traffic gets trapped # to CPU. with encap_route(m2, vrf_None, 1, "gre3"): add_forward_route(sw, vrf_None, "1.2.3.5") with dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d, \ gre(sw, None, vrf_None, local_ip="1.2.3.4", remote_ip="1.2.3.5") as g: sleep(15) before_stats = sw_if2.link_stats()["rx_packets"] ping_test(tl, m2, sw, ipv4(test_ip(1, 33, [])), m2_if1, g, count=20, fail_expected=True) after_stats = sw_if2.link_stats()["rx_packets"] delta = after_stats - before_stats if delta < 15: tl.custom(sw, "ipip", "Too few packets (%d) observed in slow path" % delta)
def do_task(ctl, hosts, native_ifaces, construct_ifaces, aliases): m1, m2, sw = hosts tl = TestLib(ctl, aliases) for iface in construct_ifaces: desc = "RED setting on %s without offloading" % iface.get_devname() msg = "" iface.set_qdisc_red(10**6, 10**3, 3*10**3, 3*10**4) red_stats = iface.qdisc_red_stats() if red_stats == {}: msg = "Setting RED on %s failed" % iface.get_devname() elif red_stats["offload"]: msg = "RED on %s appears as offloaded" % iface.get_devname() tl.custom(sw, desc, msg) for iface in native_ifaces: desc = "RED setting on %s with offloading" % iface.get_devname() msg = "" iface.set_qdisc_red(10**6, 10**3, 3*10**3, 3*10**4) red_stats = iface.qdisc_red_stats() if red_stats == {}: msg = "Setting RED on %s failed" % iface.get_devname() elif not red_stats["offload"]: msg = "RED on %s appears as offloaded" % iface.get_devname() tl.custom(sw, desc, msg) if1 = native_ifaces[0] desc = "RED setting with too high max (%d)" % (5*10**7) msg = "" iface.set_qdisc_red(10**8, 10**3, 10**7, 5*10**7, change = True, burst = 10**4) red_stats = iface.qdisc_red_stats() if red_stats == {}: msg = "Setting RED on %s with very high max failed" % \ iface.get_devname() elif red_stats["offload"]: msg = "RED on %s appears as offloaded even though max is not " \ "possible" % iface.get_devname() tl.custom(sw, desc, msg) desc = "RED re-setting with legal max" msg = "" iface.set_qdisc_red(10**7, 10**3, 2*10**6, 3*10**6, change = True, burst = 2*10**3) red_stats = iface.qdisc_red_stats() if red_stats == {}: msg = "Setting RED on %s with legal max failed" % iface.get_devname() elif not red_stats["offload"]: msg = "RED on %s appears as not offloaded even though max is legal" % \ iface.get_devname() tl.custom(sw, desc, msg)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces m1_if1.reset(ip=["192.168.101.10/24", "2002::1/64"]) m2_if1.reset(ip=["192.168.101.11/24", "2002::2/64"]) # For ETS to take effect we need to create congestion in the # egress port, so change ports' speeds accordingly. sw_if1.set_speed(int(aliases["speed_hi"])) sw_if2.set_speed(int(aliases["speed_lo"])) sleep(30) sw.create_bridge(slaves=[sw_if1, sw_if2], options={"vlan_filtering": 1}) sw_if1.add_br_vlan(10) sw_if2.add_br_vlan(10) tl = TestLib(ctl, aliases) # Hosts should be set to default values. m1.enable_service("lldpad") m1_if1.enable_lldp() tl.lldp_ets_default_set(m1_if1) tl.lldp_pfc_set(m1_if1, prio=[]) m2.enable_service("lldpad") m2_if1.enable_lldp() tl.lldp_ets_default_set(m2_if1) tl.lldp_pfc_set(m2_if1, prio=[]) # Get two different random priorities that will represent both # competing flows. p1 = randint(1, 7) p2 = 7 - p1 # And two random weights for the ETS algorithm. bw1 = randint(0, 100) bw2 = 100 - bw1 sw.enable_service("lldpad") # Configure the egress port using chosen values. sw_if2.enable_lldp() tl.lldp_ets_default_set(sw_if2, willing=False) tl.lldp_ets_up2tc_set(sw_if2, [(p1, p1), (p2, p2)]) tl.lldp_ets_tsa_set(sw_if2, [(p1, "ets"), (p2, "ets")], [(p1, bw1), (p2, bw2)]) tl.lldp_pfc_set(sw_if1, prio=[], willing=False) # Make sure the flows are also separated at ingress. sw_if1.enable_lldp() tl.lldp_ets_default_set(sw_if1, willing=False) tl.lldp_ets_up2tc_set(sw_if1, [(p1, p1), (p2, p2)]) tl.lldp_pfc_set(sw_if1, prio=[], willing=False) # ETS won't work if there aren't enough packets in the shared buffer # awaiting transmission. Therefore, let each port take up to ~98% of # free buffer in the pool and each PG/TC up to 50%. We assume pools # 0 and 4 are configured with non-zero sizes. tl.devlink_pool_thtype_set(sw, sw_if1.get_devlink_name(), 0, False) tl.devlink_port_tc_quota_set(sw_if1, p1, True, 0, 10) tl.devlink_port_tc_quota_set(sw_if1, p2, True, 0, 10) tl.devlink_port_quota_set(sw_if1, 0, 16) tl.devlink_pool_thtype_set(sw, sw_if1.get_devlink_name(), 4, False) tl.devlink_port_tc_quota_set(sw_if2, p1, False, 4, 10) tl.devlink_port_tc_quota_set(sw_if2, p2, False, 4, 10) tl.devlink_port_quota_set(sw_if2, 4, 16) tl.ping_simple(m1_if1, m2_if1) # Record the stats before the test for comparison. tx_stats_p1_t0 = tl.get_tx_prio_stats(sw_if2, p1) tx_stats_p2_t0 = tl.get_tx_prio_stats(sw_if2, p2) # Transmit each flow using as many threads as possible, thereby # making sure the egress port is congested. Otherwise, ETS won't # take effect. num_cpus = m1.get_num_cpus() packet_count = 10 * 10 ** 6 thread_option = ["vlan_p {}".format(p1)] * (num_cpus / 2) thread_option += ["vlan_p {}".format(p2)] * (num_cpus / 2) tl.pktgen(m1_if1, m2_if1, m1_if1.get_mtu(), thread_option=thread_option, vlan_id=10, count=packet_count, flag="QUEUE_MAP_CPU") # Record the stats after the test and check if ETS worked as # expected. tx_stats_p1_t1 = tl.get_tx_prio_stats(sw_if2, p1) tx_stats_p2_t1 = tl.get_tx_prio_stats(sw_if2, p2) p1_count = tx_stats_p1_t1 - tx_stats_p1_t0 p2_count = tx_stats_p2_t1 - tx_stats_p2_t0 total = p1_count + p2_count bw1_oper = p1_count / float(total) * 100 bw2_oper = p2_count / float(total) * 100 # Log useful information. logging.info("p1_count={} p2_count={}".format(p1_count, p2_count)) bw_str = "bw1_oper={:.2f}% ({}%) bw2_oper={:.2f}% ({}%)".format(bw1_oper, bw1, bw2_oper, bw2) logging.info(bw_str) # The 802.1Qaz standard states a deviation of no more than 10%. if abs(bw1_oper - bw1) < 10 and abs(bw2_oper - bw2) < 10: err_msg = "" else: err_msg = "bandwidth deviation exceeded 10%" tl.custom(sw, "ets test", err_msg)
def do_task(ctl, hosts, ifaces, bridges, aliases): m1, m2, sw = hosts m1_if, m2_if, m3_if, m4_if, sw_if1, sw_if2, sw_if3, sw_if4 = ifaces peers = {m1_if: sw_if1, m2_if: sw_if2, m3_if: sw_if3, m4_if: sw_if4} for bridge in bridges: bridge.set_br_mcast_snooping(False) # Create a bridge sw_ports = peers.values() sw_br = sw.create_bridge(slaves=sw_ports, options={ "vlan_filtering": 1, "multicast_querier": 1 }) sw_br.set_br_mcast_hash_max(8192) sw_br.set_br_mcast_hash_elasticity(16) m1_if.set_addresses(test_ip(1, 1)) m2_if.set_addresses(test_ip(1, 2)) m3_if.set_addresses(test_ip(1, 3)) m4_if.set_addresses(test_ip(1, 4)) for iface in [m1_if, m2_if, m3_if, m4_if]: iface.enable_multicast() tl = TestLib(ctl, aliases) tl.wait_for_if(ifaces) tl.check_cpu_traffic(sw_ports, test=False) used_mdb = max(8, sw_br.show_br_mdb().count("offload") + 2) max_mdb = int(aliases["max_mdb"]) - used_mdb bridged = [m2_if, m3_if, m4_if] logging.info("Add %d mdb entries" % max_mdb) for i in range(max_mdb): group = mcgrp(i) listeners = get_listeners(i, bridged) for l in listeners: sw_br.add_br_mdb(str(peers[l].get_devname()), group, permanent=True) mdb_str = sw_br.show_br_mdb() msg = "" logging.info("Check mdb entries are offloaded") pattern = "(?:dev)?\s*?%s (?:port)?\s*? (\S+)\s+(?:grp)?\s*?(\S+) \s*permanent\s* offload" % ( str(sw_br.get_devname())) p = re.compile(pattern) mdb_pairs = p.findall(mdb_str) for i in range(max_mdb): group = mcgrp(i) listeners = get_listeners(i, bridged) for l in listeners: if not (str(peers[l].get_devname()), group) in mdb_pairs: msg = "mdb entry %d: group %s port %s was not offloaded" % ( i, group, str(peers[l].get_devname())) break if msg: break tl.custom(sw, "Check mdb was offloaded", msg) for _ in range(5): logging.info("Check random group %s" % group) i = random.randint(0, max_mdb - 1) group = mcgrp(i) listeners = get_listeners(i, bridged) res = tl.iperf_mc(m1_if, bridged, group) expected = [i in listeners for i in bridged] tl.mc_ipref_compare_result(bridged, res, expected) logging.info("Del mdb entries") for i in range(max_mdb): group = mcgrp(i) listeners = get_listeners(i, bridged) for l in listeners: sw_br.del_br_mdb(str(peers[l].get_devname()), group, permanent=True) for _ in range(5): i = random.randint(0, max_mdb - 1) group = mcgrp(i) logging.info("Check random group %s" % group) res = tl.iperf_mc(m1_if, bridged, group) expected = [False for i in bridged] tl.mc_ipref_compare_result(bridged, res, expected) for iface in [m1_if, m2_if, m3_if, m4_if]: iface.disable_multicast() tl.check_cpu_traffic(sw_ports)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces m1_if1.reset(ip=["192.168.101.10/24", "2002::1/64"]) m2_if1.reset(ip=["192.168.101.11/24", "2002::2/64"]) # For ETS to take effect we need to create congestion in the # egress port, so change ports' speeds accordingly. sw_if1.set_speed(int(aliases["speed_hi"])) sw_if2.set_speed(int(aliases["speed_lo"])) sleep(30) sw.create_bridge(slaves=[sw_if1, sw_if2], options={"vlan_filtering": 1}) sw_if1.add_br_vlan(10) sw_if2.add_br_vlan(10) tl = TestLib(ctl, aliases) # Hosts should be set to default values. m1.enable_service("lldpad") m1_if1.enable_lldp() tl.lldp_ets_default_set(m1_if1) tl.lldp_pfc_set(m1_if1, prio=[]) m2.enable_service("lldpad") m2_if1.enable_lldp() tl.lldp_ets_default_set(m2_if1) tl.lldp_pfc_set(m2_if1, prio=[]) # Get two different random priorities that will represent both # competing flows. p1 = randint(1, 7) p2 = 7 - p1 # And two random weights for the ETS algorithm. bw1 = randint(0, 100) bw2 = 100 - bw1 sw.enable_service("lldpad") # Configure the egress port using chosen values. sw_if2.enable_lldp() tl.lldp_ets_default_set(sw_if2, willing=False) tl.lldp_ets_up2tc_set(sw_if2, [(p1, p1), (p2, p2)]) tl.lldp_ets_tsa_set(sw_if2, [(p1, "ets"), (p2, "ets")], [(p1, bw1), (p2, bw2)]) tl.lldp_pfc_set(sw_if2, prio=[], willing=False) # Make sure the flows are also separated at ingress. sw_if1.enable_lldp() tl.lldp_ets_default_set(sw_if1, willing=False) tl.lldp_ets_up2tc_set(sw_if1, [(p1, p1), (p2, p2)]) tl.lldp_pfc_set(sw_if1, prio=[], willing=False) # ETS won't work if there aren't enough packets in the shared buffer # awaiting transmission. Therefore, let each port take up to ~98% of # free buffer in the pool and each PG/TC up to 50%. We assume pools # 0 and 4 are configured with non-zero sizes. tl.devlink_pool_thtype_set(sw, sw_if1.get_devlink_name(), 0, False) tl.devlink_port_tc_quota_set(sw_if1, p1, True, 0, 10) tl.devlink_port_tc_quota_set(sw_if1, p2, True, 0, 10) tl.devlink_port_quota_set(sw_if1, 0, 16) tl.devlink_pool_thtype_set(sw, sw_if1.get_devlink_name(), 4, False) tl.devlink_port_tc_quota_set(sw_if2, p1, False, 4, 10) tl.devlink_port_tc_quota_set(sw_if2, p2, False, 4, 10) tl.devlink_port_quota_set(sw_if2, 4, 16) tl.ping_simple(m1_if1, m2_if1) # Record the stats before the test for comparison. tx_stats_p1_t0 = tl.get_tx_prio_stats(sw_if2, p1) tx_stats_p2_t0 = tl.get_tx_prio_stats(sw_if2, p2) # Transmit each flow using as many threads as possible, thereby # making sure the egress port is congested. Otherwise, ETS won't # take effect. num_cpus = m1.get_num_cpus() packet_count = 10 * 10**6 thread_option = ["vlan_p {}".format(p1)] * (num_cpus / 2) thread_option += ["vlan_p {}".format(p2)] * (num_cpus / 2) tl.pktgen(m1_if1, m2_if1, m1_if1.get_mtu(), thread_option=thread_option, vlan_id=10, count=packet_count, flag="QUEUE_MAP_CPU") # Record the stats after the test and check if ETS worked as # expected. tx_stats_p1_t1 = tl.get_tx_prio_stats(sw_if2, p1) tx_stats_p2_t1 = tl.get_tx_prio_stats(sw_if2, p2) p1_count = tx_stats_p1_t1 - tx_stats_p1_t0 p2_count = tx_stats_p2_t1 - tx_stats_p2_t0 total = p1_count + p2_count bw1_oper = p1_count / float(total) * 100 bw2_oper = p2_count / float(total) * 100 # Log useful information. logging.info("p1_count={} p2_count={}".format(p1_count, p2_count)) bw_str = "bw1_oper={:.2f}% ({}%) bw2_oper={:.2f}% ({}%)".format( bw1_oper, bw1, bw2_oper, bw2) logging.info(bw_str) # The 802.1Qaz standard states a deviation of no more than 10%. if abs(bw1_oper - bw1) < 10 and abs(bw2_oper - bw2) < 10: err_msg = "" else: err_msg = "bandwidth deviation exceeded 10%" tl.custom(sw, "ets test", err_msg)