Hi All: This patch tries to add tap network support in kvm-autotest. Multiple nics connected to different bridges could be achieved through this script. Public bridge is important for testing real network traffic and migration. The patch gives each nic with randomly generated mac address. The ip address required in the test could be dynamically probed through nmap/arp. Only the ip address of first NIC is used through the test. Example: nics = nic1 nic2 network = bridge bridge = switch ifup =/etc/qemu-ifup-switch ifdown =/etc/qemu-ifdown-switch This would make the virtual machine have two nics both of which are connected to a bridge with the name of 'switch'. Ifup/ifdown scripts are also specified. Another Example: nics = nic1 nic2 network = bridge bridge = switch bridge_nic2 = virbr0 ifup =/etc/qemu-ifup-switch ifup_nic2 = /etc/qemu-ifup-virbr0 This would makes the virtual machine have two nics: nic1 are connected to bridge 'switch' and nci2 are connected to bridge 'virbr0'. Public mode and user mode nic could also be mixed: nics = nic1 nic2 network = bridge network_nic2 = user Looking forward for comments and suggestions. From: jason <jasowang@xxxxxxxxxx> Date: Wed, 13 May 2009 16:15:28 +0800 Subject: [PATCH] Add tap networking support. --- client/tests/kvm_runtest_2/kvm_utils.py | 7 +++ client/tests/kvm_runtest_2/kvm_vm.py | 74 ++++++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/client/tests/kvm_runtest_2/kvm_utils.py b/client/tests/kvm_runtest_2/kvm_utils.py index be8ad95..0d1f7f8 100644 --- a/client/tests/kvm_runtest_2/kvm_utils.py +++ b/client/tests/kvm_runtest_2/kvm_utils.py @@ -773,3 +773,10 @@ def md5sum_file(filename, size=None): size -= len(data) f.close() return o.hexdigest() + +def random_mac(): + mac=[0x00,0x16,0x30, + random.randint(0x00,0x09), + random.randint(0x00,0x09), + random.randint(0x00,0x09)] + return ':'.join(map(lambda x: "%02x" %x,mac)) diff --git a/client/tests/kvm_runtest_2/kvm_vm.py b/client/tests/kvm_runtest_2/kvm_vm.py index fab839f..ea7dab6 100644 --- a/client/tests/kvm_runtest_2/kvm_vm.py +++ b/client/tests/kvm_runtest_2/kvm_vm.py @@ -105,6 +105,10 @@ class VM: self.qemu_path = qemu_path self.image_dir = image_dir self.iso_dir = iso_dir + self.macaddr = [] + for nic_name in kvm_utils.get_sub_dict_names(params,"nics"): + macaddr = kvm_utils.random_mac() + self.macaddr.append(macaddr) def verify_process_identity(self): """Make sure .pid really points to the original qemu process. @@ -189,9 +193,25 @@ class VM: for nic_name in kvm_utils.get_sub_dict_names(params, "nics"): nic_params = kvm_utils.get_sub_dict(params, nic_name) qemu_cmd += " -net nic,vlan=%d" % vlan + net = nic_params.get("network") + if net == "bridge": + qemu_cmd += ",macaddr=%s" % self.macaddr[vlan] if nic_params.get("nic_model"): qemu_cmd += ",model=%s" % nic_params.get("nic_model") - qemu_cmd += " -net user,vlan=%d" % vlan + if net == "bridge": + qemu_cmd += " -net tap,vlan=%d" % vlan + ifup = nic_params.get("ifup") + if ifup: + qemu_cmd += ",script=%s" % ifup + else: + qemu_cmd += ",script=/etc/qemu-ifup" + ifdown = nic_params.get("ifdown") + if ifdown: + qemu_cmd += ",downscript=%s" % ifdown + else: + qemu_cmd += ",downscript=no" + else: + qemu_cmd += " -net user,vlan=%d" % vlan vlan += 1 mem = params.get("mem") @@ -206,11 +226,11 @@ class VM: extra_params = params.get("extra_params") if extra_params: qemu_cmd += " %s" % extra_params - + for redir_name in kvm_utils.get_sub_dict_names(params, "redirs"): redir_params = kvm_utils.get_sub_dict(params, redir_name) guest_port = int(redir_params.get("guest_port")) - host_port = self.get_port(guest_port) + host_port = self.get_port(guest_port,True) qemu_cmd += " -redir tcp:%s::%s" % (host_port, guest_port) if params.get("display") == "vnc": @@ -467,27 +487,57 @@ class VM: If port redirection is used, return 'localhost' (the guest has no IP address of its own). Otherwise return the guest's IP address. """ - # Currently redirection is always used, so return 'localhost' - return "localhost" + if self.params.get("network") == "bridge": + # probing ip address through arp + bridge_name = self.params['bridge'] + macaddr = self.macaddr[0] + lines = os.popen("arp -a").readlines() + for line in lines: + if macaddr in line: + return line.split()[1].strip('()') + + # probing ip address through nmap + lines = os.popen("ip route").readlines() + birdge_network = None + for line in lines: + if bridge_name in line: + bridge_network = line.split()[0] + break + + if bridge_network != None: + lines = os.popen("nmap -sP -n %s" % bridge_network).readlines() + lastline = None + for line in lines: + if macaddr in line: + return lastline.split()[1] + lastline = line + + # could not found ip address + return None + else: + return "localhost" - def get_port(self, port): + def get_port(self, port, query = False): """Return the port in host space corresponding to port in guest space. If port redirection is used, return the host port redirected to guest port port. Otherwise return port. """ - # Currently redirection is always used, so use the redirs dict - if self.redirs.has_key(port): - return self.redirs[port] + + if query == True or self.params.get("network") != "bridge": + if self.redirs.has_key(port): + return self.redirs[port] + else: + kvm_log.debug("Warning: guest port %s requested but not redirected" % port) + return None else: - kvm_log.debug("Warning: guest port %s requested but not redirected" % port) - return None + return port def is_sshd_running(self, timeout=10): """Return True iff the guest's SSH port is responsive.""" address = self.get_address() port = self.get_port(int(self.params.get("ssh_port"))) - if not port: + if not port or not address: return False return kvm_utils.is_sshd_running(address, port, timeout=timeout) -- 1.5.5.6 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html