diff --git a/bin/mn b/bin/mn
index 3edfdad932513109590a19b55fe4677c7a8858bb..b2b2e0de715c6c0406e816fe28dbcc7e068878f5 100755
--- a/bin/mn
+++ b/bin/mn
@@ -151,6 +151,10 @@ class MininetRunner( object ):
         "Setup and validate environment."
 
         # set logging verbosity
+        if LEVELS[self.options.verbosity] > LEVELS['cliinfo']:
+            print ( '*** WARNING: selected verbosity level (%s) will hide CLI '
+                    'output!\n'
+                    'Please restart Mininet with -v [debug, info, cliinfo].' )
         lg.setLogLevel( self.options.verbosity )
 
         # validate environment setup
diff --git a/mininet/cli.py b/mininet/cli.py
index ce2328ac1ee690e1300c55ce24eb994b467feb52..ab9a2c1db86f6b2fdd923f676ed0fa31e9d92cd5 100644
--- a/mininet/cli.py
+++ b/mininet/cli.py
@@ -38,7 +38,7 @@
 from subprocess import call
 from cmd import Cmd
 
-from mininet.log import info, warn
+from mininet.log import info, warn, cliinfo
 
 class CLI( Cmd ):
     "Simple command-line interface to talk to nodes."
@@ -84,16 +84,16 @@ def do_help( self, args ):
     def do_nodes( self, args ):
         "List all nodes."
         nodes = ' '.join( [ node.name for node in sorted( self.nodelist ) ] )
-        info( 'available nodes are: \n%s\n' % nodes )
+        cliinfo( 'available nodes are: \n%s\n' % nodes )
 
     def do_net( self, args ):
         "List network connections."
         for switch in self.mn.switches:
-            info( switch.name, '<->' )
+            cliinfo( switch.name, '<->' )
             for intf in switch.intfs.values():
                 name = switch.connection[ intf ][ 1 ]
-                info( ' %s' % name )
-            info( '\n' )
+                cliinfo( ' %s' % name )
+            cliinfo( '\n' )
 
     def do_sh( self, args ):
         "Run an external shell command"
@@ -128,7 +128,7 @@ def do_pingpair( self, args ):
 
     def do_iperf( self, args ):
         "Simple iperf TCP test between two hosts."
-        self.mn.iperf( verbose=True )
+        self.mn.iperf()
 
     def do_iperfudp( self, args ):
         "Simple iperf UDP test between two hosts."
@@ -138,13 +138,13 @@ def do_iperfudp( self, args ):
     def do_intfs( self, args ):
         "List interfaces."
         for node in self.nodelist:
-            info( '%s: %s\n' %
+            cliinfo( '%s: %s\n' %
                 ( node.name, ' '.join( sorted( node.intfs.values() ) ) ) )
 
     def do_dump( self, args ):
         "Dump node info."
         for node in self.nodelist:
-            info( '%s\n' % node )
+            cliinfo( '%s\n' % node )
 
     def do_exit( self, args ):
         "Exit"
diff --git a/mininet/log.py b/mininet/log.py
index f8ed653ef9bd0470a240d82a544a1a05b53ac2a4..5352345454d00b7cb62a4de57e9348dc3e99b63d 100644
--- a/mininet/log.py
+++ b/mininet/log.py
@@ -4,8 +4,15 @@
 from logging import Logger
 import types
 
+# Create a new loglevel, 'CLI info', which enables a Mininet user to see only
+# the output of the commands they execute, plus any errors or warnings.  This
+# level is in between info and warning.  CLI info-level commands should not be
+# printed during regression tests.
+CLIINFO = 25
+
 LEVELS = { 'debug': logging.DEBUG,
           'info': logging.INFO,
+          'cliinfo': CLIINFO,
           'warning': logging.WARNING,
           'error': logging.ERROR,
           'critical': logging.CRITICAL }
@@ -119,6 +126,20 @@ def setLogLevel( self, levelname=None ):
         self.setLevel( level )
         self.handlers[ 0 ].setLevel( level )
 
+    # See /usr/lib/python2.5/logging/__init__.py; modified from warning()
+    def cliinfo( self, msg, *args, **kwargs ):
+        """Log 'msg % args' with severity 'CLIINFO'.
+
+           To pass exception information, use the keyword argument exc_info
+           with a true value, e.g.
+
+           logger.warning("Houston, we have a %s", "cli output", exc_info=1)
+        """
+        if self.manager.disable >= CLIINFO:
+            return
+        if self.isEnabledFor( CLIINFO ):
+            apply( self._log, ( CLIINFO, msg, args ), kwargs )
+
 
 lg = MininetLogger()
 
@@ -144,5 +165,6 @@ def newfn( *args ):
     setattr( newfn, '__doc__', fn.__doc__ )
     return newfn
 
-info, warn, error, debug = lg.info, lg.warn, lg.error, lg.debug = [
-    makeListCompatible( f ) for f in lg.info, lg.warn, lg.error, lg.debug ]
+info, cliinfo, warn, error, debug = lg.info, lg.cliinfo, lg.warn, lg.error, \
+    lg.debug = [ makeListCompatible( f ) for f in lg.info, lg.cliinfo, lg.warn,
+                 lg.error, lg.debug ]
diff --git a/mininet/net.py b/mininet/net.py
index a4ed8a57f07680462359e01172c8ea7554e1f36c..39720bbe470761c6b8326ff3437651fb8d8506e0 100755
--- a/mininet/net.py
+++ b/mininet/net.py
@@ -89,7 +89,7 @@
 from time import sleep
 
 from mininet.cli import CLI
-from mininet.log import info, error, debug
+from mininet.log import info, error, debug, cliinfo
 from mininet.node import Host, UserSwitch, KernelSwitch, Controller
 from mininet.node import ControllerParams
 from mininet.util import quietRun, fixLimits
@@ -402,9 +402,9 @@ def ping( self, hosts=None ):
         ploss = None
         if not hosts:
             hosts = self.hosts
-            info( '*** Ping: testing ping reachability\n' )
+            cliinfo( '*** Ping: testing ping reachability\n' )
         for node in hosts:
-            info( '%s -> ' % node.name )
+            cliinfo( '%s -> ' % node.name )
             for dest in hosts:
                 if node != dest:
                     result = node.cmd( 'ping -c1 ' + dest.IP() )
@@ -416,10 +416,10 @@ def ping( self, hosts=None ):
                         node.cmdPrint( 'route' )
                         exit( 1 )
                     lost += sent - received
-                    info( ( '%s ' % dest.name ) if received else 'X ' )
-            info( '\n' )
+                    cliinfo( ( '%s ' % dest.name ) if received else 'X ' )
+            cliinfo( '\n' )
             ploss = 100 * lost / packets
-        info( "*** Results: %i%% dropped (%d/%d lost)\n" %
+        cliinfo( "*** Results: %i%% dropped (%d/%d lost)\n" %
                 ( ploss, lost, packets ) )
         return ploss
 
@@ -446,21 +446,18 @@ def _parseIperf( iperfOutput ):
         else:
             raise Exception( 'could not parse iperf output: ' + iperfOutput )
 
-    def iperf( self, hosts=None, l4Type='TCP', udpBw='10M',
-              verbose=False ):
+    def iperf( self, hosts=None, l4Type='TCP', udpBw='10M' ):
         """Run iperf between two hosts.
            hosts: list of hosts; if None, uses opposite hosts
            l4Type: string, one of [ TCP, UDP ]
-           verbose: verbose printing
            returns: results two-element array of server and client speeds"""
-        log = info if verbose else debug
         if not hosts:
             hosts = [ self.hosts[ 0 ], self.hosts[ -1 ] ]
         else:
             assert len( hosts ) == 2
         host0, host1 = hosts
-        log( '*** Iperf: testing ' + l4Type + ' bandwidth between ' )
-        log( "%s and %s\n" % ( host0.name, host1.name ) )
+        cliinfo( '*** Iperf: testing ' + l4Type + ' bandwidth between ' )
+        cliinfo( "%s and %s\n" % ( host0.name, host1.name ) )
         host0.cmd( 'killall -9 iperf' )
         iperfArgs = 'iperf '
         bwArgs = ''
@@ -470,16 +467,16 @@ def iperf( self, hosts=None, l4Type='TCP', udpBw='10M',
         elif l4Type != 'TCP':
             raise Exception( 'Unexpected l4 type: %s' % l4Type )
         server = host0.cmd( iperfArgs + '-s &' )
-        log( '%s\n' % server )
+        debug( '%s\n' % server )
         client = host1.cmd( iperfArgs + '-t 5 -c ' + host0.IP() + ' ' +
                            bwArgs )
-        log( '%s\n' % client )
+        debug( '%s\n' % client )
         server = host0.cmd( 'killall -9 iperf' )
-        log( '%s\n' % server )
+        debug( '%s\n' % server )
         result = [ self._parseIperf( server ), self._parseIperf( client ) ]
         if l4Type == 'UDP':
             result.insert( 0, udpBw )
-        log( '*** Results: %s\n' % result )
+        cliinfo( '*** Results: %s\n' % result )
         return result
 
     def iperfUdp( self, udpBw='10M' ):