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