WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Add new networking infrastructure to Xm-Test. The goal i

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Add new networking infrastructure to Xm-Test. The goal is to make
From: Xen staging patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 08 May 2006 13:58:21 +0000
Delivery-date: Mon, 08 May 2006 07:05:34 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User stekloff@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Node ID 51908f382f926475834a807a6e7e357212c0db28
# Parent  bef7f5fcf207b97f74eeb2e68fa00a81e3a81f85
Add new networking infrastructure to Xm-Test. The goal is to make
creating domains with networking very easy. This patch:

1) Adds new XenDevice class, with the XenNetDevice subclass. These
   classes represent devices for xm-test and are tied to XenDomains.
   This can eventually be used for block devices as well. Currently,
   devices must be added to domains prior to starting the domain. The
   attach and detach needs to be handled.

2) Adds a new NetConfig class to handle configuring the network
   environment in which the tests run. This patch only handles ranges
   of IPs in a bridged environment. DHCP needs to be added as well as
   handling NAT and routed environments.

3) Modifies XenDomain class to handle XenDevices.

4) Adds new configuration options for defining a range of IPs, their
   network address, and their netmask.

5) Removes the old Network.py and Network class.

6) Modifies the existing tests to use the new infrastructure.

7) Adds some documentation to help creating domains.

Signed-off-by: Daniel Stekloff <dsteklof@xxxxxxxxxx>
---
 tools/xm-test/lib/XmTestLib/Network.py                   |  110 ------
 tools/xm-test/configure.ac                               |   30 +
 tools/xm-test/lib/XmTestLib/NetConfig.py                 |  264 ++++++++++++++
 tools/xm-test/lib/XmTestLib/XenDevice.py                 |  271 +++++++++++++++
 tools/xm-test/lib/XmTestLib/XenDomain.py                 |   79 ++++
 tools/xm-test/lib/XmTestLib/__init__.py                  |   10 
 tools/xm-test/lib/XmTestLib/config.py.in                 |    4 
 tools/xm-test/tests/create/13_create_multinic_pos.py     |    7 
 tools/xm-test/tests/network/02_network_local_ping_pos.py |   27 -
 tools/xm-test/tests/network/03_network_local_tcp_pos.py  |   30 -
 tools/xm-test/tests/network/04_network_local_udp_pos.py  |   30 -
 tools/xm-test/tests/network/05_network_dom0_ping_pos.py  |   36 -
 tools/xm-test/tests/network/06_network_dom0_tcp_pos.py   |   41 --
 tools/xm-test/tests/network/07_network_dom0_udp_pos.py   |   36 -
 tools/xm-test/tests/network/11_network_domU_ping_pos.py  |   49 +-
 tools/xm-test/tests/network/12_network_domU_tcp_pos.py   |   49 +-
 tools/xm-test/tests/network/13_network_domU_udp_pos.py   |   49 +-
 17 files changed, 777 insertions(+), 345 deletions(-)

diff -r bef7f5fcf207 -r 51908f382f92 tools/xm-test/configure.ac
--- a/tools/xm-test/configure.ac        Thu May 04 14:22:17 2006 +0100
+++ b/tools/xm-test/configure.ac        Thu May 04 14:22:29 2006 +0100
@@ -37,6 +37,36 @@ fi
 
 AM_CONDITIONAL(HVM, test x$ENABLE_HVM = xTrue)
 AC_SUBST(ENABLE_HVM)
+
+# Network needs to know ips to use: dhcp or a range of IPs in the form
+# of: 192.168.1.1-192.168.1.100
+# If not dhcp, a netmask and network address must be supplied. Defaults to
+# zeroconf range.
+NET_IP_RANGE="169.254.0.1-169.254.255.255"
+AC_ARG_WITH(net-ip-range,
+       [  --with-net-ip-range=ip-range Set a range of ip addresses to use for 
xm-test guest domain networks. Can specify dhcp or a range of IPs: 
192.168.1.1-192.168.1.100 [[default="169.254.0.1-169.254.255.255"]]],
+       [ NET_IP_RANGE="$withval" ])
+
+iprange=`echo $NET_IP_RANGE | perl -e 'while(<>) { print if 
/\d+\.\d+\.\d+\.\d+-\d+\.\d+\.\d+\.\d+/ }'`
+
+NETWORK_ADDRESS="169.254.0.0"
+AC_ARG_WITH(network-address,
+       [ --with-network-address=ip Set network address to use with ip range 
[[default="169.254.0.0"]]],
+       [ NETWORK_ADDRESS="$withval" ])
+
+NETMASK="255.255.0.0"
+AC_ARG_WITH(netmask,
+       [ --with-netmask=mask Set netmask to use with ip range 
[[default="255.255.0.0"]]],
+       [ NETMASK="$withval" ])
+
+if test "x$NET_IP_RANGE" != "xdhcp" && test -z "$iprange"
+then
+       AC_MSG_ERROR(Invalid net-ip-range.)
+fi
+
+AC_SUBST(NET_IP_RANGE)
+AC_SUBST(NETWORK_ADDRESS)
+AC_SUBST(NETMASK)
 
 AC_ARG_WITH(hvm-kernel,
       [[  --with-hvm-kernel=kernel       Use this kernel for hvm disk.img 
testing]],
diff -r bef7f5fcf207 -r 51908f382f92 tools/xm-test/lib/XmTestLib/XenDomain.py
--- a/tools/xm-test/lib/XmTestLib/XenDomain.py  Thu May 04 14:22:17 2006 +0100
+++ b/tools/xm-test/lib/XmTestLib/XenDomain.py  Thu May 04 14:22:29 2006 +0100
@@ -28,6 +28,7 @@ from Test import *
 from Test import *
 from config import *
 from Console import *
+from XenDevice import *
 
 BLOCK_ROOT_DEV = "hda"
 
@@ -195,6 +196,8 @@ class XenDomain:
 
         self.config = config
         self.console = None
+        self.devices = {}
+        self.netEnv = "bridge"
 
         # Set domain type, either PV for ParaVirt domU or HVM for 
         # FullVirt domain
@@ -216,6 +219,10 @@ class XenDomain:
         if self.getDomainType() == "HVM":
             waitForBoot()
 
+        # Go through device list and run console cmds
+        for dev in self.devices.keys():
+            self.devices[dev].execAddCmds()
+
         if self.console and noConsole == True:
             self.closeConsole()
 
@@ -229,6 +236,8 @@ class XenDomain:
         prog = "xm"
         cmd = " shutdown "
 
+        self.removeAllDevices()
+
         if self.console:
             self.closeConsole()
 
@@ -239,6 +248,8 @@ class XenDomain:
     def destroy(self):
         prog = "xm"
         cmd = " destroy "
+
+        self.removeAllDevices()
 
         if self.console:
             self.closeConsole()
@@ -273,6 +284,50 @@ class XenDomain:
         self.console.sendInput("input")
 
         return self.console
+
+    def newDevice(self, Device, *args):
+        """Device Factory: Generic factory for creating new XenDevices.
+           All device creation should be done through the XenDomain
+           factory. Supply a XenDevice instance and its args and the
+           constructor will be called."""
+        # Make sure device with id hasn't already been added
+        if self.devices.has_key(args[0]):
+            raise DeviceError("Error: Domain already has device %s" % args[0])
+
+        # Call constructor for supplied Device instance
+        dargs = (self,)
+        dargs += args
+        dev = apply(Device, dargs)
+
+        if self.isRunning():
+            # Note: This needs to be done, XenDevice should have an attach
+            #       method.
+            print "Domain is running, need to attach new device to domain."
+
+        self.devices[dev.id] = dev
+        self.config.appOpt(dev.configNode, str(dev))
+        return dev
+
+    def removeDevice(self, id):
+        if self.devices.has_key(id):
+            self.devices[id].removeDevice()
+
+    def removeAllDevices(self):
+        for k in self.devices.keys():
+            self.removeDevice(k)
+
+    def isRunning(self):
+        return isDomainRunning(self.name)
+
+    def getNetEnv(self):
+        # We need to know the network environment: bridge, NAT, or routed.
+        return self.netEnv
+
+    def getDevice(self, id):
+        dev = self.devices[id]
+        if dev:
+            return dev
+        print "Device %s not found for domain %s" % (id, self.getName())
 
 
 class XmTestDomain(XenDomain):
@@ -298,6 +353,30 @@ class XmTestDomain(XenDomain):
     def minSafeMem(self):
         return 32
 
+class XmTestNetDomain(XmTestDomain):
+
+    def __init__(self, name=None, extraConfig=None, baseConfig=configDefaults):
+        """Create a new xm-test domain with one network device
+        @param name: The requested domain name
+        @param extraConfig: Additional configuration options
+        @param baseConfig: The initial configuration defaults to use
+        """
+        config = XenConfig()
+        config.setOpts(baseConfig)
+        if extraConfig:
+            config.setOpts(extraConfig)
+
+        if name:
+            config.setOpt("name", name)
+        elif not config.getOpt("name"):
+            config.setOpt("name", getUniqueName())
+
+        XenDomain.__init__(self, config.getOpt("name"), config=config)
+
+        # Add one network devices to domain
+        self.newDevice(XenNetDevice, "eth0")
+
+
 if __name__ == "__main__":
 
     c = XenConfig()
diff -r bef7f5fcf207 -r 51908f382f92 tools/xm-test/lib/XmTestLib/__init__.py
--- a/tools/xm-test/lib/XmTestLib/__init__.py   Thu May 04 14:22:17 2006 +0100
+++ b/tools/xm-test/lib/XmTestLib/__init__.py   Thu May 04 14:22:29 2006 +0100
@@ -4,11 +4,15 @@
 #
 
 from Console import *
-from Network import *
 from Test import *
 from Xm import *
 from XenDomain import *
 from config import *
+from XenDevice import *
+from NetConfig import *
+
+# Make sure xen modules are in path
+sys.path.append('/usr/lib/python')
 
 # Give this test a clean slate
 destroyAllDomUs();
@@ -18,6 +22,8 @@ else:
 else:
     verbose = False
 
-
 if verbose:
     timeStamp()
+
+# We need to track network configuration, like ips, etc.
+xmtest_netconf = NetConfig()
diff -r bef7f5fcf207 -r 51908f382f92 tools/xm-test/lib/XmTestLib/config.py.in
--- a/tools/xm-test/lib/XmTestLib/config.py.in  Thu May 04 14:22:17 2006 +0100
+++ b/tools/xm-test/lib/XmTestLib/config.py.in  Thu May 04 14:22:29 2006 +0100
@@ -1,4 +1,6 @@
 #!/usr/bin/python
 
 ENABLE_HVM_SUPPORT = @ENABLE_HVM@
-
+NETWORK_IP_RANGE = "@NET_IP_RANGE@"
+NETWORK = "@NETWORK_ADDRESS@"
+NETMASK = "@NETMASK@"
diff -r bef7f5fcf207 -r 51908f382f92 
tools/xm-test/tests/create/13_create_multinic_pos.py
--- a/tools/xm-test/tests/create/13_create_multinic_pos.py      Thu May 04 
14:22:17 2006 +0100
+++ b/tools/xm-test/tests/create/13_create_multinic_pos.py      Thu May 04 
14:22:29 2006 +0100
@@ -5,17 +5,14 @@
 
 from XmTestLib import *
 
-# The current device model, qemu-dm, only supports 8 MAX_NICS currently.
+# The device model, qemu-dm, only supports 8 MAX_NICS currently.
 if ENABLE_HVM_SUPPORT:
     MAX_NICS = 8
-    nic = "type=ioemu, bridge=xenbr0"
 else:
     MAX_NICS = 10
-    nic = ''
 
 for i in range(0,MAX_NICS):
-    config = {"vif": [ nic ] * i}
-    domain = XmTestDomain(extraConfig=config)
+    domain = XmTestNetDomain()
 
     try:
         console = domain.start()
diff -r bef7f5fcf207 -r 51908f382f92 
tools/xm-test/tests/network/02_network_local_ping_pos.py
--- a/tools/xm-test/tests/network/02_network_local_ping_pos.py  Thu May 04 
14:22:17 2006 +0100
+++ b/tools/xm-test/tests/network/02_network_local_ping_pos.py  Thu May 04 
14:22:29 2006 +0100
@@ -16,24 +16,17 @@ pingsizes = [ 1, 48, 64, 512, 1440, 1500
 pingsizes = [ 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192, 
               32767, 65507 ]
 
-
-
 from XmTestLib import *
 rc = 0
 
-Net = XmNetwork()
+# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(2) == False:
+    SKIP("Don't have enough free configured IPs to run this test")
 
-# read an IP address from the config
-ip   = Net.ip("dom1", "eth0")
-mask = Net.mask("dom1", "eth0")
+domain = XmTestDomain()
+domain.newDevice(XenNetDevice, "eth0")
 
-# Fire up a guest domain w/1 nic
-if ENABLE_HVM_SUPPORT:
-    config = {"vif" : ['type=ioemu']}
-else:
-    config = {"vif" : ['ip=%s' % ip ]}
-
-domain = XmTestDomain(extraConfig=config)
 try:
     console = domain.start()
 except DomainError, e:
@@ -43,10 +36,7 @@ except DomainError, e:
     FAIL(str(e))
 
 try:
-    # Bring up the "lo" interface.
-    console.runCmd("ifconfig lo 127.0.0.1")
-
-    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
+    console.setHistorySaveCmds(value=True)
 
     # First the loopback pings
     lofails=""
@@ -57,6 +47,8 @@ try:
 
     # Next comes eth0
     eth0fails=""
+    netdev = domain.getDevice("eth0")
+    ip = netdev.getNetDevIP()
     for size in pingsizes:
         out = console.runCmd("ping -q -c 1 -s " + str(size) + " " + ip)
         if out["return"]:
@@ -66,6 +58,7 @@ except NetworkError, e:
 except NetworkError, e:
         FAIL(str(e))
 
+domain.stop()
 
 # Tally up failures
 failures=""
diff -r bef7f5fcf207 -r 51908f382f92 
tools/xm-test/tests/network/03_network_local_tcp_pos.py
--- a/tools/xm-test/tests/network/03_network_local_tcp_pos.py   Thu May 04 
14:22:17 2006 +0100
+++ b/tools/xm-test/tests/network/03_network_local_tcp_pos.py   Thu May 04 
14:22:29 2006 +0100
@@ -17,28 +17,18 @@ trysizes = [ 1, 48, 64, 512, 1440, 1448,
 trysizes = [ 1, 48, 64, 512, 1440, 1448, 1500, 1505, 4096, 4192, 
               32767, 65495 ]
 
-
 from XmTestLib import *
 rc = 0
 
-Net = XmNetwork()
-
-try:
-    # read an IP address from the config
-    ip   = Net.ip("dom1", "eth0")
-    mask = Net.mask("dom1", "eth0")
-except NetworkError, e:
-    FAIL(str(e))
+# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(2) == False:
+    SKIP("Don't have enough free configured IPs to run this test")
 
 # Fire up a guest domain w/1 nic
-if ENABLE_HVM_SUPPORT:
-    brg = "xenbr0"
-    config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
-else:
-    brg = None
-    config = {"vif" : ['ip=%s' % ip]}
+domain = XmTestDomain()
+domain.newDevice(XenNetDevice, "eth0")
 
-domain = XmTestDomain(extraConfig=config)
 try:
     console = domain.start()
 except DomainError, e:
@@ -48,10 +38,7 @@ except DomainError, e:
     FAIL(str(e))
 
 try:
-    # Bring up the "lo" interface.
-    console.runCmd("ifconfig lo 127.0.0.1")
-
-    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
+    console.setHistorySaveCmds(value=True)
 
     # First do loopback 
     lofails=""
@@ -63,6 +50,8 @@ try:
 
     # Next comes eth0
     eth0fails=""
+    netdev = domain.getDevice("eth0")
+    ip = netdev.getNetDevIP()
     for size in trysizes:
         out = console.runCmd("hping2 " + ip + " -E /dev/urandom -q -c 20 "
               + "--fast -d "+ str(size))
@@ -73,6 +62,7 @@ except NetworkError, e:
 except NetworkError, e:
         FAIL(str(e))
 
+domain.stop()
 
 # Tally up failures
 failures=""
diff -r bef7f5fcf207 -r 51908f382f92 
tools/xm-test/tests/network/04_network_local_udp_pos.py
--- a/tools/xm-test/tests/network/04_network_local_udp_pos.py   Thu May 04 
14:22:17 2006 +0100
+++ b/tools/xm-test/tests/network/04_network_local_udp_pos.py   Thu May 04 
14:22:29 2006 +0100
@@ -20,24 +20,14 @@ from XmTestLib import *
 from XmTestLib import *
 rc = 0
 
-Net = XmNetwork()
+# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(2) == False:
+    SKIP("Don't have enough free configured IPs to run this test")
 
-try:
-    # read an IP address from the config
-    ip   = Net.ip("dom1", "eth0")
-    mask = Net.mask("dom1", "eth0")
-except NetworkError, e:
-    FAIL(str(e))
+domain = XmTestDomain()
+domain.newDevice(XenNetDevice, "eth0")
 
-# Fire up a guest domain w/1 nic
-if ENABLE_HVM_SUPPORT:
-    brg = "xenbr0"
-    config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
-else:
-    brg = None
-    config = {"vif" : ['ip=%s' % ip]}
-
-domain = XmTestDomain(extraConfig=config)
 try:
     console = domain.start()
 except DomainError, e:
@@ -47,10 +37,7 @@ except DomainError, e:
     FAIL(str(e))
 
 try:
-    # Bring up the "lo" interface.
-    console.runCmd("ifconfig lo 127.0.0.1")
-
-    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
+    console.setHistorySaveCmds(value=True)
 
     # First do loopback 
     lofails=""
@@ -63,6 +50,8 @@ try:
 
     # Next comes eth0
     eth0fails=""
+    netdev = domain.getDevice("eth0")
+    ip = netdev.getNetDevIP()
     for size in trysizes:
         out = console.runCmd("hping2 " + ip + " -E /dev/urandom -2 -q -c 20 "
               + "--fast -d " + str(size))
@@ -74,6 +63,7 @@ except NetworkError, e:
 except NetworkError, e:
         FAIL(str(e))
 
+domain.stop()
 
 # Tally up failures
 failures=""
diff -r bef7f5fcf207 -r 51908f382f92 
tools/xm-test/tests/network/05_network_dom0_ping_pos.py
--- a/tools/xm-test/tests/network/05_network_dom0_ping_pos.py   Thu May 04 
14:22:17 2006 +0100
+++ b/tools/xm-test/tests/network/05_network_dom0_ping_pos.py   Thu May 04 
14:22:29 2006 +0100
@@ -16,29 +16,18 @@ pingsizes = [ 1, 48, 64, 512, 1440, 1500
 pingsizes = [ 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192, 
                 32767, 65507 ]
 
-
-
 from XmTestLib import *
 rc = 0
 
-Net = XmNetwork()
-
-try:
-    # read an IP address from the config
-    ip     = Net.ip("dom1", "eth0")
-    mask   = Net.mask("dom1", "eth0")
-except NetworkError, e:
-        FAIL(str(e))
+# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(2) == False:
+    SKIP("Don't have enough free configured IPs to run this test")
 
 # Fire up a guest domain w/1 nic
-if ENABLE_HVM_SUPPORT:
-    brg = "xenbr0"
-    config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
-else:
-    config = {"vif" : ['ip=%s' % ip ]}
-    brg = None
+domain = XmTestDomain()
+domain.newDevice(XenNetDevice, "eth0")
 
-domain = XmTestDomain(extraConfig=config)
 try:
     console = domain.start()
 except DomainError, e:
@@ -48,16 +37,10 @@ except DomainError, e:
     FAIL(str(e))
 
 try:
-    # Add a suitable dom0 IP address 
-    dom0ip = Net.ip("dom0", "eth0", todomname=domain.getName(), toeth="eth0", 
bridge=brg)
-except NetworkError, e:
-        FAIL(str(e))
-
-try:
-    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
-
     # Ping dom0
     fails=""
+    netdev = domain.getDevice("eth0")
+    dom0ip = netdev.getDom0AliasIP()
     for size in pingsizes:
         out = console.runCmd("ping -q -c 1 -s " + str(size) + " " + dom0ip)
         if out["return"]:
@@ -65,6 +48,7 @@ except ConsoleError, e:
 except ConsoleError, e:
         FAIL(str(e))
 
+domain.stop()
+
 if len(fails):
     FAIL("Ping to dom0 failed for size" + fails + ".")
-
diff -r bef7f5fcf207 -r 51908f382f92 
tools/xm-test/tests/network/06_network_dom0_tcp_pos.py
--- a/tools/xm-test/tests/network/06_network_dom0_tcp_pos.py    Thu May 04 
14:22:17 2006 +0100
+++ b/tools/xm-test/tests/network/06_network_dom0_tcp_pos.py    Thu May 04 
14:22:29 2006 +0100
@@ -16,31 +16,21 @@ trysizes = [ 1, 48, 64, 512, 1440, 1500,
 trysizes = [ 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192, 
                 32767, 65495 ]
 
-
-
 from XmTestLib import *
 rc = 0
 
-Net = XmNetwork()
+# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(2) == False:
+    SKIP("Don't have enough free configured IPs to run this test")
+
+# Fire up a guest domain w/1 nic
+domain = XmTestDomain()
+domain.newDevice(XenNetDevice, "eth0")
 
 try:
-    # read an IP address from the config
-    ip     = Net.ip("dom1", "eth0")
-    mask   = Net.mask("dom1", "eth0")
-except NetworkError, e:
-        FAIL(str(e))
-
-# Fire up a guest domain w/1 nic
-if ENABLE_HVM_SUPPORT:
-    brg = "xenbr0"
-    config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
-else:
-    brg = None
-    config = {"vif"  : ["ip=%s" % ip]}
-
-domain = XmTestDomain(extraConfig=config)
-try:
     console = domain.start()
+    console.setHistorySaveCmds(value=True)
 except DomainError, e:
     if verbose:
         print "Failed to create test domain because:"
@@ -48,16 +38,10 @@ except DomainError, e:
     FAIL(str(e))
 
 try:
-    # Add a suitable dom0 IP address 
-    dom0ip = Net.ip("dom0", "eth0", todomname=domain.getName(), toeth="eth0", 
bridge=brg)
-except NetworkError, e:
-        FAIL(str(e))
-
-try:
-    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
-
     # Ping dom0
     fails=""
+    netdev = domain.getDevice("eth0")
+    dom0ip = netdev.getDom0AliasIP()
     for size in trysizes:
         out = console.runCmd("hping2 " + dom0ip + " -E /dev/urandom -q -c 20 "
               + "--fast -d " + str(size))
@@ -67,6 +51,7 @@ except ConsoleError, e:
 except ConsoleError, e:
         FAIL(str(e))
 
+domain.stop()
+
 if len(fails):
     FAIL("TCP hping2 to dom0 failed for size" + fails + ".")
-
diff -r bef7f5fcf207 -r 51908f382f92 
tools/xm-test/tests/network/07_network_dom0_udp_pos.py
--- a/tools/xm-test/tests/network/07_network_dom0_udp_pos.py    Thu May 04 
14:22:17 2006 +0100
+++ b/tools/xm-test/tests/network/07_network_dom0_udp_pos.py    Thu May 04 
14:22:29 2006 +0100
@@ -16,29 +16,18 @@ trysizes = [ 1, 48, 64, 512, 1440, 1500,
 trysizes = [ 1, 48, 64, 512, 1440, 1500, 1505, 4096, 4192, 
                 32767, 65495 ]
 
-
-
 from XmTestLib import *
 rc = 0
 
-Net = XmNetwork()
-
-try:
-    # read an IP address from the config
-    ip     = Net.ip("dom1", "eth0")
-    mask   = Net.mask("dom1", "eth0")
-except NetworkError, e:
-        FAIL(str(e))
+# Test creates 1 domain, which requires 2 ips: 1 for the domains and 1 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(2) == False:
+    SKIP("Don't have enough free configured IPs to run this test")
 
 # Fire up a guest domain w/1 nic
-if ENABLE_HVM_SUPPORT:
-    brg = "xenbr0"
-    config = {"vif" : ['type=ioemu, bridge=%s' % brg]}
-else:
-    brg = None
-    config = {"vif"  : ["ip=%s" % ip]}
+domain = XmTestDomain()
+domain.newDevice(XenNetDevice, "eth0")
 
-domain = XmTestDomain(extraConfig=config)
 try:
     console = domain.start()
 except DomainError, e:
@@ -48,16 +37,10 @@ except DomainError, e:
     FAIL(str(e))
 
 try:
-    # Add a suitable dom0 IP address 
-    dom0ip = Net.ip("dom0", "eth0", todomname=domain.getName(), toeth="eth0", 
bridge=brg)
-except NetworkError, e:
-        FAIL(str(e))
-
-try:
-    console.runCmd("ifconfig eth0 inet "+ip+" netmask "+mask+" up")
-
     # Ping dom0
     fails=""
+    netdev = domain.getDevice("eth0")
+    dom0ip = netdev.getDom0AliasIP()
     for size in trysizes:
         out = console.runCmd("hping2 " + dom0ip + " -E /dev/urandom -2 -q -c 
20"
              + " --fast -d " + str(size))
@@ -67,6 +50,7 @@ except ConsoleError, e:
 except ConsoleError, e:
         FAIL(str(e))
 
+domain.stop()
+
 if len(fails):
     FAIL("UDP hping2 to dom0 failed for size" + fails + ".")
-
diff -r bef7f5fcf207 -r 51908f382f92 
tools/xm-test/tests/network/11_network_domU_ping_pos.py
--- a/tools/xm-test/tests/network/11_network_domU_ping_pos.py   Thu May 04 
14:22:17 2006 +0100
+++ b/tools/xm-test/tests/network/11_network_domU_ping_pos.py   Thu May 04 
14:22:29 2006 +0100
@@ -17,50 +17,37 @@ pingsizes = [ 1, 48, 64, 512, 1440, 1500
 
 from XmTestLib import *
 
-def netDomain(ip):
-    if ENABLE_HVM_SUPPORT:
-        config = {"vif" : ['type=ioemu']}
-    else:
-        config = {"vif" : ['ip=%s' % ip ]}
+def netDomain():
 
-    dom = XmTestDomain(extraConfig=config)
+    dom = XmTestDomain()
+    dom.newDevice(XenNetDevice, "eth0")
     try:
         console = dom.start()
+        console.setHistorySaveCmds(value=True)
     except DomainError, e:
         if verbose:
             print "Failed to create test domain because:"
             print e.extra
         FAIL(str(e))
-    return console
+    return dom
     
 rc = 0
 
-Net = XmNetwork()
+# Test creates 2 domains, which requires 4 ips: 2 for the domains and 2 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(4) == False:
+    SKIP("Don't have enough free configured IPs to run this test")
+
+# Fire up a pair of guest domains w/1 nic each
+pinger = netDomain()
+pinger_console = pinger.getConsole()
+victim = netDomain()
 
 try:
-    # pick an IP address 
-    ip1   = Net.ip("dom1", "eth2")
-    mask1 = Net.mask("dom1", "eth2")
-except NetworkError, e:
-    FAIL(str(e))
-
-try:
-    # pick another IP address 
-    ip2   = Net.ip("dom2", "eth2")
-    mask2 = Net.mask("dom2", "eth2")
-except NetworkError, e:
-    FAIL(str(e))
-
-# Fire up a pair of guest domains w/1 nic each
-pinger_console = netDomain(ip1)
-victim_console = netDomain(ip2)
-
-try:
-    pinger_console.runCmd("ifconfig eth0 inet "+ip1+" netmask "+mask1+" up")
-    victim_console.runCmd("ifconfig eth0 inet "+ip2+" netmask "+mask2+" up")
-
     # Ping the victim over eth0
     fails=""
+    v_netdev = victim.getDevice("eth0")
+    ip2 = v_netdev.getNetDevIP()
     for size in pingsizes:
         out = pinger_console.runCmd("ping -q -c 1 -s " + str(size) + " " + ip2)
         if out["return"]:
@@ -68,6 +55,8 @@ except ConsoleError, e:
 except ConsoleError, e:
     FAIL(str(e))
 
+pinger.stop()
+victim.stop()
+
 if len(fails):
     FAIL("Ping failed for size" + fails + ".")
-
diff -r bef7f5fcf207 -r 51908f382f92 
tools/xm-test/tests/network/12_network_domU_tcp_pos.py
--- a/tools/xm-test/tests/network/12_network_domU_tcp_pos.py    Thu May 04 
14:22:17 2006 +0100
+++ b/tools/xm-test/tests/network/12_network_domU_tcp_pos.py    Thu May 04 
14:22:29 2006 +0100
@@ -17,50 +17,37 @@ pingsizes = [ 1, 48, 64, 512, 1440, 1500
 
 from XmTestLib import *
 
-def netDomain(ip):
-    if ENABLE_HVM_SUPPORT:
-        config = {"vif" : ['type=ioemu']}
-    else:
-        config = {"vif"  : ["ip=%s" % ip]}
+def netDomain():
 
-    dom = XmTestDomain(extraConfig=config)
+    dom = XmTestDomain()
+    dom.newDevice(XenNetDevice, "eth0")
     try:
         console = dom.start()
+        console.setHistorySaveCmds(value=True)
     except DomainError, e:
         if verbose:
             print "Failed to create test domain because:"
             print e.extra
         FAIL(str(e))
-    return console
+    return dom
     
 rc = 0
 
-Net = XmNetwork()
+# Test creates 2 domains, which requires 4 ips: 2 for the domains and 2 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(4) == False:
+    SKIP("Don't have enough free configured IPs to run this test")
+
+# Fire up a pair of guest domains w/1 nic each
+src = netDomain()
+src_console = src.getConsole()
+dst = netDomain()
 
 try:
-    # pick an IP address 
-    ip1   = Net.ip("dom1", "eth2")
-    mask1 = Net.mask("dom1", "eth2")
-except NetworkError, e:
-    FAIL(str(e))
-
-try:
-    # pick another IP address 
-    ip2   = Net.ip("dom2", "eth2")
-    mask2 = Net.mask("dom2", "eth2")
-except NetworkError, e:
-    FAIL(str(e))
-
-# Fire up a pair of guest domains w/1 nic each
-src_console = netDomain(ip1)
-dst_console = netDomain(ip2)
-
-try:
-    src_console.runCmd("ifconfig eth0 inet "+ip1+" netmask "+mask1+" up")
-    dst_console.runCmd("ifconfig eth0 inet "+ip2+" netmask "+mask2+" up")
-
     # Ping the victim over eth0
     fails=""
+    dst_netdev = dst.getDevice("eth0")
+    ip2 = dst_netdev.getNetDevIP()
     for size in pingsizes:
         out = src_console.runCmd("hping2 " + ip2 + " -E /dev/urandom -q -c 20 "
               + "--fast -d " + str(size))
@@ -70,6 +57,8 @@ except ConsoleError, e:
 except ConsoleError, e:
     FAIL(str(e))
 
+src.stop()
+dst.stop()
+
 if len(fails):
     FAIL("TCP hping2 failed for size" + fails + ".")
-
diff -r bef7f5fcf207 -r 51908f382f92 
tools/xm-test/tests/network/13_network_domU_udp_pos.py
--- a/tools/xm-test/tests/network/13_network_domU_udp_pos.py    Thu May 04 
14:22:17 2006 +0100
+++ b/tools/xm-test/tests/network/13_network_domU_udp_pos.py    Thu May 04 
14:22:29 2006 +0100
@@ -17,50 +17,37 @@ pingsizes = [ 1, 48, 64, 512, 1440, 1500
 
 from XmTestLib import *
 
-def netDomain(ip):
-    if ENABLE_HVM_SUPPORT:
-        config = {"vif" : ['type=ioemu']}
-    else:
-        config = {"vif"  : ["ip=%s" % ip]}
+def netDomain():
 
-    dom = XmTestDomain(extraConfig=config)
+    dom = XmTestDomain()
+    dom.newDevice(XenNetDevice, "eth0")
     try:
         console = dom.start()
+        console.setHistorySaveCmds(value=True)
     except DomainError, e:
         if verbose:
             print "Failed to create test domain because:"
             print e.extra
         FAIL(str(e))
-    return console
+    return dom
     
 rc = 0
 
-Net = XmNetwork()
+# Test creates 2 domains, which requires 4 ips: 2 for the domains and 2 for
+# aliases on dom0
+if xmtest_netconf.canRunNetTest(4) == False:
+    SKIP("Don't have enough free configured IPs to run this test")
+
+# Fire up a pair of guest domains w/1 nic each
+src = netDomain()
+src_console = src.getConsole()
+dst = netDomain()
 
 try:
-    # pick an IP address 
-    ip1   = Net.ip("dom1", "eth2")
-    mask1 = Net.mask("dom1", "eth2")
-except NetworkError, e:
-    FAIL(str(e))
-
-try:
-    # pick another IP address 
-    ip2   = Net.ip("dom2", "eth2")
-    mask2 = Net.mask("dom2", "eth2")
-except NetworkError, e:
-    FAIL(str(e))
-
-# Fire up a pair of guest domains w/1 nic each
-src_console = netDomain(ip1)
-dst_console = netDomain(ip2)
-
-try:
-    src_console.runCmd("ifconfig eth0 inet "+ip1+" netmask "+mask1+" up")
-    dst_console.runCmd("ifconfig eth0 inet "+ip2+" netmask "+mask2+" up")
-
     # Ping the victim over eth0
     fails=""
+    dst_netdev = dst.getDevice("eth0")
+    ip2 = dst_netdev.getNetDevIP()
     for size in pingsizes:
         out = src_console.runCmd("hping2 " + ip2 + " -E /dev/urandom -2 -q "
               + "-c 20 --fast -d " + str(size))
@@ -70,6 +57,8 @@ except ConsoleError, e:
 except ConsoleError, e:
     FAIL(str(e))
 
+src.stop()
+dst.stop()
+
 if len(fails):
     FAIL("UDP hping2 failed for size" + fails + ".")
-
diff -r bef7f5fcf207 -r 51908f382f92 tools/xm-test/lib/XmTestLib/NetConfig.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/lib/XmTestLib/NetConfig.py  Thu May 04 14:22:29 2006 +0100
@@ -0,0 +1,264 @@
+#!/usr/bin/python
+"""
+ Copyright (C) International Business Machines Corp., 2005, 2006
+ Authors: Dan Smith <danms@xxxxxxxxxx>
+          Daniel Stekloff <dsteklof@xxxxxxxxxx>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; under version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+"""
+
+import sys
+import commands
+import os
+import re
+import time
+import random
+from xen.xend.sxp import Parser
+
+from Xm import *
+from Test import *
+from config import *
+
+class NetworkError(Exception):
+    def __init__(self, msg):
+        self.errMsg = msg
+
+    def __str__(self):
+        return str(self.errMsg)
+
+def getXendNetConfig():
+    # Find out what environment we're in: bridge, nat, or route
+    xconfig = os.getenv("XEND_CONFIG")
+    if not xconfig:
+        xconfig = "/etc/xen/xend-config.sxp"
+
+    configfile = open(xconfig, 'r')
+    S = configfile.read()
+    pin = Parser()
+    pin.input(S)
+    pin.input_eof()
+    val = pin.get_val()
+    while val[0] != 'network-script':
+        val = pin.get_val()
+
+    if val[1] == "network-bridge":
+        netenv = "bridge"
+    elif val[1] == "network-route":
+        netenv = "route"
+    elif val[1] == "network-nat":
+        netenv = "nat"
+    else:
+        raise NetworkError("Failed to get network env from xend config")
+
+    configfile.close()
+    return netenv
+
+def checkZeroconfAddresses():
+    # Make sure there aren't existing zeroconf addresses.
+    rc, out = traceCommand("ip addr show |grep \"inet 169.254\" | grep -v vif")
+    if rc == 0:
+        raise NetworkError("Zeroconf addresses already used: %s" % out)
+
+class NetConfig:
+
+    def __init__(self):
+        self.netenv = getXendNetConfig()
+        self.used_ips = {}
+        self.free_oct_ips = [ 0, 0, 0, 0 ]
+        self.total_ips = 0
+
+        if NETWORK_IP_RANGE == 'dhcp':
+            self.netmask = NETWORK_IP_RANGE
+            self.network = NETWORK_IP_RANGE
+            self.max_ip = NETWORK_IP_RANGE
+            self.min_ip = NETWORK_IP_RANGE
+        else:
+            self.netmask = NETMASK
+            self.network = NETWORK
+           s_ip = ''
+
+            # Get starting ip and max ip from configured ip range
+            s_ip = NETWORK_IP_RANGE
+            ips = s_ip.split("-")
+            self.max_ip = ips[1]
+            self.min_ip = ips[0]
+
+            self.__setMaxNumberIPs()
+
+            if self.network == "169.254.0.0":
+                checkZeroconfAddresses()
+
+            # Clean out any aliases in the network range for vif0.0. If
+            # an alias exists, a test xendevice add command could fail.
+            if NETWORK_IP_RANGE != "dhcp":
+                self.__cleanDom0Aliases()
+
+    def __setMaxNumberIPs(self):
+        # Count the number of IPs available, to help tests know whether they
+        # have enough to run or not
+        masko = self.netmask.split('.')
+        maxo = self.max_ip.split('.')
+        mino = self.min_ip.split('.')
+        ips = 0
+
+        # Last octet
+        self.free_oct_ips[3] = (int(maxo[3]) - int(mino[3])) + 1
+
+        # 3rd octet
+        self.free_oct_ips[2] = (int(maxo[2]) - int(mino[2])) + 1
+
+        # 2nd octet
+        self.free_oct_ips[1] = (int(maxo[1]) - int(mino[1])) + 1
+
+        # 1st octet
+        self.free_oct_ips[0] = (int(maxo[0]) - int(mino[0])) + 1
+
+        self.total_ips = self.free_oct_ips[3]
+        if self.free_oct_ips[2] > 1:
+            self.total_ips = (self.total_ips * self.free_oct_ips[2])
+        if self.free_oct_ips[1] > 1:
+            self.total_ips = (self.total_ips * self.free_oct_ips[1])
+        if self.free_oct_ips[0] > 1:
+            self.total_ips = (self.total_ips * self.free_oct_ips[0])
+
+    def __cleanDom0Aliases(self):
+        # Remove any aliases within the supplied network IP range on dom0
+        scmd = 'ip addr show dev vif0.0'
+
+        status, output = traceCommand(scmd)
+        if status:
+            raise NetworkError("Failed to show vif0.0 aliases: %d" % status)
+
+        lines = output.split("\n")
+        for line in lines:
+            ip = re.search('(\d+\.\d+\.\d+\.\d+)', line)
+            if ip and self.isIPInRange(ip.group(1)) == True:
+                dcmd = 'ip addr del %s dev vif0.0' % ip.group(1)
+                dstatus, doutput = traceCommand(dcmd)
+                if dstatus:
+                    raise NetworkError("Failed to remove vif0.0 aliases: %d" % 
status)
+                
+    def getNetEnv(self):
+        return self.netenv
+ 
+    def setUsedIP(self, domname, interface, ip):
+        self.used_ips['%s:%s' % (domname, interface)] = ip
+
+    def __findFirstOctetIP(self, prefix, min, max):
+        for i in range(min, max):
+            ip = '%s%s' % (prefix, str(i))
+            found = False
+            for k in self.used_ips.keys():
+                if self.used_ips[k] == ip:
+                    found = True
+            if found == False:
+                return ip
+
+        if found == True:
+            return None
+
+    def getFreeIP(self, domname, interface):
+        # Get a free IP. It uses the starting ip octets and then the 
+        # total number of allowed numbers for that octet. It only
+        # calculates ips for the last two octets, we shouldn't need more
+        start_octets = self.min_ip.split(".")
+        ip = None
+
+        # Only working with ips from last two octets, shouldn't need more
+        max = int(start_octets[2]) + self.free_oct_ips[2]
+        for i in range(int(start_octets[2]), max):
+            prefix = '%s.%s.%s.' % (start_octets[0], start_octets[1], str(i))
+            ip = self.__findFirstOctetIP(prefix, int(start_octets[3]), 
self.free_oct_ips[3])
+            if ip:
+                break
+
+        if not ip:
+            raise NetworkError("Ran out of configured addresses.")
+
+        self.setUsedIP(domname, interface, ip)
+        return ip
+
+    def getNetMask(self):
+        return self.netmask
+
+    def getNetwork(self):
+        return self.network
+
+    def getIP(self, domname, interface):
+        # Depending on environment, set an IP. Uses the configured range
+        # of IPs, network address, and netmask
+        if NETWORK_IP_RANGE == "dhcp":
+            return None
+
+        # Make sure domain and interface aren't already assigned an IP
+        if self.used_ips.has_key('%s:%s' % (domname, interface)):
+            raise NetworkError("Domain %s interface %s is already has IP"
+                               % (domname, interface))
+
+        return self.getFreeIP(domname, interface)
+
+    def setIP(self, domname, interface, ip):
+        # Make sure domain and interface aren't already assigned an IP
+        if self.used_ips.has_key('%s:%s' % (domname, interface)):
+            raise NetworkError("Domain %s interface %s is already has IP"
+                               % (domname, interface))
+
+        self.setUsedIP(domname, interface, ip)
+
+    def releaseIP(self, domname, interface, ip):
+        if self.used_ips.has_key('%s:%s' % (domname, interface)):
+            del self.used_ips['%s:%s' % (domname, interface)]
+
+    def getNumberAllowedIPs(self):
+        return self.total_ips
+
+    def canRunNetTest(self, ips):
+        # Check to see if a test can run, returns true or false. Input is
+        # number of ips needed.
+        if NETWORK_IP_RANGE == "dhcp":
+            return True
+
+        if self.total_ips >= ips:
+            return True
+
+        return False
+
+    def isIPInRange(self, ip):
+        # Checks to see if supplied ip is in the range of allowed ips
+        maxo = self.max_ip.split('.')
+        mino = self.min_ip.split('.')
+        ipo = ip.split('.')
+
+        if int(ipo[0]) < int(mino[0]):
+            return False
+        elif int(ipo[0]) > int(maxo[0]):
+            return False
+
+        if int(ipo[1]) < int(mino[1]):
+            return False
+        elif int(ipo[1]) > int(maxo[1]):
+            return False
+
+        if int(ipo[2]) < int(mino[2]):
+            return False
+        elif int(ipo[2]) > int(maxo[2]):
+            return False
+
+        if int(ipo[3]) < int(mino[3]):
+            return False
+        elif int(ipo[3]) > int(maxo[3]):
+            return False
+
+        return True
diff -r bef7f5fcf207 -r 51908f382f92 tools/xm-test/lib/XmTestLib/XenDevice.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/lib/XmTestLib/XenDevice.py  Thu May 04 14:22:29 2006 +0100
@@ -0,0 +1,271 @@
+#!/usr/bin/python
+"""
+ Copyright (C) International Business Machines Corp., 2005, 2006
+ Authors: Dan Smith <danms@xxxxxxxxxx>
+          Daniel Stekloff <dsteklof@xxxxxxxxxx>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; under version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+"""
+
+import sys
+import commands
+import os
+import re
+import time
+
+from Xm import *
+from Test import *
+from config import *
+from XenDomain import *
+from NetConfig import *
+from XmTestLib import *
+from __init__ import *
+
+class XenNetDevCmd:
+
+    def __init__(self, netDevice, addCmd, removeCmd):
+        """Object representing a network device command"""
+        self.addcmd = addCmd
+        self.removecmd = removeCmd
+        self.addhasrun = False
+        self.rmvhasrun = False
+        self.netdevice = netDevice
+
+    def getAddCmd(self):
+        return self.addcmd
+
+    def getRemoveCmd(self):
+        return self.removecmd
+
+    def hasAddRun(self):
+        return self.addhasrun
+
+    def hasRemoveRun(self):
+        self.rmvhasrun
+
+    def runAddCmd(self, runOnDom0=False):
+        # Defaults running command on dom0, if console then will run there
+        if runOnDom0 == False:
+            dom = self.netdevice.getDomain()
+            console = dom.getConsole()
+            console.runCmd(self.addcmd)
+        else:
+            status, output = traceCommand(self.addcmd)
+            if status:
+                raise NetworkError("Device add cmd failed: %s Status: %d"
+                                   % (self.addcmd, status))
+        self.addhasrun = True
+
+    def runRemoveCmd(self, runOnDom0=False):
+        # Defaults running command on dom0, if console then will run there
+        if runOnDom0 == False:
+            dom = self.netdevice.getDomain()
+            console = dom.getConsole()
+            console.runCmd(self.removecmd)
+        else:
+            status, output = traceCommand(self.removecmd)
+            if status:
+                raise NetworkError("Device remove cmd failed: %s Status: %d"
+                                   % (self.removecmd, status))
+        self.removehasrun = True
+
+class XenDevice:
+
+    def __init__(self, domain, id, devConfig=None):
+        """An object to represent Xen Devices like network and block
+        @param domain: Domain the device will be added to
+        @param id: Device identifier
+        @param devConfig: Initial configuration dictionary for XenDevice
+        """
+        if config:
+            self.config = devConfig
+        else:
+            self.config = {}
+
+        self.id = id
+        self.domain = domain
+        self.configNode = None
+        # Commands run when domain is started or devices added and removed.
+       self.dom0_cmds = []
+       self.domU_cmds = []
+
+    def __str__(self):
+        """Convert device config to XenConfig node compatible string"""
+        confstr = ''
+        for k, v in self.config.items():
+            if len(confstr) > 0:
+                confstr += ', '
+            if isinstance(v, int):
+                confstr += "%s=%i" % (k, v)
+            elif isinstance(v, list) and v:
+                confstr += "%s=%s" % (k, v)
+            elif isinstance(v, str) and v:
+                confstr += "%s=%s" % (k, v)
+
+        return confstr
+
+    def execAddCmds(self):
+        # Cmds for when a device is added to the system
+        if len(self.dom0_cmds) > 0:
+            for i in range(0, len(self.dom0_cmds)):
+                if self.dom0_cmds[i].getAddCmd():
+                    self.dom0_cmds[i].runAddCmd(runOnDom0=True)
+
+        if len(self.domU_cmds) > 0:
+            for i in range(0, len(self.domU_cmds)):
+                if self.domU_cmds[i].getAddCmd():
+                    self.domU_cmds[i].runAddCmd()
+
+    def execRemoveCmds(self):
+        # Cmds for when a device is removed from the system
+        if len(self.dom0_cmds) > 0:
+            for i in range(0, len(self.dom0_cmds)):
+                if (self.dom0_cmds[i].getRemoveCmd() 
+                    and self.dom0_cmds[i].hasAddRun() == True):
+                    self.dom0_cmds[i].runRemoveCmd(runOnDom0=True)
+
+        if len(self.domU_cmds) > 0:
+            for i in range(0, len(self.domU_cmds)):
+                if (self.domU_cmds[i].getRemoveCmd()
+                    and self.domU_cmds[i].hasAddRun() == True):
+                    self.domU_cmds[i].runRemoveCmd()
+
+    def removeDevice(self):
+        self.execRemoveCmds()
+
+    def getId(self):
+        return self.id
+
+    def getConfigOpt(self):
+        return self.configNode
+
+    def getDomain(self):
+        return self.domain
+
+class XenNetDevice(XenDevice):
+
+    def __init__(self, domain, id, devConfig=None):
+        """An object to represent Xen Network Device
+        @param domain: Domain the device is being added to
+        @param id: Network device identifier, interface name like eth0
+        @param devConfig: Initial dictionary configuration for XenNetDevice
+        """
+        if devConfig:
+            self.config = devConfig
+        else:
+            self.config = {}
+
+        self.id = id
+        self.domain = domain
+        self.configNode = "vif"
+        self.dom0_cmds = []
+        self.domU_cmds = []
+        self.network = None
+        self.netmask = None
+        self.ip = None
+        self.dom0_alias_ip = None
+
+        if domain.getDomainType() == "HVM":
+           self.config["type"] = "ioemu"
+            if not self.config.has_key('bridge'):
+                self.config["bridge"] = "xenbr0"
+
+        if self.config.has_key("ip"):
+            self.setNetDevIP(ip=self.config["ip"])
+        else:
+            if NETWORK_IP_RANGE != "dhcp":
+                self.setNetDevIP()
+
+    def __del__(self):
+        # Make sure we clean up NetConfig's list of ips, so the ip can be
+        # reused
+        self.releaseNetDevIP()
+
+    def addIfconfigCmd(self, domU=True):
+        # Method to add start and remove ifconfig functions
+        if domU == True:
+            locmd = XenNetDevCmd(self, addCmd="ifconfig lo 127.0.0.1", 
removeCmd=None)
+        ifcmd = []
+
+
+        # Start or Add cmd
+        acmd = 'ifconfig %s inet %s netmask %s up' % (self.id, self.ip, 
self.netmask)
+        rcmd = 'ifconfig %s down' % self.id
+        ifcmd = XenNetDevCmd(self, addCmd=acmd, removeCmd=rcmd)
+
+        if domU == True:
+            self.domU_cmds.append(locmd) 
+            self.domU_cmds.append(ifcmd) 
+        else:
+            self.dom0_cmds.append(ifcmd) 
+
+    def removeDevice(self):
+        self.releaseNetDevIP()
+
+    def addDom0AliasCmd(self, dev="vif0.0"):
+        # Method to add start and remove dom0 alias cmds
+        acmd = 'ip addr add %s dev %s' % (self.dom0_alias_ip, dev)
+        rcmd = 'ip addr del %s dev %s' % (self.dom0_alias_ip, dev) 
+        aliascmd = XenNetDevCmd(self, addCmd=acmd, removeCmd=rcmd)
+
+        self.dom0_cmds.append(aliascmd)
+
+    def releaseNetDevIP(self):
+        # Must remove start cmds for ip configuration and then release from
+        # NetConfig
+        self.execRemoveCmds()
+        self.dom0_cmds = []
+        self.domU_cmds = []
+        if self.config.has_key("ip"):
+            del self.config["ip"]
+
+        if self.dom0_alias_ip:
+                xmtest_netconf.releaseIP("domain0", self.domain.getName(), 
self.dom0_alias_ip)
+        xmtest_netconf.releaseIP(self.domain.getName(), self.id, self.ip)
+
+    def getNetDevIP(self):
+        return self.ip
+
+    def getDom0AliasIP(self):
+        return self.dom0_alias_ip
+
+    def getNetwork(self):
+        return self.network
+
+    def setNetDevIP(self, ip=None):
+        # Function to set a new IP for NetDevice.
+        if NETWORK_IP_RANGE == "dhcp":
+            raise NetworkError("System configured for dhcp, cannot set new 
ip.")
+
+        if (self.ip and not ip) or ((self.ip and ip) and (self.ip != ip)): 
+            self.releaseNetDevIP()
+
+       if not self.netmask:
+            self.netmask = xmtest_netconf.getNetMask()
+
+        if not self.network:
+            self.network = xmtest_netconf.getNetwork()
+
+        if ip:
+            xmtest_netconf.setIP(self.domain.getName(), self.id, ip)
+            self.ip = ip
+        else:
+            self.ip = xmtest_netconf.getIP(self.domain.getName(), self.id)
+
+        self.addIfconfigCmd()
+
+        # Setup an alias for Dom0
+        self.dom0_alias_ip = xmtest_netconf.getIP("domain0", 
self.domain.getName())
+        self.addDom0AliasCmd()
diff -r bef7f5fcf207 -r 51908f382f92 tools/xm-test/lib/XmTestLib/Network.py
--- a/tools/xm-test/lib/XmTestLib/Network.py    Thu May 04 14:22:17 2006 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-#!/usr/bin/python
-"""
- Network.py - Common utilities for network tests
-
- Copyright (C) International Business Machines Corp., 2005
- Author: Jim Dykman <dykman@xxxxxxxxxx>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; under version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-"""
-import sys;
-import os;
-import atexit;
-import random;
-
-from Test import *
-from Xm import *
-from config import *
-
-class NetworkError(Exception):
-    def __init__(self, msg):
-        self.errMsg = msg
-
-    def __str__(self):
-        return str(self.errMsg)
-
-def undo_dom0_alias(eth, ip):
-    traceCommand("ip addr del " + ip + " dev " + eth)
-
-def net_from_ip(ip):
-    return ip[:ip.rfind(".")] + ".0/24"
-    
-class XmNetwork:
-
-    def __init__(self):
-        # Check for existing zeroconf address. We are using the zeroconf 
-        # address range as static IP addresses.... if someone is using 
-        # real zeroconf addresses, then we're going to skip tests to 
-        # avoid interfering with them.
-        rc, out = traceCommand(
-                  "ip addr show |grep \"inet 169.254\" | grep -v vif")
-
-        if rc == 0:
-            SKIP("Zeroconf address found: " + out)
-
-        # Randomize one octet of the IP addresses we choose, so that
-        # multiple machines running network tests don't interfere 
-        # with each other. 
-        self.subnet = random.randint(1,254)
-
-    def calc_ip_address(self, dom, interface):
-        # Generate an IP address from the dom# and eth#:
-        #      169.254.(self.subnet).(eth#)*16 + (dom# + 1)
-        ethnum = int(interface[len("eth"):])
-        if (ethnum > 15):
-            raise NetworkError("ethnum > 15 : " + interface)
-        domnum = int(dom[len("dom"):])
-        if (domnum > 14):
-            raise NetworkError("domnum > 14 : " + dom)
-
-        return "169.254."+ str(self.subnet) + "." + str(ethnum*16+domnum+1)
-
-    def ip(self, dom, interface, todomname=None, toeth=None, bridge=None):
-        newip = self.calc_ip_address(dom, interface)
-
-        # If the testcase is going to talk to dom0, we need to add an 
-        # IP address in the proper subnet
-        if dom == "dom0":
-           if ENABLE_HVM_SUPPORT:
-               # HVM uses ioemu which uses a bridge
-               if not bridge:
-                   SKIP("no bridge supplied")
-               else:
-                   vifname = bridge
-           else:
-                # The domain's vif is a convenient place to add to
-                vifname = "vif" + str(domid(todomname)) + "." + toeth[3:]
-
-            # register the exit handler FIRST, just in case
-            atexit.register(undo_dom0_alias, vifname, newip)
-
-            # add the alias
-            status, output = traceCommand("ip addr add " + newip + 
-                                              " dev " + vifname)
-            if status:
-                SKIP("\"ip addr add\" failed")
-
-           if ENABLE_HVM_SUPPORT:
-               # We need to add a route to the bridge device
-               network = net_from_ip(newip)
-               status, output = traceCommand("ip route add " + network + " dev 
" + vifname + " scope link")
-
-                if status:
-                   SKIP("\"ip route add\" failed")
-
-        return newip
-
-    def mask(self, dom, interface):
-        return "255.255.255.240"

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Add new networking infrastructure to Xm-Test. The goal is to make, Xen staging patchbot-unstable <=