router = self.addHost(name, cls=Router, quaggaConfFile=quaggaConf, zebraConfFile=zebraConf, intfDict=intfs) host = self.addHost(‘h%s‘ % i, cls=SdnIpHost, ip=‘192.168.%s.1/24‘ % i, route=‘192.168.%s.254‘ % i)
class SdnIpHost(Host): def __init__(self, name, ip, route, *args, **kwargs): Host.__init__(self, name, ip=ip, *args, **kwargs) self.route = route def config(self, **kwargs): Host.config(self, **kwargs) debug("configuring route %s" % self.route) self.cmd(‘ip route add default via %s‘ % self.route) class Router(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(‘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(‘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)
mininet> dump <Router bgp: bgp-eth0:10.0.0.1,bgp-eth1:None pid=57128> <SdnIpHost h1: h1-eth0:192.168.1.1 pid=57133> <SdnIpHost h2: h2-eth0:192.168.2.1 pid=57135> <SdnIpHost h3: h3-eth0:192.168.3.1 pid=57137> <SdnIpHost h4: h4-eth0:192.168.4.1 pid=57139> <Router r1: r1-eth0:10.0.0.6,r1-eth1:None pid=57141> <Router r2: r2-eth0:10.0.0.7,r2-eth1:None pid=57143> <Router r3: r3-eth0:10.0.0.8,r3-eth1:None pid=57145> <Router r4: r4-eth0:10.0.0.9,r4-eth1:None pid=57147> <Host root: root-eth0:10.10.10.2 pid=57151> <Host sdnh1: sdnh1-eth0:192.168.0.1 pid=57153> <Host sdnh2: sdnh2-eth0:192.168.0.2 pid=57155> <OVSSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=57160> <OVSSwitch s2: lo:127.0.0.1,s2-eth1:None,s2-eth2:None,s2-eth3:None pid=57163> <OVSSwitch s3: lo:127.0.0.1,s3-eth1:None,s3-eth2:None,s3-eth3:None,s3-eth4:None,s3-eth5:None pid=57166> <OVSSwitch s4: lo:127.0.0.1,s4-eth1:None,s4-eth2:None,s4-eth3:None,s4-eth4:None pid=57169> <OVSSwitch s5: lo:127.0.0.1,s5-eth1:None,s5-eth2:None,s5-eth3:None pid=57172> <OVSSwitch s6: lo:127.0.0.1,s6-eth1:None,s6-eth2:None,s6-eth3:None pid=57175> <RemoteController c0: 127.0.0.1:6653 pid=57122> mininet> bgp ip a *** errRun: [‘stty‘, ‘-icanon‘, ‘min‘, ‘1‘] 01: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: bgp-eth0@if424: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:00:00:00:00:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.0.1.101/24 scope global bgp-eth0 valid_lft forever preferred_lft forever inet 10.0.2.101/24 scope global bgp-eth0 valid_lft forever preferred_lft forever inet 10.0.3.101/24 scope global bgp-eth0 valid_lft forever preferred_lft forever inet 10.0.4.101/24 scope global bgp-eth0 valid_lft forever preferred_lft forever inet6 fe80::200:ff:fe00:1/64 scope link valid_lft forever preferred_lft forever 3: bgp-eth1@if429: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 8a:0c:5b:bc:87:35 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.10.10.1/24 scope global bgp-eth1 valid_lft forever preferred_lft forever mininet> bgp ping 10.10.10.1 *** errRun: [‘stty‘, ‘-icanon‘, ‘min‘, ‘1‘] 0PING 10.10.10.1 (10.10.10.1) 56(84) bytes of data. 64 bytes from 10.10.10.1: icmp_seq=1 ttl=64 time=0.056 ms 64 bytes from 10.10.10.1: icmp_seq=2 ttl=64 time=0.014 ms ^CsendInt: writing chr(3) --- 10.10.10.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1035ms rtt min/avg/max/mdev = 0.014/0.035/0.056/0.021 ms mininet> bgp ping 10.10.10.2 *** errRun: [‘stty‘, ‘-icanon‘, ‘min‘, ‘1‘] 0PING 10.10.10.2 (10.10.10.2) 56(84) bytes of data. 64 bytes from 10.10.10.2: icmp_seq=1 ttl=64 time=0.055 ms 64 bytes from 10.10.10.2: icmp_seq=2 ttl=64 time=0.013 ms 64 bytes from 10.10.10.2: icmp_seq=3 ttl=64 time=0.012 ms ^CsendInt: writing chr(3) --- 10.10.10.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2104ms rtt min/avg/max/mdev = 0.012/0.026/0.055/0.020 ms mininet> sdnh1 ping sdnh2 _popen [‘mnexec‘, ‘-da‘, ‘57155‘, ‘ifconfig‘, ‘sdnh2-eth0‘] 62659*** errRun: [‘stty‘, ‘-icanon‘, ‘min‘, ‘1‘] 0PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data. From 192.168.0.1 icmp_seq=1 Destination Host Unreachable From 192.168.0.1 icmp_seq=2 Destination Host Unreachable From 192.168.0.1 icmp_seq=3 Destination Host Unreachable ^CsendInt: writing chr(3) --- 192.168.0.2 ping statistics --- 5 packets transmitted, 0 received, +3 errors, 100% packet loss, time 4141ms pipe 4 mininet> bgp netstat -lpn *** errRun: [‘stty‘, ‘-icanon‘, ‘min‘, ‘1‘] 0Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name Active UNIX domain sockets (only servers) Proto RefCnt Flags Type State I-Node PID/Program name Path mininet> bgp ls *** errRun: [‘stty‘, ‘-icanon‘, ‘min‘, ‘1‘] 0configs quagga2.conf quagga4.conf quagga-test1.py quagga1.conf quagga3.conf quagga-sdn.conf zebra.conf mininet> bgp ps -elf | grep zebra *** errRun: [‘stty‘, ‘-icanon‘, ‘min‘, ‘1‘] 01 S quagga 36047 1 0 80 0 - 418 do_sel 03:48 ? 00:00:00 /usr/sbin/zebra -d -A 127.0.0.1 -f /etc/quagga/zebra.conf 0 S root 63958 57128 0 80 0 - 1730 pipe_w 11:31 pts/4 00:00:00 grep zebra mininet>