diff --git a/tools/tutorials/artemis/topo.py b/tools/tutorials/artemis/topo.py
new file mode 100755
index 0000000..a612611
--- /dev/null
+++ b/tools/tutorials/artemis/topo.py
@@ -0,0 +1,259 @@
+#!/usr/bin/python
+
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.cli import CLI
+from mininet.log import setLogLevel, info, debug
+from mininet.node import Host, RemoteController, OVSSwitch
+import os
+
+QUAGGA_DIR = '/usr/lib/quagga'
+# Must exist and be owned by quagga user (quagga:quagga by default on Ubuntu)
+QUAGGA_RUN_DIR = '/var/run/quagga'
+EXABGP_RUN_EXE = '~/exabgp/sbin/exabgp'
+CONFIG_DIR = 'configs/'
+
+onos = RemoteController('onos', ip='192.168.0.1', port=6633)
+
+
+class Onos(Host):
+
+    def __init__(self, name, intfDict, *args, **kwargs):
+        Host.__init__(self, name, *args, **kwargs)
+
+        self.intfDict = intfDict
+
+    def config(self, **kwargs):
+        Host.config(self, **kwargs)
+
+        for intf, attrs in self.intfDict.items():
+            self.cmd('ip addr flush dev %s' % intf)
+            if 'mac' in attrs:
+                self.cmd('ip link set %s down' % intf)
+                self.cmd('ip link set %s address %s' % (intf, attrs['mac']))
+                self.cmd('ip link set %s up ' % intf)
+            for addr in attrs['ipAddrs']:
+                self.cmd('ip addr add %s dev %s' % (addr, intf))
+
+
+class QuaggaRouter(Host):
+
+    def __init__(self, name, quaggaConfFile, zebraConfFile, intfDict, *args, **kwargs):
+        Host.__init__(self, name, *args, **kwargs)
+
+        self.quaggaConfFile = quaggaConfFile
+        self.zebraConfFile = zebraConfFile
+        self.intfDict = intfDict
+
+    def config(self, **kwargs):
+        Host.config(self, **kwargs)
+        self.cmd('sysctl net.ipv4.ip_forward=1')
+
+        for intf, attrs in self.intfDict.items():
+            self.cmd('ip addr flush dev %s' % intf)
+            if 'mac' in attrs:
+                self.cmd('ip link set %s down' % intf)
+                self.cmd('ip link set %s address %s' % (intf, attrs['mac']))
+                self.cmd('ip link set %s up ' % intf)
+            for addr in attrs['ipAddrs']:
+                self.cmd('ip addr add %s dev %s' % (addr, intf))
+
+        self.cmd('/usr/lib/quagga/zebra -d -f %s -z %s/zebra%s.api -i %s/zebra%s.pid' %
+                 (self.zebraConfFile, QUAGGA_RUN_DIR, self.name, QUAGGA_RUN_DIR, self.name))
+        self.cmd('/usr/lib/quagga/bgpd -d -f %s -z %s/zebra%s.api -i %s/bgpd%s.pid' %
+                 (self.quaggaConfFile, QUAGGA_RUN_DIR, self.name, QUAGGA_RUN_DIR, self.name))
+
+    def terminate(self):
+        self.cmd("ps ax | egrep 'bgpd%s.pid|zebra%s.pid' | awk '{print $1}' | xargs kill" % (
+            self.name, self.name))
+
+        Host.terminate(self)
+
+
+class ExaBGPRouter(Host):
+
+    def __init__(self, name, exaBGPconf, intfDict, *args, **kwargs):
+        Host.__init__(self, name, *args, **kwargs)
+
+        self.exaBGPconf = exaBGPconf
+        self.intfDict = intfDict
+
+    def config(self, **kwargs):
+        Host.config(self, **kwargs)
+        self.cmd('sysctl net.ipv4.ip_forward=1')
+
+        for intf, attrs in self.intfDict.items():
+            self.cmd('ip addr flush dev %s' % intf)
+            if 'mac' in attrs:
+                self.cmd('ip link set %s down' % intf)
+                self.cmd('ip link set %s address %s' % (intf, attrs['mac']))
+                self.cmd('ip link set %s up ' % intf)
+            for addr in attrs['ipAddrs']:
+                self.cmd('ip addr add %s dev %s' % (addr, intf))
+
+        self.cmd('%s %s > /dev/null 2> exabgp.log &' % (EXABGP_RUN_EXE, self.exaBGPconf))
+
+    def terminate(self):
+        self.cmd(
+            "ps ax | egrep 'lib/exabgp/application/bgp.py' | awk '{print $1}' | xargs kill")
+        self.cmd(
+            "ps ax | egrep 'server.py' | awk '{print $1}' | xargs kill")
+        Host.terminate(self)
+
+
+class ONOSSwitch(OVSSwitch):
+
+    def start(self, controllers):
+        return OVSSwitch.start(self, [onos])
+
+
+class L2Switch(OVSSwitch):
+
+    def start(self, controllers):
+        return OVSSwitch.start(self, [])
+
+
+class ArtemisTopo(Topo):
+    "Artemis tutorial topology"
+
+    def build(self):
+        zebraConf = '%szebra.conf' % CONFIG_DIR
+
+        quaggaConf = '%sR1-quagga.conf' % CONFIG_DIR
+        name = 'R1'
+        eth0 = {
+            'ipAddrs': ['150.1.1.2/30']
+        }
+        eth1 = {
+            'ipAddrs': ['10.0.0.1/8']
+        }
+        eth2 = {
+            'ipAddrs': ['150.1.2.1/30']
+        }
+        intfs = {
+            '%s-eth0' % name: eth0,
+            '%s-eth1' % name: eth1,
+            '%s-eth2' % name: eth2
+        }
+        r1 = self.addHost(name, cls=QuaggaRouter, quaggaConfFile=quaggaConf,
+                          zebraConfFile=zebraConf, intfDict=intfs)
+
+        quaggaConf = '%sR2-quagga.conf' % CONFIG_DIR
+        name = 'R2'
+        eth0 = {
+            'ipAddrs': ['150.1.3.1/30']
+        }
+        eth1 = {
+            'ipAddrs': ['150.1.2.2/30']
+        }
+        intfs = {
+            '%s-eth0' % name: eth0,
+            '%s-eth1' % name: eth1
+        }
+        r2 = self.addHost(name, cls=QuaggaRouter, quaggaConfFile=quaggaConf,
+                          zebraConfFile=zebraConf, intfDict=intfs)
+
+        quaggaConf = '%sR3-quagga.conf' % CONFIG_DIR
+        name = 'R3'
+        eth0 = {
+            'ipAddrs': ['40.0.0.1/8']
+        }
+        eth1 = {
+            'ipAddrs': ['150.1.1.1/30']
+        }
+        intfs = {
+            '%s-eth0' % name: eth0,
+            '%s-eth1' % name: eth1
+        }
+        r3 = self.addHost(name, cls=QuaggaRouter, quaggaConfFile=quaggaConf,
+                          zebraConfFile=zebraConf, intfDict=intfs)
+
+        quaggaConf = '%sR4-quagga.conf' % CONFIG_DIR
+        name = 'R4'
+        eth0 = {
+            'ipAddrs': ['150.1.3.2/30'],
+            'mac': 'e2:f5:32:16:9a:46'
+        }
+        eth1 = {
+            'ipAddrs': ['10.10.10.1/24']
+        }
+        intfs = {
+            '%s-eth0' % name: eth0,
+            '%s-eth1' % name: eth1
+        }
+        r4 = self.addHost(name, cls=QuaggaRouter, quaggaConfFile=quaggaConf,
+                          zebraConfFile=zebraConf, intfDict=intfs)
+
+        ovs = self.addSwitch('ovs', dpid='00002a45d713e141', cls=ONOSSwitch)
+
+        l2_switch = self.addSwitch(
+            'l2_switch', dpid='0000000000000001', failMode='standalone', cls=L2Switch)
+
+        h1 = self.addHost('h1', ip='10.0.0.100/8', defaultRoute='via 10.0.0.1')
+        h4 = self.addHost('h4', ip='40.0.0.100/8', defaultRoute='via 40.0.0.1')
+
+        # Set up the internal BGP speaker
+
+        name = 'exabgp'
+        eth0 = {
+            'ipAddrs': ['10.0.0.3/8']
+        }
+        eth1 = {
+            'ipAddrs': ['192.168.1.2/24']
+        }
+        intfs = {
+            '%s-eth0' % name: eth0,
+            '%s-eth1' % name: eth1
+        }
+        exabgp = self.addHost(name, cls=ExaBGPRouter,
+                              exaBGPconf='%sexabgp.conf' % CONFIG_DIR,
+                              intfDict=intfs)
+
+        self.addLink(r1, r3, port1=0, port2=1)
+        self.addLink(r1, l2_switch, port1=1, port2=2)
+        self.addLink(r1, r2, port1=2, port2=1)
+
+        self.addLink(ovs, r2, port1=2, port2=0)
+        self.addLink(ovs, h4, port1=3, port2=0)
+        self.addLink(ovs, r4, port1=4, port2=0)
+
+        self.addLink(l2_switch, h1, port1=1, port2=0)
+        self.addLink(l2_switch, exabgp, port1=3, port2=0)
+
+        name = 'onos'
+        eth0 = {
+            'ipAddrs': ['192.168.0.1/24']
+        }
+        eth1 = {
+            'ipAddrs': ['10.10.10.2/24']
+        }
+        eth2 = {
+            'ipAddrs': ['192.168.1.1/24']
+        }
+        intfs = {
+            '%s-eth0' % name: eth0,
+            '%s-eth1' % name: eth1,
+            '%s-eth2' % name: eth2
+        }
+        onos = self.addHost(name, inNamespace=False, cls=Onos, intfDict=intfs)
+
+        self.addLink(onos, ovs, port1=0, port2=1)
+        self.addLink(onos, r4, port1=1, port2=1)
+        self.addLink(onos, exabgp, port1=2, port2=1)
+
+topos = {'artemis': ArtemisTopo}
+
+if __name__ == '__main__':
+    setLogLevel('debug')
+    topo = ArtemisTopo()
+
+    net = Mininet(topo=topo, build=False)
+    net.addController(onos)
+    net.build()
+    net.start()
+
+    CLI(net)
+
+    net.stop()
+
+    info("done\n")
