#!/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")