blob: 9b183a0e2aaaff2d468fd5a1481988241e2e5fd0 [file] [log] [blame]
ashuef3490b2015-02-17 11:01:04 -06001#!/usr/bin/env python
2
3from mininet.topo import Topo
4from mininet.net import Mininet
5from mininet.log import setLogLevel, output, info
6from mininet.cli import CLI
7from mininet.link import TCLink
ashu2ad32e22015-05-29 13:37:40 -05008from mininet.util import ipStr, ipParse
ashuef3490b2015-02-17 11:01:04 -06009
Vince Lehman3b8bc652015-06-18 15:01:47 -050010
11from ndn import ExperimentManager
ashuef3490b2015-02-17 11:01:04 -060012from ndn.ndn_host import NdnHost, CpuLimitedNdnHost
ashu2ad32e22015-05-29 13:37:40 -050013from ndn.conf_parser import parse_hosts, parse_links
ashuef3490b2015-02-17 11:01:04 -060014
15import os.path, time
16import optparse
17import datetime
ashu01b62f72015-03-12 15:16:11 -050018from os.path import expanduser
Vince Lehman3b8bc652015-06-18 15:01:47 -050019import sys
ashuef3490b2015-02-17 11:01:04 -060020
21from ndn.nlsr import Nlsr, NlsrConfigGenerator
ashu34c3ee02015-03-25 14:41:14 -050022from ndn.nfd import Nfd
ashuef3490b2015-02-17 11:01:04 -060023
Vince Lehman3b8bc652015-06-18 15:01:47 -050024def printExperimentNames():
25 experimentNames = ExperimentManager.getExperimentNames()
26
27 print "Mini-NDN experiments:"
28 for experiment in experimentNames:
29 print " %s" % experiment
30
ashuef3490b2015-02-17 11:01:04 -060031def parse_args():
32 usage="""Usage: minindn [template_file] [ -t | --testbed ]
Ashlesh Gawande20f70762015-06-17 15:18:19 -050033 If no template_file is given, ndn_utils/default-topology.conf (given sample file)
34 will be used.
ashuef3490b2015-02-17 11:01:04 -060035 If --testbed is used, minindn will run the NDN Project Testbed.
ashuef3490b2015-02-17 11:01:04 -060036 """
37
38 testbed = False
ashuef3490b2015-02-17 11:01:04 -060039 hr = False
ashuef3490b2015-02-17 11:01:04 -060040
41 parser = optparse.OptionParser(usage)
42
43 parser.add_option("-t", "--testbed", action="store_true", dest="testbed",
44 help="instantiates NDN Testbed")
45
Vince Lehman3b8bc652015-06-18 15:01:47 -050046 parser.add_option("--experiment", action="store", dest="experiment",
47 help="Runs the specified experiment")
48
49 parser.add_option("--list-experiments", action="store_true", dest="shouldListExperiments",
50 help="Lists the names of all available experiments")
51
52 parser.add_option("--nPings", action="store", dest="nPings", type="int",
53 help="Number of pings to perform between each node in the experiment")
ashuef3490b2015-02-17 11:01:04 -060054
55 parser.add_option("--ctime", action="store", dest="ctime", type="int",
56 help="Specify convergence time for the topology (Default 60 seconds)")
57
58 parser.add_option("--hr", action="store_true", dest="hr",
59 help="--hr is used to turn on hyperbolic routing")
60
61 parser.add_option("--faces", action="store", dest="faces", type="int",
62 help="Specify number of faces 0-60")
63
ashuef3490b2015-02-17 11:01:04 -060064 parser.add_option("--no-cli", action="store_false", dest="isCliEnabled",
65 help="Run experiments and exit without showing the command line interface")
66
67 (options, arg) = parser.parse_args()
68
69 testbed = options.testbed
Vince Lehman3b8bc652015-06-18 15:01:47 -050070 experimentName = options.experiment
71 shouldListExperiments = options.shouldListExperiments
72 nPings = options.nPings
ashuef3490b2015-02-17 11:01:04 -060073 ctime = options.ctime
74 hr = options.hr
75 faces = options.faces
ashuef3490b2015-02-17 11:01:04 -060076 isCliEnabled = options.isCliEnabled
77
Vince Lehman3b8bc652015-06-18 15:01:47 -050078 if shouldListExperiments is not None:
79 printExperimentNames()
80 sys.exit()
81
ashuef3490b2015-02-17 11:01:04 -060082 if ctime is None:
83 ctime = 60
84
Vince Lehman3b8bc652015-06-18 15:01:47 -050085 if nPings is None:
86 nPings = 300
87
ashuef3490b2015-02-17 11:01:04 -060088 if isCliEnabled is None:
89 isCliEnabled = True
90
91 if len(arg) == 0 or len(arg) > 2:
92 file = ''
93 else:
94 file = arg[0]
95
Vince Lehman3b8bc652015-06-18 15:01:47 -050096 return file, testbed, experimentName, nPings, ctime, hr, faces, isCliEnabled
ashuef3490b2015-02-17 11:01:04 -060097
98class NdnTopo(Topo):
99 def __init__(self, conf_arq, **opts):
100 Topo.__init__(self, **opts)
101
102 global hosts_conf
103 global links_conf
104 hosts_conf = parse_hosts(conf_arq)
105 links_conf = parse_links(conf_arq)
106
107 self.isTCLink = False
108 self.isLimited = False
109
110 for host in hosts_conf:
111 if host.cpu != None and self.isLimited != True:
112 self.isLimited = True
Ashlesh Gawande3a4afb12015-07-09 09:23:30 -0500113 self.addHost(host.name, app=host.app, params=host.uri_tuples, cpu=host.cpu,cores=host.cores,cache=host.cache)
ashuef3490b2015-02-17 11:01:04 -0600114
115 for link in links_conf:
116 if len(link.linkDict) == 0:
117 self.addLink(link.h1, link.h2)
118 else:
119 self.addLink(link.h1, link.h2, **link.linkDict)
120 self.isTCLink = True
121
122 info('Parse of ' + conf_arq + ' done.\n')
123
Vince Lehman3b8bc652015-06-18 15:01:47 -0500124def execute(template_file='minindn.conf', testbed=False, experimentName=None, nPings=None, ctime=None, hr=False, faces=3, isCliEnabled=True):
ashuef3490b2015-02-17 11:01:04 -0600125 "Create a network based on template_file"
126
Ashlesh Gawande20f70762015-06-17 15:18:19 -0500127 install_dir='/usr/local/etc/mini-ndn/'
128
ashuef3490b2015-02-17 11:01:04 -0600129 if template_file == '':
Ashlesh Gawande20f70762015-06-17 15:18:19 -0500130 template_file = install_dir + 'default-topology.conf'
131
132 if testbed:
133 template_file = install_dir + 'minindn.testbed.conf'
ashuef3490b2015-02-17 11:01:04 -0600134
135 if os.path.exists(template_file) == False:
Ashlesh Gawande20f70762015-06-17 15:18:19 -0500136 info('No template file given and default template file cannot be found. Exiting...\n')
ashuef3490b2015-02-17 11:01:04 -0600137 quit()
Ashlesh Gawande20f70762015-06-17 15:18:19 -0500138
ashuef3490b2015-02-17 11:01:04 -0600139 topo = NdnTopo(template_file)
140
141 t = datetime.datetime.now()
142
143 if topo.isTCLink == True and topo.isLimited == True:
144 net = Mininet(topo,host=CpuLimitedNdnHost,link=TCLink)
145 elif topo.isTCLink == True and topo.isLimited == False:
146 net = Mininet(topo,host=NdnHost,link=TCLink)
147 elif topo.isTCLink == False and topo.isLimited == True:
148 net = Mininet(topo,host=CpuLimitedNdnHost)
149 else:
150 net = Mininet(topo,host=NdnHost)
151
152 t2 = datetime.datetime.now()
153
154 delta = t2 - t
155
156 info('Setup time: ' + str(delta.seconds) + '\n')
157
158 net.start()
159
ashu2ad32e22015-05-29 13:37:40 -0500160 # Giving proper IPs to intf so neighbor nodes can communicate
161 # This is one way of giving connectivity, another way could be
162 # to insert a switch between each pair of neighbors
163 ndnNetBase = "1.0.0.0"
164 interfaces = []
165 for host in net.hosts:
166 for intf in host.intfList():
167 link = intf.link
168 node1, node2 = link.intf1.node, link.intf2.node
169 if link.intf1 not in interfaces and link.intf2 not in interfaces:
170 interfaces.append(link.intf1)
171 interfaces.append(link.intf2)
172 node1.setIP(ipStr(ipParse(ndnNetBase) + 1) + '/30', intf=link.intf1)
173 node2.setIP(ipStr(ipParse(ndnNetBase) + 2) + '/30', intf=link.intf2)
174 ndnNetBase = ipStr(ipParse(ndnNetBase) + 4)
175
ashuef3490b2015-02-17 11:01:04 -0600176 nodes = "" # Used later to check prefix name in checkFIB
177
178 # NLSR initialization
179 for host in net.hosts:
180 nodes += str(host.name) + ","
181
182 conf = next(x for x in hosts_conf if x.name == host.name)
183 host.nlsrParameters = conf.nlsrParameters
184
185 if faces is not None:
186 host.nlsrParameters["max-faces-per-prefix"] = faces
187
188 if hr is True:
189 host.nlsrParameters["hyperbolic-state"] = "on"
190
191 # Generate NLSR configuration file
ashu2ad32e22015-05-29 13:37:40 -0500192 configGenerator = NlsrConfigGenerator(host)
ashuef3490b2015-02-17 11:01:04 -0600193 configGenerator.createConfigFile()
194
195 # Start NLSR
ashu34c3ee02015-03-25 14:41:14 -0500196 host.nlsr = Nlsr(host)
197 host.nlsr.start()
ashuef3490b2015-02-17 11:01:04 -0600198
199 nodes = nodes[0:-1]
200
ashuef3490b2015-02-17 11:01:04 -0600201 for host in net.hosts:
202 if 'app' in host.params:
Ashlesh Gawande557cb842015-07-01 15:39:44 -0500203 if host.params['app'] != '':
204 app = host.params['app']
205 print "Starting " + app + " on node " + host.name
206 print(host.cmd(app))
ashuef3490b2015-02-17 11:01:04 -0600207
Vince Lehman3b8bc652015-06-18 15:01:47 -0500208 # Load experiment
209 if experimentName is not None:
210 print "Loading experiment: %s" % experimentName
211
212 experimentArgs = {
213 "net": net,
214 "nodes": nodes,
215 "ctime": ctime,
216 "nPings": nPings,
217 "strategy": Nfd.STRATEGY_BEST_ROUTE_V3
218 }
219
220 experiment = ExperimentManager.create(experimentName, experimentArgs)
221
222 if experiment is not None:
223 experiment.start()
224 else:
225 print "ERROR: Experiment '%s' does not exist" % experimentName
226 return
227
ashuef3490b2015-02-17 11:01:04 -0600228 if isCliEnabled is True:
229 CLI(net)
230
231 net.stop()
232
233if __name__ == '__main__':
Vince Lehman3b8bc652015-06-18 15:01:47 -0500234
ashuef3490b2015-02-17 11:01:04 -0600235 hosts_conf = []
236 links_conf = []
Vince Lehman3b8bc652015-06-18 15:01:47 -0500237 template, testbed, experimentName, nPings, ctime, hr, faces, isCliEnabled = parse_args()
ashuef3490b2015-02-17 11:01:04 -0600238
239 setLogLevel('info')
Vince Lehman3b8bc652015-06-18 15:01:47 -0500240 execute(template, testbed, experimentName, nPings, ctime, hr, faces, isCliEnabled)