blob: 2699bfd99bbc1538555d00411f2fd79d87ecce80 [file] [log] [blame]
#!/usr/bin/env python
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.log import setLogLevel, output, info
from mininet.cli import CLI
from mininet.link import TCLink
from mininet.util import ipStr, ipParse
from ndn import ExperimentManager
from ndn.ndn_host import NdnHost, CpuLimitedNdnHost
from ndn.conf_parser import parse_hosts, parse_links
import os.path, time
import optparse
import datetime
from os.path import expanduser
import sys
from ndn.nlsr import Nlsr, NlsrConfigGenerator
from ndn.nfd import Nfd
def printExperimentNames():
experimentNames = ExperimentManager.getExperimentNames()
print "Mini-NDN experiments:"
for experiment in experimentNames:
print " %s" % experiment
def parse_args():
usage="""Usage: minindn [template_file] [ -t | --testbed ]
If no template_file is given, ndn_utils/default-topology.conf (given sample file)
will be used.
If --testbed is used, minindn will run the NDN Project Testbed.
"""
testbed = False
hr = False
parser = optparse.OptionParser(usage)
parser.add_option("-t", "--testbed", action="store_true", dest="testbed",
help="instantiates NDN Testbed")
parser.add_option("--experiment", action="store", dest="experiment",
help="Runs the specified experiment")
parser.add_option("--list-experiments", action="store_true", dest="shouldListExperiments",
help="Lists the names of all available experiments")
parser.add_option("--nPings", action="store", dest="nPings", type="int",
help="Number of pings to perform between each node in the experiment")
parser.add_option("--ctime", action="store", dest="ctime", type="int",
help="Specify convergence time for the topology (Default 60 seconds)")
parser.add_option("--hr", action="store_true", dest="hr",
help="--hr is used to turn on hyperbolic routing")
parser.add_option("--faces", action="store", dest="faces", type="int",
help="Specify number of faces 0-60")
parser.add_option("--no-cli", action="store_false", dest="isCliEnabled",
help="Run experiments and exit without showing the command line interface")
(options, arg) = parser.parse_args()
testbed = options.testbed
experimentName = options.experiment
shouldListExperiments = options.shouldListExperiments
nPings = options.nPings
ctime = options.ctime
hr = options.hr
faces = options.faces
isCliEnabled = options.isCliEnabled
if shouldListExperiments is not None:
printExperimentNames()
sys.exit()
if ctime is None:
ctime = 60
if nPings is None:
nPings = 300
if isCliEnabled is None:
isCliEnabled = True
if len(arg) == 0 or len(arg) > 2:
file = ''
else:
file = arg[0]
return file, testbed, experimentName, nPings, ctime, hr, faces, isCliEnabled
class NdnTopo(Topo):
def __init__(self, conf_arq, **opts):
Topo.__init__(self, **opts)
global hosts_conf
global links_conf
hosts_conf = parse_hosts(conf_arq)
links_conf = parse_links(conf_arq)
self.isTCLink = False
self.isLimited = False
for host in hosts_conf:
if host.cpu != None and self.isLimited != True:
self.isLimited = True
self.addHost(host.name, app=host.app, params=host.uri_tuples, cpu=host.cpu,cores=host.cores,cache=host.cache)
for link in links_conf:
if len(link.linkDict) == 0:
self.addLink(link.h1, link.h2)
else:
self.addLink(link.h1, link.h2, **link.linkDict)
self.isTCLink = True
info('Parse of ' + conf_arq + ' done.\n')
def execute(template_file='minindn.conf', testbed=False, experimentName=None, nPings=None, ctime=None, hr=False, faces=3, isCliEnabled=True):
"Create a network based on template_file"
install_dir='/usr/local/etc/mini-ndn/'
if template_file == '':
template_file = install_dir + 'default-topology.conf'
if testbed:
template_file = install_dir + 'minindn.testbed.conf'
if os.path.exists(template_file) == False:
info('No template file given and default template file cannot be found. Exiting...\n')
quit()
topo = NdnTopo(template_file)
t = datetime.datetime.now()
if topo.isTCLink == True and topo.isLimited == True:
net = Mininet(topo,host=CpuLimitedNdnHost,link=TCLink)
elif topo.isTCLink == True and topo.isLimited == False:
net = Mininet(topo,host=NdnHost,link=TCLink)
elif topo.isTCLink == False and topo.isLimited == True:
net = Mininet(topo,host=CpuLimitedNdnHost)
else:
net = Mininet(topo,host=NdnHost)
t2 = datetime.datetime.now()
delta = t2 - t
info('Setup time: ' + str(delta.seconds) + '\n')
net.start()
# Giving proper IPs to intf so neighbor nodes can communicate
# This is one way of giving connectivity, another way could be
# to insert a switch between each pair of neighbors
ndnNetBase = "1.0.0.0"
interfaces = []
for host in net.hosts:
for intf in host.intfList():
link = intf.link
node1, node2 = link.intf1.node, link.intf2.node
if link.intf1 not in interfaces and link.intf2 not in interfaces:
interfaces.append(link.intf1)
interfaces.append(link.intf2)
node1.setIP(ipStr(ipParse(ndnNetBase) + 1) + '/30', intf=link.intf1)
node2.setIP(ipStr(ipParse(ndnNetBase) + 2) + '/30', intf=link.intf2)
ndnNetBase = ipStr(ipParse(ndnNetBase) + 4)
nodes = "" # Used later to check prefix name in checkFIB
# NLSR initialization
for host in net.hosts:
nodes += str(host.name) + ","
conf = next(x for x in hosts_conf if x.name == host.name)
host.nlsrParameters = conf.nlsrParameters
if faces is not None:
host.nlsrParameters["max-faces-per-prefix"] = faces
if hr is True:
host.nlsrParameters["hyperbolic-state"] = "on"
# Generate NLSR configuration file
configGenerator = NlsrConfigGenerator(host)
configGenerator.createConfigFile()
# Start NLSR
host.nlsr = Nlsr(host)
host.nlsr.start()
nodes = nodes[0:-1]
for host in net.hosts:
if 'app' in host.params:
if host.params['app'] != '_':
host.cmd(host.params['app'])
# Load experiment
if experimentName is not None:
print "Loading experiment: %s" % experimentName
experimentArgs = {
"net": net,
"nodes": nodes,
"ctime": ctime,
"nPings": nPings,
"strategy": Nfd.STRATEGY_BEST_ROUTE_V3
}
experiment = ExperimentManager.create(experimentName, experimentArgs)
if experiment is not None:
experiment.start()
else:
print "ERROR: Experiment '%s' does not exist" % experimentName
return
if isCliEnabled is True:
CLI(net)
net.stop()
if __name__ == '__main__':
hosts_conf = []
links_conf = []
template, testbed, experimentName, nPings, ctime, hr, faces, isCliEnabled = parse_args()
setLogLevel('info')
execute(template, testbed, experimentName, nPings, ctime, hr, faces, isCliEnabled)