Merge remote-tracking branch 'origin/master'
diff --git a/tools/test/bin/onos-topo-cfg b/tools/test/bin/onos-topo-cfg
new file mode 100755
index 0000000..d3a4f0d
--- /dev/null
+++ b/tools/test/bin/onos-topo-cfg
@@ -0,0 +1,13 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# ONOS topology configuration uploader.
+# -----------------------------------------------------------------------------
+
+[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
+. $ONOS_ROOT/tools/build/envDefaults
+
+node="${1:-$OC1}"
+file="${2:-$ONOS_ROOT/tools/test/topos/oe-linear-3.json}"
+
+curl -sS --fail -L -X POST -H 'Content-Type:application/json' \
+    http://$node:8181/onos/v1/config/topology -d@$file
diff --git a/tools/test/topos/optical-topo.py b/tools/test/topos/optical-topo.py
deleted file mode 100755
index 63e8496..0000000
--- a/tools/test/topos/optical-topo.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env python
-
-''' file: custom/optical.py '''
-
-from mininet.topo import Topo
-from mininet.net import Mininet
-from mininet.cli import CLI
-from mininet.log import setLogLevel, info
-from mininet.util import irange
-
-class OpticalTopo( Topo ):
-
-    def build( self, n=3, tapStart=3 ):
-
-        # Add hosts and switches
-        hosts = []
-        switches = []
-        for i in irange( 1, n ):
-            h = self.addHost( 'h%d' % i )
-            s = self.addSwitch( 's%d' % i )
-            self.addLink( h, s )
-            hosts.append( h )
-            switches.append( s )
-
-        # Add optical tap interfaces
-        tapNum = tapStart
-        for sw in switches:
-            self.addLink( sw, sw, intfName1='%s-eth0' % sw, intfName2='tap%d' % tapNum )
-            tapNum += 1
-
-# if you use, sudo mn --custom custom/optical.py, then register the topo:
-#sudo mn --custom optical-topo.py --topo optical,5
-topos = { 'optical': OpticalTopo }
-
-def installStaticFlows( net ):
-    for swName in [ 's1', 's2', 's3', 's4', 's5', 's6' ]:
-      info( 'Adding flows to %s...' % swName )
-      sw = net[ swName ]
-      sw.dpctl( 'add-flow', 'in_port=1,actions=output=2' )
-      sw.dpctl( 'add-flow', 'in_port=2,actions=output=1' )
-      info( sw.dpctl( 'dump-flows' ) )
-
-def run():
-    net = Mininet( topo=OpticalTopo() )
-    net.start()
-    #installStaticFlows( net )
-    CLI( net )
-    net.stop()
-
-# if the script is run directly (sudo custom/optical.py):
-if __name__ == '__main__':
-    setLogLevel( 'info' )
-    run()
diff --git a/tools/test/topos/optical.py b/tools/test/topos/optical.py
new file mode 100755
index 0000000..300332a
--- /dev/null
+++ b/tools/test/topos/optical.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+
+''' file: optical.py '''
+
+from mininet.topo import Topo
+from mininet.node import RemoteController
+from mininet.net import Mininet
+from mininet.cli import CLI
+from mininet.log import setLogLevel, info
+from mininet.link import Intf, Link
+from mininet.util import irange
+
+class NullIntf( Intf ):
+    "A dummy interface with a blank name that doesn't do any configuration"
+    def __init__( self, name, **params ):
+        self.name = ''
+
+class NullLink( Link ):
+    "A dummy link that doesn't touch either interface"
+    def makeIntfPair( cls, intf1, intf2, addr1=None, addr2=None ):
+        pass
+    def delete( self ):
+        pass
+
+class OpticalTopo( Topo ):
+
+    def addIntf( self, switch, intfName ):
+        "Add intf intfName to switch"
+        self.addLink( switch, switch, cls=NullLink,
+                      intfName1=intfName, cls2=NullIntf, intfName2=intfName )
+
+    def build( self, n=2, tapStart=3 ):
+
+        # Add hosts and switches
+        hosts = []
+        switches = []
+        for i in irange( 1, n ):
+            h = self.addHost( 'h%d' % i )
+            s = self.addSwitch( 's%d' % i, dpid="0000ffffffff%04d" % i )
+            self.addLink( h, s )
+            hosts.append( h )
+            switches.append( s )
+
+        # Add optical tap interfaces
+        tapNum = tapStart
+        for sw in switches:
+            self.addIntf( sw, 'tap%d' % tapNum )
+            tapNum += 1
+
+# if you use, sudo mn --custom custom/optical.py, then register the topo:
+#sudo mn --custom optical.py --topo optical,5
+topos = { 'optical': OpticalTopo }
+
+def installStaticFlows( net ):
+    for sw in net.switches:
+      info( 'Adding flows to %s...' % sw.name )
+      sw.dpctl( 'add-flow', 'in_port=1,actions=output=2' )
+      sw.dpctl( 'add-flow', 'in_port=2,actions=output=1' )
+      info( sw.dpctl( 'dump-flows' ) )
+
+def run( n ):
+    topo = OpticalTopo( n )
+    net = Mininet( topo=topo, controller=RemoteController, autoSetMacs=True )
+    net.start()
+    #installStaticFlows( net )
+    CLI( net )
+    net.stop()
+
+# if the script is run directly (sudo custom/optical.py):
+if __name__ == '__main__':
+    import sys
+    try:
+        n = int( sys.argv[1] )
+    except:
+        print ( 'Usage: ./optical.py n    # n is number of switches\n'
+                'Starting with default of 2 switches...\n' )
+        n = 2
+    setLogLevel( 'info' )
+    run( n )