def run(test, params, env): """ Test the RX jumbo frame function of vnics: 1) Boot the VM. 2) Change the MTU of guest nics and host taps depending on the NIC model. 3) Add the static ARP entry for guest NIC. 4) Wait for the MTU ok. 5) Verify the path MTU using ping. 6) Ping the guest with large frames. 7) Increment size ping. 8) Flood ping the guest with large frames. 9) Verify the path MTU. 10) Recover the MTU. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_ovs_ports(ovs): ''' get the ovs bridge all Interface list. :param ovs: Ovs bridge name ''' cmd = "ovs-vsctl list-ports %s" % ovs return process.getoutput(cmd, shell=True) netdst = params.get("netdst", "switch") host_bridges = utils_net.find_bridge_manager(netdst) if not isinstance(host_bridges, utils_net.Bridge): ovs = host_bridges host_hw_interface = get_ovs_ports(netdst) tmp_ports = re.findall(r"t[0-9]{1,}-[a-zA-Z0-9]{6}", host_hw_interface) if tmp_ports: for p in tmp_ports: process.system_output("ovs-vsctl del-port %s %s" % (netdst, p)) params["start_vm"] = "yes" env_process.preprocess_vm(test, params, env, params["main_vm"]) timeout = int(params.get("login_timeout", 360)) mtu_default = 1500 mtu = params.get("mtu", "1500") def_max_icmp_size = int(mtu) - 28 max_icmp_pkt_size = int(params.get("max_icmp_pkt_size", def_max_icmp_size)) flood_time = params.get("flood_time", "300") os_type = params.get("os_type") os_variant = params.get("os_variant") vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) session_serial = vm.wait_for_serial_login(timeout=timeout) ifname = vm.get_ifname(0) guest_ip = vm.get_address(0) if guest_ip is None: test.error("Could not get the guest ip address") host_mtu_cmd = "ifconfig %s mtu %s" if not isinstance(host_bridges, utils_net.Bridge): target_ifaces = set(get_ovs_ports(netdst).splitlines()) else: br_in_use = host_bridges.list_br() ifaces_in_use = host_bridges.list_iface() target_ifaces = set(ifaces_in_use) - set(br_in_use) error_context.context("Change all Bridge NICs MTU to %s" % mtu, logging.info) for iface in target_ifaces: process.run(host_mtu_cmd % (iface, mtu), shell=True) try: error_context.context("Changing the MTU of guest", logging.info) # Environment preparation mac = vm.get_mac_address(0) if os_type == "linux": ethname = utils_net.get_linux_ifname(session, mac) guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname, mtu) else: connection_id = utils_net.get_windows_nic_attribute( session, "macaddress", mac, "netconnectionid") index = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "index") if os_variant == "winxp": pnpdevice_id = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "pnpdeviceid") cd_num = utils_misc.get_winutils_vol(session) copy_cmd = r"xcopy %s:\devcon\wxp_x86\devcon.exe c:\ " % cd_num session.cmd(copy_cmd) reg_set_mtu_pattern = params.get("reg_mtu_cmd") mtu_key_word = params.get("mtu_key", "MTU") reg_set_mtu = reg_set_mtu_pattern % (int(index), mtu_key_word, int(mtu)) guest_mtu_cmd = "%s " % reg_set_mtu session.cmd(guest_mtu_cmd) if os_type == "windows": mode = "netsh" if os_variant == "winxp": connection_id = pnpdevice_id.split("&")[-1] mode = "devcon" utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) error_context.context("Chaning the MTU of host tap ...", logging.info) host_mtu_cmd = "ifconfig %s mtu %s" # Before change macvtap mtu, must set the base interface mtu if params.get("nettype") == "macvtap": base_if = utils_net.get_macvtap_base_iface(params.get("netdst")) process.run(host_mtu_cmd % (base_if, mtu), shell=True) process.run(host_mtu_cmd % (ifname, mtu), shell=True) error_context.context("Add a temporary static ARP entry ...", logging.info) arp_add_cmd = "arp -s %s %s -i %s" % (guest_ip, mac, ifname) process.run(arp_add_cmd, shell=True) def is_mtu_ok(): status, _ = utils_test.ping(guest_ip, 1, packetsize=max_icmp_pkt_size, hint="do", timeout=2) return status == 0 def verify_mtu(): logging.info("Verify the path MTU") status, output = utils_test.ping(guest_ip, 10, packetsize=max_icmp_pkt_size, hint="do", timeout=15) if status != 0: logging.error(output) test.fail("Path MTU is not as expected") if utils_test.get_loss_ratio(output) != 0: logging.error(output) test.fail("Packet loss ratio during MTU " "verification is not zero") def flood_ping(): logging.info("Flood with large frames") utils_test.ping(guest_ip, packetsize=max_icmp_pkt_size, flood=True, timeout=float(flood_time)) def large_frame_ping(count=100): logging.info("Large frame ping") _, output = utils_test.ping(guest_ip, count, packetsize=max_icmp_pkt_size, timeout=float(count) * 2) ratio = utils_test.get_loss_ratio(output) if ratio != 0: test.fail("Loss ratio of large frame ping is %s" % ratio) def size_increase_ping(step=random.randrange(90, 110)): logging.info("Size increase ping") for size in range(0, max_icmp_pkt_size + 1, step): logging.info("Ping %s with size %s", guest_ip, size) status, output = utils_test.ping(guest_ip, 1, packetsize=size, hint="do", timeout=1) if status != 0: status, output = utils_test.ping(guest_ip, 10, packetsize=size, adaptive=True, hint="do", timeout=20) fail_ratio = int(params.get("fail_ratio", 50)) if utils_test.get_loss_ratio(output) > fail_ratio: test.fail("Ping loss ratio is greater " "than 50% for size %s" % size) logging.info("Waiting for the MTU to be OK") wait_mtu_ok = 10 if not utils_misc.wait_for(is_mtu_ok, wait_mtu_ok, 0, 1): logging.debug( process.getoutput("ifconfig -a", verbose=False, ignore_status=True, shell=True)) test.error("MTU is not as expected even after %s " "seconds" % wait_mtu_ok) # Functional Test error_context.context("Checking whether MTU change is ok", logging.info) verify_mtu() large_frame_ping() size_increase_ping() # Stress test flood_ping() verify_mtu() finally: # Environment clean if session: session.close() grep_cmd = "grep '%s.*%s' /proc/net/arp" % (guest_ip, ifname) if process.system(grep_cmd, shell=True) == '0': process.run("arp -d %s -i %s" % (guest_ip, ifname), shell=True) logging.info("Removing the temporary ARP entry successfully") logging.info("Change back Bridge NICs MTU to %s", mtu_default) for iface in target_ifaces: process.run(host_mtu_cmd % (iface, mtu_default), shell=True)
def run(test, params, env): """ Test the RX jumbo frame function of vnics: 1) Boot the VM. 2) Change the MTU of guest nics and host taps depending on the NIC model. 3) Add the static ARP entry for guest NIC. 4) Wait for the MTU ok. 5) Verify the path MTU using ping. 6) Ping the guest with large frames. 7) Increment size ping. 8) Flood ping the guest with large frames. 9) Verify the path MTU. 10) Recover the MTU. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_ovs_ports(ovs): ''' get the ovs bridge all Interface list. :param ovs: Ovs bridge name ''' cmd = "ovs-vsctl list-ports %s" % ovs return process.getoutput(cmd, shell=True) netdst = params.get("netdst", "switch") host_bridges = utils_net.find_bridge_manager(netdst) if not isinstance(host_bridges, utils_net.Bridge): ovs = host_bridges host_hw_interface = get_ovs_ports(netdst) tmp_ports = re.findall(r"t[0-9]{1,}-[a-zA-Z0-9]{6}", host_hw_interface) if tmp_ports: for p in tmp_ports: process.system_output("ovs-vsctl del-port %s %s" % (netdst, p)) params["start_vm"] = "yes" env_process.preprocess_vm(test, params, env, params["main_vm"]) timeout = int(params.get("login_timeout", 360)) mtu_default = 1500 mtu = params.get("mtu", "1500") def_max_icmp_size = int(mtu) - 28 max_icmp_pkt_size = int(params.get("max_icmp_pkt_size", def_max_icmp_size)) flood_time = params.get("flood_time", "300") os_type = params.get("os_type") os_variant = params.get("os_variant") vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) session_serial = vm.wait_for_serial_login(timeout=timeout) ifname = vm.get_ifname(0) guest_ip = vm.get_address(0) if guest_ip is None: test.error("Could not get the guest ip address") host_mtu_cmd = "ifconfig %s mtu %s" if not isinstance(host_bridges, utils_net.Bridge): target_ifaces = set(get_ovs_ports(netdst).splitlines()) else: br_in_use = host_bridges.list_br() ifaces_in_use = host_bridges.list_iface() target_ifaces = set(ifaces_in_use) - set(br_in_use) error_context.context("Change all Bridge NICs MTU to %s" % mtu, logging.info) for iface in target_ifaces: process.run(host_mtu_cmd % (iface, mtu), shell=True) try: error_context.context("Changing the MTU of guest", logging.info) # Environment preparation mac = vm.get_mac_address(0) if os_type == "linux": ethname = utils_net.get_linux_ifname(session, mac) guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname, mtu) else: connection_id = utils_net.get_windows_nic_attribute( session, "macaddress", mac, "netconnectionid") index = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "index") if os_variant == "winxp": pnpdevice_id = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "pnpdeviceid") cd_num = utils_misc.get_winutils_vol(session) copy_cmd = r"xcopy %s:\devcon\wxp_x86\devcon.exe c:\ " % cd_num session.cmd(copy_cmd) reg_set_mtu_pattern = params.get("reg_mtu_cmd") mtu_key_word = params.get("mtu_key", "MTU") reg_set_mtu = reg_set_mtu_pattern % (int(index), mtu_key_word, int(mtu)) guest_mtu_cmd = "%s " % reg_set_mtu session.cmd(guest_mtu_cmd) if os_type == "windows": mode = "netsh" if os_variant == "winxp": connection_id = pnpdevice_id.split("&")[-1] mode = "devcon" utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) error_context.context("Chaning the MTU of host tap ...", logging.info) host_mtu_cmd = "ifconfig %s mtu %s" # Before change macvtap mtu, must set the base interface mtu if params.get("nettype") == "macvtap": base_if = utils_net.get_macvtap_base_iface(params.get("netdst")) process.run(host_mtu_cmd % (base_if, mtu), shell=True) process.run(host_mtu_cmd % (ifname, mtu), shell=True) error_context.context("Add a temporary static ARP entry ...", logging.info) arp_add_cmd = "arp -s %s %s -i %s" % (guest_ip, mac, ifname) process.run(arp_add_cmd, shell=True) def is_mtu_ok(): status, _ = utils_test.ping(guest_ip, 1, packetsize=max_icmp_pkt_size, hint="do", timeout=2) return status == 0 def verify_mtu(): logging.info("Verify the path MTU") status, output = utils_test.ping(guest_ip, 10, packetsize=max_icmp_pkt_size, hint="do", timeout=15) if status != 0: logging.error(output) test.fail("Path MTU is not as expected") if utils_test.get_loss_ratio(output) != 0: logging.error(output) test.fail("Packet loss ratio during MTU " "verification is not zero") def flood_ping(): logging.info("Flood with large frames") utils_test.ping(guest_ip, packetsize=max_icmp_pkt_size, flood=True, timeout=float(flood_time)) def large_frame_ping(count=100): logging.info("Large frame ping") _, output = utils_test.ping(guest_ip, count, packetsize=max_icmp_pkt_size, timeout=float(count) * 2) ratio = utils_test.get_loss_ratio(output) if ratio != 0: test.fail("Loss ratio of large frame ping is %s" % ratio) def size_increase_ping(step=random.randrange(90, 110)): logging.info("Size increase ping") for size in range(0, max_icmp_pkt_size + 1, step): logging.info("Ping %s with size %s", guest_ip, size) status, output = utils_test.ping(guest_ip, 1, packetsize=size, hint="do", timeout=1) if status != 0: status, output = utils_test.ping(guest_ip, 10, packetsize=size, adaptive=True, hint="do", timeout=20) fail_ratio = int(params.get("fail_ratio", 50)) if utils_test.get_loss_ratio(output) > fail_ratio: test.fail("Ping loss ratio is greater " "than 50% for size %s" % size) logging.info("Waiting for the MTU to be OK") wait_mtu_ok = 10 if not utils_misc.wait_for(is_mtu_ok, wait_mtu_ok, 0, 1): logging.debug(process.getoutput("ifconfig -a", verbose=False, ignore_status=True, shell=True)) test.error("MTU is not as expected even after %s " "seconds" % wait_mtu_ok) # Functional Test error_context.context("Checking whether MTU change is ok", logging.info) verify_mtu() large_frame_ping() size_increase_ping() # Stress test flood_ping() verify_mtu() finally: # Environment clean if session: session.close() grep_cmd = "grep '%s.*%s' /proc/net/arp" % (guest_ip, ifname) if process.system(grep_cmd, shell=True) == '0': process.run("arp -d %s -i %s" % (guest_ip, ifname), shell=True) logging.info("Removing the temporary ARP entry successfully") logging.info("Change back Bridge NICs MTU to %s" % mtu_default) for iface in target_ifaces: process.run(host_mtu_cmd % (iface, mtu_default), shell=True)
def run(test, params, env): """ create/delete macvtap in host 1) Verify no other macvtap share the physical network device. 2) Create a macvtap device in host. 3) Check configuraton of macvtap device. 4) Ping out from host with the interface that create macvtap. 5) Delete the macvtap device create in step 2. 6) Ping out from host with the interface that create macvtap. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ ifname = params.get("macvtap_base_interface") macvtap_mode = params.get("macvtap_mode", "passthru") dest_host = params.get("dest_host") set_mac = params.get("set_mac", "yes") == "yes" macvtaps = [] if not ifname: ifname = params.get("netdst") ifname = utils_net.get_macvtap_base_iface(ifname) error.context("Verify no other macvtap share the physical network device.", logging.info) macvtap_devices = get_macvtap_device_on_ifname(ifname) for device in macvtap_devices: utils.system_output("ip link delete %s" % device) for mode in macvtap_mode.split(): macvtap_name = "%s_01" % mode txt = "Create %s mode macvtap device %s on %s." % (mode, macvtap_name, ifname) error.context(txt, logging.info) cmd = " ip link add link %s name %s type macvtap mode %s" % ( ifname, macvtap_name, mode) utils.system(cmd, timeout=240) if set_mac: txt = "Determine and configure mac address of %s, " % macvtap_name txt += "Then link up it." error.context(txt, logging.info) mac = utils_net.generate_mac_address_simple() cmd = " ip link set %s address %s up" % (macvtap_name, mac) utils.system(cmd, timeout=240) error.context("Check configuraton of macvtap device", logging.info) check_cmd = " ip -d link show %s" % macvtap_name try: tap_info = utils.system_output(check_cmd, timeout=240) except error.CmdError: err = "Fail to create %s mode macvtap on %s" % (mode, ifname) raise error.TestFail(err) if set_mac: if mac not in tap_info: err = "Fail to set mac for %s" % macvtap_name raise error.TestFail(err) macvtaps.append(macvtap_name) if not dest_host: dest_host_get_cmd = "ip route | awk '/default/ { print $3 }'" dest_host_get_cmd = params.get("dest_host_get_cmd", dest_host_get_cmd) dest_host = utils.system_output(dest_host_get_cmd).split()[-1] txt = "Ping dest host %s from " % dest_host txt += "localhost with the interface %s" % ifname error.context(txt, logging.info) status, output = utils_test.ping(dest_host, 10, interface=ifname, timeout=20) ratio = utils_test.get_loss_ratio(output) if "passthru" in macvtap_mode: ifnames = utils_net.get_host_iface() ifnames.remove(ifname) logging.info("ifnames = %s", ifnames) ips = [] for name in ifnames: try: _ip = utils_net.get_ip_address_by_interface(name) if _ip != "127.0.0.1": ips.append(_ip) except Exception: pass logging.info("ips = %s", ips) if not ips: if ratio != 100: err = "%s did not lost network connection after " % ifname err += " creating %s mode macvtap on it." % macvtap_mode raise error.TestFail(err) else: err = "%s is not the only network device in host" % ifname logging.debug(err) else: if ratio != 0: err = "Package lost during ping %s from %s " % (dest_host, ifname) err += "after creating %s mode macvtap on it." % macvtap_mode raise error.TestFail(err) for name in macvtaps: txt = "Delete macvtap device %s on %s." % (name, ifname) error.context(txt, logging.info) del_cmd = "ip link delete %s" % name utils.system(del_cmd) devices = get_macvtap_device_on_ifname(ifname) if name in devices: err = "Fail to delete macvtap %s on %s" % (name, ifname) raise error.TestFail(err) logging.info("dest_host = %s", dest_host) txt = "Ping dest host %s from " % dest_host txt += "localhost with the interface %s" % ifname error.context(txt, logging.info) status, output = utils_test.ping(dest_host, 10, interface=ifname, timeout=20) if status != 0: raise error.TestFail("Ping failed, status: %s," " output: %s" % (status, output)) ratio = utils_test.get_loss_ratio(output) if ratio != 0: err = "Package lost during ping %s from %s " % (dest_host, ifname) raise error.TestFail(err)
def run(test, params, env): """ create/delete macvtap in host 1) Verify no other macvtap share the physical network device. 2) Create a macvtap device in host. 3) Check configuraton of macvtap device. 4) Ping out from host with the interface that create macvtap. 5) Delete the macvtap device create in step 2. 6) Ping out from host with the interface that create macvtap. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ ifname = params.get("macvtap_base_interface") macvtap_mode = params.get("macvtap_mode", "passthru") dest_host = params.get("dest_host") set_mac = params.get("set_mac", "yes") == "yes" macvtaps = [] if not ifname: ifname = params.get("netdst") ifname = utils_net.get_macvtap_base_iface(ifname) error.context("Verify no other macvtap share the physical network device.", logging.info) macvtap_devices = get_macvtap_device_on_ifname(ifname) for device in macvtap_devices: utils.system_output("ip link delete %s" % device) for mode in macvtap_mode.split(): macvtap_name = "%s_01" % mode txt = "Create %s mode macvtap device %s on %s." % (mode, macvtap_name, ifname) error.context(txt, logging.info) cmd = " ip link add link %s name %s type macvtap mode %s" % (ifname, macvtap_name, mode) utils.system(cmd, timeout=240) if set_mac: txt = "Determine and configure mac address of %s, " % macvtap_name txt += "Then link up it." error.context(txt, logging.info) mac = utils_net.generate_mac_address_simple() cmd = " ip link set %s address %s up" % (macvtap_name, mac) utils.system(cmd, timeout=240) error.context("Check configuraton of macvtap device", logging.info) check_cmd = " ip -d link show %s" % macvtap_name try: tap_info = utils.system_output(check_cmd, timeout=240) except error.CmdError: err = "Fail to create %s mode macvtap on %s" % (mode, ifname) raise error.TestFail(err) if set_mac: if mac not in tap_info: err = "Fail to set mac for %s" % macvtap_name raise error.TestFail(err) macvtaps.append(macvtap_name) if not dest_host: dest_host_get_cmd = "ip route | awk '/default/ { print $3 }'" dest_host_get_cmd = params.get("dest_host_get_cmd", dest_host_get_cmd) dest_host = utils.system_output(dest_host_get_cmd).split()[-1] txt = "Ping dest host %s from " % dest_host txt += "localhost with the interface %s" % ifname error.context(txt, logging.info) status, output = utils_test.ping(dest_host, 10, interface=ifname, timeout=20) ratio = utils_test.get_loss_ratio(output) if "passthru" in macvtap_mode: ifnames = utils_net.get_host_iface() ifnames.remove(ifname) logging.info("ifnames = %s", ifnames) ips = [] for name in ifnames: try: _ip = utils_net.get_ip_address_by_interface(name) if _ip != "127.0.0.1": ips.append(_ip) except Exception: pass logging.info("ips = %s", ips) if not ips: if ratio != 100: err = "%s did not lost network connection after " % ifname err += " creating %s mode macvtap on it." % macvtap_mode raise error.TestFail(err) else: err = "%s is not the only network device in host" % ifname logging.debug(err) else: if ratio != 0: err = "Package lost during ping %s from %s " % (dest_host, ifname) err += "after creating %s mode macvtap on it." % macvtap_mode raise error.TestFail(err) for name in macvtaps: txt = "Delete macvtap device %s on %s." % (name, ifname) error.context(txt, logging.info) del_cmd = "ip link delete %s" % name utils.system(del_cmd) devices = get_macvtap_device_on_ifname(ifname) if name in devices: err = "Fail to delete macvtap %s on %s" % (name, ifname) raise error.TestFail(err) logging.info("dest_host = %s", dest_host) txt = "Ping dest host %s from " % dest_host txt += "localhost with the interface %s" % ifname error.context(txt, logging.info) status, output = utils_test.ping(dest_host, 10, interface=ifname, timeout=20) if status != 0: raise error.TestFail("Ping failed, status: %s," " output: %s" % (status, output)) ratio = utils_test.get_loss_ratio(output) if ratio != 0: err = "Package lost during ping %s from %s " % (dest_host, ifname) raise error.TestFail(err)