Exemple #1
0
    def cleanup_ovs_ports(netdst, ports):
        """
        Clean up created ovs ports in this case

        :param netdst: netdst get from command line
        :param ports: existing ports need to be remain before this test
        """

        host_bridge = utils_net.find_bridge_manager(netdst)
        if utils_net.ovs_br_exists(netdst) is True:
            ports = set(host_bridge.list_ports(netdst)) - set(ports)
            for p in ports:
                utils_net.find_bridge_manager(netdst).del_port(netdst, p)
Exemple #2
0
    def cleanup_ovs_ports(netdst, ports):
        """
        Clean up created ovs ports in this case

        :param netdst: netdst get from command line
        :param ports: existing ports need to be remain before this test
        """

        host_bridge = utils_net.find_bridge_manager(netdst)
        if utils_net.ovs_br_exists(netdst) is True:
            ports = set(host_bridge.list_ports(netdst)) - set(ports)
            for p in ports:
                utils_net.find_bridge_manager(netdst).del_port(netdst, p)
Exemple #3
0
def run(test, params, env):
    """
    Test tap device deleted after vm quit with error

    1) Boot a with invaild params.
    1) Check qemu-kvm quit with error.
    2) Check vm tap device delete from ovs bridge.

    :param test: Kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """

    netdst = params.get("netdst")
    if not utils_net.ovs_br_exists(netdst):
        test.cancel("%s isn't an openvswith bridge" % netdst)

    host_bridge = utils_net.find_bridge_manager(netdst)
    deps_dir = data_dir.get_deps_dir("ovs")
    nic_script = utils_misc.get_path(deps_dir, params["nic_script"])
    nic_downscript = utils_misc.get_path(deps_dir, params["nic_downscript"])
    params["nic_script"] = nic_script
    params["nic_downscript"] = nic_downscript

    params["qemu_command_prefix"] = "export SHELL=/usr/bin/bash;"
    params["start_vm"] = "yes"
    params["nettype"] = "bridge"
    params["nic_model"] = "virtio-net-pci"

    ports = set(host_bridge.list_ports(netdst))
    try:
        env_process.preprocess_vm(test, params, env, params["main_vm"])
        env.get_vm(params["main_vm"])
    except virt_vm.VMCreateError:
        ports = set(host_bridge.list_ports(netdst)) - ports
        if ports:
            for p in ports:
                host_bridge.del_port(netdst, p)
            test.fail("%s not delete after qemu quit." % ports)
    else:
        test.fail("Qemu should quit with error")
Exemple #4
0
def run(test, params, env):
    """
    Enslave a port which is already a member of ovs into another

    1) Check current ovs bridge and list the ports in it
    2) Create a new ovs bridge
    3) Enslave one port which is a member of current ovs bridge
       into the new one
    4) Delete the new ovs bridge

    :param test: Kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """

    netdst = params["netdst"]
    if utils_net.ovs_br_exists(netdst) is not True:
        test.cancel("%s isn't an openvswith bridge" % netdst)

    new_br_name = params.get("new_ovs_bridge_name", "temp_ovs_bridge")
    host_bridge = utils_net.find_bridge_manager(netdst)
    if host_bridge.br_exist(new_br_name) is True:
        host_bridge.del_br(new_br_name)
    host_bridge.add_br(new_br_name)
    error_context.context("OVS bridge %s created." % new_br_name,
                          logging.info)

    try:
        ports = host_bridge.list_ports(netdst)
        host_bridge.add_port(new_br_name, ports[0])
    except process.CmdError as e:
        if "already exists on bridge" not in e.result.stderr_text:
            test.fail("Port %s should not be enslaved to another bridge."
                      " Output: %s" % (ports[0], e.result.stderr_text))
    else:
        test.fail("Add port cmd successfully excuted. However, port %s "
                  "should not be enslaved to another bridge." % ports[0])
    finally:
        host_bridge.del_br(new_br_name)
def run(test, params, env):
    """
    Enslave a port which is already a member of ovs into another

    1) Check current ovs bridge and list the ports in it
    2) Create a new ovs bridge
    3) Enslave one port which is a member of current ovs bridge
       into the new one
    4) Delete the new ovs bridge

    :param test: Kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """

    netdst = params["netdst"]
    if utils_net.ovs_br_exists(netdst) is not True:
        test.cancel("%s isn't an openvswith bridge" % netdst)

    new_br_name = params.get("new_ovs_bridge_name", "temp_ovs_bridge")
    host_bridge = utils_net.find_bridge_manager(netdst)
    if host_bridge.br_exist(new_br_name) is True:
        host_bridge.del_br(new_br_name)
    host_bridge.add_br(new_br_name)
    error_context.context("OVS bridge %s created." % new_br_name, logging.info)

    try:
        ports = host_bridge.list_ports(netdst)
        host_bridge.add_port(new_br_name, ports[0])
    except process.CmdError as e:
        if "already exists on bridge" not in e.result.stderr_text:
            test.fail("Port %s should not be enslaved to another bridge."
                      " Output: %s" % (ports[0], e.result.stderr_text))
    else:
        test.fail("Add port cmd successfully excuted. However, port %s "
                  "should not be enslaved to another bridge." % ports[0])
    finally:
        host_bridge.del_br(new_br_name)
Exemple #6
0
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)
Exemple #7
0
def run(test, params, env):
    """
    Expose host MTU to guest test

    1) Boot up guest with param 'host_mtu=4000' in nic part
    2) Disable NetworkManager in guest
    3) set mtu of guest tap (eg: tap0) and physical nic (eg: eno1) to
       4000 in host
    4) check the mtu in guest
    5) ping from guest to external host with packet size 3972

    :param test: kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    def cleanup_ovs_ports(netdst, ports):
        """
        Clean up created ovs ports in this case

        :param netdst: netdst get from command line
        :param ports: existing ports need to be remain before this test
        """

        host_bridge = utils_net.find_bridge_manager(netdst)
        if utils_net.ovs_br_exists(netdst) is True:
            ports = set(host_bridge.list_ports(netdst)) - set(ports)
            for p in ports:
                utils_net.find_bridge_manager(netdst).del_port(netdst, p)

    netdst = params.get("netdst", "switch")
    mtu_value = params.get_numeric("mtu_value")
    host_bridge = utils_net.find_bridge_manager(netdst)
    localhost = LocalHost()
    try:
        if netdst in utils_net.Bridge().list_br():
            host_hw_interface = utils_net.Bridge().list_iface(netdst)[0]
        else:
            host_hw_interface = host_bridge.list_ports(netdst)
            tmp_ports = re.findall(r"t[0-9]{1,}-[a-zA-Z0-9]{6}",
                                   ' '.join(host_hw_interface))
            if tmp_ports:
                for p in tmp_ports:
                    host_bridge.del_port(netdst, p)
                host_hw_interface = host_bridge.list_ports(netdst)
    except IndexError:
        host_hw_interface = netdst

    params["start_vm"] = "yes"
    env_process.preprocess_vm(test, params, env, params["main_vm"])

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    vm_iface = vm.get_ifname()
    # Get host interface original mtu value before setting
    if netdst in utils_net.Bridge().list_br():
        host_hw_iface = NetworkInterface(host_hw_interface, localhost)
    elif utils_net.ovs_br_exists(netdst) is True:
        host_hw_iface = NetworkInterface(' '.join(host_hw_interface),
                                         localhost)
    host_mtu_origin = host_hw_iface.get_mtu()

    set_mtu_host(vm_iface, mtu_value)
    host_hw_iface.set_mtu(mtu_value)

    os_type = params.get("os_type", "linux")
    login_timeout = float(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=login_timeout)

    host_ip = utils_net.get_ip_address_by_interface(params["netdst"])
    if os_type == "linux":
        session.cmd_output_safe(params["nm_stop_cmd"])
        guest_ifname = utils_net.get_linux_ifname(session,
                                                  vm.get_mac_address())
        output = session.cmd_output_safe(params["check_linux_mtu_cmd"] %
                                         guest_ifname)
        error_context.context(output, logging.info)
        match_string = "mtu %s" % params["mtu_value"]
        if match_string not in output:
            test.fail("host mtu %s not exposed to guest" % params["mtu_value"])
    elif os_type == "windows":
        connection_id = utils_net.get_windows_nic_attribute(
            session, "macaddress", vm.get_mac_address(), "netconnectionid")
        output = session.cmd_output_safe(params["check_win_mtu_cmd"] %
                                         connection_id)
        error_context.context(output, logging.info)
        lines = output.strip().splitlines()
        lines_len = len(lines)

        line_table = lines[0].split('  ')
        line_value = lines[2].split('  ')
        while '' in line_table:
            line_table.remove('')
        while '' in line_value:
            line_value.remove('')
        index = 0
        for name in line_table:
            if re.findall("MTU", name):
                break
            index += 1
        guest_mtu_value = line_value[index]
        logging.info("MTU is %s", guest_mtu_value)
        if not int(guest_mtu_value) == mtu_value:
            test.fail("Host mtu %s is not exposed to "
                      "guest!" % params["mtu_value"])

    logging.info("Ping from guest to host with packet size 3972")
    status, output = utils_test.ping(host_ip,
                                     10,
                                     packetsize=3972,
                                     timeout=30,
                                     session=session)
    ratio = utils_test.get_loss_ratio(output)
    if ratio != 0:
        test.fail("Loss ratio is %s", ratio)

    # Restore host mtu after finish testing
    set_mtu_host(vm_iface, host_mtu_origin)
    host_hw_iface.set_mtu(host_mtu_origin)

    if netdst not in utils_net.Bridge().list_br():
        cleanup_ovs_ports(netdst, host_hw_interface)
    session.close()
Exemple #8
0
def run(test, params, env):
    """
    Test port mirror with linux bridge backend.

    1) Create a private bridge
    2) Set private bridge promisc mode and up
    3) Boot 3 VMs over private bridge
    4) Mirror all traffic on bridge to tap device connected to VM1
    5) Start tcpdump in VM1 to dump icmp packets from VM2 to VM3
    6) Ping VM3 from VM2
    7) Stop Ping in VM2
    8) Stop tcpdump and check results

    :param test: KVM test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def mirror_bridge_to_tap(tap_name):
        """
        Mirror all packages on bridge to tap device connected to vm vNIC

        :param tap_name: name of tap connected to vm
        """

        tc_qdisc_add_ingress = params.get("tc_qdisc_add_ingress")
        tc_filter_show_dev = params.get("tc_filter_show_dev")
        tc_filter_replace_dev = params.get("tc_filter_replace_dev") % tap_name
        tc_qdisc_replace = params.get("tc_qdisc_replace")
        process.system_output(tc_qdisc_add_ingress)
        process.system_output(tc_filter_show_dev)
        process.system_output(tc_filter_replace_dev)
        process.system_output(tc_qdisc_replace)

        tc_qdisc_show_dev = params.get("tc_qdisc_show_dev")
        output = process.system_output(tc_qdisc_show_dev).decode()
        port = re.findall("qdisc prio (.*):", output)[0]

        tc_filter_show_dev_port = params.get("tc_filter_show_dev_port") % port
        tc_filter_replace_dev_port = params.get(
            "tc_filter_replace_dev_port") % (port, tap_name)
        process.system_output(tc_filter_show_dev_port)
        process.system_output(tc_filter_replace_dev_port)

    def check_tcpdump(output, src_ip, des_ip, ping_count):
        """
        Check tcpdump result.

        :parm output: string of tcpdump output.
        :parm src_ip: ip to ping
        :parm des_ip: ip to receive ping
        :parm ping_count: total ping packets number

        :return: bool type result.
        """
        rex_request = r".*IP %s > %s.*ICMP echo request.*" % (
            src_ip, des_ip)
        rex_reply = r".*IP %s > %s.*ICMP echo reply.*" % (
            des_ip, src_ip)
        request_num = 0
        reply_num = 0
        for idx, _ in enumerate(output.splitlines()):
            if re.match(rex_request, _):
                request_num += 1
            elif re.match(rex_reply, _):
                reply_num += 1

        if request_num != ping_count or reply_num != ping_count:
            logging.debug("Unexpected request or reply number. "
                          "current request number is: %d, "
                          "current reply number is: %d, "
                          "expected request and reply number is: %d. "
                          % (request_num, reply_num, ping_count))
            return False
        return True

    netdst = params.get("netdst", "switch")
    br_backend = utils_net.find_bridge_manager(netdst)
    if not isinstance(br_backend, utils_net.Bridge):
        test.cancel("Host does not use Linux Bridge")

    brname = params.get("private_bridge", "tmpbr")
    net_mask = params.get("net_mask", "24")
    login_timeout = int(params.get("login_timeout", "600"))
    stop_NM_cmd = params.get("stop_NM_cmd")
    stop_firewall_cmd = params.get("stop_firewall_cmd")
    tcpdump_cmd = params.get("tcpdump_cmd")
    tcpdump_log = params.get("tcpdump_log")
    get_tcpdump_log_cmd = params.get("get_tcpdump_log_cmd")
    ping_count = int(params.get("ping_count"))

    error_context.context("Create a private bridge", logging.info)
    br_backend.add_bridge(brname)
    br_iface = utils_net.Interface(brname)
    br_iface.up()
    br_iface.promisc_on()

    params['netdst'] = brname
    params["start_vm"] = "yes"
    vm_names = params.get("vms").split()
    vms_info = {}
    try:
        for vm_name in vm_names:
            env_process.preprocess_vm(test, params, env, vm_name)
            vm = env.get_vm(vm_name)
            vm.verify_alive()
            ip = params["ip_%s" % vm_name]
            mac = vm.get_mac_address()
            session = vm.wait_for_serial_login(timeout=login_timeout)
            session.cmd(stop_NM_cmd, ignore_all_errors=True)
            session.cmd(stop_firewall_cmd, ignore_all_errors=True)
            nic_name = utils_net.get_linux_ifname(session, mac)
            ifname = vm.get_ifname()
            ifset_cmd = "ip addr add %s/%s dev %s" % (ip, net_mask, nic_name)
            ifup_cmd = "ip link set dev %s up" % nic_name
            session.cmd(ifset_cmd)
            session.cmd(ifup_cmd)
            vms_info[vm_name] = [vm, ifname, ip, session, nic_name]

        vm_mirror = vm_names[0]
        vm_src = vm_names[1]
        vm_des = vm_names[2]

        error_context.context(
            "Mirror all packets on bridge to tap device conncted to %s"
            % vm_mirror)
        tap_ifname = vms_info[vm_mirror][0].virtnet[0].ifname
        mirror_bridge_to_tap(tap_ifname)

        error_context.context("Start tcpdump in %s"
                              % vm_mirror, logging.info)
        tcpdump_cmd = tcpdump_cmd % (vms_info[vm_des][2], tcpdump_log)
        logging.info("tcpdump command: %s" % tcpdump_cmd)
        vms_info[vm_mirror][3].sendline(tcpdump_cmd)
        time.sleep(5)

        error_context.context("Start ping from %s to %s" %
                              (vm_src, vm_des), logging.info)
        ping_cmd = params.get("ping_cmd") % vms_info[vm_des][2]
        vms_info[vm_src][3].cmd(ping_cmd, timeout=150)

        error_context.context("Check tcpdump results", logging.info)
        time.sleep(5)
        vms_info[vm_mirror][3].cmd_output_safe("pkill tcpdump")
        tcpdump_content = vms_info[vm_mirror][3].cmd_output(
            get_tcpdump_log_cmd).strip()
        if not check_tcpdump(tcpdump_content, vms_info[vm_src][2],
                             vms_info[vm_des][2], ping_count):
            test.fail("tcpdump results are not expected, mirror fail.")
    finally:
        for vm in vms_info:
            vms_info[vm][0].destroy(gracefully=False)

        br_iface.down()
        br_backend.del_bridge(brname)
Exemple #9
0
def run(test, params, env):
    """
    Test port mirror with linux bridge backend.

    1) Create a private bridge
    2) Set private bridge promisc mode and up
    3) Boot 3 VMs over private bridge
    4) Mirror all traffic on bridge to tap device connected to VM1
    5) Start tcpdump in VM1 to dump icmp packets from VM2 to VM3
    6) Ping VM3 from VM2
    7) Stop Ping in VM2
    8) Stop tcpdump and check results

    :param test: KVM test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def mirror_bridge_to_tap(tap_name):
        """
        Mirror all packages on bridge to tap device connected to vm vNIC

        :param tap_name: name of tap connected to vm
        """

        tc_qdisc_add_ingress = params.get("tc_qdisc_add_ingress")
        tc_filter_show_dev = params.get("tc_filter_show_dev")
        tc_filter_replace_dev = params.get("tc_filter_replace_dev") % tap_name
        tc_qdisc_replace = params.get("tc_qdisc_replace")
        process.system_output(tc_qdisc_add_ingress)
        process.system_output(tc_filter_show_dev)
        process.system_output(tc_filter_replace_dev)
        process.system_output(tc_qdisc_replace)

        tc_qdisc_show_dev = params.get("tc_qdisc_show_dev")
        output = process.system_output(tc_qdisc_show_dev).decode()
        port = re.findall("qdisc prio (.*):", output)[0]

        tc_filter_show_dev_port = params.get("tc_filter_show_dev_port") % port
        tc_filter_replace_dev_port = params.get(
            "tc_filter_replace_dev_port") % (port, tap_name)
        process.system_output(tc_filter_show_dev_port)
        process.system_output(tc_filter_replace_dev_port)

    def check_tcpdump(output, src_ip, des_ip, ping_count):
        """
        Check tcpdump result.

        :parm output: string of tcpdump output.
        :parm src_ip: ip to ping
        :parm des_ip: ip to receive ping
        :parm ping_count: total ping packets number

        :return: bool type result.
        """
        rex_request = r".*IP %s > %s.*ICMP echo request.*" % (src_ip, des_ip)
        rex_reply = r".*IP %s > %s.*ICMP echo reply.*" % (des_ip, src_ip)
        request_num = 0
        reply_num = 0
        for idx, _ in enumerate(output.splitlines()):
            if re.match(rex_request, _):
                request_num += 1
            elif re.match(rex_reply, _):
                reply_num += 1

        if request_num != ping_count or reply_num != ping_count:
            logging.debug(
                "Unexpected request or reply number. "
                "current request number is: %d, "
                "current reply number is: %d, "
                "expected request and reply number is: %d. ", request_num,
                reply_num, ping_count)
            return False
        return True

    netdst = params.get("netdst", "switch")
    br_backend = utils_net.find_bridge_manager(netdst)
    if not isinstance(br_backend, utils_net.Bridge):
        test.cancel("Host does not use Linux Bridge")

    brname = params.get("private_bridge", "tmpbr")
    net_mask = params.get("net_mask", "24")
    login_timeout = int(params.get("login_timeout", "600"))
    stop_NM_cmd = params.get("stop_NM_cmd")
    stop_firewall_cmd = params.get("stop_firewall_cmd")
    tcpdump_cmd = params.get("tcpdump_cmd")
    tcpdump_log = params.get("tcpdump_log")
    get_tcpdump_log_cmd = params.get("get_tcpdump_log_cmd")
    ping_count = int(params.get("ping_count"))

    error_context.context("Create a private bridge", logging.info)
    br_backend.add_bridge(brname)
    br_iface = utils_net.Interface(brname)
    br_iface.up()
    br_iface.promisc_on()

    params['netdst'] = brname
    params["start_vm"] = "yes"
    vm_names = params.get("vms").split()
    vms_info = {}
    try:
        for vm_name in vm_names:
            env_process.preprocess_vm(test, params, env, vm_name)
            vm = env.get_vm(vm_name)
            vm.verify_alive()
            ip = params["ip_%s" % vm_name]
            mac = vm.get_mac_address()
            serial_session = vm.wait_for_serial_login(timeout=login_timeout)
            serial_session.cmd_output_safe(stop_NM_cmd)
            serial_session.cmd_output_safe(stop_firewall_cmd)
            nic_name = utils_net.get_linux_ifname(serial_session, mac)
            ifname = vm.get_ifname()
            ifset_cmd = "ip addr add %s/%s dev %s" % (ip, net_mask, nic_name)
            ifup_cmd = "ip link set dev %s up" % nic_name
            serial_session.cmd_output_safe(ifset_cmd)
            serial_session.cmd_output_safe(ifup_cmd)
            vms_info[vm_name] = [vm, ifname, ip, serial_session, nic_name]

        vm_mirror = vm_names[0]
        vm_src = vm_names[1]
        vm_des = vm_names[2]

        error_context.context(
            "Mirror all packets on bridge to tap device conncted to %s" %
            vm_mirror)
        tap_ifname = vms_info[vm_mirror][0].virtnet[0].ifname
        mirror_bridge_to_tap(tap_ifname)

        error_context.context("Start tcpdump in %s" % vm_mirror, logging.info)
        tcpdump_cmd = tcpdump_cmd % (vms_info[vm_des][2], tcpdump_log)
        logging.info("tcpdump command: %s", tcpdump_cmd)
        vms_info[vm_mirror][3].sendline(tcpdump_cmd)
        time.sleep(5)

        error_context.context("Start ping from %s to %s" % (vm_src, vm_des),
                              logging.info)
        ping_cmd = params.get("ping_cmd") % vms_info[vm_des][2]
        vms_info[vm_src][3].cmd(ping_cmd, timeout=150)

        error_context.context("Check tcpdump results", logging.info)
        time.sleep(5)
        vms_info[vm_mirror][3].cmd_output_safe("pkill tcpdump")
        tcpdump_content = vms_info[vm_mirror][3].cmd_output(
            get_tcpdump_log_cmd).strip()
        if not check_tcpdump(tcpdump_content, vms_info[vm_src][2],
                             vms_info[vm_des][2], ping_count):
            test.fail("tcpdump results are not expected, mirror fail.")
    finally:
        for vm in vms_info:
            vms_info[vm][0].destroy(gracefully=False)

        br_iface.down()
        br_backend.del_bridge(brname)
Exemple #10
0
def run(test, params, env):
    """
    Test 802.1Q vlan of NIC among guests and host with linux bridge backend.

    1) Configure vlan interface over host bridge interface.
    2) Create two VMs over vlan interface.
    3) Load 8021q module in guest.
    4) Configure ip address of guest with 192.168.*.*
    5) Test by ping between guest and host, should fail.
    6) Test by ping beween guests, should pass.
    7) Setup vlan in guests and using hard-coded ip address 192.168.*.*
    8) Test by ping between guest and host, should pass.
    9) Test by ping among guests, should pass.
    10) Test by netperf between guests and host.
    11) Test by netperf between guests.
    12) Delete vlan interface in host.

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """

    def add_vlan(interface, v_id, session=None):
        """
        Create a vlan-device on interface.
        :params interface: Interface.
        :params v_id: Vlan id.
        :params session: VM session or none.
        """
        vlan_if = '%s.%s' % (interface, v_id)
        add_cmd = params["add_vlan_cmd"] % (interface, vlan_if, v_id)
        error_context.context("Create vlan interface '%s' on %s" %
                              (vlan_if, interface), logging.info)
        if session:
            session.cmd(add_cmd)
        else:
            process.system(add_cmd)
        return vlan_if

    def set_ip_vlan(vlan_if, vlan_ip, session=None):
        """
        Set ip address of vlan interface.
        :params vlan_if: Vlan interface.
        :params vlan_ip: Vlan internal ip.
        :params session: VM session or none.
        """
        error_context.context("Assign IP '%s' to vlan interface '%s'" %
                              (vlan_ip, vlan_if), logging.info)
        if session:
            session.cmd("ifconfig %s 0.0.0.0" % vlan_if)
            session.cmd("ifconfig %s down" % vlan_if)
            session.cmd("ifconfig %s %s up" % (vlan_if, vlan_ip))
        else:
            process.system("ifconfig %s %s up" % (vlan_if, vlan_ip))

    def set_mac_vlan(vlan_if, mac_str, session):
        """
        Give a new mac address for vlan interface in guest.
        :params: vlan_if: Vlan interface.
        :params: mac_str: New mac address for vlan.
        :params: session: VM session.
        """
        mac_cmd = "ip link set %s add %s up" % (vlan_if, mac_str)
        error_context.context("Give a new mac address '%s' for vlan interface "
                              "'%s'" % (mac_str, vlan_if), logging.info)
        session.cmd(mac_cmd)

    def set_arp_ignore(session):
        """
        Enable arp_ignore for all ipv4 device in guest
        """
        error_context.context("Enable arp_ignore for all ipv4 device in guest",
                              logging.info)
        ignore_cmd = "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore"
        session.cmd(ignore_cmd)

    def ping_vlan(vm, dest, vlan_if, session):
        """
        Test ping between vlans, from guest to host/guest.
        :params vm: VM object
        :params dest: Dest ip to ping.
        :params vlan_if: Vlan interface.
        :params session: VM session.
        """
        error_context.context("Test ping from '%s' to '%s' on guest '%s'" %
                              (vlan_if, dest, vm.name))
        status, output = utils_test.ping(dest=dest, count=10,
                                         interface=vlan_if,
                                         session=session,
                                         timeout=30)
        if status:
            raise NetPingError(vlan_if, dest, output)

    def netperf_vlan(client='main_vm', server='localhost',
                     sub_type='netperf_stress'):
        """
        Test netperf stress among guests and host.
        :params client: Netperf client.
        :params server: Netperf server.
        :params sub_type: Sub_type to run.
        """
        params["netperf_client"] = client
        params["netperf_server"] = server
        error_context.context("Run netperf stress test among guests and host, "
                              "server: %s, client: %s" % (server, client),
                              logging.info)
        utils_test.run_virt_sub_test(test, params, env, sub_type)

    vms = []
    sessions = []
    ifname = []
    vm_ip = []
    vm_vlan_ip = []
    vm_vlan_if = []
    sub_type = params["sub_type"]
    host_br = params.get("netdst", "switch")
    host_vlan_id = params.get("host_vlan_id", "10")
    host_vlan_ip = params.get("host_vlan_ip", "192.168.10.10")
    subnet = params.get("subnet", "192.168")
    mac_str = params.get("mac_str").split(',')

    br_backend = utils_net.find_bridge_manager(host_br)
    if not isinstance(br_backend, utils_net.Bridge):
        test.cancel("Host does not use Linux Bridge")

    linux_modules.load_module("8021q")

    host_vlan_if = "%s.%s" % (host_br, host_vlan_id)
    if host_vlan_if not in utils_net.get_net_if():
        host_vlan_if = add_vlan(interface=host_br, v_id=host_vlan_id)
        if host_vlan_if in utils_net.get_net_if():
            set_ip_vlan(vlan_if=host_vlan_if, vlan_ip=host_vlan_ip)
            rm_host_vlan_cmd = params["rm_host_vlan_cmd"] % host_vlan_if
            funcatexit.register(env, params["type"], _system,
                                rm_host_vlan_cmd)
        else:
            test.cancel("Fail to set up vlan over bridge interface in host!")

    if params.get("start_vm", "yes") == "no":
        vm_main = env.get_vm(params["main_vm"])
        vm_main.create(params=params)
        vm2 = env.get_vm("vm2")
        vm2.create(params=params)
        vms.append(vm_main)
        vms.append(vm2)
    else:
        vms.append(env.get_vm([params["main_vm"]]))
        vms.append(env.get_vm('vm2'))

    for vm_ in vms:
        vm_.verify_alive()

    for vm_index, vm in enumerate(vms):
        error_context.context("Prepare test env on %s" % vm.name)
        session = vm.wait_for_serial_login()
        if not session:
            err_msg = "Could not log into guest %s" % vm.name
            test.error(err_msg)

        interface = utils_net.get_linux_ifname(session, vm.get_mac_address())

        error_context.context("Load 8021q module in guest %s" % vm.name,
                              logging.info)
        session.cmd_output_safe("modprobe 8021q")

        error_context.context("Setup vlan environment in guest %s" % vm.name,
                              logging.info)
        inter_ip = "%s.%s.%d" % (subnet, host_vlan_id, vm_index + 1)
        set_ip_vlan(interface, inter_ip, session=session)
        set_arp_ignore(session)
        params["vlan_nic"] = "%s.%s" % (interface, host_vlan_id)
        error_context.context("Test ping from guest '%s' to host with "
                              "interface '%s'" %
                              (vm.name, interface), logging.info)
        try:
            ping_vlan(vm, dest=host_vlan_ip, vlan_if=interface,
                      session=session)
        except NetPingError:
            logging.info("Guest ping fail to host as expected with "
                         "interface '%s'" % interface)
        else:
            test.fail("Guest ping to host should fail with interface"
                      " '%s'" % interface)
        ifname.append(interface)
        vm_ip.append(inter_ip)
        sessions.append(session)

    # Ping succeed between guests
    error_context.context("Test ping between guests with interface %s"
                          % ifname[0], logging.info)
    ping_vlan(vms[0], dest=vm_ip[1], vlan_if=ifname[0], session=sessions[0])

    # set vlan tag for guest
    for vm_index, vm in enumerate(vms):
        session = sessions[vm_index]
        error_context.context("Add vlan interface on guest '%s'" % vm.name)
        session.cmd("ifconfig %s 0.0.0.0" % ifname[vm_index])
        vlan_if = add_vlan(interface=ifname[vm_index], v_id=host_vlan_id,
                           session=session)
        vm_vlan_if.append(vlan_if)
        set_mac_vlan(vlan_if, mac_str[vm_index], session=session)
        vlan_ip = "%s.%s.%d" % (subnet, host_vlan_id, vm_index + 11)
        set_ip_vlan(vlan_if, vlan_ip, session=session)
        vm_vlan_ip.append(vlan_ip)

        error_context.context("Test ping from interface '%s' on guest "
                              "'%s' to host." %
                              (vm_vlan_if[vm_index], vm.name), logging.info)
        ping_vlan(vm, dest=host_vlan_ip, vlan_if=vm_vlan_if[vm_index],
                  session=session)
        netperf_vlan(client=vm.name, server="localhost")

    error_context.context("Test ping and netperf between guests with "
                          "interface '%s'" %
                          vm_vlan_if[vm_index], logging.info)
    ping_vlan(vms[0], dest=vm_vlan_ip[1], vlan_if=vm_vlan_if[0],
              session=sessions[0])
    netperf_vlan(client=params["main_vm"], server='vm2')

    exithandlers = "exithandlers__%s" % sub_type
    sub_exit_timeout = int(params.get("sub_exit_timeout", 10))
    start_time = time.time()
    end_time = start_time + float(sub_exit_timeout)

    while time.time() < end_time:
        logging.debug("%s (%f secs)", sub_type + " is running",
                      (time.time() - start_time))
        if env.data.get(exithandlers):
            break
        time.sleep(1)

    for sess in sessions:
        if sess:
            sess.close()
Exemple #11
0
def run(test, params, env):
    """
    Expose host MTU to guest test

    1) Boot up guest with param 'host_mtu=4000' in nic part
    2) Disable NetworkManager in guest
    3) set mtu of guest tap (eg: tap0) and physical nic (eg: eno1) to
       4000 in host
    4) check the mtu in guest
    5) ping from guest to external host with packet size 3972

    :param test: kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """

    def cleanup_ovs_ports(netdst, ports):
        """
        Clean up created ovs ports in this case

        :param netdst: netdst get from command line
        :param ports: existing ports need to be remain before this test
        """

        host_bridge = utils_net.find_bridge_manager(netdst)
        if utils_net.ovs_br_exists(netdst) is True:
            ports = set(host_bridge.list_ports(netdst)) - set(ports)
            for p in ports:
                utils_net.find_bridge_manager(netdst).del_port(netdst, p)

    netdst = params.get("netdst", "switch")
    host_bridge = utils_net.find_bridge_manager(netdst)
    if netdst in utils_net.Bridge().list_br():
        host_hw_interface = utils_net.Bridge().list_iface(netdst)[0]
    else:
        host_hw_interface = host_bridge.list_ports(netdst)
        tmp_ports = re.findall(r"t[0-9]{1,}-[a-zA-Z0-9]{6}",
                               ' '.join(host_hw_interface))
        if tmp_ports:
            for p in tmp_ports:
                host_bridge.del_port(netdst, p)
            host_hw_interface = host_bridge.list_ports(netdst)

    params["start_vm"] = "yes"
    env_process.preprocess_vm(test, params, env, params["main_vm"])

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    vm_iface = vm.get_ifname()
    # Get host interface original mtu value before setting
    if netdst in utils_net.Bridge().list_br():
        host_hw_iface = utils_net.Interface(host_hw_interface)
    elif utils_net.ovs_br_exists(netdst) is True:
        host_hw_iface = utils_net.Interface(' '.join(host_hw_interface))
    host_mtu_origin = host_hw_iface.get_mtu()

    utils_net.Interface(vm_iface).set_mtu(int(params["mtu_value"]))
    host_hw_iface.set_mtu(int(params["mtu_value"]))

    os_type = params.get("os_type", "linux")
    login_timeout = float(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=login_timeout)

    host_ip = utils_net.get_ip_address_by_interface(params["netdst"])
    if os_type == "linux":
        session.cmd_output_safe(params["nm_stop_cmd"])
        guest_ifname = utils_net.get_linux_ifname(session,
                                                  vm.get_mac_address())
        output = session.cmd_output_safe(
            params["check_linux_mtu_cmd"] % guest_ifname)
        error_context.context(output, logging.info)
        match_string = "mtu %s" % params["mtu_value"]
        if match_string not in output:
            test.fail("host mtu %s not exposed to guest" % params["mtu_value"])
    elif os_type == "windows":
        connection_id = utils_net.get_windows_nic_attribute(
            session, "macaddress", vm.get_mac_address(), "netconnectionid")
        output = session.cmd_output_safe(
            params["check_win_mtu_cmd"] % connection_id)
        error_context.context(output, logging.info)
        lines = output.strip().splitlines()
        lines_len = len(lines)

        line_table = lines[0].split('  ')
        line_value = lines[2].split('  ')
        while '' in line_table:
            line_table.remove('')
        while '' in line_value:
            line_value.remove('')
        index = 0
        for name in line_table:
            if re.findall("MTU", name):
                break
            index += 1
        mtu_value = line_value[index]
        logging.info("MTU is %s", mtu_value)
        if not int(mtu_value) == int(params["mtu_value"]):
            test.fail("Host mtu %s is not exposed to "
                      "guest!" % params["mtu_value"])

    logging.info("Ping from guest to host with packet size 3972")
    status, output = utils_test.ping(host_ip, 10, packetsize=3972,
                                     timeout=30, session=session)
    ratio = utils_test.get_loss_ratio(output)
    if ratio != 0:
        test.fail("Loss ratio is %s", ratio)

    # Restore host mtu after finish testing
    utils_net.Interface(vm_iface).set_mtu(host_mtu_origin)
    host_hw_iface.set_mtu(host_mtu_origin)

    if netdst not in utils_net.Bridge().list_br():
        cleanup_ovs_ports(netdst, host_hw_interface)
    session.close()