blob: 4d2b744a8e5fdcee7fb099c7bc6d8be4faf931db [file] [log] [blame]
Charles Chanb0dd5ed2017-03-29 17:36:21 -07001#!/usr/bin/python
2
3import sys
4sys.path.append('..')
5from mininet.topo import Topo
6from mininet.net import Mininet
7from mininet.cli import CLI
8from mininet.log import setLogLevel
hwchiu0d696b32017-12-07 21:31:07 +08009from mininet.node import RemoteController, OVSBridge, Host, OVSSwitch
Charles Chanb0dd5ed2017-03-29 17:36:21 -070010from mininet.link import TCLink
11from mininet.nodelib import NAT
12from ipaddress import ip_network
13from routinglib import BgpRouter
Yi Tseng45ee6922017-07-17 14:49:17 -070014from routinglib import RoutedHost, RoutedHost6
15from trellislib import DhcpClient, Dhcp6Client, DhcpRelay, DhcpServer, Dhcp6Server
Charles Chanec57b952017-04-24 17:05:06 -070016from trellislib import DualHomedDhcpClient
hwchiu0d696b32017-12-07 21:31:07 +080017from functools import partial
Charles Chanb0dd5ed2017-03-29 17:36:21 -070018
19class Trellis( Topo ):
20 "Trellis basic topology"
21
22 def __init__( self, *args, **kwargs ):
23 Topo.__init__( self, *args, **kwargs )
24
25 # Spines
26 s226 = self.addSwitch('s226', dpid='226')
27 s227 = self.addSwitch('s227', dpid='227')
28
29 # Leaves
30 s203 = self.addSwitch('s203', dpid='203')
31 s204 = self.addSwitch('s204', dpid='204')
32 s205 = self.addSwitch('s205', dpid='205')
33 s206 = self.addSwitch('s206', dpid='206')
34
35 # Leaf-Spine Links
36 self.addLink(s226, s203)
37 self.addLink(s226, s203)
38 self.addLink(s226, s204)
39 self.addLink(s226, s204)
40 self.addLink(s226, s205)
41 self.addLink(s226, s205)
42 self.addLink(s226, s206)
43 self.addLink(s226, s206)
44 self.addLink(s227, s203)
45 self.addLink(s227, s203)
46 self.addLink(s227, s204)
47 self.addLink(s227, s204)
48 self.addLink(s227, s205)
49 self.addLink(s227, s205)
50 self.addLink(s227, s206)
51 self.addLink(s227, s206)
52
53 # Leaf-Leaf Links
54 self.addLink(s203, s204)
55 self.addLink(s205, s206)
56
57 # NOTE avoid using 10.0.1.0/24 which is the default subnet of quaggas
58 # NOTE avoid using 00:00:00:00:00:xx which is the default mac of host behind upstream router
59 # IPv4 Hosts
60 h1 = self.addHost('h1', cls=DhcpClient, mac='00:aa:00:00:00:01')
61 h2 = self.addHost('h2', cls=DhcpClient, mac='00:aa:00:00:00:02')
62 h3 = self.addHost('h3', cls=DhcpClient, mac='00:aa:00:00:00:03')
63 h4 = self.addHost('h4', cls=DhcpClient, mac='00:aa:00:00:00:04')
64 self.addLink(h1, s204)
65 self.addLink(h2, s204)
66 self.addLink(h3, s205)
67 self.addLink(h4, s205)
68
69 # IPv6 Hosts
Yi Tseng45ee6922017-07-17 14:49:17 -070070 h1v6 = self.addHost('h1v6', cls=Dhcp6Client, mac='00:bb:00:00:00:01')
71 h2v6 = self.addHost('h2v6', cls=Dhcp6Client, mac='00:bb:00:00:00:02')
72 h3v6 = self.addHost('h3v6', cls=Dhcp6Client, mac='00:bb:00:00:00:03')
73 h4v6 = self.addHost('h4v6', cls=Dhcp6Client, mac='00:bb:00:00:00:04')
Charles Chanb0dd5ed2017-03-29 17:36:21 -070074 self.addLink(h1v6, s204)
75 self.addLink(h2v6, s204)
76 self.addLink(h3v6, s205)
77 self.addLink(h4v6, s205)
78
79 # Dual-homed IPv4 Hosts
80 dh1 = self.addHost('dh1', cls=DualHomedDhcpClient, mac='00:cc:00:00:00:01')
81 self.addLink(dh1, s204)
82 self.addLink(dh1, s203)
83
84 # DHCP server
85 dhcp = self.addHost('dhcp', cls=DhcpServer, mac='00:99:00:00:00:01', ips=['10.0.3.253/24'], gateway='10.0.3.254')
Yi Tseng45ee6922017-07-17 14:49:17 -070086
87 # DHCPv6 server
88 dhcp6 = self.addHost('dhcp6', cls=Dhcp6Server, mac='00:99:66:00:00:01', ips=['2000::3fd/120'], gateway='2000::3ff')
89
90 # Control plane switch (for DHCP servers)
91 cs1 = self.addSwitch('cs1', cls=OVSBridge)
92 self.addLink(cs1, s205)
93 self.addLink(dhcp, cs1)
94 self.addLink(dhcp6, cs1)
Charles Chanb0dd5ed2017-03-29 17:36:21 -070095
96 # Control plane switch (for quagga fpm)
97 cs0 = self.addSwitch('cs0', cls=OVSBridge)
98
99 # Control plane NAT (for quagga fpm)
100 nat = self.addHost('nat', cls=NAT,
101 ip='172.16.0.1/12',
102 subnet=str(ip_network(u'172.16.0.0/12')), inNamespace=False)
103 self.addLink(cs0, nat)
104
105 # Internal Quagga bgp1
Charles Chanc3122db2017-09-01 10:58:24 -0700106 intfs = {'bgp1-eth0': [{'ipAddrs': ['10.0.1.2/24', '2000::102/120'], 'mac': '00:88:00:00:00:03', 'vlan': '110'},
107 {'ipAddrs': ['10.0.7.2/24', '2000::702/120'], 'mac': '00:88:00:00:00:03', 'vlan': '170'}],
108 'bgp1-eth1': {'ipAddrs': ['172.16.0.3/12']}}
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700109 bgp1 = self.addHost('bgp1', cls=BgpRouter,
110 interfaces=intfs,
111 quaggaConfFile='./bgpdbgp1.conf',
112 zebraConfFile='./zebradbgp1.conf')
113 self.addLink(bgp1, s205)
114 self.addLink(bgp1, cs0)
115
Charles Chanc3122db2017-09-01 10:58:24 -0700116 # Internal Quagga bgp2
117 intfs = {'bgp2-eth0': [{'ipAddrs': ['10.0.5.2/24', '2000::502/120'], 'mac': '00:88:00:00:00:04', 'vlan': '150'},
118 {'ipAddrs': ['10.0.6.2/24', '2000::602/120'], 'mac': '00:88:00:00:00:04', 'vlan': '160'}],
119 'bgp2-eth1': {'ipAddrs': ['172.16.0.4/12']}}
120 bgp2 = self.addHost('bgp2', cls=BgpRouter,
121 interfaces=intfs,
122 quaggaConfFile='./bgpdbgp2.conf',
123 zebraConfFile='./zebradbgp2.conf')
124 self.addLink(bgp2, s206)
125 self.addLink(bgp2, cs0)
126
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700127 # External Quagga r1
128 intfs = {'r1-eth0': {'ipAddrs': ['10.0.1.1/24', '2000::101/120'], 'mac': '00:88:00:00:00:01'},
Charles Chanc3122db2017-09-01 10:58:24 -0700129 'r1-eth1': {'ipAddrs': ['10.0.5.1/24', '2000::501/120'], 'mac': '00:88:00:00:00:11'},
130 'r1-eth2': {'ipAddrs': ['10.0.99.1/16']},
131 'r1-eth3': {'ipAddrs': ['2000::9901/120']},
132 'r1-eth4': {'ipAddrs': ['2000::7701/120']}}
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700133 r1 = self.addHost('r1', cls=BgpRouter,
134 interfaces=intfs,
135 quaggaConfFile='./bgpdr1.conf')
136 self.addLink(r1, s205)
Charles Chanc3122db2017-09-01 10:58:24 -0700137 self.addLink(r1, s206)
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700138
139 # External IPv4 Host behind r1
140 rh1 = self.addHost('rh1', cls=RoutedHost, ips=['10.0.99.2/24'], gateway='10.0.99.1')
141 self.addLink(r1, rh1)
142
143 # External IPv6 Host behind r1
144 rh1v6 = self.addHost('rh1v6', cls=RoutedHost, ips=['2000::9902/120'], gateway='2000::9901')
145 self.addLink(r1, rh1v6)
146
Charles Chanc3122db2017-09-01 10:58:24 -0700147 # Another external IPv6 Host behind r1
148 rh11v6 = self.addHost('rh11v6', cls=RoutedHost, ips=['2000::7702/120'], gateway='2000::7701')
149 self.addLink(r1, rh11v6)
150
151 # External Quagga r2
152 intfs = {'r2-eth0': {'ipAddrs': ['10.0.6.1/24', '2000::601/120'], 'mac': '00:88:00:00:00:02'},
153 'r2-eth1': {'ipAddrs': ['10.0.7.1/24', '2000::701/120'], 'mac': '00:88:00:00:00:22'},
154 'r2-eth2': {'ipAddrs': ['10.0.99.1/16']},
155 'r2-eth3': {'ipAddrs': ['2000::9901/120']},
156 'r2-eth4': {'ipAddrs': ['2000::8801/120']}}
157 r2 = self.addHost('r2', cls=BgpRouter,
158 interfaces=intfs,
159 quaggaConfFile='./bgpdr2.conf')
160 self.addLink(r2, s206)
161 self.addLink(r2, s205)
162
163 # External IPv4 Host behind r2
164 rh2 = self.addHost('rh2', cls=RoutedHost, ips=['10.0.99.2/24'], gateway='10.0.99.1')
165 self.addLink(r2, rh2)
166
167 # External IPv6 Host behind r2
168 rh2v6 = self.addHost('rh126', cls=RoutedHost, ips=['2000::9902/120'], gateway='2000::9901')
169 self.addLink(r2, rh2v6)
170
171 # Another external IPv6 Host behind r1
172 rh22v6 = self.addHost('rh22v6', cls=RoutedHost, ips=['2000::8802/120'], gateway='2000::8801')
173 self.addLink(r2, rh22v6)
174
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700175topos = { 'trellis' : Trellis }
176
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700177if __name__ == "__main__":
178 setLogLevel('debug')
179 topo = Trellis()
180
hwchiu0d696b32017-12-07 21:31:07 +0800181 switch = partial(OVSSwitch, protocols='OpenFlow13')
182 net = Mininet(topo=topo, controller=None, switch=switch)
Charles Chanc3122db2017-09-01 10:58:24 -0700183 #net.addController(RemoteController('c0', ip='192.168.56.11'))
184 #net.addController(RemoteController('c1', ip='192.168.56.12'))
185 #net.addController(RemoteController('c2', ip='192.168.56.13'))
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700186
187 net.start()
188 CLI(net)
189 net.stop()