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