blob: 2180a9456ba0d7434d5200cd3c3eec5b992f87a8 [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
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
52 info("vlan2 = %s" % vlan2)
53
54 if vlan2 != 0:
55 self.cmd( 'ifconfig %s inet 0' % intf2 )
56 self.cmd( 'vconfig add %s %d' % ( intf2, vlan2 ) )
57 self.cmd( 'ifconfig %s.%d inet %s' % ( intf2, vlan2, ip2 ) )
58
59 # update the intf name and host's intf map
60 newName = '%s.%d' % ( intf, vlan )
61 # update the (Mininet) interface to refer to VLAN interface name
62 defaultIntf = self.defaultIntf()
63 defaultIntf.name = newName
64 # add VLAN interface to host's name to intf map
65 self.nameToIntf[ newName ] = defaultIntf
66
67 return r
68
69class SDNIpModifiedTopo( Topo ):
70 "SDN Ip Modified Topology"
71
72 def __init__( self, *args, **kwargs ):
73 global numHost101
74 global numHost200
75 numHost101 = 101
76 numHost200 = 200
77 Topo.__init__( self, *args, **kwargs )
78 sw1 = self.addSwitch('sw1', dpid='0000000000000001')
79 sw2 = self.addSwitch('sw2', dpid='0000000000000002')
80 #add a switch for 3 quagga hosts
81 swTestOn = self.addSwitch('swTestOn', dpid='0000000000000102')
82 #Note this switch isn't part of the SDN topology
83 #We'll use the ovs-controller to turn this into a learning switch
84 as6sw = self.addSwitch('as6sw', dpid='00000000000000a7')
85
86 host1 = self.addHost( 'host1' )
87 root1 = self.addHost( 'root1', inNamespace=False , ip='0')
88 rootTestOn = self.addHost( 'rootTestOn', inNamespace=False, ip='0' )
89
90 #AS2 host
91 host3 = self.addHost( 'host3', cls=VLANHost, vlan=10, intf2="host3-eth1", ip2="192.168.20.1", vlan2=20, inf="host3-eth0", ip="192.168.10.1")
92
93 as2host = self.addHost( 'as2host' )
94 #AS3 host
95 host4 = self.addHost( 'host4', cls=VLANHost, vlan=30, inf="host4-eth0", ip="192.168.30.1" )
96 as3host = self.addHost( 'as3host' )
97 #AS6 host
98 host5 = self.addHost( 'host5', cls=VLANHost, vlan=60, inf="host5-eth0", ip="192.168.60.1" )
99 as6host = self.addHost( 'as6host' )
100
101 self.addLink( host1, sw2 )
102 #Links to the multihomed AS
103 self.addLink( host3, sw1 )
104 self.addLink( host3, sw1 )
105 self.addLink( as2host, host3 )
106 #Single links to the remaining two ASes
107 self.addLink( host4, sw1 )
108 self.addLink( as3host, host4 )
109
110 #AS3-AS4 link
111 #self.addLink( host4, host5)
112 #Add new AS6 to its bridge
113 self.addLink( host5, as6sw )
114 self.addLink( as6host, host5 )
115 #test the host behind the router(behind the router server)
116# for i in range(1, 10):
117 # host = self.addHost('as6host%d' % i)
118 # self.addLink(host, as6router)
119
120 ## Internal Connection To Hosts ##
121 self.addLink( root1, host1 )
122
123 # self.addLink( sw1, sw2 )
124 # self.addLink( sw1, sw3 )
125 # self.addLink( sw2, sw4 )
126 # self.addLink( sw3, sw4 )
127 # self.addLink( sw3, sw5 )
128 # self.addLink( sw4, sw6 )
129 # self.addLink( sw5, sw6 )
130 self.addLink( as6sw, sw1 )
131
132
133 self.addLink(swTestOn, rootTestOn)
134 #self.addLink(swTestOn, host1)
135 self.addLink(swTestOn, host3)
136 self.addLink(swTestOn, host4)
137 self.addLink(swTestOn, host5)
138 self.addLink(swTestOn, as2host)
139
140
141 #self.addLink(rootTestOn, host4)
142
143def startsshd( host ):
144 "Start sshd on host"
145 info( '*** Starting sshd\n' )
146 name, intf, ip = host.name, host.defaultIntf(), host.IP()
147 banner = '/tmp/%s.banner' % name
148 host.cmd( 'echo "Welcome to %s at %s" > %s' % ( name, ip, banner ) )
149 host.cmd( '/usr/sbin/sshd -o "Banner %s"' % banner, '-o "UseDNS no"' )
150 info( '***', host.name, 'is running sshd on', intf, 'at', ip, '\n' )
151
152def startsshds ( hosts ):
153 for h in hosts:
154 startsshd( h )
155
156def stopsshd( ):
157 "Stop *all* sshd processes with a custom banner"
158 info( '*** Shutting down stale sshd/Banner processes ',
159 quietRun( "pkill -9 -f Banner" ), '\n' )
160
161def startquagga( host, num, config_file ):
162 info( '*** Starting Quagga on %s\n' % host )
163 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)
164 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)
165
166 print zebra_cmd
167 print quagga_cmd
168
169 host.cmd( zebra_cmd )
170 host.cmd( quagga_cmd )
171
172def startquaggahost5( host, num ):
173 info( '*** Starting Quagga on %s\n' % host )
174 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)
175 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)
176
177 host.cmd( zebra_cmd )
178 host.cmd( quagga_cmd )
179
180
181def stopquagga( ):
182 quietRun( 'sudo pkill -9 -f bgpd' )
183 quietRun( 'sudo pkill -9 -f zebra' )
184
185def sdn1net():
186 topo = SDNIpModifiedTopo()
187 info( '*** Creating network\n' )
188 net = Mininet( topo=topo, controller=RemoteController )
189 net = Mininet( topo=topo, controller=RemoteController )
190
191 host1, host3, host4, host5 = net.get( 'host1', 'host3', 'host4', 'host5' )
192
193 #host100.setIP('1.168.30.' + str(i), 24, str(host100) + "-eth2")
194
195 #host500.setMAC('00:00:00:00:04:%d' % (i-101), 'host%d-eth0' %(i))
196 #add IP prefixes
197 #for j in range(0,121):
198 #host100.cmd('sudo ip addr add %s.0.40.%s/24 dev host%s-eth0' %(i,j,i))
199
200 ## Adding 2nd, 3rd and 4th interface to host1 connected to sw1 (for another BGP peering)
201 #sw1 = net.get('sw1')
202 host1.setMAC('00:00:00:00:00:01', 'host1-eth0')
203 host1.cmd('ip addr add 192.168.20.101/24 dev host1-eth0')
204 host1.cmd('ip addr add 192.168.30.101/24 dev host1-eth0')
205 host1.cmd('ip addr add 192.168.60.101/24 dev host1-eth0')
206
207 # Net has to be start after adding the above link
208 net.start()
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 = 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 # Run BGPd
227 #host1.cmd('%s -d -f %s' % (BGPD, BGPD_CONF))
228 #host1.cmd('/sbin/route add default gw 192.168.10.254 dev %s-eth0' % (host1.name))
229
230 # Configure new host interfaces
231 #host2.defaultIntf().setIP('172.16.10.2/24')
232 #host2.defaultIntf().setMAC('00:00:00:00:01:02')
233 #host2.cmd('/sbin/route add default gw 172.16.10.254 dev %s-eth0' % (host2.name))
234
235 # Set up AS2
236 host3.setMAC('00:00:00:00:02:01', 'host3-eth0')
237 host3.setMAC('00:00:00:00:02:02', 'host3-eth1')
238
239 newName = "host3-eth1.20"
240 secondIntf = host3.intf("host3-eth1")
241 secondIntf.name = newName
242 # add VLAN interface to host's name to intf map
243 host3.nameToIntf[ newName ] = secondIntf
244
245 #host3.setIP('172.16.20.254', 24, 'host3-eth2')
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 #as2host.defaultIntf().setIP('172.16.20.1/24')
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.setMAC('00:00:00:00:03:01', 'host4-eth0')
262 host4.setIP('4.0.0.254', 8, 'host4-eth1')
263 host4.setMAC('00:00:00:00:03:99', 'host4-eth1')
264 host4.cmd('sysctl net.ipv4.conf.all.forwarding=1')
265 as3host = net.get('as3host')
266 for i in range(0, 20):
267 as3host.cmd('sudo ip addr add 4.0.%d.1/24 dev as3host-eth0' %i)
268 as3host.cmd('ip route add default via 4.0.0.254')
269
270 #root space
271 host4.setIP('1.168.30.3', 24, 'host4-eth2')
272 host4.setMAC('00:00:00:00:03:03', 'host4-eth2')
273
274 # Set up AS4
275 #as4host = net.get('as4host')
276 #as4host.defaultIntf().setIP('172.16.40.1/24')
277 #as4host.cmd('ip route add default via 172.16.40.254')
278
279 # setup interface address for 100 quagga hosts
280 time.sleep(10)
281 #for i in range(numHost101, numHost200 + 1):
282 #host100 = net.get('host' + str(i))
283 #host100.cmd(str(i)+'.0.1.254', 24, 'host'+str(i)+'-eth1')
284 #as4host100 = net.get('as4host%s' %(i))
285 #as4host100.defaultIntf().setIP(str(i) + '.0.0.1/24')
286 #as4host100.cmd('ip route add default via ' + str(i) + '.0.0.254')
287 #for j in range(0, 100):
288 #as4host100.cmd('sudo ip addr add %d.0.%d.1/24 dev %s-eth0' %(i, j, as4host100))
289
290 # Set up AS6 - This has a router and a route server
291 host5 = net.get('host5')
292 host5.setMAC('00:00:00:00:06:02', 'host5-eth0')
293 #as6router.setIP('172.16.60.254', 24, 'as6router-eth1')
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 for i in range(0, 10):
302 as6host.cmd('sudo ip addr add 5.0.%d.1/24 dev as6host-eth0' %i)
303 as6host.cmd('ip route add default via 5.0.0.254')
304
305 # test the host in the as6
306 #for i in range(1, 10):
307 # baseip = (i-1)*4
308 # host = net.get('as6host%d' % i)
309 # host.defaultIntf().setIP('172.16.70.%d/24' % (baseip+1))
310 # host.cmd('ip route add default via 172.16.70.%d' % (baseip+2))
311 # as6router.setIP('172.16.70.%d' % (baseip+2), 30, 'as6router-eth%d' % (i+1))
312
313 # Start Quagga on border routers
314 startquagga(host3, 1, QUAGGA_CONFIG_FILE_DIR + '/quagga1.conf')
315 startquagga(host4, 2, QUAGGA_CONFIG_FILE_DIR + '/quagga2.conf')
316 #for i in range(numHost101, numHost200 + 1):
317 #host100=net.get('host%d' % (i))
318 #startquaggahost5(host100, i)
319
320 #startquagga(as6rs, 4, 'quagga-as6-rs.conf')
321 startquagga(host5, 5, QUAGGA_CONFIG_FILE_DIR + '/quagga-as6.conf')
322
323 #root1, root2, rootTestOn = net.get( 'root1', 'root2', 'rootTestOn' )
324 root1, rootTestOn = net.get( 'root1', 'rootTestOn' )
325 host1.intf('host1-eth1').setIP('1.1.1.1/24')
326 root1.intf('root1-eth0').setIP('1.1.1.2/24')
327 #host2.intf('host2-eth1').setIP('1.1.2.1/24')
328 #root2.intf('root2-eth0').setIP('1.1.2.2/24')
329
330 #rootTestOn.cmd('ip addr add 1.168.30.102/24 dev rootTestOn-eth0')
331 rootTestOn.cmd('ip addr add 1.168.30.99/24 dev rootTestOn-eth0')
332
333 stopsshd()
334
335 startquagga(host1, 100, QUAGGA_CONFIG_FILE_DIR + '/quagga-sdn-modified.conf')
336 hosts = [ host1, host3, host4, host5, as2host ];
337 #sshdHosts = sshdHosts + hosts
338 startsshds( hosts )
339 #
340 onos1 = '127.0.0.1'
341 forwarding1 = '%s:2000:%s:2000' % ('1.1.1.2', onos1)
342 root1.cmd( 'ssh -nNT -o "PasswordAuthentication no" -o "StrictHostKeyChecking no" -l sdn -L %s %s & ' % (forwarding1, onos1) )
343
344 # Forward 2605 to root namespace for easier access to SDN domain BGPd
345 # If root can ssh to itself without a password this should work
346 root1.cmd('ssh -N -o "PasswordAuthentication no" -o "StrictHostKeyChecking no" -L 2605:1.1.1.1:2605 1.1.1.1 &')
347 #time.sleep(3000000000)
348 CLI( net )
349
350 # Close the ssh port forwarding
351 #quietRun('sudo pkill -f 1.1.1.1')
352
353 stopsshd()
354 stopquagga()
355 net.stop()
356
357if __name__ == '__main__':
358 setLogLevel( 'debug' )
359 if len(sys.argv) > 1:
360 QUAGGA_CONFIG_FILE_DIR = sys.argv[1]
361 sdn1net()