From dd6424fee8322168a6261efa31102852546bb342 Mon Sep 17 00:00:00 2001
From: Bob Lantz <rlantz@cs.stanford.edu>
Date: Wed, 9 Oct 2013 15:54:27 -0700
Subject: [PATCH] Simple mobility example.

---
 examples/README.md             |  9 +++-
 examples/mobility.py           | 93 ++++++++++++++++++++++++++++++++++
 examples/test/test_mobility.py | 20 ++++++++
 3 files changed, 120 insertions(+), 2 deletions(-)
 create mode 100755 examples/mobility.py
 create mode 100755 examples/test/test_mobility.py

diff --git a/examples/README.md b/examples/README.md
index 96e30d75..1931964b 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -13,7 +13,7 @@ process running in a namespace. Doesn't use OpenFlow.
 
 #### consoles.py:
 
-This example creates a grid of console windows, one for each node, 
+This example creates a grid of console windows, one for each node,
 and allows interaction with and monitoring of each console, including
 graphical monitoring.
 
@@ -60,9 +60,14 @@ by subclassing Topo, and how to run a series of tests on it.
 
 This example demonstrates creating a network via a graphical editor.
 
+#### mobility.py
+
+This example demonstrates detaching an interface from one switch and
+attaching it another as a basic way to move a host around a network.
+
 #### multiping.py:
 
-This example demonstrates one method for 
+This example demonstrates one method for
 monitoring output from multiple hosts, using `node.monitor()`.
 
 #### multipoll.py:
diff --git a/examples/mobility.py b/examples/mobility.py
new file mode 100755
index 00000000..dda400c0
--- /dev/null
+++ b/examples/mobility.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python
+
+"""
+Simple example of Mobility with Mininet
+(aka enough rope to hang yourself.)
+
+We move a host from s1 to s2, s2 to s3,
+and then back to s1.
+
+Gotchas:
+
+1. The interfaces are not renamed; this
+   means that s1-eth1 will show up on other
+   switches.
+
+2. The reference controller doesn't support
+   mobility, so we need to flush the switch
+   flow tables.
+
+3. The port numbers reported by the switch
+   may not match the actual OpenFlow port
+   numbers used by OVS.
+
+Good luck!
+"""
+
+from mininet.net import Mininet
+from mininet.node import OVSSwitch, Controller
+from mininet.topo import LinearTopo
+from mininet.cli import CLI
+from mininet.util import dumpNetConnections
+from time import sleep
+
+class MobilitySwitch( OVSSwitch ):
+    "Switch that can delete interfaces"
+
+    def delIntf( self, intf ):
+        "Remove an interface"
+        port = self.ports[ intf ]
+        del self.ports[ intf ]
+        del self.intfs[ port ]
+        del self.nameToIntf[ intf.name ]
+        self.detach( intf )
+
+
+def printConnections( switches ):
+    "Compactly print connected nodes to each switch"
+    for sw in switches:
+        print '%s:' % sw,
+        for intf in sw.intfList():
+            link = intf.link
+            if link:
+                intfs = [ link.intf1, link.intf2 ]
+                if intfs[ 0 ].node != sw:
+                    intfs.reverse()
+                local, remote = intfs
+                print remote.node,
+        print
+
+
+def mobilityTest():
+    "A simple test of mobility"
+    print '* Simple mobility test'
+    net = Mininet( topo=LinearTopo( 3 ), switch=MobilitySwitch )
+    net.start()
+    print '* Starting network:'
+    printConnections( net.switches )
+    net.pingAll()
+    print '* Identifying switch interface for h1'
+    h1, s1 = net.get( 'h1', 's1' )
+    hintf, sintf = h1.connectionsTo( s1 )[ 0 ]
+    last = s1
+    for s in 2, 3, 1:
+        next = net['s%d' % s ]
+        print '* Moving', sintf, 'from', last, 'to', next
+        last.detach( sintf )
+        last.delIntf( sintf )
+        next.attach( sintf )
+        next.addIntf( sintf )
+        sintf.node = next
+        print '* Clearing out old flows'
+        for sw in net.switches:
+            sw.dpctl( 'del-flows' )
+        print '* New network:'
+        printConnections( net.switches )
+        print '* Testing connectivity:'
+        net.pingAll()
+        last = next
+    net.stop()
+
+if __name__ == '__main__':
+    mobilityTest()
+
diff --git a/examples/test/test_mobility.py b/examples/test/test_mobility.py
new file mode 100755
index 00000000..6eb28ee2
--- /dev/null
+++ b/examples/test/test_mobility.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+
+"""
+Test for mobility.py
+"""
+
+import unittest
+from subprocess import check_output
+
+class testMobility( unittest.TestCase ):
+
+    def testMobility( self ):
+        "Run the example and verify its 4 ping results"
+        cmd = 'python -m mininet.examples.mobility 2>&1'
+        grep = ' | grep -c " 0% dropped" '
+        result = check_output( cmd + grep, shell=True )
+        assert int( result ) == 4
+
+if __name__ == '__main__':
+    unittest.main()
-- 
GitLab