@@ -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))
@@ -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)
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@redhat.com> 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(-)