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