diff --git a/mininet/link.py b/mininet/link.py
index 747f2bd364c39213bd73cb962ce8a2f0558ba7c9..74b9821661587bb64a9c78d8cf220ac8952b1a36 100644
--- a/mininet/link.py
+++ b/mininet/link.py
@@ -32,7 +32,7 @@ class Intf( object ):
 
     "Basic interface object that can configure itself."
 
-    def __init__( self, name, node=None, port=None, link=None, **params ):
+    def __init__( self, name, node=None, port=None, link=None, mac=None, **params ):
         """name: interface name (e.g. h1-eth0)
            node: owning node (where this intf most likely lives)
            link: parent link if we're part of a link
@@ -40,7 +40,13 @@ def __init__( self, name, node=None, port=None, link=None, **params ):
         self.node = node
         self.name = name
         self.link = link
-        self.mac, self.ip, self.prefixLen = None, None, None
+        self.mac = mac
+        self.ip, self.prefixLen = None, None
+        
+        # if interface is lo, we know the ip is 127.0.0.1.
+        # This saves an ifconfig command per node
+        if self.name == 'lo':
+            self.ip = '127.0.0.1'
         # Add to node (and move ourselves if necessary )
         node.addIntf( self, port=port )
         # Save params for future reference
@@ -91,6 +97,19 @@ def updateMAC( self ):
         self.mac = macs[ 0 ] if macs else None
         return self.mac
 
+    # Instead of updating ip and mac separately,
+    # use one ifconfig call to do it simultaneously.
+    # This saves an ifconfig command, which improves performance.
+
+    def updateAddr( self ):
+        "Return IP address and MAC address based on ifconfig."
+        ifconfig = self.ifconfig()
+        ips = self._ipMatchRegex.findall( ifconfig )
+        macs = self._macMatchRegex.findall( ifconfig )
+        self.ip = ips[ 0 ] if ips else None
+        self.mac = macs[ 0 ] if macs else None
+        return self.ip, self.mac
+
     def IP( self ):
         "Return IP address"
         return self.ip
@@ -102,8 +121,15 @@ def MAC( self ):
     def isUp( self, setUp=False ):
         "Return whether interface is up"
         if setUp:
-            self.ifconfig( 'up' )
-        return "UP" in self.ifconfig()
+            cmdOutput = self.ifconfig( 'up' )
+            # no output indicates success
+            if cmdOutput:
+                error( "Error setting %s up: %s " % ( self.name, cmdOutput ) )
+                return False
+            else:
+                return True
+        else:
+            return "UP" in self.ifconfig()
 
     def rename( self, newname ):
         "Rename interface"
@@ -154,8 +180,6 @@ def config( self, mac=None, ip=None, ifconfig=None,
         self.setParam( r, 'setIP', ip=ip )
         self.setParam( r, 'isUp', up=up )
         self.setParam( r, 'ifconfig', ifconfig=ifconfig )
-        self.updateIP()
-        self.updateMAC()
         return r
 
     def delete( self ):
@@ -328,7 +352,7 @@ class Link( object ):
        Other types of links could be tunnels, link emulators, etc.."""
 
     def __init__( self, node1, node2, port1=None, port2=None,
-                  intfName1=None, intfName2=None,
+                  intfName1=None, intfName2=None, addr1=None, addr2=None,
                   intf=Intf, cls1=None, cls2=None, params1=None,
                   params2=None ):
         """Create veth link to another node, making two new interfaces.
@@ -354,7 +378,7 @@ def __init__( self, node1, node2, port1=None, port2=None,
         if not intfName2:
             intfName2 = self.intfName( node2, port2 )
 
-        self.makeIntfPair( intfName1, intfName2 )
+        self.makeIntfPair( intfName1, intfName2, addr1, addr2 )
 
         if not cls1:
             cls1 = intf
@@ -366,9 +390,9 @@ def __init__( self, node1, node2, port1=None, port2=None,
             params2 = {}
 
         intf1 = cls1( name=intfName1, node=node1, port=port1,
-                      link=self, **params1  )
+                      link=self, mac=addr1, **params1  )
         intf2 = cls2( name=intfName2, node=node2, port=port2,
-                      link=self, **params2 )
+                      link=self, mac=addr2, **params2 )
 
         # All we are is dust in the wind, and our two interfaces
         self.intf1, self.intf2 = intf1, intf2
@@ -379,13 +403,13 @@ def intfName( cls, node, n ):
         return node.name + '-eth' + repr( n )
 
     @classmethod
-    def makeIntfPair( cls, intf1, intf2 ):
+    def makeIntfPair( cls, intf1, intf2, addr1=None, addr2=None ):
         """Create pair of interfaces
            intf1: name of interface 1
            intf2: name of interface 2
            (override this class method [and possibly delete()]
            to change link type)"""
-        makeIntfPair( intf1, intf2  )
+        makeIntfPair( intf1, intf2, addr1, addr2 )
 
     def delete( self ):
         "Delete this link"
@@ -398,10 +422,12 @@ def __str__( self ):
 class TCLink( Link ):
     "Link with symmetric TC interfaces configured via opts"
     def __init__( self, node1, node2, port1=None, port2=None,
-                  intfName1=None, intfName2=None, **params ):
+                  intfName1=None, intfName2=None,
+                  addr1=None, addr2=None, **params ):
         Link.__init__( self, node1, node2, port1=port1, port2=port2,
                        intfName1=intfName1, intfName2=intfName2,
                        cls1=TCIntf,
                        cls2=TCIntf,
+                       addr1=addr1, addr2=addr2,
                        params1=params,
                        params2=params)
diff --git a/mininet/net.py b/mininet/net.py
index 880780401847226905b183a4ddf1a791c3b70f0e..a4477d37aa03c0b76823b303698949d4bef82bc9 100755
--- a/mininet/net.py
+++ b/mininet/net.py
@@ -90,6 +90,7 @@
 import re
 import select
 import signal
+import random
 import copy
 from time import sleep
 from itertools import chain, groupby
@@ -326,8 +327,12 @@ def addLink( self, node1, node2, port1=None, port2=None,
             port1: source port
             port2: dest port
             returns: link object"""
+        mac1 = macColonHex( random.randint(1, 2**48 - 1) & 0xfeffffffffff  | 0x020000000000 )
+        mac2 = macColonHex( random.randint(1, 2**48 - 1) & 0xfeffffffffff  | 0x020000000000 )
         defaults = { 'port1': port1,
                      'port2': port2,
+                     'addr1': mac1,
+                     'addr2': mac2,
                      'intf': self.intf }
         defaults.update( params )
         if not cls:
@@ -350,7 +355,6 @@ def configHosts( self ):
             # quietRun( 'renice +18 -p ' + repr( host.pid ) )
             # This may not be the right place to do this, but
             # it needs to be done somewhere.
-            host.cmd( 'ifconfig lo up' )
         info( '\n' )
 
     def buildFromTopo( self, topo=None ):
diff --git a/mininet/node.py b/mininet/node.py
index 7eb632217774fa76b0979d560569e1826b2c9814..19f26d7f5ce36b453d347c89198eb402dcb8a62c 100644
--- a/mininet/node.py
+++ b/mininet/node.py
@@ -924,7 +924,6 @@ def start( self, controllers ):
                             for c in controllers ] )
         ofdlog = '/tmp/' + self.name + '-ofd.log'
         ofplog = '/tmp/' + self.name + '-ofp.log'
-        self.cmd( 'ifconfig lo up' )
         intfs = [ str( i ) for i in self.intfList() if not i.IP() ]
         self.cmd( 'ofdatapath -i ' + ','.join( intfs ) +
                   ' punix:/tmp/' + self.name + ' -d %s ' % self.dpid +
@@ -975,7 +974,6 @@ def setup( cls ):
     def start( self, controllers ):
         "Start up kernel datapath."
         ofplog = '/tmp/' + self.name + '-ofp.log'
-        quietRun( 'ifconfig lo up' )
         # Delete local datapath if it exists;
         # then create a new one monitoring the given interfaces
         self.cmd( 'ovs-dpctl del-dp ' + self.dp )
@@ -1093,9 +1091,6 @@ def start( self, controllers ):
         if self.inNamespace:
             raise Exception(
                 'OVS kernel switch does not work in a namespace' )
-        # We should probably call config instead, but this
-        # requires some rethinking...
-        self.cmd( 'ifconfig lo up' )
         # Annoyingly, --if-exists option seems not to work
         self.cmd( 'ovs-vsctl del-br', self )
         int( self.dpid, 16 ) # DPID must be a hex string
@@ -1200,7 +1195,6 @@ def start( self, controllers ):
 
         logfile = '/tmp/ivs.%s.log' % self.name
 
-        self.cmd( 'ifconfig lo up' )
         self.cmd( ' '.join(args) + ' >' + logfile + ' 2>&1 </dev/null &' )
 
     def stop( self ):
@@ -1240,7 +1234,6 @@ def __init__( self, name, inNamespace=False, command='controller',
         self.protocol = protocol
         Node.__init__( self, name, inNamespace=inNamespace,
                        ip=ip, **params  )
-        self.cmd( 'ifconfig lo up' )  # Shouldn't be necessary
         self.checkListening()
 
     def checkListening( self ):
diff --git a/mininet/test/test_hifi.py b/mininet/test/test_hifi.py
index c888e29620a4edfd4aea6468feff43be11c44ba8..d5a09f93476c6f51f9346007a59102df34189078 100755
--- a/mininet/test/test_hifi.py
+++ b/mininet/test/test_hifi.py
@@ -45,7 +45,7 @@ def runOptionsTopoTest( self, n, hopts=None, lopts=None ):
         mn = Mininet( topo=SingleSwitchOptionsTopo( n=n, hopts=hopts,
                                                     lopts=lopts ),
                       host=CPULimitedHost, link=TCLink,
-                      switch=self.switchClass )
+                      switch=self.switchClass, waitConnected=True )
         dropped = mn.run( mn.ping )
         self.assertEqual( dropped, 0 )
 
@@ -67,7 +67,8 @@ def testCPULimits( self ):
         #self.runOptionsTopoTest( N, hopts=hopts )
 
         mn = Mininet( SingleSwitchOptionsTopo( n=N, hopts=hopts ),
-                      host=CPULimitedHost, switch=self.switchClass )
+                      host=CPULimitedHost, switch=self.switchClass,
+                      waitConnected=True )
         mn.start()
         results = mn.runCpuLimitTest( cpu=CPU_FRACTION )
         mn.stop()
@@ -77,13 +78,16 @@ def testCPULimits( self ):
 
     def testLinkBandwidth( self ):
         "Verify that link bandwidths are accurate within a bound."
-        BW = .5  # Mbps
+        if self.switchClass is UserSwitch:
+            self.skipTest ( 'UserSwitch has very poor performance, so skip for now' )
+        BW = 5  # Mbps
         BW_TOLERANCE = 0.8  # BW fraction below which test should fail
         # Verify ability to create limited-link topo first;
         lopts = { 'bw': BW, 'use_htb': True }
         # Also verify correctness of limit limitng within a bound.
         mn = Mininet( SingleSwitchOptionsTopo( n=N, lopts=lopts ),
-                      link=TCLink, switch=self.switchClass )
+                      link=TCLink, switch=self.switchClass,
+                      waitConnected=True )
         bw_strs = mn.run( mn.iperf, format='m' )
         for bw_str in bw_strs:
             bw = float( bw_str.split(' ')[0] )
@@ -95,7 +99,8 @@ def testLinkDelay( self ):
         DELAY_TOLERANCE = 0.8  # Delay fraction below which test should fail
         lopts = { 'delay': '%sms' % DELAY_MS, 'use_htb': True }
         mn = Mininet( SingleSwitchOptionsTopo( n=N, lopts=lopts ),
-                      link=TCLink, switch=self.switchClass, autoStaticArp=True )
+                      link=TCLink, switch=self.switchClass, autoStaticArp=True,
+                      waitConnected=True )
         ping_delays = mn.run( mn.pingFull )
         test_outputs = ping_delays[0]
         # Ignore unused variables below
@@ -117,7 +122,8 @@ def testLinkLoss( self ):
         lopts = { 'loss': LOSS_PERCENT, 'use_htb': True }
         mn = Mininet( topo=SingleSwitchOptionsTopo( n=N, lopts=lopts ),
                       host=CPULimitedHost, link=TCLink,
-                      switch=self.switchClass )
+                      switch=self.switchClass,
+                      waitConnected=True )
         # Drops are probabilistic, but the chance of no dropped packets is
         # 1 in 100 million with 4 hops for a link w/99% loss.
         dropped_total = 0
diff --git a/mininet/util.py b/mininet/util.py
index 5cb27f449d5ecad2dc62691c218307ab97ae18d0..69d31273f21ed858d35aca3004c74f3e17d6597e 100644
--- a/mininet/util.py
+++ b/mininet/util.py
@@ -145,7 +145,7 @@ def isShellBuiltin( cmd ):
 # live in the root namespace and thus do not have to be
 # explicitly moved.
 
-def makeIntfPair( intf1, intf2 ):
+def makeIntfPair( intf1, intf2, addr1=None, addr2=None ):
     """Make a veth pair connecting intf1 and intf2.
        intf1: string, interface
        intf2: string, interface
@@ -154,7 +154,11 @@ def makeIntfPair( intf1, intf2 ):
     quietRun( 'ip link del ' + intf1 )
     quietRun( 'ip link del ' + intf2 )
     # Create new pair
-    cmd = 'ip link add name ' + intf1 + ' type veth peer name ' + intf2
+    if addr1 is None and addr2 is None:
+        cmd = 'ip link add name ' + intf1 + ' type veth peer name ' + intf2
+    else:
+        cmd = ( 'ip link add name ' + intf1 + ' address ' + addr1 +
+                ' type veth peer name ' + intf2 + ' address ' + addr2 )
     cmdOutput = quietRun( cmd )
     if cmdOutput == '':
         return True
@@ -185,10 +189,12 @@ def moveIntfNoRetry( intf, dstNode, srcNode=None, printError=False ):
     intf = str( intf )
     cmd = 'ip link set %s netns %s' % ( intf, dstNode.pid )
     if srcNode:
-        srcNode.cmd( cmd )
+        cmdOutput = srcNode.cmd( cmd )
     else:
-        quietRun( cmd )
-    if ( ' %s:' % intf ) not in dstNode.cmd( 'ip link show', intf ):
+        cmdOutput = quietRun( cmd )
+    # If ip link set does not produce any output, then we can assume
+    # that the link has been moved successfully.
+    if cmdOutput:
         if printError:
             error( '*** Error: moveIntf: ' + intf +
                    ' not successfully moved to ' + dstNode.name + '\n' )