diff --git a/examples/README.md b/examples/README.md
index 96e30d75c6f7d69c062fee50bbd1080db4029cf3..45eabb434315053f91694324d8a06c6034b7b04b 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -56,6 +56,11 @@ This example shows how to use link and CPU limits.
 This example shows how to create a custom topology programatically
 by subclassing Topo, and how to run a series of tests on it.
 
+### linuxrouter.py:
+
+This example shows how to create and configure a router in Mininet
+that uses Linux IP forwarding.
+
 #### miniedit.py:
 
 This example demonstrates creating a network via a graphical editor.
diff --git a/examples/linuxrouter.py b/examples/linuxrouter.py
index 1d625ba7190bd636d675b3b9471d255b1c656e05..11444ea466734ff855ba621a42ac0b12d34b847c 100755
--- a/examples/linuxrouter.py
+++ b/examples/linuxrouter.py
@@ -3,6 +3,18 @@
 """
 linuxrouter.py: Example network with Linux IP router
  
+This example converts a Node into a router using IP forwarding
+already built into Linux.
+
+The topology contains a router with three IP subnets:
+ - 192.168.1.0/24 (interface IP: 192.168.1.1)
+ - 172.16.0.0/12 (interface IP: 172.16.0.1)
+ - 10.0.0.0/8 (interface IP: 10.0.0.1)
+
+ It also contains three hosts, one in each subnet:
+ - h1 (IP: 192.168.1.100)
+ - h2 (IP: 172.16.0.100)
+ - h3 (IP: 10.0.0.100)
 
 """
 
@@ -14,6 +26,7 @@
 from mininet.util import irange
 
 class Router( Node ):
+    "A Node with IP forwarding enabled."
 
     def config( self, **params ):
         super( Router, self).config( **params )
@@ -25,25 +38,25 @@ def terminate( self ):
         super( Router, self ).terminate()
 
 
-class NetworkTopo(Topo):
-    def __init__(self, n=2, h=1, **opts):
-        Topo.__init__(self, **opts)
+class NetworkTopo( Topo ):
+    "A simple topology of a router with three subnets (one host in each)."
 
-        router = self.addNode('r0', cls=Router, ip='192.168.1.1/24')
-        h1 = self.addHost('h1', ip='192.168.1.100/8', defaultRoute='via 192.168.1.1')
-        h2 = self.addHost('h2', ip='172.16.0.100/8', defaultRoute='via 172.16.0.1')
-        h3 = self.addHost('h3', ip='10.0.0.100/24', defaultRoute='via 10.0.0.1')
-        self.addLink(h1, router, intfName2='r0-eth1', params2={ 'ip' : '192.168.1.1/24' })
-        self.addLink(h2, router, intfName2='r0-eth2', params2={ 'ip' : '172.16.0.1/24' })
-        self.addLink(h3, router, intfName2='r0-eth3', params2={ 'ip' : '10.0.0.1/24' })
+    def build( self, n=2, h=1, **opts ):
+        router = self.addNode( 'r0', cls=Router, ip='192.168.1.1/24' )
+        h1 = self.addHost( 'h1', ip='192.168.1.100/24', defaultRoute='via 192.168.1.1' )
+        h2 = self.addHost( 'h2', ip='172.16.0.100/12', defaultRoute='via 172.16.0.1' )
+        h3 = self.addHost( 'h3', ip='10.0.0.100/8', defaultRoute='via 10.0.0.1' )
+        self.addLink( h1, router, intfName2='r0-eth1', params2={ 'ip' : '192.168.1.1/24' } )
+        self.addLink( h2, router, intfName2='r0-eth2', params2={ 'ip' : '172.16.0.1/12' } )
+        self.addLink( h3, router, intfName2='r0-eth3', params2={ 'ip' : '10.0.0.1/8' } )
 
 def run():
     topo = NetworkTopo()
-    net = Mininet(topo=topo)
+    net = Mininet( topo=topo, controller=None ) # no controller needed
     net.start()
-    CLI(net)
+    CLI( net )
     net.stop()
 
 if __name__ == '__main__':
-    setLogLevel('info')
+    setLogLevel( 'info' )
     run()
diff --git a/examples/test/test_linuxrouter.py b/examples/test/test_linuxrouter.py
new file mode 100644
index 0000000000000000000000000000000000000000..60af201446756fcc743bd26130f26835d444bba7
--- /dev/null
+++ b/examples/test/test_linuxrouter.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+
+"""
+Test for linuxrouter.py
+"""
+
+import unittest
+import pexpect
+from mininet.util import quietRun
+
+class testLinuxRouter( unittest.TestCase ):
+
+    prompt = 'mininet>'
+
+    def testPingall( self ):
+        "Test connectivity between hosts"
+        p = pexpect.spawn( 'python -m mininet.examples.linuxrouter' )
+        p.expect( self.prompt )
+        p.sendline( 'pingall' )
+        p.expect ( '(\d+)% dropped' )
+        percent = int( p.match.group( 1 ) ) if p.match else -1
+        p.expect( self.prompt )
+        p.sendline( 'exit' )
+        p.wait()
+        self.assertEqual( percent, 0 )
+
+    def testRouterPing( self ):
+        "Test connectivity from h1 to router"
+        p = pexpect.spawn( 'python -m mininet.examples.linuxrouter' )
+        p.expect( self.prompt )
+        p.sendline( 'h1 ping -c 1 r0' )
+        p.expect ( '(\d+)% packet loss' )
+        percent = int( p.match.group( 1 ) ) if p.match else -1
+        p.expect( self.prompt )
+        p.sendline( 'exit' )
+        p.wait()
+        self.assertEqual( percent, 0 )
+
+    def testTTL( self ):
+        "Verify that the TTL is decremented"
+        p = pexpect.spawn( 'python -m mininet.examples.linuxrouter' )
+        p.expect( self.prompt )
+        p.sendline( 'h1 ping -c 1 h2' )
+        p.expect ( 'ttl=(\d+)' )
+        ttl = int( p.match.group( 1 ) ) if p.match else -1
+        p.expect( self.prompt )
+        p.sendline( 'exit' )
+        p.wait()
+        self.assertEqual( ttl, 63 ) # 64 - 1
+
+if __name__ == '__main__':
+    unittest.main()