blob: 56c459900b83fb2671ebca3a7b0ab4907ae85aaf [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
Ray Milkey1df260d2018-03-28 11:52:34 -070017from trellislib import get_mininet, parse_trellis_args, set_up_zebra_config
hwchiu0d696b32017-12-07 21:31:07 +080018from functools import partial
Charles Chanb0dd5ed2017-03-29 17:36:21 -070019
20class Trellis( Topo ):
21 "Trellis basic topology"
22
23 def __init__( self, *args, **kwargs ):
24 Topo.__init__( self, *args, **kwargs )
25
26 # Spines
27 s226 = self.addSwitch('s226', dpid='226')
28 s227 = self.addSwitch('s227', dpid='227')
29
30 # Leaves
31 s203 = self.addSwitch('s203', dpid='203')
32 s204 = self.addSwitch('s204', dpid='204')
33 s205 = self.addSwitch('s205', dpid='205')
34 s206 = self.addSwitch('s206', dpid='206')
35
36 # Leaf-Spine Links
37 self.addLink(s226, s203)
38 self.addLink(s226, s203)
39 self.addLink(s226, s204)
40 self.addLink(s226, s204)
41 self.addLink(s226, s205)
42 self.addLink(s226, s205)
43 self.addLink(s226, s206)
44 self.addLink(s226, s206)
45 self.addLink(s227, s203)
46 self.addLink(s227, s203)
47 self.addLink(s227, s204)
48 self.addLink(s227, s204)
49 self.addLink(s227, s205)
50 self.addLink(s227, s205)
51 self.addLink(s227, s206)
52 self.addLink(s227, s206)
53
54 # Leaf-Leaf Links
55 self.addLink(s203, s204)
56 self.addLink(s205, s206)
57
58 # NOTE avoid using 10.0.1.0/24 which is the default subnet of quaggas
59 # NOTE avoid using 00:00:00:00:00:xx which is the default mac of host behind upstream router
60 # IPv4 Hosts
61 h1 = self.addHost('h1', cls=DhcpClient, mac='00:aa:00:00:00:01')
62 h2 = self.addHost('h2', cls=DhcpClient, mac='00:aa:00:00:00:02')
63 h3 = self.addHost('h3', cls=DhcpClient, mac='00:aa:00:00:00:03')
64 h4 = self.addHost('h4', cls=DhcpClient, mac='00:aa:00:00:00:04')
65 self.addLink(h1, s204)
66 self.addLink(h2, s204)
67 self.addLink(h3, s205)
68 self.addLink(h4, s205)
69
70 # IPv6 Hosts
Yi Tseng45ee6922017-07-17 14:49:17 -070071 h1v6 = self.addHost('h1v6', cls=Dhcp6Client, mac='00:bb:00:00:00:01')
72 h2v6 = self.addHost('h2v6', cls=Dhcp6Client, mac='00:bb:00:00:00:02')
73 h3v6 = self.addHost('h3v6', cls=Dhcp6Client, mac='00:bb:00:00:00:03')
74 h4v6 = self.addHost('h4v6', cls=Dhcp6Client, mac='00:bb:00:00:00:04')
Charles Chanb0dd5ed2017-03-29 17:36:21 -070075 self.addLink(h1v6, s204)
76 self.addLink(h2v6, s204)
77 self.addLink(h3v6, s205)
78 self.addLink(h4v6, s205)
79
80 # Dual-homed IPv4 Hosts
81 dh1 = self.addHost('dh1', cls=DualHomedDhcpClient, mac='00:cc:00:00:00:01')
82 self.addLink(dh1, s204)
83 self.addLink(dh1, s203)
84
85 # DHCP server
86 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 -070087
88 # DHCPv6 server
89 dhcp6 = self.addHost('dhcp6', cls=Dhcp6Server, mac='00:99:66:00:00:01', ips=['2000::3fd/120'], gateway='2000::3ff')
90
91 # Control plane switch (for DHCP servers)
92 cs1 = self.addSwitch('cs1', cls=OVSBridge)
93 self.addLink(cs1, s205)
94 self.addLink(dhcp, cs1)
95 self.addLink(dhcp6, cs1)
Charles Chanb0dd5ed2017-03-29 17:36:21 -070096
97 # Control plane switch (for quagga fpm)
98 cs0 = self.addSwitch('cs0', cls=OVSBridge)
99
100 # Control plane NAT (for quagga fpm)
101 nat = self.addHost('nat', cls=NAT,
102 ip='172.16.0.1/12',
103 subnet=str(ip_network(u'172.16.0.0/12')), inNamespace=False)
104 self.addLink(cs0, nat)
105
106 # Internal Quagga bgp1
Charles Chanc3122db2017-09-01 10:58:24 -0700107 intfs = {'bgp1-eth0': [{'ipAddrs': ['10.0.1.2/24', '2000::102/120'], 'mac': '00:88:00:00:00:03', 'vlan': '110'},
108 {'ipAddrs': ['10.0.7.2/24', '2000::702/120'], 'mac': '00:88:00:00:00:03', 'vlan': '170'}],
109 'bgp1-eth1': {'ipAddrs': ['172.16.0.3/12']}}
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700110 bgp1 = self.addHost('bgp1', cls=BgpRouter,
111 interfaces=intfs,
112 quaggaConfFile='./bgpdbgp1.conf',
113 zebraConfFile='./zebradbgp1.conf')
114 self.addLink(bgp1, s205)
115 self.addLink(bgp1, cs0)
116
Charles Chanc3122db2017-09-01 10:58:24 -0700117 # Internal Quagga bgp2
118 intfs = {'bgp2-eth0': [{'ipAddrs': ['10.0.5.2/24', '2000::502/120'], 'mac': '00:88:00:00:00:04', 'vlan': '150'},
119 {'ipAddrs': ['10.0.6.2/24', '2000::602/120'], 'mac': '00:88:00:00:00:04', 'vlan': '160'}],
120 'bgp2-eth1': {'ipAddrs': ['172.16.0.4/12']}}
121 bgp2 = self.addHost('bgp2', cls=BgpRouter,
122 interfaces=intfs,
123 quaggaConfFile='./bgpdbgp2.conf',
124 zebraConfFile='./zebradbgp2.conf')
125 self.addLink(bgp2, s206)
126 self.addLink(bgp2, cs0)
127
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700128 # External Quagga r1
129 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 -0700130 'r1-eth1': {'ipAddrs': ['10.0.5.1/24', '2000::501/120'], 'mac': '00:88:00:00:00:11'},
131 'r1-eth2': {'ipAddrs': ['10.0.99.1/16']},
132 'r1-eth3': {'ipAddrs': ['2000::9901/120']},
133 'r1-eth4': {'ipAddrs': ['2000::7701/120']}}
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700134 r1 = self.addHost('r1', cls=BgpRouter,
135 interfaces=intfs,
136 quaggaConfFile='./bgpdr1.conf')
137 self.addLink(r1, s205)
Charles Chanc3122db2017-09-01 10:58:24 -0700138 self.addLink(r1, s206)
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700139
140 # External IPv4 Host behind r1
141 rh1 = self.addHost('rh1', cls=RoutedHost, ips=['10.0.99.2/24'], gateway='10.0.99.1')
142 self.addLink(r1, rh1)
143
144 # External IPv6 Host behind r1
145 rh1v6 = self.addHost('rh1v6', cls=RoutedHost, ips=['2000::9902/120'], gateway='2000::9901')
146 self.addLink(r1, rh1v6)
147
Charles Chanc3122db2017-09-01 10:58:24 -0700148 # Another external IPv6 Host behind r1
149 rh11v6 = self.addHost('rh11v6', cls=RoutedHost, ips=['2000::7702/120'], gateway='2000::7701')
150 self.addLink(r1, rh11v6)
151
152 # External Quagga r2
153 intfs = {'r2-eth0': {'ipAddrs': ['10.0.6.1/24', '2000::601/120'], 'mac': '00:88:00:00:00:02'},
154 'r2-eth1': {'ipAddrs': ['10.0.7.1/24', '2000::701/120'], 'mac': '00:88:00:00:00:22'},
155 'r2-eth2': {'ipAddrs': ['10.0.99.1/16']},
156 'r2-eth3': {'ipAddrs': ['2000::9901/120']},
157 'r2-eth4': {'ipAddrs': ['2000::8801/120']}}
158 r2 = self.addHost('r2', cls=BgpRouter,
159 interfaces=intfs,
160 quaggaConfFile='./bgpdr2.conf')
161 self.addLink(r2, s206)
162 self.addLink(r2, s205)
163
164 # External IPv4 Host behind r2
165 rh2 = self.addHost('rh2', cls=RoutedHost, ips=['10.0.99.2/24'], gateway='10.0.99.1')
166 self.addLink(r2, rh2)
167
168 # External IPv6 Host behind r2
169 rh2v6 = self.addHost('rh126', cls=RoutedHost, ips=['2000::9902/120'], gateway='2000::9901')
170 self.addLink(r2, rh2v6)
171
172 # Another external IPv6 Host behind r1
173 rh22v6 = self.addHost('rh22v6', cls=RoutedHost, ips=['2000::8802/120'], gateway='2000::8801')
174 self.addLink(r2, rh22v6)
175
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700176topos = { 'trellis' : Trellis }
177
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700178if __name__ == "__main__":
179 setLogLevel('debug')
180 topo = Trellis()
hwchiu0d696b32017-12-07 21:31:07 +0800181 switch = partial(OVSSwitch, protocols='OpenFlow13')
Ray Milkey1df260d2018-03-28 11:52:34 -0700182 arguments = parse_trellis_args()
183 set_up_zebra_config(arguments.controllers)
184 net = get_mininet(arguments, topo, switch)
Charles Chanb0dd5ed2017-03-29 17:36:21 -0700185
186 net.start()
187 CLI(net)
188 net.stop()