diff --git a/bin/mn_run.py b/bin/mn_run.py
index 0aa724823e495e0c84140c936aefd8ceae174832..2c566c48d02c171590287c3782ca2c9da99d7978 100755
--- a/bin/mn_run.py
+++ b/bin/mn_run.py
@@ -11,7 +11,7 @@
 
 from mininet.logging_mod import lg, set_loglevel, LEVELS
 from mininet.net import Mininet, init
-from mininet.node import Switch, Host, Controller, ControllerParams, NOX
+from mininet.node import KernelSwitch, Host, Controller, ControllerParams, NOX
 from mininet.topo import TreeTopo
 
 # built in topologies, created only when run
@@ -24,7 +24,7 @@
          'fattree6' : (lambda: FatTreeTopo(k = 6))}
 
 SWITCH_DEF = 'kernel'
-SWITCHES = {'kernel' : Switch}
+SWITCHES = {'kernel' : KernelSwitch}
 
 HOST_DEF = 'process'
 HOSTS = {'process' : Host}
diff --git a/mininet/net.py b/mininet/net.py
index 063ca23f71123dbbeb8417fbbb9d8eb61ace75b0..0a72349d9127127754cb1a29699038aa9bff262e 100755
--- a/mininet/net.py
+++ b/mininet/net.py
@@ -377,14 +377,20 @@ def ping(self, hosts = None):
         return ploss
 
     def ping_all(self):
-        '''Ping between all hosts.'''
-        self.ping()
+        '''Ping between all hosts.
+
+        @return ploss packet loss percentage
+        '''
+        return self.ping()
 
     def ping_pair(self):
-        '''Ping between first two hosts, useful for testing.'''
+        '''Ping between first two hosts, useful for testing.
+
+        @return ploss packet loss percentage
+        '''
         hosts_sorted = sorted(self.topo.hosts())
         hosts = [hosts_sorted[0], hosts_sorted[1]]
-        self.ping(hosts = hosts)
+        return self.ping(hosts = hosts)
 
     @staticmethod
     def _parseIperf(iperfOutput):
diff --git a/mininet/node.py b/mininet/node.py
index 023d01c30861e135ef92e460b6c5de284f9b1893..dab98ddd98b220caf4aa8b76563fec9ae0520d52 100644
--- a/mininet/node.py
+++ b/mininet/node.py
@@ -211,49 +211,38 @@ class Host(Node):
     pass
 
 
-class Controller(Node):
-    '''A Controller is a Node that is running (or has execed) an
-      OpenFlow controller.'''
-
-    def __init__(self, name, inNamespace = False, controller = 'controller',
-                 cargs = '-v ptcp:', cdir = None):
-        self.controller = controller
-        self.cargs = cargs
-        self.cdir = cdir
-        Node.__init__(self, name, inNamespace = inNamespace)
+class Switch(Node):
+    '''A Switch is a Node that is running (or has execed)
+       an OpenFlow switch.'''
 
-    def start(self):
-        '''Start <controller> <args> on controller.
+    def sendCmd(self, cmd):
+        '''Send command to Node.
 
-        Log to /tmp/cN.log
+        @param cmd string
         '''
-        cout = '/tmp/' + self.name + '.log'
-        if self.cdir is not None:
-            self.cmdPrint('cd ' + self.cdir)
-        self.cmdPrint(self.controller + ' ' + self.cargs +
-            ' 1> ' + cout + ' 2> ' + cout + ' &')
-        self.execed = False # XXX Until I fix it
-
-    def stop(self):
-        '''Stop controller.'''
-        self.cmd('kill %' + self.controller)
-        self.terminate()
+        if not self.execed:
+            return Node.sendCmd(self, cmd)
+        else:
+            lg.error('*** Error: %s has execed and cannot accept commands' %
+                     self.name)
 
+    def monitor(self):
+        '''Monitor node.'''
+        if not self.execed:
+            return Node.monitor(self)
+        else:
+            return True, ''
 
-class Switch(Node):
-    '''A Switch is a Node that is running (or has execed)
-       an OpenFlow switch.'''
+class UserSwitch(Switch):
 
-    def __init__(self, name, datapath = None):
+    def __init__(self, name):
         '''Init.
 
         @param name
-        @param datapath string, datapath name
         '''
-        self.dp = datapath
-        Node.__init__(self, name, inNamespace = (datapath == None))
+        Node.__init__(self, name, inNamespace = True)
 
-    def _startUserDatapath(self, controllers):
+    def start(self, controllers):
         '''Start OpenFlow reference user datapath.
 
         Log to /tmp/sN-{ofd,ofp}.log.
@@ -273,12 +262,24 @@ def _startUserDatapath(self, controllers):
                       ' tcp:localhost --fail=closed 1> ' + ofplog + ' 2>' +
                       ofplog + ' &')
 
-    def _stopUserDatapath(self):
+    def stop(self):
         '''Stop OpenFlow reference user datapath.'''
         self.cmd('kill %ofdatapath')
         self.cmd('kill %ofprotocol')
 
-    def _startKernelDatapath(self):
+
+class KernelSwitch(Switch):
+
+    def __init__(self, name, datapath = None):
+        '''Init.
+
+        @param name
+        @param datapath string, datapath name
+        '''
+        self.dp = datapath
+        Node.__init__(self, name, inNamespace = (datapath == None))
+
+    def start(self, ignore):
         '''Start up reference kernel datapath.'''
         ofplog = '/tmp/' + self.name + '-ofp.log'
         quietRun('ifconfig lo up')
@@ -293,7 +294,7 @@ def _startKernelDatapath(self):
                       ' --fail=closed 1> ' + ofplog + ' 2>' + ofplog + ' &')
         self.execed = False # XXX until I fix it
 
-    def _stopKernelDatapath(self):
+    def stop(self):
         '''Terminate reference kernel datapath.'''
         quietRun('dpctl deldp ' + self.dp)
         # In theory the interfaces should go away after we shut down.
@@ -305,40 +306,46 @@ def _stopKernelDatapath(self):
             quietRun('ip link del ' + intf)
             lg.info('.')
 
-    def start(self, controllers):
-        '''Start datapath.
 
-        @param controllers dict of controller names to objects
+class Controller(Node):
+    '''A Controller is a Node that is running (or has execed) an
+      OpenFlow controller.'''
+
+    def __init__(self, name, inNamespace = False, controller = 'controller',
+                 cargs = '-v ptcp:', cdir = None):
+        self.controller = controller
+        self.cargs = cargs
+        self.cdir = cdir
+        Node.__init__(self, name, inNamespace = inNamespace)
+
+    def start(self):
+        '''Start <controller> <args> on controller.
+
+        Log to /tmp/cN.log
         '''
-        if self.dp is None:
-            self._startUserDatapath(controllers)
-        else:
-            self._startKernelDatapath()
+        cout = '/tmp/' + self.name + '.log'
+        if self.cdir is not None:
+            self.cmdPrint('cd ' + self.cdir)
+        self.cmdPrint(self.controller + ' ' + self.cargs +
+            ' 1> ' + cout + ' 2> ' + cout + ' &')
+        self.execed = False # XXX Until I fix it
 
     def stop(self):
-        '''Stop datapath.'''
-        if self.dp is None:
-            self._stopUserDatapath()
-        else:
-            self._stopKernelDatapath()
+        '''Stop controller.'''
+        self.cmd('kill %' + self.controller)
+        self.terminate()
 
-    def sendCmd(self, cmd):
-        '''Send command to Node.
 
-        @param cmd string
-        '''
-        if not self.execed:
-            return Node.sendCmd(self, cmd)
-        else:
-            lg.error('*** Error: %s has execed and cannot accept commands' %
-                     self.name)
+class ControllerParams(object):
+    '''Container for controller IP parameters.'''
+    def __init__(self, ip, subnet_size):
+        '''Init.
 
-    def monitor(self):
-        '''Monitor node.'''
-        if not self.execed:
-            return Node.monitor(self)
-        else:
-            return True, ''
+        @param ip integer, controller IP
+        @param subnet_size integer, ex 8 for slash-8, covering 17M
+        '''
+        self.ip = ip
+        self.subnet_size = subnet_size
 
 
 class NOX(Controller):
@@ -360,16 +367,4 @@ def __init__(self, name, inNamespace = False, nox_args = None, **kwargs):
             controller = nox_core_dir + '/nox_core',
             cargs = '--libdir=/usr/local/lib -v -i ptcp: ' + \
                     ' '.join(nox_args),
-            cdir = nox_core_dir, **kwargs)
-
-
-class ControllerParams(object):
-    '''Container for controller IP parameters.'''
-    def __init__(self, ip, subnet_size):
-        '''Init.
-
-        @param ip integer, controller IP
-        @param subnet_size integer, ex 8 for slash-8, covering 17M
-        '''
-        self.ip = ip
-        self.subnet_size = subnet_size
\ No newline at end of file
+            cdir = nox_core_dir, **kwargs)
\ No newline at end of file
diff --git a/mininet/test/test_nets.py b/mininet/test/test_nets.py
index ed6570df08c582d6ef148a1f562300f1318cc5d3..2c65fd191833654eb9f8a0706f62bc9d1660acb4 100755
--- a/mininet/test/test_nets.py
+++ b/mininet/test/test_nets.py
@@ -8,12 +8,12 @@
 import unittest
 
 from mininet.net import init, Mininet #, DATAPATHS
-from mininet.node import Switch, Host, NOXController, ControllerParams
+from mininet.node import KernelSwitch, Host, ControllerParams
 from mininet.node import Controller
 from mininet.topo import TreeTopo
 
 # temporary, until user-space side is tested
-DATAPATHS = ['kernel']
+SWITCHES = {'kernel' : KernelSwitch}
 
 class testMinimal(unittest.TestCase):
     '''For each datapath type, test ping with a minimal topology.
@@ -24,15 +24,12 @@ class testMinimal(unittest.TestCase):
     def testMinimal(self):
         '''Ping test with both datapaths on minimal topology'''
         init()
-        for datapath in DATAPATHS:
-            k = datapath == 'kernel'
+        for switch in SWITCHES.values():
             controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8
-            mn = Mininet(TreeTopo(), Switch, Host, Controller,
+            mn = Mininet(TreeTopo(), switch, Host, Controller,
                          controller_params)
-            mn.start()
-            dropped = mn.ping_test()
+            dropped = mn.run('ping')
             self.assertEqual(dropped, 0)
-            mn.stop()
 
 
 class testTree(unittest.TestCase):
@@ -41,16 +38,13 @@ class testTree(unittest.TestCase):
     def testTree16(self):
         '''Ping test with both datapaths on 16-host topology'''
         init()
-        for datapath in DATAPATHS:
-            k = datapath == 'kernel'
+        for switch in SWITCHES.values():
             controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8
             tree_topo = TreeTopo(depth = 3, fanout = 4)
-            mn = Mininet(tree_topo, Switch, Host, Controller,
+            mn = Mininet(tree_topo, switch, Host, Controller,
                          controller_params)
-            mn.start()
-            dropped = mn.ping_test()
+            dropped = mn.run('ping')
             self.assertEqual(dropped, 0)
-            mn.stop()
 
 #class testLinear(unittest.TestCase):
 #    '''For each datapath type, test all-pairs ping with LinearNet.'''