blob: 0784c2ad8a0d32e02fd01aca0980bdffbe916b6a [file] [log] [blame]
pingping-linebb6fe42015-08-31 17:59:33 -07001#!/usr/bin/python
2
3"""
4Set up the SDN-IP performance test topology
5"""
6
7"""
8AS1 = 64513, (SDN AS)
9AS2 = 64514, reachable by 192.168.10.1, 192.168.20.1
10AS3 = 64516, reachable by 192.168.30.1
11AS4 = 64517, reachable by 192.168.40.1
12AS6 = 64520, reachable by 192.168.60.2, (route server 192.168.60.1)
13"""
14
15from mininet.net import Mininet
16from mininet.node import Controller, RemoteController
17from mininet.log import setLogLevel, info
18from mininet.cli import CLI
19from mininet.topo import Topo
20from mininet.util import quietRun
21from mininet.moduledeps import pathCheck
22
23import os.path
24import time
25from subprocess import Popen, STDOUT, PIPE
26
27QUAGGA_DIR = '/usr/lib/quagga'
28QUAGGA_RUN_DIR = '/usr/local/var/run/quagga'
29
30class SDNTopo( Topo ):
31 "SDN Topology"
32
33 def __init__( self, *args, **kwargs ):
34 global numHost101
35 global numHost200
36 numHost101 = 101
37 numHost200 = 200
38
39 Topo.__init__( self, *args, **kwargs )
40 sw1 = self.addSwitch( 'sw1', dpid = '00000000000000a1' )
41 sw2 = self.addSwitch( 'sw2', dpid = '00000000000000a2' )
42 sw3 = self.addSwitch( 'sw3', dpid = '00000000000000a3' )
43 sw4 = self.addSwitch( 'sw4', dpid = '00000000000000a4' )
44 sw5 = self.addSwitch( 'sw5', dpid = '00000000000000a5' )
45 sw6 = self.addSwitch( 'sw6', dpid = '00000000000000a6' )
46 # add a switch for 100 quagga hosts
47 sw100 = self.addSwitch( 'sw100', dpid = '0000000000000100' )
48 swTestOn = self.addSwitch( 'swTestOn', dpid = '0000000000000102' )
49 # Note this switch isn't part of the SDN topology
50 # We'll use the ovs-controller to turn this into a learning switch
51 as6sw = self.addSwitch( 'as6sw', dpid = '00000000000000a7' )
52
53 host1 = self.addHost( 'host1' )
54 host2 = self.addHost( 'host2' )
55 root1 = self.addHost( 'root1', inNamespace = False , ip = '0' )
56 root2 = self.addHost( 'root2', inNamespace = False, ip = '0' )
57 rootTestOn = self.addHost( 'rootTestOn', inNamespace = False, ip = '0' )
58
59 # AS2 host
60 host3 = self.addHost( 'host3' )
61 as2host = self.addHost( 'as2host' )
62 # AS3 host
63 host4 = self.addHost( 'host4' )
64 as3host = self.addHost( 'as3host' )
65 # AS4 host
66 for i in range( numHost101, numHost200 + 1 ):
67 self.addHost( 'host%s' % ( i ) )
68
69 '''as4host = self.addHost( 'as4host' )
70 for i in range(numHost101, numHost200 + 1):
71 self.addHost('as4host%s' %(i))
72 '''
73 # AS6 host
74 as6rs = self.addHost( 'as6rs' )
75 host5 = self.addHost( 'host5' )
76 as6host = self.addHost( 'as6host' )
77
78 self.addLink( host1, sw1 )
79 self.addLink( host2, sw1 )
80 # Links to the multihomed AS
81 self.addLink( host3, sw3 )
82 self.addLink( host3, sw5 )
83 self.addLink( as2host, host3 )
84 # Single links to the remaining two ASes
85 self.addLink( host4, sw2 )
86 self.addLink( sw100, sw6 )
87 self.addLink( as3host, host4 )
88 for i in range( numHost101, numHost200 + 1 ):
89 self.addLink( 'host%s' % ( i ), sw100 )
90 '''
91 for i in range(numHost101, numHost200 + 1):
92 self.addLink('host%s' % (i), 'as4host%s' % (i))
93 '''
94 # AS3-AS4 link
95 # self.addLink( host4, host5)
96 # Add new AS6 to its bridge
97 self.addLink( as6rs, as6sw )
98 self.addLink( host5, as6sw )
99 self.addLink( as6host, host5 )
100 # test the host behind the router(behind the router server)
101 '''
102 for i in range(1, 10):
103 host = self.addHost('as6host%d' % i)
104 self.addLink(host, as6router)
105 '''
106 # Internal Connection To Hosts
107 self.addLink( root1, host1 )
108 self.addLink( root2, host2 )
109
110 self.addLink( sw1, sw2 )
111 self.addLink( sw1, sw3 )
112 self.addLink( sw2, sw4 )
113 self.addLink( sw3, sw4 )
114 self.addLink( sw3, sw5 )
115 self.addLink( sw4, sw6 )
116 self.addLink( sw5, sw6 )
117 self.addLink( as6sw, sw4 )
118
119 self.addLink( swTestOn, rootTestOn )
120 self.addLink( swTestOn, host3 )
121 self.addLink( swTestOn, host4 )
122 self.addLink( swTestOn, host5 )
123 self.addLink( swTestOn, as2host )
124
125 for i in range( numHost101, numHost200 + 1 ):
126 self.addLink( swTestOn, 'host' + str( i ) )
127
128def startsshd( host ):
129 "Start sshd on host"
130 info( '*** Starting sshd\n' )
131 name, intf, ip = host.name, host.defaultIntf(), host.IP()
132 banner = '/tmp/%s.banner' % name
133 host.cmd( 'echo "Welcome to %s at %s" > %s' % ( name, ip, banner ) )
134 host.cmd( '/usr/sbin/sshd -o "Banner %s"' % banner, '-o "UseDNS no"' )
135 info( '***', host.name, 'is running sshd on', intf, 'at', ip, '\n' )
136
137def startsshds ( hosts ):
138 for h in hosts:
139 startsshd( h )
140
141def stopsshd():
142 "Stop *all* sshd processes with a custom banner"
143 info( '*** Shutting down stale sshd/Banner processes ',
144 quietRun( "pkill -9 -f Banner" ), '\n' )
145
146def startquagga( host, num, config_file ):
147 info( '*** Starting Quagga on %s\n' % host )
148 quagga_cmd = '%s/bgpd -d -n -f %s -i %s/bgpd%s.pid' \
149 % ( QUAGGA_DIR, config_file, QUAGGA_RUN_DIR, num )
150 print quagga_cmd
151 host.cmd( quagga_cmd )
152
153def startquaggahost5( host, num ):
154 info( '*** Starting Quagga on %s\n' % host )
155 quagga_cmd = '%s/bgpd -d -n -f ./as4quaggas/quagga%s.conf -i %s/bgpd%s.pid'\
156 % ( QUAGGA_DIR, num, QUAGGA_RUN_DIR, num )
157 host.cmd( quagga_cmd )
158
159def stopquagga():
160 quietRun( 'sudo pkill -9 -f bgpd' )
161 quietRun( 'sudo pkill -9 -f zebra' )
162
163def sdn1net():
164 topo = SDNTopo()
165 info( '*** Creating network\n' )
166 net = Mininet( topo = topo, controller = RemoteController )
167
168 host1, host2, host3, host4, host5 = net.get( 'host1', 'host2' ,
169 'host3', 'host4', 'host5' )
170
171 # Adding 2nd, 3rd and 4th interface to host1 connected to sw1
172 # for another BGP peering
173 host1.setMAC( '00:00:00:00:00:01', 'host1-eth0' )
174 host1.cmd( 'ip addr add 192.168.20.101/24 dev host1-eth0' )
175 host1.cmd( 'ip addr add 192.168.30.101/24 dev host1-eth0' )
176 host1.cmd( 'ip addr add 192.168.40.101/24 dev host1-eth0' )
177 host1.cmd( 'ip addr add 192.168.60.101/24 dev host1-eth0' )
178
179 # Net has to be start after adding the above link
180 net.start()
181 for i in range( numHost101, numHost200 + 1 ):
182 host100 = net.get( 'host%s' % ( i ) )
183 host100.cmd( 'ifconfig host%s-eth0 192.168.40.%s up' % ( i, i - 100 ) )
184 host100.setIP( str( i ) + ".0.0.254", 8, str( host100 ) + "-eth1" )
185 host100.setMAC( '00:00:' + str( i - 101 ) + ':00:00:90', 'host' \
186 + str( i ) + '-eth0' )
187 host100.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
188
189 # Set up as6sw as a learning switch as quickly as possible so it
190 # hopefully doesn't connect to the actual controller
191 # TODO figure out how to change controller before starting switch
192 as6sw = net.get( 'as6sw' )
193 as6sw.cmd( 'ovs-vsctl set-controller as6sw none' )
194 as6sw.cmd( 'ovs-vsctl set-fail-mode as6sw standalone' )
195
196
197 sw1, sw2, sw3, sw4, sw5, sw6 = net.get( 'sw1', 'sw2', 'sw3', 'sw4', 'sw5', 'sw6' )
Charles Chan029be652015-08-24 01:46:10 +0800198 sw1.cmd( 'ovs-vsctl set-controller sw1 tcp:10.254.1.201:6653' )
199 sw2.cmd( 'ovs-vsctl set-controller sw2 tcp:10.254.1.201:6653' )
200 sw3.cmd( 'ovs-vsctl set-controller sw3 tcp:10.254.1.201:6653' )
201 sw4.cmd( 'ovs-vsctl set-controller sw4 tcp:10.254.1.201:6653' )
202 sw5.cmd( 'ovs-vsctl set-controller sw5 tcp:10.254.1.201:6653' )
203 sw6.cmd( 'ovs-vsctl set-controller sw6 tcp:10.254.1.201:6653' )
pingping-linebb6fe42015-08-31 17:59:33 -0700204
205 # Set up sw100 as a learning
206 sw100 = net.get( 'sw100' )
207 sw100.cmd( 'ovs-vsctl set-controller sw100 none' )
208 sw100.cmd( 'ovs-vsctl set-fail-mode sw100 standalone' )
209
210 swTestOn = net.get( 'swTestOn' )
211 swTestOn.cmd( 'ovs-vsctl set-controller swTestOn none' )
212 swTestOn.cmd( 'ovs-vsctl set-fail-mode swTestOn standalone' )
213
214 host1.defaultIntf().setIP( '192.168.10.101/24' )
215
216 # Configure new host interfaces
217 host2.defaultIntf().setIP( '172.16.10.2/24' )
218 host2.defaultIntf().setMAC( '00:00:00:00:01:02' )
219
220 # Set up AS2
221 host3.setIP( '192.168.10.1', 24, 'host3-eth0' )
222 host3.setIP( '192.168.20.1', 24, 'host3-eth1' )
223 host3.setMAC( '00:00:00:00:02:01', 'host3-eth0' )
224 host3.setMAC( '00:00:00:00:02:02', 'host3-eth1' )
225 host3.setIP( '3.0.0.254', 8, 'host3-eth2' )
226 host3.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
227
228 host3.setIP( '1.168.30.2', 24, 'host3-eth3' )
229 host3.cmd( 'sysctl net.ipv4.conf.all.arp_ignore=1' )
230 host3.cmd( 'sysctl net.ipv4.conf.all.arp_announce=1' )
231 as2host = net.get( 'as2host' )
232
233 for i in range( 0, 20 ):
234 as2host.cmd( 'sudo ip addr add 3.0.%d.1/24 dev as2host-eth0' % i )
235 as2host.setIP( '1.168.30.100', 24, 'as2host-eth1' )
236
237 as2host.cmd( 'ip route add default via 3.0.0.254' )
238
239 # Set up AS3
240 host4.setIP( '192.168.30.1', 24, 'host4-eth0' )
241 host4.setMAC( '00:00:00:00:03:01', 'host4-eth0' )
242 host4.setIP( '4.0.0.254', 8, 'host4-eth1' )
243 host4.setMAC( '00:00:00:00:03:99', 'host4-eth1' )
244 host4.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
245 as3host = net.get( 'as3host' )
246 for i in range( 0, 20 ):
247 as3host.cmd( 'sudo ip addr add 4.0.%d.1/24 dev as3host-eth0' % i )
248 as3host.cmd( 'ip route add default via 4.0.0.254' )
249
250 # root space
251 host4.setIP( '1.168.30.3', 24, 'host4-eth2' )
252 host4.setMAC( '00:00:00:00:03:03', 'host4-eth2' )
253
254 # setup interface address for 100 quagga hosts
255 time.sleep( 10 )
256 '''
257 for i in range(numHost101, numHost200 + 1):
258 #host100 = net.get('host' + str(i))
259 #host100.cmd(str(i)+'.0.1.254', 24, 'host'+str(i)+'-eth1')
260 as4host100 = net.get('as4host%s' %(i))
261 as4host100.defaultIntf().setIP(str(i) + '.0.0.1/24')
262 as4host100.cmd('ip route add default via ' + str(i) + '.0.0.254')
263 for j in range(0, 100):
264 as4host100.cmd('sudo ip addr add %d.0.%d.1/24 dev %s-eth0' \
265 %(i, j, as4host100))
266 '''
267 # Set up AS6 - This has a router and a route server
268 as6rs, host5 = net.get( 'as6rs', 'host5' )
269 as6rs.setIP( '192.168.60.1', 24, 'as6rs-eth0' )
270 as6rs.setMAC( '00:00:00:00:06:01', 'as6rs-eth0' )
271 host5.setIP( '192.168.60.2', 24, 'host5-eth0' )
272 host5.setMAC( '00:00:00:00:06:02', 'host5-eth0' )
273 host5.setIP( '5.0.0.254', 8, 'host5-eth1' )
274 host5.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
275 host5.setIP( '1.168.30.5', 24, 'host5-eth2' )
276 host5.setMAC( '00:00:00:00:06:05', 'host5-eth2' )
277
278 as6host = net.get( 'as6host' )
279 as6host.defaultIntf().setIP( '5.0.0.1/24' )
280 as6host.cmd( 'ip route add default via 5.0.0.254' )
281 for i in range( 0, 10 ):
282 as6host.cmd( 'sudo ip addr add 5.0.%d.1/24 dev as6host-eth0' % i )
283
284 # Start Quagga on border routers
285 startquagga( host3, 1, 'quagga1.conf' )
286 startquagga( host4, 2, 'quagga2.conf' )
287 for i in range( numHost101, 200 + 1 ):
288 host100 = net.get( 'host%d' % ( i ) )
289 startquaggahost5( host100, i )
290
291 startquagga( as6rs, 4, 'quagga-as6-rs.conf' )
292 startquagga( host5, 5, 'quagga-as6.conf' )
293
294 root1, root2, rootTestOn = net.get( 'root1', 'root2', 'rootTestOn' )
295 host1.intf( 'host1-eth1' ).setIP( '1.1.1.1/24' )
296 root1.intf( 'root1-eth0' ).setIP( '1.1.1.2/24' )
297 host2.intf( 'host2-eth1' ).setIP( '1.1.2.1/24' )
298 root2.intf( 'root2-eth0' ).setIP( '1.1.2.2/24' )
299
300 rootTestOn.cmd( 'ip addr add 1.168.30.99/24 dev rootTestOn-eth0' )
301
302 stopsshd()
303 '''
304 for i in range(numHost101, numHost200 + 1):
305 hostX = net.get('host%s' %(i))
306 hostX.setIP('1.168.30.' + str(i), 24, str("host") + str(i) + "-eth2")
307 startsshd(hostX)
308 #sshdHosts = []
309 #sshdHosts = sshdHosts + [hostX]
310 #print(sshdHosts)
311 '''
312
313 '''startquagga(host1, 100, 'quagga-sdn.conf')'''
314 host1.cmd( "/home/admin/bird-1.5.0/bird" )
315 hosts = [ host1, host2, host3, host4, host5, as2host ];
316 # sshdHosts = sshdHosts + hosts
317 startsshds( hosts )
318 #
319 onos1 = '10.254.1.201'
320 forwarding1 = '%s:179:%s:179' % ( '1.1.1.2', onos1 )
321 root1.cmd( 'ssh -nNT -o "PasswordAuthentication no" \
322 -o "StrictHostKeyChecking no" -l sdn -L %s %s & ' % ( forwarding1, onos1 ) )
323
324 # Forward 2605 to root namespace for easier access to SDN domain BGPd
325 # If root can ssh to itself without a password this should work
326 # root1.cmd( 'ssh -N -o "PasswordAuthentication no" \
327 # -o "StrictHostKeyChecking no" -L 2605:1.1.1.1:2605 1.1.1.1 &' )
328 time.sleep( 3000000000 )
329 CLI( net )
330
331 # Close the ssh port forwarding
332 # quietRun('sudo pkill -f 1.1.1.1')
333
334 stopsshd()
335 stopquagga()
336 net.stop()
337
338if __name__ == '__main__':
339 setLogLevel( 'debug' )
340 sdn1net()