blob: 3ba30cde823e342c9e69913494e4035a570f5b49 [file] [log] [blame]
Srikanth Vavilapallida0b4e52015-03-09 16:09:15 -07001#!/usr/bin/python
2
3"""
4Start up the SDN-IP demo 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.node import Host
16from mininet.net import Mininet
17from mininet.node import Controller, RemoteController
18from mininet.log import setLogLevel, info
19from mininet.cli import CLI
20from mininet.topo import Topo
21from mininet.util import quietRun
22from mininet.moduledeps import pathCheck
23
24import os.path
25import time
26import sys
27from subprocess import Popen, STDOUT, PIPE
28
29QUAGGA_DIR = '/usr/lib/quagga'
30#QUAGGA_DIR = '/usr/local/sbin'
31QUAGGA_RUN_DIR = '/usr/local/var/run/quagga'
32
33QUAGGA_CONFIG_FILE_DIR = '/home/tutorial1/ONLabTest/TestON/tests/PeeringRouterTest/mininet'
34
35class VLANHost( Host ):
36 "Host connected to VLAN interface"
37
38 def config( self, vlan=10, intf2 = '', ip2 = 0, vlan2 = 0, **params):
39 """Configure VLANHost according to (optional) parameters:
40 vlan: VLAN ID for default interface"""
41
42 r = super( VLANHost, self ).config( **params )
43
44 intf = params['inf']
45 # remove IP from default, "physical" interface
46 self.cmd( 'ifconfig %s inet 0' % intf )
47 # create VLAN interface
48 self.cmd( 'vconfig add %s %d' % ( intf, vlan ) )
49 # assign the host's IP to the VLAN interface
50 self.cmd( 'ifconfig %s.%d inet %s' % ( intf, vlan, params['ip'] ) )
51 # update the intf name and host's intf map
52 newName = '%s.%d' % ( intf, vlan )
53 # update the (Mininet) interface to refer to VLAN interface name
54 defaultIntf = self.defaultIntf()
55 defaultIntf.name = newName
56 # add VLAN interface to host's name to intf map
57 self.nameToIntf[ newName ] = defaultIntf
58
59 return r
60
61class SDNIpModifiedTopo( Topo ):
62 "SDN Ip Modified Topology"
63
64 def __init__( self, *args, **kwargs ):
65 global numHost101
66 global numHost200
67 numHost101 = 101
68 numHost200 = 200
69 Topo.__init__( self, *args, **kwargs )
70 sw1 = self.addSwitch('sw1', dpid='0000000000000001')
71 sw2 = self.addSwitch('sw2', dpid='0000000000000002')
72 #add a switch for 3 quagga hosts
73 swTestOn = self.addSwitch('swTestOn', dpid='0000000000000102')
74 #Note this switch isn't part of the SDN topology
75 #We'll use the ovs-controller to turn this into a learning switch
76 as6sw = self.addSwitch('as6sw', dpid='00000000000000a7')
77
78 host1 = self.addHost( 'host1' )
79 root1 = self.addHost( 'root1', inNamespace=False , ip='0')
80 rootTestOn = self.addHost( 'rootTestOn', inNamespace=False, ip='0' )
81
82 #AS2 host
83 host3 = self.addHost( 'host3', cls=VLANHost, vlan=10, inf="host3-eth0", ip="192.168.10.1")
84
85 as2host = self.addHost( 'as2host' )
86 #AS3 host
87 host4 = self.addHost( 'host4', cls=VLANHost, vlan=30, inf="host4-eth0", ip="192.168.30.1" )
88 as3host = self.addHost( 'as3host' )
89 #AS6 host
90 as6rs = self.addHost( 'as6rs', cls=VLANHost, vlan=60, inf="as6rs-eth0", ip="192.168.60.1" )
91 host5 = self.addHost( 'host5', cls=VLANHost, vlan=60, inf="host5-eth0", ip="192.168.60.2" )
92 as6host = self.addHost( 'as6host' )
93
94 self.addLink( host1, sw2 )
95 #Links to the multihomed AS
96 self.addLink( host3, sw1 )
97 self.addLink( host3, sw1 )
98 self.addLink( as2host, host3 )
99 #Single links to the remaining two ASes
100 self.addLink( host4, sw1 )
101 self.addLink( as3host, host4 )
102
103 #AS3-AS4 link
104 #self.addLink( host4, host5)
105 #Add new AS6 to its bridge
106 self.addLink( as6rs, as6sw )
107 self.addLink( host5, as6sw )
108 self.addLink( as6host, host5 )
109 #Backup link from router5 to router4
110 self.addLink( host4, host5)
111 #test the host behind the router(behind the router server)
112# for i in range(1, 10):
113 # host = self.addHost('as6host%d' % i)
114 # self.addLink(host, as6router)
115
116 ## Internal Connection To Hosts ##
117 self.addLink( root1, host1 )
118
119 # self.addLink( sw1, sw2 )
120 # self.addLink( sw1, sw3 )
121 # self.addLink( sw2, sw4 )
122 # self.addLink( sw3, sw4 )
123 # self.addLink( sw3, sw5 )
124 # self.addLink( sw4, sw6 )
125 # self.addLink( sw5, sw6 )
126 self.addLink( as6sw, sw1 )
127
128
129 self.addLink(swTestOn, rootTestOn)
130 #self.addLink(swTestOn, host1)
131 self.addLink(swTestOn, host3)
132 self.addLink(swTestOn, host4)
133 self.addLink(swTestOn, host5)
134 self.addLink(swTestOn, as2host)
135 self.addLink(swTestOn, as6rs)
136
137
138 #self.addLink(rootTestOn, host4)
139
140def startsshd( host ):
141 "Start sshd on host"
142 info( '*** Starting sshd\n' )
143 name, intf, ip = host.name, host.defaultIntf(), host.IP()
144 banner = '/tmp/%s.banner' % name
145 host.cmd( 'echo "Welcome to %s at %s" > %s' % ( name, ip, banner ) )
146 host.cmd( '/usr/sbin/sshd -o "Banner %s"' % banner, '-o "UseDNS no"' )
147 info( '***', host.name, 'is running sshd on', intf, 'at', ip, '\n' )
148
149def startsshds ( hosts ):
150 for h in hosts:
151 startsshd( h )
152
153def stopsshd( ):
154 "Stop *all* sshd processes with a custom banner"
155 info( '*** Shutting down stale sshd/Banner processes ',
156 quietRun( "pkill -9 -f Banner" ), '\n' )
157
158def startquagga( host, num, config_file ):
159 info( '*** Starting Quagga on %s\n' % host )
160 zebra_cmd = 'sudo %s/zebra -d -f %s/zebra.conf -z %s/zserv%s.api -i %s/zebra%s.pid' % (QUAGGA_DIR, QUAGGA_CONFIG_FILE_DIR, QUAGGA_RUN_DIR, num, QUAGGA_RUN_DIR, num)
161 quagga_cmd = 'sudo %s/bgpd -d -f %s -z %s/zserv%s.api -i %s/bgpd%s.pid' % (QUAGGA_DIR, config_file, QUAGGA_RUN_DIR, num, QUAGGA_RUN_DIR, num)
162
163 print zebra_cmd
164 print quagga_cmd
165
166 host.cmd( zebra_cmd )
167 host.cmd( quagga_cmd )
168
169def startquaggahost5( host, num ):
170 info( '*** Starting Quagga on %s\n' % host )
171 zebra_cmd = 'sudo %s/zebra -d -f %s/zebra.conf -z %s/zserv%s.api -i %s/zebra%s.pid' % (QUAGGA_DIR, QUAGGA_CONFIG_FILE_DIR, QUAGGA_RUN_DIR, num, QUAGGA_RUN_DIR, num)
172 quagga_cmd = 'sudo %s/bgpd -d -f ./as4quaggas/quagga%s.conf -z %s/zserv%s.api -i %s/bgpd%s.pid' % (QUAGGA_DIR, num, QUAGGA_RUN_DIR, num, QUAGGA_RUN_DIR, num)
173
174 host.cmd( zebra_cmd )
175 host.cmd( quagga_cmd )
176
177
178def stopquagga( ):
179 quietRun( 'sudo pkill -9 -f bgpd' )
180 quietRun( 'sudo pkill -9 -f zebra' )
181
182def sdn1net():
183 topo = SDNIpModifiedTopo()
184 info( '*** Creating network\n' )
185 net = Mininet( topo=topo, controller=RemoteController )
186 net = Mininet( topo=topo, controller=RemoteController )
187
188 host1, host3, host4, host5 = net.get( 'host1', 'host3', 'host4', 'host5' )
189
190 #host100.setIP('1.168.30.' + str(i), 24, str(host100) + "-eth2")
191
192 #host500.setMAC('00:00:00:00:04:%d' % (i-101), 'host%d-eth0' %(i))
193 #add IP prefixes
194 #for j in range(0,121):
195 #host100.cmd('sudo ip addr add %s.0.40.%s/24 dev host%s-eth0' %(i,j,i))
196
197 ## Adding 2nd, 3rd and 4th interface to host1 connected to sw1 (for another BGP peering)
198 #sw1 = net.get('sw1')
199 host1.setMAC('00:00:00:00:00:01', 'host1-eth0')
200 #host1.cmd('ip addr add 192.168.20.101/24 dev host1-eth0')
201 #host1.cmd('ip addr add 192.168.30.101/24 dev host1-eth0')
202 #host1.cmd('ip addr add 192.168.60.101/24 dev host1-eth0')
203
204 # Net has to be start after adding the above link
205 net.start()
206
207 # Set up as6sw as a learning switch as quickly as possible so it
208 # hopefully doesn't connect to the actual controller
209 # TODO figure out how to change controller before starting switch
210 as6sw = net.get('as6sw')
211 as6sw.cmd('ovs-vsctl set-controller as6sw none')
212 as6sw.cmd('ovs-vsctl set-fail-mode as6sw standalone')
213
214 as6sw.cmd( 'sudo ovs-vsctl set port as6sw-eth1 trunk=60')
215 as6sw.cmd( 'sudo ovs-vsctl set port as6sw-eth2 trunk=60')
216
217
218 sw1 = net.get('sw1')
219 sw1.cmd('ovs-vsctl set-controller sw1 tcp:127.0.0.1:6633')
220
221 swTestOn = net.get('swTestOn')
222 swTestOn.cmd('ovs-vsctl set-controller swTestOn none')
223 swTestOn.cmd('ovs-vsctl set-fail-mode swTestOn standalone')
224
225 #host1.defaultIntf().setIP('192.168.10.101/24')
226
227 host1.cmd( 'ifconfig host1-eth0 inet 0')
228 host1.cmd( 'vconfig add host1-eth0 10')
229 host1.cmd( 'ifconfig host1-eth0.10 inet 192.168.10.101')
230
231 host1.cmd( 'vconfig add host1-eth0 20')
232 host1.cmd( 'ifconfig host1-eth0.20 inet 192.168.20.101')
233
234 host1.cmd( 'vconfig add host1-eth0 30')
235 host1.cmd( 'ifconfig host1-eth0.30 inet 192.168.30.101')
236
237 host1.cmd( 'vconfig add host1-eth0 60')
238 host1.cmd( 'ifconfig host1-eth0.60 inet 192.168.60.101')
239
240 # Run BGPd
241 #host1.cmd('%s -d -f %s' % (BGPD, BGPD_CONF))
242 #host1.cmd('/sbin/route add default gw 192.168.10.254 dev %s-eth0' % (host1.name))
243
244 # Configure new host interfaces
245 #host2.defaultIntf().setIP('172.16.10.2/24')
246 #host2.defaultIntf().setMAC('00:00:00:00:01:02')
247 #host2.cmd('/sbin/route add default gw 172.16.10.254 dev %s-eth0' % (host2.name))
248
249 # Set up AS2
250 # add additional VLAN interface
251 host3.cmd( 'ifconfig host3-eth1 inet 0')
252 host3.cmd( 'vconfig add host3-eth1 20')
253 host3.cmd( 'ifconfig host3-eth1.20 inet 192.168.20.1')
254 # change the interface for the sencond connection to sw1 to vlan interface
255 newName = "host3-eth1.20"
256 secondIntf = host3.intf("host3-eth1")
257 secondIntf.name = newName
258 host3.nameToIntf[ newName ] = secondIntf
259
260 host3.setMAC('00:00:00:00:02:01', 'host3-eth0.10')
261 host3.setMAC('00:00:00:00:02:02', 'host3-eth1.20')
262
263 #host3.setIP('172.16.20.254', 24, 'host3-eth2')
264 host3.setIP('3.0.0.254', 8, 'host3-eth2')
265 host3.cmd('sysctl net.ipv4.conf.all.forwarding=1')
266
267 host3.setIP('1.168.30.2', 24, 'host3-eth3')
268 host3.cmd('sysctl net.ipv4.conf.all.arp_ignore=1')
269 host3.cmd('sysctl net.ipv4.conf.all.arp_announce=1')
270 as2host = net.get('as2host')
271 #as2host.defaultIntf().setIP('172.16.20.1/24')
272 for i in range(0, 20):
273 as2host.cmd('sudo ip addr add 3.0.%d.1/24 dev as2host-eth0' %i)
274 as2host.setIP('1.168.30.100', 24, 'as2host-eth1')
275
276 as2host.cmd('ip route add default via 3.0.0.254')
277
278 # Set up AS3
279 host4.setMAC('00:00:00:00:03:01', 'host4-eth0.30')
280 host4.setIP('4.0.0.254', 8, 'host4-eth1')
281 host4.setMAC('00:00:00:00:03:99', 'host4-eth1')
282 host4.cmd('sysctl net.ipv4.conf.all.forwarding=1')
283 as3host = net.get('as3host')
284 for i in range(0, 20):
285 as3host.cmd('sudo ip addr add 4.0.%d.1/24 dev as3host-eth0' %i)
286 as3host.cmd('ip route add default via 4.0.0.254')
287
288 host4.setIP('10.0.0.4', 24, 'host4-eth2')
289 host4.setMAC('00:00:00:00:03:33', 'host4-eth2')
290
291 #root space
292 host4.setIP('1.168.30.3', 24, 'host4-eth3')
293 host4.setMAC('00:00:00:00:03:03', 'host4-eth3')
294
295 # Set up AS4
296 #as4host = net.get('as4host')
297 #as4host.defaultIntf().setIP('172.16.40.1/24')
298 #as4host.cmd('ip route add default via 172.16.40.254')
299
300 # setup interface address for 100 quagga hosts
301 time.sleep(10)
302 #for i in range(numHost101, numHost200 + 1):
303 #host100 = net.get('host' + str(i))
304 #host100.cmd(str(i)+'.0.1.254', 24, 'host'+str(i)+'-eth1')
305 #as4host100 = net.get('as4host%s' %(i))
306 #as4host100.defaultIntf().setIP(str(i) + '.0.0.1/24')
307 #as4host100.cmd('ip route add default via ' + str(i) + '.0.0.254')
308 #for j in range(0, 100):
309 #as4host100.cmd('sudo ip addr add %d.0.%d.1/24 dev %s-eth0' %(i, j, as4host100))
310
311 # Set up AS6 - This has a router and a route server
312 as6rs, host5 = net.get('as6rs', 'host5')
313
314 as6rs.setMAC('00:00:00:06:06:01', 'as6rs-eth0')
315 as6rs.setIP('1.168.30.6', 24, 'as6rs-eth1')
316 as6rs.setMAC('00:00:00:06:06:06', 'as6rs-eth1')
317
318 host5.setMAC('00:00:00:00:06:02', 'host5-eth0.60')
319 #as6router.setIP('172.16.60.254', 24, 'as6router-eth1')
320 host5.setIP('5.0.0.254', 8, 'host5-eth1')
321 host5.cmd('sysctl net.ipv4.conf.all.forwarding=1')
322 host5.setIP('10.0.0.5', 24, 'host5-eth2')
323 host5.setMAC('00:00:00:00:06:66', 'host5-eth2')
324 host5.setIP('1.168.30.5', 24, 'host5-eth3')
325 host5.setMAC('00:00:00:00:06:05', 'host5-eth3')
326
327 as6host = net.get('as6host')
328 #as6host.defaultIntf().setIP('5.0.0.1/24')
329 for i in range(0, 10):
330 as6host.cmd('sudo ip addr add 5.0.%d.1/24 dev as6host-eth0' %i)
331 as6host.cmd('ip route add default via 5.0.0.254')
332
333 # test the host in the as6
334 #for i in range(1, 10):
335 # baseip = (i-1)*4
336 # host = net.get('as6host%d' % i)
337 # host.defaultIntf().setIP('172.16.70.%d/24' % (baseip+1))
338 # host.cmd('ip route add default via 172.16.70.%d' % (baseip+2))
339 # as6router.setIP('172.16.70.%d' % (baseip+2), 30, 'as6router-eth%d' % (i+1))
340
341 # Start Quagga on border routers
342 startquagga(host3, 1, QUAGGA_CONFIG_FILE_DIR + '/quagga1.conf')
343 startquagga(host4, 2, QUAGGA_CONFIG_FILE_DIR + '/quagga2.conf')
344 #for i in range(numHost101, numHost200 + 1):
345 #host100=net.get('host%d' % (i))
346 #startquaggahost5(host100, i)
347
348 startquagga(as6rs, 4, QUAGGA_CONFIG_FILE_DIR + '/quagga-as6-rs.conf')
349 startquagga(host5, 5, QUAGGA_CONFIG_FILE_DIR + '/quagga-as6.conf')
350
351 #root1, root2, rootTestOn = net.get( 'root1', 'root2', 'rootTestOn' )
352 root1, rootTestOn = net.get( 'root1', 'rootTestOn' )
353 host1.intf('host1-eth1').setIP('1.1.1.1/24')
354 root1.intf('root1-eth0').setIP('1.1.1.2/24')
355 #host2.intf('host2-eth1').setIP('1.1.2.1/24')
356 #root2.intf('root2-eth0').setIP('1.1.2.2/24')
357
358 #rootTestOn.cmd('ip addr add 1.168.30.102/24 dev rootTestOn-eth0')
359 rootTestOn.cmd('ip addr add 1.168.30.99/24 dev rootTestOn-eth0')
360
361 stopsshd()
362
363 startquagga(host1, 100, QUAGGA_CONFIG_FILE_DIR + '/quagga-sdn-modified.conf')
364 hosts = [ host1, host3, host4, host5, as2host, as6rs ];
365 #sshdHosts = sshdHosts + hosts
366 startsshds( hosts )
367 #
368 onos1 = '127.0.0.1'
369 forwarding1 = '%s:2000:%s:2000' % ('1.1.1.2', onos1)
370 root1.cmd( 'ssh -nNT -o "PasswordAuthentication no" -o "StrictHostKeyChecking no" -l sdn -L %s %s & ' % (forwarding1, onos1) )
371
372 # Forward 2605 to root namespace for easier access to SDN domain BGPd
373 # If root can ssh to itself without a password this should work
374 root1.cmd('ssh -N -o "PasswordAuthentication no" -o "StrictHostKeyChecking no" -L 2605:1.1.1.1:2605 1.1.1.1 &')
375 #time.sleep(3000000000)
376 CLI( net )
377
378 # Close the ssh port forwarding
379 #quietRun('sudo pkill -f 1.1.1.1')
380
381 stopsshd()
382 stopquagga()
383 net.stop()
384
385if __name__ == '__main__':
386 setLogLevel( 'debug' )
387 if len(sys.argv) > 1:
388 QUAGGA_CONFIG_FILE_DIR = sys.argv[1]
389 sdn1net()