diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/routinglib.py b/TestON/tests/USECASE/SegmentRouting/dependencies/routinglib.py
new file mode 100644
index 0000000..81ed5ec
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/routinglib.py
@@ -0,0 +1,677 @@
+#!/usr/bin/python
+
+"""
+Libraries for creating L3 topologies with routing protocols.
+"""
+
+from mininet.node import Host, OVSBridge
+from mininet.nodelib import NAT
+from mininet.log import info, debug, error
+from mininet.cli import CLI
+from ipaddress import ip_network, ip_address, ip_interface
+import os
+
+class RoutedHost(Host):
+    """Host that can be configured with multiple IP addresses."""
+    def __init__(self, name, ips, gateway, *args, **kwargs):
+        super(RoutedHost, self).__init__(name, *args, **kwargs)
+
+        self.ips = ips
+        self.gateway = gateway
+
+    def config(self, **kwargs):
+        Host.config(self, **kwargs)
+
+        self.cmd('ip -4 addr flush dev %s' % self.defaultIntf())
+        for ip in self.ips:
+            self.cmd('ip addr add %s dev %s' % (ip, self.defaultIntf()))
+
+        self.cmd('ip route add default via %s' % self.gateway)
+
+class RoutedHost6(Host):
+    """Host that can be configured with multiple IP addresses."""
+    def __init__(self, name, ips, gateway, *args, **kwargs):
+        super(RoutedHost6, self).__init__(name, *args, **kwargs)
+
+        self.ips = ips
+        self.gateway = gateway
+
+    def config(self, **kwargs):
+        Host.config(self, **kwargs)
+
+        self.cmd('ip -6 addr flush dev %s' % self.defaultIntf())
+        for ip in self.ips:
+            self.cmd('ip -6 addr add %s dev %s' % (ip, self.defaultIntf()))
+
+        self.cmd('ip -6 route add default via %s' % self.gateway)
+
+class Router(Host):
+
+    """An L3 router.
+    Configures the Linux kernel for L3 forwarding and supports rich interface
+    configuration of IP addresses, MAC addresses and VLANs."""
+
+    def __init__(self, name, interfaces, *args, **kwargs):
+        super(Router, self).__init__(name, **kwargs)
+
+        self.interfaces = interfaces
+
+    def config(self, **kwargs):
+        super(Host, self).config(**kwargs)
+
+        self.cmd('sysctl net.ipv4.ip_forward=1')
+        self.cmd('sysctl net.ipv4.conf.all.rp_filter=0')
+        self.cmd('sysctl net.ipv6.conf.all.forwarding=1')
+
+        for intf, configs in self.interfaces.items():
+            self.cmd('ip -4 addr flush dev %s' % intf)
+            self.cmd( 'sysctl net.ipv4.conf.%s.rp_filter=0' % intf )
+
+            if not isinstance(configs, list):
+                configs = [configs]
+
+            for attrs in configs:
+                # Configure the vlan if there is one
+                if 'vlan' in attrs:
+                    vlanName = '%s.%s' % (intf, attrs['vlan'])
+                    self.cmd('ip link add link %s name %s type vlan id %s' %
+                             (intf, vlanName, attrs['vlan']))
+                    self.cmd('ip link set %s up' % vlanName)
+                    addrIntf = vlanName
+                else:
+                    addrIntf = intf
+
+                # Now configure the addresses on the vlan/native interface
+                if 'mac' in attrs:
+                    self.cmd('ip link set %s down' % addrIntf)
+                    self.cmd('ip link set %s address %s' % (addrIntf, attrs['mac']))
+                    self.cmd('ip link set %s up' % addrIntf)
+                for addr in attrs['ipAddrs']:
+                    self.cmd('ip addr add %s dev %s' % (addr, addrIntf))
+
+class QuaggaRouter(Router):
+
+    """Runs Quagga to create a router that can speak routing protocols."""
+
+    binDir = '/usr/lib/quagga'
+    logDir = '/var/log/quagga'
+
+    def __init__(self, name, interfaces,
+                 defaultRoute=None,
+                 zebraConfFile=None,
+                 protocols= [],
+                 fpm=None,
+                 runDir='/var/run/quagga', *args, **kwargs):
+        super(QuaggaRouter, self).__init__(name, interfaces, **kwargs)
+
+        self.protocols = protocols
+        self.fpm = fpm
+
+        for p in self.protocols:
+            p.setQuaggaRouter(self)
+
+        self.runDir = runDir
+        self.defaultRoute = defaultRoute
+
+        # Ensure required directories exist
+        try:
+            original_umask = os.umask(0)
+            if (not os.path.isdir(QuaggaRouter.logDir)):
+                os.makedirs(QuaggaRouter.logDir, 0777)
+            if (not os.path.isdir(self.runDir)):
+                os.makedirs(self.runDir, 0777)
+        finally:
+            os.umask(original_umask)
+
+        self.zebraConfFile = zebraConfFile
+        if (self.zebraConfFile is None):
+            self.zebraConfFile = '%s/zebrad%s.conf' % (self.runDir, self.name)
+            self.generateZebra()
+
+        self.socket = '%s/zebra%s.api' % (self.runDir, self.name)
+
+        self.zebraPidFile = '%s/zebra%s.pid' % (self.runDir, self.name)
+
+    def generateZebra(self):
+        configFile = open(self.zebraConfFile, 'w+')
+        configFile.write('log file %s/zebrad%s.log\n' % (QuaggaRouter.logDir, self.name))
+        configFile.write('hostname zebra-%s\n' % self.name)
+        configFile.write('password %s\n' % 'quagga')
+        if (self.fpm is not None):
+            configFile.write('fpm connection ip %s port 2620' % self.fpm)
+        configFile.close()
+
+    def config(self, **kwargs):
+        super(QuaggaRouter, self).config(**kwargs)
+
+        self.cmd('%s/zebra -d -f %s -z %s -i %s'
+                 % (QuaggaRouter.binDir, self.zebraConfFile, self.socket, self.zebraPidFile))
+
+        for p in self.protocols:
+            p.config(**kwargs)
+
+        if self.defaultRoute:
+            self.cmd('ip route add default via %s' % self.defaultRoute)
+
+    def terminate(self, **kwargs):
+        self.cmd("ps ax | grep '%s' | awk '{print $1}' | xargs kill"
+                 % (self.socket))
+
+        for p in self.protocols:
+            p.terminate(**kwargs)
+
+        super(QuaggaRouter, self).terminate()
+
+class Protocol(object):
+
+    """Base abstraction of a protocol that the QuaggaRouter can run."""
+
+    def setQuaggaRouter(self, qr):
+        self.qr = qr
+
+    def config(self, **kwargs):
+        pass
+
+    def terminate(self, **kwargs):
+        pass
+
+class BgpProtocol(Protocol):
+
+    """Configures and runs the BGP protocol in Quagga."""
+
+    def __init__(self, configFile=None, asNum=None, neighbors=[], routes=[], *args, **kwargs):
+        self.configFile = configFile
+
+        self.asNum = asNum
+        self.neighbors = neighbors
+        self.routes = routes
+
+    def config(self, **kwargs):
+        if self.configFile is None:
+            self.configFile = '%s/bgpd%s.conf' % (self.qr.runDir, self.qr.name)
+            self.generateConfig()
+
+        bgpdPidFile = '%s/bgpd%s.pid' % (self.qr.runDir, self.qr.name)
+
+        self.qr.cmd('%s/bgpd -d -f %s -z %s -i %s'
+                     % (QuaggaRouter.binDir, self.configFile, self.qr.socket, bgpdPidFile))
+
+    def generateConfig(self):
+        conf = ConfigurationWriter(self.configFile)
+
+        def getRouterId(interfaces):
+            intfAttributes = interfaces.itervalues().next()
+            print intfAttributes
+            if isinstance(intfAttributes, list):
+                # Try use the first set of attributes, but if using vlans they might not have addresses
+                intfAttributes = intfAttributes[1] if not intfAttributes[0]['ipAddrs'] else intfAttributes[0]
+            return intfAttributes['ipAddrs'][0].split('/')[0]
+
+        conf.writeLine('log file %s/bgpd%s.log' % (QuaggaRouter.logDir, self.qr.name))
+        conf.writeLine('hostname bgp-%s' % self.qr.name)
+        conf.writeLine('password %s' % 'quagga')
+        conf.writeLine('!')
+        conf.writeLine('router bgp %s' % self.asNum)
+
+        conf.indent()
+
+        conf.writeLine('bgp router-id %s' % getRouterId(self.qr.interfaces))
+        conf.writeLine('timers bgp %s' % '3 9')
+        conf.writeLine('!')
+
+        for neighbor in self.neighbors:
+            conf.writeLine('neighbor %s remote-as %s' % (neighbor['address'], neighbor['as']))
+            conf.writeLine('neighbor %s ebgp-multihop' % neighbor['address'])
+            conf.writeLine('neighbor %s timers connect %s' % (neighbor['address'], '5'))
+            conf.writeLine('neighbor %s advertisement-interval %s' % (neighbor['address'], '5'))
+            if 'port' in neighbor:
+                conf.writeLine('neighbor %s port %s' % (neighbor['address'], neighbor['port']))
+            conf.writeLine('!')
+
+        for route in self.routes:
+            conf.writeLine('network %s' % route)
+
+        conf.close()
+
+class OspfProtocol(Protocol):
+
+    """Configures and runs the OSPF protocol in Quagga."""
+
+    def __init__(self, configFile=None, *args, **kwargs):
+        self.configFile = configFile
+
+    def config(self, **kwargs):
+        if self.configFile is None:
+            self.configFile = '%s/ospfd%s.conf' % (self.qr.runDir, self.qr.name)
+            self.generateConfig()
+
+        ospfPidFile = '%s/ospf%s.pid' % (self.qr.runDir, self.qr.name)
+
+        self.qr.cmd('%s/ospfd -d -f %s -z %s -i %s'
+                     % (QuaggaRouter.binDir, self.configFile, self.qr.socket, ospfPidFile))
+
+    def generateConfig(self):
+        conf = ConfigurationWriter(self.configFile)
+
+        def getRouterId(interfaces):
+            intfAttributes = interfaces.itervalues().next()
+            print intfAttributes
+            if isinstance(intfAttributes, list):
+                # Try use the first set of attributes, but if using vlans they might not have addresses
+                intfAttributes = intfAttributes[1] if not intfAttributes[0]['ipAddrs'] else intfAttributes[0]
+            return intfAttributes['ipAddrs'][0].split('/')[0]
+
+        conf.writeLine('hostname ospf-%s' % self.qr.name)
+        conf.writeLine('password %s' % 'hello')
+        conf.writeLine('!')
+        conf.writeLine('router ospf')
+
+        conf.indent()
+
+        conf.writeLine('ospf router-id %s' % getRouterId(self.qr.interfaces))
+        conf.writeLine('!')
+
+        for name, intf in self.qr.interfaces.items():
+            for ip in intf['ipAddrs']:
+                conf.writeLine('network %s area 0' % ip)
+            # if intf['ipAddrs'][0].startswith('192.168'):
+            #    writeLine(1, 'passive-interface %s' % name)
+
+        conf.close()
+
+class PimProtocol(Protocol):
+
+    """Configures and runs the PIM protcol in Quagga."""
+
+    def __init__(self, configFile=None, *args, **kwargs):
+        self.configFile = configFile
+
+    def config(self, **kwargs):
+        pimPidFile = '%s/pim%s.pid' % (self.qr.runDir, self.qr.name)
+
+        self.qr.cmd('%s/pimd -Z -d -f %s -z %s -i %s'
+                     % (QuaggaRouter.binDir, self.configFile, self.qr.socket, pimPidFile))
+
+class ConfigurationWriter(object):
+
+    """Utility class for writing a configuration file."""
+
+    def __init__(self, filename):
+        self.filename = filename
+        self.indentValue = 0
+
+        self.configFile = open(self.filename, 'w+')
+
+    def indent(self):
+        self.indentValue += 1
+
+    def unindent(self):
+        if (self.indentValue > 0):
+            self.indentValue -= 1
+
+    def write(self, string):
+        self.configFile.write(string)
+
+    def writeLine(self, string):
+        intentStr = ''
+        for _ in range(0, self.indentValue):
+            intentStr += '  '
+        self.write('%s%s\n' % (intentStr, string))
+
+    def close(self):
+        self.configFile.close()
+
+# Backward compatibility for BGP-only use case
+class BgpRouter(QuaggaRouter):
+
+    """Quagga router running the BGP protocol."""
+
+    def __init__(self, name, interfaces,
+                 asNum=0, neighbors=[], routes=[],
+                 defaultRoute=None,
+                 quaggaConfFile=None,
+                 zebraConfFile=None,
+                 *args, **kwargs):
+        bgp = BgpProtocol(configFile=quaggaConfFile, asNum=asNum, neighbors=neighbors, routes=routes)
+
+        super(BgpRouter, self).__init__(name, interfaces,
+                                        zebraConfFile=zebraConfFile,
+                                        defaultRoute=defaultRoute,
+                                        protocols=[bgp],
+                                        *args, **kwargs)
+
+class RouterData(object):
+
+    """Internal data structure storing information about a router."""
+
+    def __init__(self, index):
+        self.index = index
+        self.neighbors = []
+        self.interfaces = {}
+        self.switches = []
+
+    def addNeighbor(self, theirAddress, theirAsNum):
+        self.neighbors.append({'address': theirAddress.ip, 'as': theirAsNum})
+
+    def addInterface(self, intf, vlan, address):
+        if intf not in self.interfaces:
+            self.interfaces[intf] = InterfaceData(intf)
+
+        self.interfaces[intf].addAddress(vlan, address)
+
+    def setSwitch(self, switch):
+        self.switches.append(switch)
+
+class InterfaceData(object):
+
+    """Internal data structure storing information about an interface."""
+
+    def __init__(self, number):
+        self.number = number
+        self.addressesByVlan = {}
+
+    def addAddress(self, vlan, address):
+        if vlan not in self.addressesByVlan:
+            self.addressesByVlan[vlan] = []
+
+        self.addressesByVlan[vlan].append(address.with_prefixlen)
+
+class RoutedNetwork(object):
+
+    """Creates a host behind a router. This is common boilerplate topology
+    segment in routed networks."""
+
+    @staticmethod
+    def build(topology, router, hostName, networks):
+        # There's a convention that the router's addresses are already set up,
+        # and it has the last address in the network.
+
+        def getFirstAddress(network):
+            return '%s/%s' % (network[1], network.prefixlen)
+
+        defaultRoute = AutonomousSystem.getLastAddress(networks[0]).ip
+
+        host = topology.addHost(hostName, cls=RoutedHost,
+                                ips=[getFirstAddress(network) for network in networks],
+                                gateway=defaultRoute)
+
+        topology.addLink(router, host)
+
+class AutonomousSystem(object):
+
+    """Base abstraction of an autonomous system, which implies some internal
+    topology and connections to other topology elements (switches/other ASes)."""
+
+    psIdx = 1
+
+    def __init__(self, asNum, numRouters):
+        self.asNum = asNum
+        self.numRouters = numRouters
+        self.routers = {}
+        for i in range(1, numRouters + 1):
+            self.routers[i] = RouterData(i)
+
+        self.routerNodes = {}
+
+        self.neighbors = []
+        self.vlanAddresses = {}
+
+    def peerWith(self, myRouter, myAddress, theirAddress, theirAsNum, intf=1, vlan=None):
+        router = self.routers[myRouter]
+
+        router.addInterface(intf, vlan, myAddress)
+        router.addNeighbor(theirAddress, theirAsNum)
+
+    def getRouter(self, i):
+        return self.routerNodes[i]
+
+    @staticmethod
+    def generatePeeringAddresses():
+        network = ip_network(u'10.0.%s.0/24' % AutonomousSystem.psIdx)
+        AutonomousSystem.psIdx += 1
+
+        return ip_interface('%s/%s' % (network[1], network.prefixlen)), \
+            ip_interface('%s/%s' % (network[2], network.prefixlen))
+
+    @staticmethod
+    def addPeering(as1, as2, router1=1, router2=1, intf1=1, intf2=1, address1=None, address2=None, useVlans=False):
+        vlan = AutonomousSystem.psIdx if useVlans else None
+
+        if address1 is None or address2 is None:
+            (address1, address2) = AutonomousSystem.generatePeeringAddresses()
+
+        as1.peerWith(router1, address1, address2, as2.asNum, intf=intf1, vlan=vlan)
+        as2.peerWith(router2, address2, address1, as1.asNum, intf=intf2, vlan=vlan)
+
+    @staticmethod
+    def getLastAddress(network):
+        return ip_interface(network.network_address + network.num_addresses - 2)
+
+    @staticmethod
+    def getIthAddress(network, i):
+        return ip_interface('%s/%s' % (network[i], network.prefixlen))
+
+class BasicAutonomousSystem(AutonomousSystem):
+
+    """Basic autonomous system containing one host and one or more routers
+    which peer with other ASes."""
+
+    def __init__(self, num, routes, numRouters=1):
+        super(BasicAutonomousSystem, self).__init__(65000+num, numRouters)
+        self.num = num
+        self.routes = routes
+
+    def addLink(self, switch, router=1):
+        self.routers[router].setSwitch(switch)
+
+    def build(self, topology):
+        self.addRouterAndHost(topology)
+
+    def addRouterAndHost(self, topology):
+
+        # TODO implementation is messy and needs to be cleaned up
+
+        intfs = {}
+
+        router = self.routers[1]
+        for i, router in self.routers.items():
+
+            # routerName = 'r%i%i' % (self.num, i)
+            routerName = 'r%i' % self.num
+            if not i == 1:
+                routerName += ('%i' % i)
+
+            hostName = 'h%i' % self.num
+
+            for j, interface in router.interfaces.items():
+                nativeAddresses = interface.addressesByVlan.pop(None, [])
+                peeringIntf = [{'mac' : '00:00:%02x:00:%02x:%02x' % (self.num, i, j),
+                               'ipAddrs' : nativeAddresses}]
+
+                for vlan, addresses in interface.addressesByVlan.items():
+                    peeringIntf.append({'vlan': vlan,
+                                        'mac': '00:00:%02x:%02x:%02x:%02x' % (self.num, vlan, i, j),
+                                        'ipAddrs': addresses})
+
+                intfs.update({'%s-eth%s' % (routerName, j-1) : peeringIntf})
+
+            # Only add the host to the first router for now
+            if i == 1:
+                internalAddresses = []
+                for route in self.routes:
+                    internalAddresses.append('%s/%s' % (AutonomousSystem.getLastAddress(route).ip, route.prefixlen))
+
+                internalIntf = {'ipAddrs' : internalAddresses}
+
+                # This is the configuration of the next interface after all the peering interfaces
+                intfs.update({'%s-eth%s' % (routerName, len(router.interfaces.keys())) : internalIntf})
+
+            routerNode = topology.addHost(routerName,
+                                          asNum=self.asNum, neighbors=router.neighbors,
+                                          routes=self.routes,
+                                          cls=BgpRouter, interfaces=intfs)
+
+            self.routerNodes[i] = routerNode
+
+            for switch in router.switches:
+                topology.addLink(switch, routerNode)
+
+            # Only add the host to the first router for now
+            if i == 1:
+                defaultRoute = internalAddresses[0].split('/')[0]
+
+                host = topology.addHost(hostName, cls=RoutedHost,
+                                        ips=[self.getFirstAddress(route) for route in self.routes],
+                                        gateway=defaultRoute)
+
+                topology.addLink(routerNode, host)
+
+    # def getLastAddress(self, network):
+    #    return ip_address(network.network_address + network.num_addresses - 2)
+
+    def getFirstAddress(self, network):
+        return '%s/%s' % (network[1], network.prefixlen)
+
+# TODO fix this AS - doesn't currently work
+class RouteServerAutonomousSystem(BasicAutonomousSystem):
+
+    def __init__(self, routerAddress, *args, **kwargs):
+        BasicAutonomousSystem.__init__(self, *args, **kwargs)
+
+        self.routerAddress = routerAddress
+
+    def build(self, topology, connectAtSwitch):
+
+        switch = topology.addSwitch('as%isw' % self.num, cls=OVSBridge)
+
+        self.addRouterAndHost(topology, self.routerAddress, switch)
+
+        rsName = 'rs%i' % self.num
+        routeServer = topology.addHost(rsName,
+                                       self.asnum, self.neighbors,
+                                       cls=BgpRouter,
+                                       interfaces={'%s-eth0' % rsName : {'ipAddrs': [self.peeringAddress]}})
+
+        topology.addLink(routeServer, switch)
+        topology.addLink(switch, connectAtSwitch)
+
+class SdnAutonomousSystem(AutonomousSystem):
+
+    """Runs the internal BGP speakers needed for ONOS routing apps like
+    SDN-IP."""
+
+    routerIdx = 1
+
+    def __init__(self, onosIps, num=1, numBgpSpeakers=1, asNum=65000, externalOnos=True,
+                 peerIntfConfig=None, withFpm=False):
+        super(SdnAutonomousSystem, self).__init__(asNum, numBgpSpeakers)
+        self.onosIps = onosIps
+        self.num = num
+        self.numBgpSpeakers = numBgpSpeakers
+        self.peerIntfConfig = peerIntfConfig
+        self.withFpm = withFpm
+        self.externalOnos = externalOnos
+        self.internalPeeringSubnet = ip_network(u'1.1.1.0/24')
+
+        for router in self.routers.values():
+            # Add iBGP sessions to ONOS nodes
+            for onosIp in onosIps:
+                router.neighbors.append({'address': onosIp, 'as': asNum, 'port': 2000})
+
+            # Add iBGP sessions to other BGP speakers
+            for i, router2 in self.routers.items():
+                if router == router2:
+                    continue
+                cpIpBase = self.num*10
+                ip = AutonomousSystem.getIthAddress(self.internalPeeringSubnet, cpIpBase+i)
+                router.neighbors.append({'address': ip.ip, 'as': asNum})
+
+    def build(self, topology, connectAtSwitch, controlSwitch):
+
+        natIp = AutonomousSystem.getLastAddress(self.internalPeeringSubnet)
+
+        for i, router in self.routers.items():
+            num = SdnAutonomousSystem.routerIdx
+            SdnAutonomousSystem.routerIdx += 1
+            name = 'bgp%s' % num
+
+            cpIpBase = self.num*10
+            ip = AutonomousSystem.getIthAddress(self.internalPeeringSubnet, cpIpBase+i)
+
+            eth0 = { 'ipAddrs' : [ str(ip) ] }
+            if self.peerIntfConfig is not None:
+                eth1 = self.peerIntfConfig
+            else:
+                nativeAddresses = router.interfaces[1].addressesByVlan.pop(None, [])
+                eth1 = [{ 'mac': '00:00:00:00:00:%02x' % num,
+                          'ipAddrs' : nativeAddresses }]
+
+                for vlan, addresses in router.interfaces[1].addressesByVlan.items():
+                    eth1.append({'vlan': vlan,
+                                 'mac': '00:00:00:%02x:%02x:00' % (num, vlan),
+                                 'ipAddrs': addresses})
+
+            intfs = { '%s-eth0' % name : eth0,
+                      '%s-eth1' % name : eth1 }
+
+            bgp = topology.addHost( name, cls=BgpRouter, asNum=self.asNum,
+                                    neighbors=router.neighbors,
+                                    interfaces=intfs,
+                                    defaultRoute=str(natIp.ip),
+                                    fpm=self.onosIps[0] if self.withFpm else None )
+
+            topology.addLink( bgp, controlSwitch )
+            topology.addLink( bgp, connectAtSwitch )
+
+        if self.externalOnos:
+            nat = topology.addHost('nat', cls=NAT,
+                                   ip='%s/%s' % (natIp.ip, self.internalPeeringSubnet.prefixlen),
+                                   subnet=str(self.internalPeeringSubnet), inNamespace=False)
+            topology.addLink(controlSwitch, nat)
+
+def generateRoutes(baseRange, numRoutes, subnetSize=None):
+    baseNetwork = ip_network(baseRange)
+
+    # We need to get at least 2 addresses out of each subnet, so the biggest
+    # prefix length we can have is /30
+    maxPrefixLength = baseNetwork.max_prefixlen - 2
+
+    if subnetSize is not None:
+        return list(baseNetwork.subnets(new_prefix=subnetSize))
+
+    trySubnetSize = baseNetwork.prefixlen + 1
+    while trySubnetSize <= maxPrefixLength and \
+            len(list(baseNetwork.subnets(new_prefix=trySubnetSize))) < numRoutes:
+        trySubnetSize += 1
+
+    if trySubnetSize > maxPrefixLength:
+        raise Exception("Can't get enough routes from input parameters")
+
+    return list(baseNetwork.subnets(new_prefix=trySubnetSize))[:numRoutes]
+
+class RoutingCli( CLI ):
+
+    """CLI command that can bring a host up or down. Useful for simulating router failure."""
+
+    def do_host( self, line ):
+        args = line.split()
+        if len(args) != 2:
+            error( 'invalid number of args: host <host name> {up, down}\n' )
+            return
+
+        host = args[ 0 ]
+        command = args[ 1 ]
+        if host not in self.mn or self.mn.get( host ) not in self.mn.hosts:
+            error( 'invalid host: %s\n' % args[ 1 ] )
+        else:
+            if command == 'up':
+                op = 'up'
+            elif command == 'down':
+                op = 'down'
+            else:
+                error( 'invalid command: host <host name> {up, down}\n' )
+                return
+
+            for intf in self.mn.get( host ).intfList( ):
+                intf.link.intf1.ifconfig( op )
+                intf.link.intf2.ifconfig( op )
