blob: 7b55cef97cf5e6f13fd3d646c0d8ba10c669a1e5 [file] [log] [blame]
William Davies11081f82020-04-10 14:25:43 -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
9from mininet.node import RemoteController, OVSBridge, Host, OVSSwitch
10from mininet.link import TCLink
11from ipaddress import ip_network
12from routinglib import BgpRouter
13from routinglib import RoutedHost, RoutedHost6, UserNAT
14from trellislib import DhcpClient, Dhcp6Client, DhcpRelay, DhcpServer, Dhcp6Server
15from trellislib import DualHomedDhcpClient, DualHomedLacpDhcpClient
16from trellislib import get_mininet, parse_trellis_args, set_up_zebra_config
17from functools import partial
18
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
70 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')
74 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=DualHomedLacpDhcpClient, 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')
86
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, datapath='user')
92 self.addLink(cs1, s205)
93 self.addLink(dhcp, cs1)
94 self.addLink(dhcp6, cs1)
95
96 # Control plane switch (for quagga fpm)
97 cs0 = self.addSwitch('cs0', cls=OVSBridge, datapath='user')
98
99 # Control plane NAT (for quagga fpm)
100 nat = self.addHost('nat', cls=UserNAT,
101 ip='172.16.0.1/24',
102 subnet=str(ip_network(u'172.16.0.0/24')), inNamespace=False)
103 self.addLink(cs0, nat)
104
105 # Internal Quagga bgp1
106 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/24']}}
109 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
116 # 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/24']}}
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
127 # External Quagga r1
128 intfs = {'r1-eth0': {'ipAddrs': ['10.0.1.1/24', '2000::101/120'], 'mac': '00:88:00:00:00:01'},
129 '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']}}
133 r1 = self.addHost('r1', cls=BgpRouter,
134 interfaces=intfs,
135 quaggaConfFile='./bgpdr1.conf')
136 self.addLink(r1, s205)
137 self.addLink(r1, s206)
138
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
147 # 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
175topos = { 'trellis' : Trellis }
176
177if __name__ == "__main__":
178 setLogLevel('debug')
179 topo = Trellis()
180 switch = partial(OVSSwitch, protocols='OpenFlow13', datapath='user')
181 arguments = parse_trellis_args()
182 set_up_zebra_config(arguments.controllers)
183 net = get_mininet(arguments, topo, switch)
184
185 net.start()
186 CLI(net)
187 net.stop()