Add iperf VM/vhost creation

Change-Id: I27a59203f406120558f73bfcc12dca8835ae6361
Signed-off-by: John DeNisco <jdenisco@cisco.com>
diff --git a/extras/vpp_config/data/cloud-config.iso b/extras/vpp_config/data/cloud-config.iso
new file mode 100644
index 0000000..0c299fc
--- /dev/null
+++ b/extras/vpp_config/data/cloud-config.iso
Binary files differ
diff --git a/extras/vpp_config/data/iperf-centos.xml.template b/extras/vpp_config/data/iperf-centos.xml.template
new file mode 100644
index 0000000..9f585ec
--- /dev/null
+++ b/extras/vpp_config/data/iperf-centos.xml.template
@@ -0,0 +1,108 @@
+<domain type='kvm' id='54'>
+  <name>{vmname}</name>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <memoryBacking>
+    <hugepages>
+      <page size='2048' unit='KiB'/>
+    </hugepages>
+  </memoryBacking>
+  <vcpu placement='static'>1</vcpu>
+  <resource>
+    <partition>/machine</partition>
+  </resource>
+  <os>
+    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+    <apic/>
+  </features>
+  <cpu mode='host-model'>
+    <model fallback='allow'></model>
+  </cpu>
+  <clock offset='utc'>
+    <timer name='rtc' tickpolicy='catchup'/>
+    <timer name='pit' tickpolicy='delay'/>
+    <timer name='hpet' present='no'/>
+  </clock>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <pm>
+    <suspend-to-mem enabled='no'/>
+    <suspend-to-disk enabled='no'/>
+  </pm>
+  <devices>
+    <emulator>/usr/libexec/qemu-kvm</emulator>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='qcow2'/>
+      <source file='{imagename}'/>
+      <backingStore/>
+      <target dev='vda' bus='virtio'/>
+      <alias name='virtio-disk0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
+    </disk>
+    <disk type='file' device='cdrom'>
+      <driver name='qemu' type='raw'/>
+      <source file='{isoname}'/>
+      <backingStore/>
+      <target dev='hda' bus='ide'/>
+      <readonly/>
+      <alias name='ide0-0-0'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0' model='ich9-ehci1'>
+      <alias name='usb'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'>
+      <alias name='pci.0'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <alias name='ide'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='virtio-serial' index='0'>
+      <alias name='virtio-serial0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+    </controller>
+    <interface type='network'>
+      <mac address='52:54:00:4c:47:f3'/>
+      <source network='default' bridge='virbr0'/>
+      <target dev='vnet0'/>
+      <model type='virtio'/>
+      <alias name='net0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </interface>
+    <serial type='pty'>
+      <source path='/dev/pts/2'/>
+      <target port='0'/>
+      <alias name='serial0'/>
+    </serial>
+    <console type='pty' tty='/dev/pts/2'>
+      <source path='/dev/pts/2'/>
+      <target type='serial' port='0'/>
+      <alias name='serial0'/>
+    </console>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <graphics type='vnc' port='5900' autoport='yes' listen='127.0.0.1'>
+      <listen type='address' address='127.0.0.1'/>
+    </graphics>
+    <memballoon model='virtio'>
+      <alias name='balloon0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
+    </memballoon>
+  </devices>
+  <seclabel type='dynamic' model='selinux' relabel='yes'>
+    <label>system_u:system_r:svirt_t:s0:c532,c551</label>
+    <imagelabel>system_u:object_r:svirt_image_t:s0:c532,c551</imagelabel>
+  </seclabel>
+  <seclabel type='dynamic' model='dac' relabel='yes'>
+    <label>+107:+107</label>
+    <imagelabel>+107:+107</imagelabel>
+  </seclabel>
+</domain>
+
diff --git a/extras/vpp_config/data/iperf-ubuntu.xml.template b/extras/vpp_config/data/iperf-ubuntu.xml.template
new file mode 100644
index 0000000..a48a134
--- /dev/null
+++ b/extras/vpp_config/data/iperf-ubuntu.xml.template
@@ -0,0 +1,114 @@
+<domain type='kvm' id='54'>
+  <name>{vmname}</name>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <memoryBacking>
+    <hugepages>
+      <page size='2048' unit='KiB'/>
+    </hugepages>
+  </memoryBacking>
+  <vcpu placement='static'>1</vcpu>
+  <resource>
+    <partition>/machine</partition>
+  </resource>
+  <os>
+    <type arch='x86_64' machine='pc-i440fx-xenial'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+    <apic/>
+  </features>
+  <cpu mode='host-model'>
+    <model fallback='allow'></model>
+    <numa>
+      <cell id='0' cpus='0' memory='262144' unit='KiB' memAccess='shared'/>
+    </numa>
+  </cpu>
+  <clock offset='utc'>
+    <timer name='rtc' tickpolicy='catchup'/>
+    <timer name='pit' tickpolicy='delay'/>
+    <timer name='hpet' present='no'/>
+  </clock>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <pm>
+    <suspend-to-mem enabled='no'/>
+    <suspend-to-disk enabled='no'/>
+  </pm>
+  <devices>
+    <emulator>/usr/bin/kvm</emulator>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='qcow2'/>
+      <source file='{imagename}'/>
+      <backingStore/>
+      <target dev='vda' bus='virtio'/>
+      <alias name='virtio-disk0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
+    </disk>
+    <disk type='file' device='cdrom'>
+      <driver name='qemu' type='raw'/>
+      <source file='{isoname}'/>
+      <backingStore/>
+      <target dev='hda' bus='ide'/>
+      <readonly/>
+      <alias name='ide0-0-0'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0' model='ich9-ehci1'>
+      <alias name='usb'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'>
+      <alias name='pci.0'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <alias name='ide'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='virtio-serial' index='0'>
+      <alias name='virtio-serial0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+    </controller>
+    <interface type='network'>
+      <mac address='52:54:00:4c:47:f3'/>
+      <source network='default' bridge='virbr0'/>
+      <target dev='vnet0'/>
+      <model type='virtio'/>
+      <alias name='net0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </interface>
+    <interface type='vhostuser'>
+      <mac address='52:54:00:4c:47:f4'/>
+      <source type='unix' path='{vhostsocketname}' mode='client'/>
+      <model type='virtio'/>
+      <alias name='net1'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+    </interface>
+    <serial type='pty'>
+      <source path='/dev/pts/2'/>
+      <target port='0'/>
+      <alias name='serial0'/>
+    </serial>
+    <console type='pty' tty='/dev/pts/2'>
+      <source path='/dev/pts/2'/>
+      <target type='serial' port='0'/>
+      <alias name='serial0'/>
+    </console>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <graphics type='vnc' port='5900' autoport='yes' listen='127.0.0.1'>
+      <listen type='address' address='127.0.0.1'/>
+    </graphics>
+    <memballoon model='virtio'>
+      <alias name='balloon0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
+    </memballoon>
+  </devices>
+  <seclabel type='dynamic' model='apparmor' relabel='yes'>
+    <label>libvirt-2c4c9317-c7a5-4b37-b789-386ccda7348a</label>
+    <imagelabel>libvirt-2c4c9317-c7a5-4b37-b789-386ccda7348a</imagelabel>
+  </seclabel>
+</domain>
+
diff --git a/extras/vpp_config/data/startup.conf.template b/extras/vpp_config/data/startup.conf.template
index 912bbc4..19a8454 100644
--- a/extras/vpp_config/data/startup.conf.template
+++ b/extras/vpp_config/data/startup.conf.template
@@ -12,8 +12,8 @@
 
 cpu {{
 {cpu}
-  scheduler-policy fifo
-  scheduler-priority 50
+  # scheduler-policy fifo
+  # scheduler-priority 50
 
         ## In the VPP there is one main thread and optionally the user can create worker(s)
 	## The main thread and worker thread(s) can be pinned to CPU core(s) manually or automatically
diff --git a/extras/vpp_config/scripts/clean.sh b/extras/vpp_config/scripts/clean.sh
old mode 100755
new mode 100644
diff --git a/extras/vpp_config/scripts/cp-data.sh b/extras/vpp_config/scripts/cp-data.sh
old mode 100755
new mode 100644
index a0053dc..fa71661
--- a/extras/vpp_config/scripts/cp-data.sh
+++ b/extras/vpp_config/scripts/cp-data.sh
@@ -64,11 +64,16 @@
 sudo mkdir $ROOTDIR/vpp/vpp-config/dryrun
 sudo mkdir $ROOTDIR/vpp/vpp-config/scripts
 sudo mkdir $ROOTDIR/vpp/vpp-config/configs
+sudo mkdir $ROOTDIR/vpp/vpp-config/images
 sudo mkdir $ROOTDIR/vpp/vpp-config/dryrun/default
 sudo mkdir $ROOTDIR/vpp/vpp-config/dryrun/sysctl.d
 sudo mkdir $ROOTDIR/vpp/vpp-config/dryrun/vpp
+sudo cp scripts/dpdk-devbind.py $ROOTDIR/vpp/vpp-config/scripts/.
 sudo cp data/auto-config.yaml $ROOTDIR/vpp/vpp-config/configs/.
+sudo cp data/cloud-config.iso $ROOTDIR/vpp/vpp-config/configs/.
+sudo cp data/iperf-centos.xml.template $ROOTDIR/vpp/vpp-config/configs/.
+sudo cp data/iperf-ubuntu.xml.template $ROOTDIR/vpp/vpp-config/configs/.
+sudo cp data/xenial-mod.img $ROOTDIR/vpp/vpp-config/images/.
+sudo cp data/80-vpp.conf.template $ROOTDIR/vpp/vpp-config/dryrun/sysctl.d/.
 sudo cp data/grub.template $ROOTDIR/vpp/vpp-config/dryrun/default/.
 sudo cp data/startup.conf.template $ROOTDIR/vpp/vpp-config/dryrun/vpp/.
-sudo cp data/80-vpp.conf.template $ROOTDIR/vpp/vpp-config/dryrun/sysctl.d/.
-sudo cp scripts/dpdk-devbind.py $ROOTDIR/vpp/vpp-config/scripts/.
diff --git a/extras/vpp_config/scripts/dpdk-devbind.py b/extras/vpp_config/scripts/dpdk-devbind.py
old mode 100755
new mode 100644
diff --git a/extras/vpp_config/scripts/vpp-config b/extras/vpp_config/scripts/vpp-config
old mode 100755
new mode 100644
diff --git a/extras/vpp_config/setup.py b/extras/vpp_config/setup.py
index 6442f7c..c60162f 100644
--- a/extras/vpp_config/setup.py
+++ b/extras/vpp_config/setup.py
@@ -1,7 +1,7 @@
 from setuptools import setup
 
 setup(name="vpp_config",
-      version="18.01.1",
+      version="18.01.4",
       author="John DeNisco",
       author_email="jdenisco@cisco.com",
       description="VPP Configuration Utility",
@@ -14,6 +14,9 @@
       scripts=['scripts/vpp-config'],
       data_files=[('vpp/vpp-config/scripts', ['scripts/dpdk-devbind.py']),
                   ('vpp/vpp-config/configs', ['data/auto-config.yaml']),
+                  ('vpp/vpp-config/configs', ['data/cloud-config.iso']),
+                  ('vpp/vpp-config/configs', ['data/iperf-centos.xml.template']),
+                  ('vpp/vpp-config/configs', ['data/iperf-ubuntu.xml.template']),
                   ('vpp/vpp-config/dryrun/sysctl.d', ['data/80-vpp.conf.template']),
                   ('vpp/vpp-config/dryrun/default', ['data/grub.template']),
                   ('vpp/vpp-config/dryrun/vpp', ['data/startup.conf.template']),
diff --git a/extras/vpp_config/vpp_config.py b/extras/vpp_config/vpp_config.py
old mode 100755
new mode 100644
index dc1bc51..d9d6584
--- a/extras/vpp_config/vpp_config.py
+++ b/extras/vpp_config/vpp_config.py
@@ -464,14 +464,16 @@
     acfg.ipv4_interface_setup()
 
 
-def autoconfig_create_vm():
+def autoconfig_create_iperf_vm():
     """
     Setup IPv4 interfaces
 
     """
 
     acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
-    acfg.create_and_bridge_virtual_interfaces()
+    acfg.destroy_iperf_vm('iperf-server')
+    acfg.create_and_bridge_iperf_virtual_interface()
+    acfg.create_iperf_vm('iperf-server')
 
 
 def autoconfig_not_implemented():
@@ -491,12 +493,9 @@
 
     basic_menu_text = '\nWhat would you like to do?\n\n\
 1) List/Create Simple IPv4 Setup\n\
+2) Create an iperf VM and Connect to VPP an interface\n\
 9 or q) Back to main menu.'
 
-    # 1) List/Create Simple IPv4 Setup\n\
-    # 2) List/Create Create VM and Connect to VPP interfaces\n\
-    # 9 or q) Back to main menu.'
-
     print "{}".format(basic_menu_text)
 
     input_valid = False
@@ -534,8 +533,8 @@
         answer = autoconfig_basic_test_menu()
         if answer == '1':
             autoconfig_ipv4_setup()
-        # elif answer == '2':
-        #    autoconfig_create_vm()
+        elif answer == '2':
+            autoconfig_create_iperf_vm()
         elif answer == '9' or answer == 'q':
             return
         else:
@@ -664,6 +663,7 @@
             raise RuntimeError('{} failed on node {} {}'. format(cmd, node['host'], stderr))
 
 
+# noinspection PyUnresolvedReferences
 def execute_with_args(args):
     """
     Execute the configuration utility with agruments.
diff --git a/extras/vpp_config/vpplib/AutoConfig.py b/extras/vpp_config/vpplib/AutoConfig.py
index 26603e8..f435d18 100644
--- a/extras/vpp_config/vpplib/AutoConfig.py
+++ b/extras/vpp_config/vpplib/AutoConfig.py
@@ -33,6 +33,10 @@
 MIN_TOTAL_HUGE_PAGES = 1024
 MAX_PERCENT_FOR_HUGE_PAGES = 70
 
+IPERFVM_XML = 'configs/iperf-vm.xml'
+IPERFVM_IMAGE = 'images/xenial-mod.img'
+IPERFVM_ISO = 'configs/cloud-config.iso'
+
 
 class AutoConfig(object):
     """Auto Configuration Tools"""
@@ -56,6 +60,7 @@
         self._hugepage_config = ""
         self._clean = clean
         self._loadconfig()
+        self._sockfilename = ""
 
     def get_nodes(self):
         """
@@ -551,7 +556,9 @@
 
             # If total_vpp_cpus is 0 or is less than the numa nodes with ports
             #  then we shouldn't get workers
-            total_workers_node = total_vpp_cpus / len(ports_per_numa)
+            total_workers_node = 0
+            if len(ports_per_numa):
+                total_workers_node = total_vpp_cpus / len(ports_per_numa)
             total_main = 0
             if reserve_vpp_main_core:
                 total_main = 1
@@ -1637,16 +1644,20 @@
             question = "Would you like connect this interface {} to the VM [Y/n]? ".format(name)
             answer = self._ask_user_yn(question, 'y')
             if answer == 'y':
-                sockfilename = '/var/run/vpp/sock{}.sock'.format(inum)
+                sockfilename = '/var/run/vpp/{}.sock'.format(name.replace('/', '_'))
                 if os.path.exists(sockfilename):
                     os.remove(sockfilename)
                 cmd = 'vppctl create vhost-user socket {} server'.format(sockfilename)
                 (ret, stdout, stderr) = vpputl.exec_command(cmd)
                 if ret != 0:
-                    raise RuntimeError("Create vhost failed on node {} {}."
-                                       .format(node['host'], stderr))
+                    raise RuntimeError("Couldn't execute the command {}, {}.".format(cmd, stderr))
                 vintname = stdout.rstrip('\r\n')
 
+                cmd = 'chmod 777 {}'.format(sockfilename)
+                (ret, stdout, stderr) = vpputl.exec_command(cmd)
+                if ret != 0:
+                    raise RuntimeError("Couldn't execute the command {}, {}.".format(cmd, stderr))
+
                 interface = {'name': name, 'virtualinterface': '{}'.format(vintname),
                              'bridge': '{}'.format(inum)}
                 inum += 1
@@ -1710,3 +1721,184 @@
             print("\nA script as been created at {}".format(filename))
             print("This script can be run using the following:")
             print("vppctl exec {}\n".format(filename))
+
+    def _iperf_vm_questions(self, node):
+        """
+        Ask the user some questions and get a list of interfaces
+        and IPv4 addresses associated with those interfaces
+
+        :param node: Node dictionary.
+        :type node: dict
+        :returns: A list or interfaces with ip addresses
+        :rtype: list
+        """
+
+        vpputl = VPPUtil()
+        interfaces = vpputl.get_hardware(node)
+        if interfaces == {}:
+            return []
+
+        # First delete all the Virtual interfaces
+        for intf in sorted(interfaces.items()):
+            name = intf[0]
+            if name[:7] == 'Virtual':
+                cmd = 'vppctl delete vhost-user {}'.format(name)
+                (ret, stdout, stderr) = vpputl.exec_command(cmd)
+                if ret != 0:
+                    logging.debug('{} failed on node {} {}'.format(
+                        cmd, node['host'], stderr))
+
+        # Create a virtual interface, for each interface the user wants to use
+        interfaces = vpputl.get_hardware(node)
+        if interfaces == {}:
+            return []
+        interfaces_with_virtual_interfaces = []
+        inum = 1
+
+        while True:
+            print '\nPlease pick one interface to connect to the iperf VM.'
+            for intf in sorted(interfaces.items()):
+                name = intf[0]
+                if name == 'local0':
+                    continue
+
+                question = "Would you like connect this interface {} to the VM [y/N]? ".format(name)
+                answer = self._ask_user_yn(question, 'n')
+                if answer == 'y':
+                    self._sockfilename = '/var/run/vpp/{}.sock'.format(name.replace('/', '_'))
+                    if os.path.exists(self._sockfilename):
+                        os.remove(self._sockfilename)
+                    cmd = 'vppctl create vhost-user socket {} server'.format(self._sockfilename)
+                    (ret, stdout, stderr) = vpputl.exec_command(cmd)
+                    if ret != 0:
+                        raise RuntimeError("Couldn't execute the command {}, {}.".format(cmd, stderr))
+                    vintname = stdout.rstrip('\r\n')
+
+                    cmd = 'chmod 777 {}'.format(self._sockfilename)
+                    (ret, stdout, stderr) = vpputl.exec_command(cmd)
+                    if ret != 0:
+                        raise RuntimeError("Couldn't execute the command {}, {}.".format(cmd, stderr))
+
+                    interface = {'name': name, 'virtualinterface': '{}'.format(vintname),
+                                 'bridge': '{}'.format(inum)}
+                    inum += 1
+                    interfaces_with_virtual_interfaces.append(interface)
+                    return interfaces_with_virtual_interfaces
+
+    def create_and_bridge_iperf_virtual_interface(self):
+        """
+        After asking the user some questions, and create and bridge a virtual interface
+        to be used with iperf VM
+
+        """
+
+        for i in self._nodes.items():
+            node = i[1]
+
+            # Show the current bridge and interface configuration
+            print "\nThis the current bridge configuration:"
+            ifaces = VPPUtil.show_bridge(node)
+            question = "\nWould you like to keep this configuration [Y/n]? "
+            answer = self._ask_user_yn(question, 'y')
+            if answer == 'y':
+                self._sockfilename = '/var/run/vpp/{}.sock'.format(ifaces[0]['name'].replace('/', '_'))
+                if os.path.exists(self._sockfilename):
+                    continue
+
+            # Create a script that builds a bridge configuration with physical interfaces
+            # and virtual interfaces
+            ints_with_vints = self._iperf_vm_questions(node)
+            content = ''
+            for intf in ints_with_vints:
+                vhoststr = 'comment { The following command creates the socket }\n'
+                vhoststr += 'comment { and returns a virtual interface }\n'
+                vhoststr += 'comment {{ create vhost-user socket /var/run/vpp/sock{}.sock server }}\n'. \
+                    format(intf['bridge'])
+
+                setintdnstr = 'set interface state {} down\n'.format(intf['name'])
+
+                setintbrstr = 'set interface l2 bridge {} {}\n'.format(intf['name'], intf['bridge'])
+                setvintbrstr = 'set interface l2 bridge {} {}\n'.format(intf['virtualinterface'], intf['bridge'])
+
+                # set interface state VirtualEthernet/0/0/0 up
+                setintvststr = 'set interface state {} up\n'.format(intf['virtualinterface'])
+
+                # set interface state VirtualEthernet/0/0/0 down
+                setintupstr = 'set interface state {} up\n'.format(intf['name'])
+
+                content += vhoststr + setintdnstr + setintbrstr + setvintbrstr + setintvststr + setintupstr
+
+            # Write the content to the script
+            rootdir = node['rootdir']
+            filename = rootdir + '/vpp/vpp-config/scripts/create_iperf_vm'
+            with open(filename, 'w+') as sfile:
+                sfile.write(content)
+
+            # Execute the script
+            cmd = 'vppctl exec {}'.format(filename)
+            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+            if ret != 0:
+                logging.debug(stderr)
+
+            print("\nA script as been created at {}".format(filename))
+            print("This script can be run using the following:")
+            print("vppctl exec {}\n".format(filename))
+
+    @staticmethod
+    def destroy_iperf_vm(name):
+        """
+        After asking the user some questions, create a VM and connect the interfaces
+        to VPP interfaces
+
+        :param name: The name of the VM to be be destroyed
+        :type name: str
+        """
+
+        cmd = 'virsh list'
+        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+        if ret != 0:
+            logging.debug(stderr)
+            raise RuntimeError("Couldn't execute the command {} : {}".format(cmd, stderr))
+
+        if re.findall(name, stdout):
+            cmd = 'virsh destroy {}'.format(name)
+            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+            if ret != 0:
+                logging.debug(stderr)
+                raise RuntimeError("Couldn't execute the command {} : {}".format(cmd, stderr))
+
+    def create_iperf_vm(self, vmname):
+        """
+        After asking the user some questions, create a VM and connect the interfaces
+        to VPP interfaces
+
+        """
+
+        # Read the iperf VM template file
+        distro = VPPUtil.get_linux_distro()
+        if distro[0] == 'Ubuntu':
+            tfilename = '{}/vpp/vpp-config/configs/iperf-ubuntu.xml.template'.format(self._rootdir)
+        else:
+            tfilename = '{}/vpp/vpp-config/configs/iperf-centos.xml.template'.format(self._rootdir)
+
+        with open(tfilename, 'r') as tfile:
+            tcontents = tfile.read()
+        tfile.close()
+
+        # Add the variables
+        imagename = '{}/vpp/vpp-config/{}'.format(self._rootdir, IPERFVM_IMAGE)
+        isoname = '{}/vpp/vpp-config/{}'.format(self._rootdir, IPERFVM_ISO)
+        tcontents = tcontents.format(vmname=vmname, imagename=imagename, isoname=isoname,
+                                     vhostsocketname=self._sockfilename)
+
+        # Write the xml
+        ifilename = '{}/vpp/vpp-config/{}'.format(self._rootdir, IPERFVM_XML)
+        with open(ifilename, 'w+') as ifile:
+            ifile.write(tcontents)
+        ifile.close()
+
+        cmd = 'virsh create {}'.format(ifilename)
+        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+        if ret != 0:
+            logging.debug(stderr)
+            raise RuntimeError("Couldn't execute the command {} : {}".format(cmd, stderr))
diff --git a/extras/vpp_config/vpplib/VPPUtil.py b/extras/vpp_config/vpplib/VPPUtil.py
index 4ea9413..07d65b0 100644
--- a/extras/vpp_config/vpplib/VPPUtil.py
+++ b/extras/vpp_config/vpplib/VPPUtil.py
@@ -753,8 +753,10 @@
 
         :param node: VPP node.
         :type node: dict
+        :returns: A list of interfaces
         """
 
+        ifaces = []
         cmd = 'vppctl show bridge'
         (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
         if ret != 0:
@@ -766,7 +768,7 @@
         for line in lines:
             if line == 'no bridge-domains in use':
                 print line
-                return
+                return ifaces
             if len(line) == 0:
                 continue
 
@@ -781,4 +783,13 @@
                 raise RuntimeError('{} failed on node {} {} {}'.
                                    format(cmd, node['host'],
                                           stdout, stderr))
-            print stdout
+
+        lines = stdout.split('\r\n')
+        for line in lines:
+            iface = re.findall(r'[a-zA-z]+\d+/\d+/\d+', line)
+            if len(iface):
+                ifcidx ={'name': iface[0], 'index': line.split()[1] }
+                ifaces.append(ifcidx)
+
+        print stdout
+        return ifaces
\ No newline at end of file