blob: 983d666998303ec0cb81942974cd25285b667c39 [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 host5 = self.addHost( 'host5', cls=VLANHost, vlan=60, inf="host5-eth0", ip="192.168.60.2" )
91 as6host = self.addHost( 'as6host' )
92
93 self.addLink( host1, sw2 )
94 #Links to the multihomed AS
95 self.addLink( host3, sw1 )
96 self.addLink( host3, sw1 )
97 self.addLink( as2host, host3 )
98 #Single links to the remaining two ASes
99 self.addLink( host4, sw1 )
100 self.addLink( as3host, host4 )
101
102 #AS3-AS4 link
103 #self.addLink( host4, host5)
104 #Add new AS6 to its bridge
105 self.addLink( host5, as6sw )
106 self.addLink( as6host, host5 )
107 #Backup link from router5 to router4
108 self.addLink( host4, host5)
109 #test the host behind the router(behind the router server)
110# for i in range(1, 10):
111 # host = self.addHost('as6host%d' % i)
112 # self.addLink(host, as6router)
113
114 ## Internal Connection To Hosts ##
115 self.addLink( root1, host1 )
116
117 # self.addLink( sw1, sw2 )
118 # self.addLink( sw1, sw3 )
119 # self.addLink( sw2, sw4 )
120 # self.addLink( sw3, sw4 )
121 # self.addLink( sw3, sw5 )
122 # self.addLink( sw4, sw6 )
123 # self.addLink( sw5, sw6 )
124 self.addLink( as6sw, sw1 )
125
126
127 self.addLink(swTestOn, rootTestOn)
128 #self.addLink(swTestOn, host1)
129 self.addLink(swTestOn, host3)
130 self.addLink(swTestOn, host4)
131 self.addLink(swTestOn, host5)
132 self.addLink(swTestOn, as2host)
133
134
135 #self.addLink(rootTestOn, host4)
136
137def startsshd( host ):
138 "Start sshd on host"
139 info( '*** Starting sshd\n' )
140 name, intf, ip = host.name, host.defaultIntf(), host.IP()
141 banner = '/tmp/%s.banner' % name
142 host.cmd( 'echo "Welcome to %s at %s" > %s' % ( name, ip, banner ) )
143 host.cmd( '/usr/sbin/sshd -o "Banner %s"' % banner, '-o "UseDNS no"' )
144 info( '***', host.name, 'is running sshd on', intf, 'at', ip, '\n' )
145
146def startsshds ( hosts ):
147 for h in hosts:
148 startsshd( h )
149
150def stopsshd( ):
151 "Stop *all* sshd processes with a custom banner"
152 info( '*** Shutting down stale sshd/Banner processes ',
153 quietRun( "pkill -9 -f Banner" ), '\n' )
154
155def startquagga( host, num, config_file ):
156 info( '*** Starting Quagga on %s\n' % host )
157 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)
158 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)
159
160 print zebra_cmd
161 print quagga_cmd
162
163 host.cmd( zebra_cmd )
164 host.cmd( quagga_cmd )
165
166def startquaggahost5( host, num ):
167 info( '*** Starting Quagga on %s\n' % host )
168 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)
169 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)
170
171 host.cmd( zebra_cmd )
172 host.cmd( quagga_cmd )
173
174
175def stopquagga( ):
176 quietRun( 'sudo pkill -9 -f bgpd' )
177 quietRun( 'sudo pkill -9 -f zebra' )
178
179def sdn1net():
180 topo = SDNIpModifiedTopo()
181 info( '*** Creating network\n' )
182 net = Mininet( topo=topo, controller=RemoteController )
183 net = Mininet( topo=topo, controller=RemoteController )
184
185 host1, host3, host4, host5 = net.get( 'host1', 'host3', 'host4', 'host5' )
186
187 #host100.setIP('1.168.30.' + str(i), 24, str(host100) + "-eth2")
188
189 #host500.setMAC('00:00:00:00:04:%d' % (i-101), 'host%d-eth0' %(i))
190 #add IP prefixes
191 #for j in range(0,121):
192 #host100.cmd('sudo ip addr add %s.0.40.%s/24 dev host%s-eth0' %(i,j,i))
193
194 ## Adding 2nd, 3rd and 4th interface to host1 connected to sw1 (for another BGP peering)
195 #sw1 = net.get('sw1')
196 host1.setMAC('00:00:00:00:00:01', 'host1-eth0')
197 #host1.cmd('ip addr add 192.168.20.101/24 dev host1-eth0')
198 #host1.cmd('ip addr add 192.168.30.101/24 dev host1-eth0')
199 #host1.cmd('ip addr add 192.168.60.101/24 dev host1-eth0')
200
201 # Net has to be start after adding the above link
202 net.start()
203
204 # Set up as6sw as a learning switch as quickly as possible so it
205 # hopefully doesn't connect to the actual controller
206 # TODO figure out how to change controller before starting switch
207 as6sw = net.get('as6sw')
208 as6sw.cmd('ovs-vsctl set-controller as6sw none')
209 as6sw.cmd('ovs-vsctl set-fail-mode as6sw standalone')
210
211 as6sw.cmd( 'sudo ovs-vsctl set port as6sw-eth1 trunk=60')
212 as6sw.cmd( 'sudo ovs-vsctl set port as6sw-eth2 trunk=60')
213
214
215 sw1 = net.get('sw1')
216 sw1.cmd('ovs-vsctl set-controller sw1 tcp:127.0.0.1:6633')
217
218 swTestOn = net.get('swTestOn')
219 swTestOn.cmd('ovs-vsctl set-controller swTestOn none')
220 swTestOn.cmd('ovs-vsctl set-fail-mode swTestOn standalone')
221
222 #host1.defaultIntf().setIP('192.168.10.101/24')
223
224 host1.cmd( 'ifconfig host1-eth0 inet 0')
225 host1.cmd( 'vconfig add host1-eth0 10')
226 host1.cmd( 'ifconfig host1-eth0.10 inet 192.168.10.101')
227
228 host1.cmd( 'vconfig add host1-eth0 20')
229 host1.cmd( 'ifconfig host1-eth0.20 inet 192.168.20.101')
230
231 host1.cmd( 'vconfig add host1-eth0 30')
232 host1.cmd( 'ifconfig host1-eth0.30 inet 192.168.30.101')
233
234 host1.cmd( 'vconfig add host1-eth0 60')
235 host1.cmd( 'ifconfig host1-eth0.60 inet 192.168.60.101')
236
237 # Run BGPd
238 #host1.cmd('%s -d -f %s' % (BGPD, BGPD_CONF))
239 #host1.cmd('/sbin/route add default gw 192.168.10.254 dev %s-eth0' % (host1.name))
240
241 # Configure new host interfaces
242 #host2.defaultIntf().setIP('172.16.10.2/24')
243 #host2.defaultIntf().setMAC('00:00:00:00:01:02')
244 #host2.cmd('/sbin/route add default gw 172.16.10.254 dev %s-eth0' % (host2.name))
245
246 # Set up AS2
247 # add additional VLAN interface
248 host3.cmd( 'ifconfig host3-eth1 inet 0')
249 host3.cmd( 'vconfig add host3-eth1 20')
250 host3.cmd( 'ifconfig host3-eth1.20 inet 192.168.20.1')
251 # change the interface for the sencond connection to sw1 to vlan interface
252 newName = "host3-eth1.20"
253 secondIntf = host3.intf("host3-eth1")
254 secondIntf.name = newName
255 host3.nameToIntf[ newName ] = secondIntf
256
257 host3.setMAC('00:00:00:00:02:01', 'host3-eth0.10')
258 host3.setMAC('00:00:00:00:02:02', 'host3-eth1.20')
259
260 #host3.setIP('172.16.20.254', 24, 'host3-eth2')
261 host3.setIP('3.0.0.254', 8, 'host3-eth2')
262 host3.cmd('sysctl net.ipv4.conf.all.forwarding=1')
263
264 host3.setIP('1.168.30.2', 24, 'host3-eth3')
265 host3.cmd('sysctl net.ipv4.conf.all.arp_ignore=1')
266 host3.cmd('sysctl net.ipv4.conf.all.arp_announce=1')
267 as2host = net.get('as2host')
268 #as2host.defaultIntf().setIP('172.16.20.1/24')
269 for i in range(0, 20):
270 as2host.cmd('sudo ip addr add 3.0.%d.1/24 dev as2host-eth0' %i)
271 as2host.setIP('1.168.30.100', 24, 'as2host-eth1')
272
273 as2host.cmd('ip route add default via 3.0.0.254')
274
275 # Set up AS3
276 host4.setMAC('00:00:00:00:03:01', 'host4-eth0.30')
277 host4.setIP('4.0.0.254', 8, 'host4-eth1')
278 host4.setMAC('00:00:00:00:03:99', 'host4-eth1')
279 host4.cmd('sysctl net.ipv4.conf.all.forwarding=1')
280 as3host = net.get('as3host')
281 for i in range(0, 20):
282 as3host.cmd('sudo ip addr add 4.0.%d.1/24 dev as3host-eth0' %i)
283 as3host.cmd('ip route add default via 4.0.0.254')
284
285 host4.setIP('10.0.0.4', 24, 'host4-eth2')
286 host4.setMAC('00:00:00:00:03:33', 'host4-eth2')
287
288 #root space
289 host4.setIP('1.168.30.3', 24, 'host4-eth3')
290 host4.setMAC('00:00:00:00:03:03', 'host4-eth3')
291
292 # Set up AS4
293 #as4host = net.get('as4host')
294 #as4host.defaultIntf().setIP('172.16.40.1/24')
295 #as4host.cmd('ip route add default via 172.16.40.254')
296
297 # setup interface address for 100 quagga hosts
298 time.sleep(10)
299 #for i in range(numHost101, numHost200 + 1):
300 #host100 = net.get('host' + str(i))
301 #host100.cmd(str(i)+'.0.1.254', 24, 'host'+str(i)+'-eth1')
302 #as4host100 = net.get('as4host%s' %(i))
303 #as4host100.defaultIntf().setIP(str(i) + '.0.0.1/24')
304 #as4host100.cmd('ip route add default via ' + str(i) + '.0.0.254')
305 #for j in range(0, 100):
306 #as4host100.cmd('sudo ip addr add %d.0.%d.1/24 dev %s-eth0' %(i, j, as4host100))
307
308 # Set up AS6 - This has a router and a route server
309 host5 = net.get('host5')
310 host5.setMAC('00:00:00:00:06:02', 'host5-eth0.60')
311 #as6router.setIP('172.16.60.254', 24, 'as6router-eth1')
312 host5.setIP('5.0.0.254', 8, 'host5-eth1')
313 host5.cmd('sysctl net.ipv4.conf.all.forwarding=1')
314 host5.setIP('10.0.0.5', 24, 'host5-eth2')
315 host5.setMAC('00:00:00:00:06:66', 'host5-eth2')
316 host5.setIP('1.168.30.5', 24, 'host5-eth3')
317 host5.setMAC('00:00:00:00:06:05', 'host5-eth3')
318
319 as6host = net.get('as6host')
320 #as6host.defaultIntf().setIP('5.0.0.1/24')
321 for i in range(0, 10):
322 as6host.cmd('sudo ip addr add 5.0.%d.1/24 dev as6host-eth0' %i)
323 as6host.cmd('ip route add default via 5.0.0.254')
324
325 # test the host in the as6
326 #for i in range(1, 10):
327 # baseip = (i-1)*4
328 # host = net.get('as6host%d' % i)
329 # host.defaultIntf().setIP('172.16.70.%d/24' % (baseip+1))
330 # host.cmd('ip route add default via 172.16.70.%d' % (baseip+2))
331 # as6router.setIP('172.16.70.%d' % (baseip+2), 30, 'as6router-eth%d' % (i+1))
332
333 # Start Quagga on border routers
334 startquagga(host3, 1, QUAGGA_CONFIG_FILE_DIR + '/quagga1.conf')
335 startquagga(host4, 2, QUAGGA_CONFIG_FILE_DIR + '/quagga2.conf')
336 #for i in range(numHost101, numHost200 + 1):
337 #host100=net.get('host%d' % (i))
338 #startquaggahost5(host100, i)
339
340 #startquagga(as6rs, 4, 'quagga-as6-rs.conf')
341 startquagga(host5, 5, QUAGGA_CONFIG_FILE_DIR + '/quagga-as6.conf')
342
343 #root1, root2, rootTestOn = net.get( 'root1', 'root2', 'rootTestOn' )
344 root1, rootTestOn = net.get( 'root1', 'rootTestOn' )
345 host1.intf('host1-eth1').setIP('1.1.1.1/24')
346 root1.intf('root1-eth0').setIP('1.1.1.2/24')
347 #host2.intf('host2-eth1').setIP('1.1.2.1/24')
348 #root2.intf('root2-eth0').setIP('1.1.2.2/24')
349
350 #rootTestOn.cmd('ip addr add 1.168.30.102/24 dev rootTestOn-eth0')
351 rootTestOn.cmd('ip addr add 1.168.30.99/24 dev rootTestOn-eth0')
352
353 stopsshd()
354
355 startquagga(host1, 100, QUAGGA_CONFIG_FILE_DIR + '/quagga-sdn-modified.conf')
356 hosts = [ host1, host3, host4, host5, as2host ];
357 #sshdHosts = sshdHosts + hosts
358 startsshds( hosts )
359 #
360 onos1 = '127.0.0.1'
361 forwarding1 = '%s:2000:%s:2000' % ('1.1.1.2', onos1)
362 root1.cmd( 'ssh -nNT -o "PasswordAuthentication no" -o "StrictHostKeyChecking no" -l sdn -L %s %s & ' % (forwarding1, onos1) )
363
364 # Forward 2605 to root namespace for easier access to SDN domain BGPd
365 # If root can ssh to itself without a password this should work
366 root1.cmd('ssh -N -o "PasswordAuthentication no" -o "StrictHostKeyChecking no" -L 2605:1.1.1.1:2605 1.1.1.1 &')
367 #time.sleep(3000000000)
368 CLI( net )
369
370 # Close the ssh port forwarding
371 #quietRun('sudo pkill -f 1.1.1.1')
372
373 stopsshd()
374 stopquagga()
375 net.stop()
376
377if __name__ == '__main__':
378 setLogLevel( 'debug' )
379 if len(sys.argv) > 1:
380 QUAGGA_CONFIG_FILE_DIR = sys.argv[1]
381 sdn1net()