ndn: Add NFD and NLSR class abstractions
refs: #2528
Change-Id: I3241af0e85f4eec4eb640aca274ff9ca4f812656
diff --git a/bin/minindn b/bin/minindn
new file mode 100755
index 0000000..51a4c52
--- /dev/null
+++ b/bin/minindn
@@ -0,0 +1,186 @@
+#!/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.conf_parser import parse_hosts, parse_links
+
+from ndn.experiments import HyperbolicExperiment, FailureExperiment
+from ndn.ndn_host import NdnHost, CpuLimitedNdnHost
+
+import os.path, time
+import optparse
+import datetime
+
+from ndn.nlsr import Nlsr, NlsrConfigGenerator
+
+def parse_args():
+ usage="""Usage: minindn [template_file] [ -t | --testbed ]
+ If no template_file is given, will try to load template
+ from file minindn.conf in the current directory.
+ If --testbed is used, minindn will run the NDN Project Testbed.
+ This assumes you are in the testbed directory in the minindn installation
+ directory.
+ """
+
+ testbed = False
+ pingall = False
+ hr = False
+ failure = False
+
+ parser = optparse.OptionParser(usage)
+
+ parser.add_option("-t", "--testbed", action="store_true", dest="testbed",
+ help="instantiates NDN Testbed")
+
+ parser.add_option("--pingall", action="store", dest="pingall", type="int",
+ help="Sequentiall pings all the other nodes from each node")
+
+ 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("--failure", action="store_true", dest="failure",
+ help="Run failure experiment, specify the number of pings using pingall")
+
+ 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
+ pingall = options.pingall
+ ctime = options.ctime
+ hr = options.hr
+ faces = options.faces
+ failure = options.failure
+ isCliEnabled = options.isCliEnabled
+
+ if ctime is None:
+ ctime = 60
+
+ if isCliEnabled is None:
+ isCliEnabled = True
+
+ if len(arg) == 0 or len(arg) > 2:
+ file = ''
+ else:
+ file = arg[0]
+
+ return file, testbed, pingall, ctime, hr, faces, failure, 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, fib=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, pingall=None, ctime=None, hr=False, faces=3, failure=False, isCliEnabled=True):
+ "Create a network based on template_file"
+
+ home = expanduser("~")
+
+ if template_file == '':
+ template_file='minindn.conf'
+
+ if os.path.exists(template_file) == False:
+ info('No template file given and default template file minindn.conf not 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()
+
+ 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, home)
+ configGenerator.createConfigFile()
+
+ # Start NLSR
+ nlsr = Nlsr(host)
+ nlsr.start()
+
+ nodes = nodes[0:-1]
+
+ if failure is True:
+ test = FailureExperiment(net, nodes, ctime)
+ test.run()
+ elif pingall is not None:
+ test = HyperbolicExperiment(net, nodes, ctime, pingall)
+ test.run()
+
+ for host in net.hosts:
+ if 'app' in host.params:
+ if host.params['app'] != '_':
+ host.cmd(host.params['app'])
+
+ if isCliEnabled is True:
+ CLI(net)
+
+ net.stop()
+
+if __name__ == '__main__':
+ hosts_conf = []
+ links_conf = []
+ template, testbed, pingall, ctime, hr, faces, failure, isCliEnabled = parse_args()
+
+ setLogLevel('info')
+ execute(template, testbed, pingall, ctime, hr, faces, failure, isCliEnabled)
diff --git a/mininet/conf_parser.py b/mininet/conf_parser.py
index ae514f3..62cc8fa 100644
--- a/mininet/conf_parser.py
+++ b/mininet/conf_parser.py
@@ -1,19 +1,30 @@
import ConfigParser, re
-class confCCNHost():
+class confNDNHost():
- def __init__(self, name, app='', uri_tuples='', cpu=None, cores=None, cache=None):
+ def __init__(self, name, app='', params='', cpu=None, cores=None, cache=None):
self.name = name
self.app = app
- self.uri_tuples = uri_tuples
+ self.uri_tuples = params
self.cpu = cpu
self.cores = cores
- self.cache = cache
+ self.cache = cache
+
+ # For now assume leftovers are NLSR configuration parameters
+ self.nlsrParameters = params
def __repr__(self):
- return 'Name: ' + self.name + ' App: ' + self.app + ' URIS: ' + str(self.uri_tuples) + ' CPU:' + str(self.cpu) + ' Cores:' +str(self.cores) + ' Cache: ' + str(self.cache)
+ return 'Name: ' + self.name + \
+ ' App: ' + self.app + \
+ ' URIS: ' + str(self.uri_tuples) + \
+ ' CPU: ' + str(self.cpu) + \
+ ' Cores: ' + str(self.cores) + \
+ ' Cache: ' + str(self.cache) + \
+ ' Radius: ' + str(self.radius) + \
+ ' Angle: ' + str(self.angle) + \
+ ' NLSR Parameters: ' + self.nlsrParameters
-class confCCNLink():
+class confNDNLink():
def __init__(self,h1,h2,linkDict=None):
self.h1 = h1
@@ -30,18 +41,18 @@
hosts = []
- items = config.items('hosts')
-
- #makes a first-pass read to hosts section to find empty host sections
- for item in items:
- name = item[0]
- rest = item[1].split()
- if len(rest) == 0:
- config.set('hosts', name, '_')
- #updates 'items' list
- items = config.items('hosts')
+ items = config.items('nodes')
- #makes a second-pass read to hosts section to properly add hosts
+ #makes a first-pass read to hosts section to find empty host sections
+ for item in items:
+ name = item[0]
+ rest = item[1].split()
+ if len(rest) == 0:
+ config.set('nodes', name, '_')
+ #updates 'items' list
+ items = config.items('nodes')
+
+ #makes a second-pass read to hosts section to properly add hosts
for item in items:
name = item[0]
@@ -51,66 +62,27 @@
app = rest.pop(0)
uris = rest
- uri_list=[]
+ params = {}
cpu = None
cores = None
- cache = None
+ cache = None
for uri in uris:
if re.match("cpu",uri):
cpu = float(uri.split('=')[1])
elif re.match("cores",uri):
cores = uri.split('=')[1]
- elif re.match("cache",uri):
- cache = uri.split('=')[1]
- elif re.match("mem",uri):
- mem = uri.split('=')[1]
+ elif re.match("cache",uri):
+ cache = uri.split('=')[1]
+ elif re.match("mem",uri):
+ mem = uri.split('=')[1]
else:
- uri_list.append((uri.split(',')[0],uri.split(',')[1]))
+ params[uri.split('=')[0]] = uri.split('=')[1]
- hosts.append(confCCNHost(name , app, uri_list,cpu,cores,cache))
+ hosts.append(confNDNHost(name, app, params, cpu, cores, cache))
return hosts
-def parse_routers(conf_arq):
- 'Parse routers section from the conf file.'
- config = ConfigParser.RawConfigParser()
- config.read(conf_arq)
-
- routers = []
-
- items = config.items('routers')
-
- for item in items:
- name = item[0]
-
- rest = item[1].split()
-
- uris = rest
- uri_list=[]
- cpu = None
- cores = None
- cache = None
-
- if '_' in uris:
- pass
- else:
- for uri in uris:
- if re.match("cpu",uri):
- cpu = float(uri.split('=')[1])
- elif re.match("cores",uri):
- cores = uri.split('=')[1]
- elif re.match("cache",uri):
- cache = uri.split('=')[1]
- elif re.match("mem",uri):
- mem = uri.split('=')[1]
- else:
- uri_list.append((uri.split(',')[0],uri.split(',')[1]))
-
- routers.append(confCCNHost(name=name , uri_tuples=uri_list, cpu=cpu, cores=cores))
-
- return routers
-
def parse_links(conf_arq):
'Parse links section from the conf file.'
arq = open(conf_arq,'r')
@@ -128,10 +100,10 @@
break
args = line.split()
-
- #checks for non-empty line
- if len(args) == 0:
- continue
+
+ #checks for non-empty line
+ if len(args) == 0:
+ continue
h1, h2 = args.pop(0).split(':')
@@ -147,7 +119,7 @@
value = float(value)
link_dict[key] = value
- links.append(confCCNLink(h1,h2,link_dict))
+ links.append(confNDNLink(h1,h2,link_dict))
return links
diff --git a/mininet/net.py b/mininet/net.py
index 2d6bca6..847850b 100644
--- a/mininet/net.py
+++ b/mininet/net.py
@@ -164,7 +164,7 @@
if topo and build:
self.build()
- def isCCNhost(self, node):
+ def isNdnhost(self, node):
if 'fib' in node.params:
return True
else:
@@ -260,8 +260,8 @@
for host in self.hosts:
info( host.name + ' ' )
intf = host.defaultIntf()
- if self.isCCNhost(host):
- host.configCCN()
+ if self.isNdnhost(host):
+ host.configNdn()
host.configDefault(ip=None,mac=None)
elif intf:
host.configDefault( defaultRoute=intf )
@@ -315,7 +315,7 @@
params = topo.linkInfo( srcName, dstName )
srcPort, dstPort = topo.port( srcName, dstName )
self.addLink( src, dst, srcPort, dstPort, **params )
- if self.isCCNhost(src):
+ if self.isNdnhost(src):
src.setIP(ipStr(ipParse(self.ccnNetBase) + 1) + '/30', intf=src.name + '-eth' + str(srcPort))
dst.setIP(ipStr(ipParse(self.ccnNetBase) + 2) + '/30', intf=dst.name + '-eth' + str(dstPort))
self.ccnNetBase=nextCCNnet(self.ccnNetBase)
diff --git a/mininet/node.py b/mininet/node.py
index 8749987..84e0bc6 100644
--- a/mininet/node.py
+++ b/mininet/node.py
@@ -717,153 +717,6 @@
mountCgroups()
cls.inited = True
-class CCNHost( Host ):
- "CCNHost is a Host that always runs the ccnd daemon"
-
- def __init__( self, name, **kwargs ):
-
-
- Host.__init__( self, name, **kwargs )
- if not CCNHost.inited:
- CCNHost.init()
-
- self.cmd("export CCND_DEBUG=6")
- self.cmd("export CCND_LOG=./log.{0}".format(self.name))
- #pdb.set_trace()
-# print self.params['cache']
- if self.params['cache'] != None:
- self.cmd("export CCND_CAP={0}".format(self.params['cache']))
-
- self.cmd("export CCN_LOCAL_SOCKNAME=/tmp/.sock.ccnx.{0}".format(self.name))
- self.cmd("ccndstart")
- self.peerList = {}
-
- def config( self, fib=None, app=None, cache=None, **params ):
-
- r = Node.config( self, **params )
-
- self.setParam( r, 'app', fib=fib )
- self.setParam( r, 'fib', app=app)
- self.setParam( r, 'cache', cache=cache )
-
- return r
-
- def configCCN(self):
-
- self.buildPeerIP()
- self.setFIB()
-
- def buildPeerIP(self):
- for iface in self.intfList():
- link = iface.link
- if link:
- node1, node2 = link.intf1.node, link.intf2.node
- if node1 == self:
- self.peerList[node2.name] = link.intf2.node.IP(link.intf2)
- else:
- self.peerList[node1.name] = link.intf1.node.IP(link.intf1)
-
-
- def setFIB(self):
-
- for name in self.params['fib']:
- if not name:
- pass
- else:
- self.insert_fib(name[0],self.peerList[name[1]])
-
-
- def insert_fib(self, uri, host):
- self.cmd('ccndc add {0} tcp {1}'.format(uri,host))
- # self.cmd('ccndc add {0} udp {1}'.format(uri,host))
-
- def terminate( self ):
- "Stop node."
- self.cmd('ccndstop')
- self.cmd('killall -r zebra ospf')
- Host.terminate(self)
-
- inited = False
-
-
- @classmethod
- def init( cls ):
- "Initialization for CCNHost class"
- cls.inited = True
-
-class CPULimitedCCNHost( CPULimitedHost ):
- '''CPULimitedCCNHost is a Host that always runs the ccnd daemon and extends CPULimitedHost.
- It should be used when one wants to limit the resources of CCN routers and hosts '''
-
-
- def __init__( self, name, sched='cfs', **kwargs ):
-
- CPULimitedHost.__init__( self, name, sched, **kwargs )
- if not CCNHost.inited:
- CCNHost.init()
-
- self.cmd("export CCND_DEBUG=6")
- self.cmd("export CCND_LOG=./log.{0}".format(self.name))
- if self.params['cache'] != None:
- self.cmd("export CCND_CAP={0}".format(self.params['cache']))
-
- self.cmd("export CCN_LOCAL_SOCKNAME=/tmp/.sock.ccnx.{0}".format(self.name))
- self.cmd("ccndstart")
- self.peerList = {}
-
- def config( self, fib=None, app=None, cpu=None, cores=None, cache=None, **params):
-
- r = CPULimitedHost.config(self,cpu,cores, **params)
-
- self.setParam( r, 'app', fib=fib )
- self.setParam( r, 'fib', app=app)
- self.setParam( r, 'cache', cache=cache)
-
- return r
-
- def configCCN(self):
-
- self.buildPeerIP()
- self.setFIB()
-
- def buildPeerIP(self):
- for iface in self.intfList():
- link = iface.link
- if link:
- node1, node2 = link.intf1.node, link.intf2.node
- if node1 == self:
- self.peerList[node2.name] = link.intf2.node.IP(link.intf2)
- else:
- self.peerList[node1.name] = link.intf1.node.IP(link.intf1)
-
-
- def setFIB(self):
-
- for name in self.params['fib']:
- if not name:
- pass
- else:
- self.insert_fib(name[0],self.peerList[name[1]])
-
-
- def insert_fib(self, uri, host):
- self.cmd('ccndc add {0} tcp {1}'.format(uri,host))
-# self.cmd('ccndc add {0} udp {1}'.format(uri,host))
-
- def terminate( self ):
- "Stop node."
- self.cmd('ccndstop')
- self.cmd('killall -r zebra ospf')
- Host.terminate(self)
-
- inited = False
-
-
- @classmethod
- def init( cls ):
- "Initialization for CCNHost class"
- cls.inited = True
-
# Some important things to note:
#
# The "IP" address which setIP() assigns to the switch is not
diff --git a/ndn/__init__.py b/ndn/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ndn/__init__.py
diff --git a/ndn/ndn_host.py b/ndn/ndn_host.py
new file mode 100644
index 0000000..427aced
--- /dev/null
+++ b/ndn/ndn_host.py
@@ -0,0 +1,84 @@
+from mininet.node import CPULimitedHost, Host, Node
+from ndn.nfd import Nfd
+
+class NdnHostCommon():
+ "Common methods of NdnHost and CpuLimitedNdnHost"
+
+ def configNdn(self):
+ self.buildPeerIp()
+
+ def buildPeerIp(self):
+ for iface in self.intfList():
+ link = iface.link
+ if link:
+ node1, node2 = link.intf1.node, link.intf2.node
+ if node1 == self:
+ self.peerList[node2.name] = link.intf2.node.IP(link.intf2)
+ else:
+ self.peerList[node1.name] = link.intf1.node.IP(link.intf1)
+
+ inited = False
+
+ @classmethod
+ def init(cls):
+ "Initialization for NDNHost class"
+ cls.inited = True
+
+class NdnHost(Host, NdnHostCommon):
+ "NDNHost is a Host that always runs NFD"
+
+ def __init__(self, name, **kwargs):
+
+ Host.__init__(self, name, **kwargs)
+ if not NdnHost.inited:
+ NdnHostCommon.init()
+
+ self.nfd = Nfd(self)
+ self.nfd.start()
+
+ self.peerList = {}
+
+ def config(self, fib=None, app=None, cache=None, **params):
+
+ r = Node.config(self, **params)
+
+ self.setParam(r, 'app', fib=fib) # why is this not app=app, to be investigated
+ self.setParam(r, 'fib', app=app) # and this fib=fib
+ self.setParam(r, 'cache', cache=cache)
+
+ return r
+
+ def terminate(self):
+ "Stop node."
+ self.nfd.stop()
+ Host.terminate(self)
+
+class CpuLimitedNdnHost(CPULimitedHost, NdnHostCommon):
+ '''CPULimitedNDNHost is a Host that always runs NFD and extends CPULimitedHost.
+ It should be used when one wants to limit the resources of NDN routers and hosts '''
+
+ def __init__(self, name, sched='cfs', **kwargs):
+
+ CPULimitedHost.__init__(self, name, sched, **kwargs)
+ if not NdnHost.inited:
+ NdnHostCommon.init()
+
+ self.nfd = Nfd(self)
+ self.nfd.start()
+
+ self.peerList = {}
+
+ def config(self, fib=None, app=None, cpu=None, cores=None, cache=None, **params):
+
+ r = CPULimitedHost.config(self,cpu,cores, **params)
+
+ self.setParam(r, 'app', fib=fib) #????? shoud it be app=app
+ self.setParam(r, 'fib', app=app)
+ self.setParam(r, 'cache', cache=cache)
+
+ return r
+
+ def terminate(self):
+ "Stop node."
+ self.nfd.stop()
+ Host.terminate(self)
diff --git a/ndn/nfd.py b/ndn/nfd.py
new file mode 100644
index 0000000..8ee9423
--- /dev/null
+++ b/ndn/nfd.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+
+import time
+from os.path import expanduser
+
+class Nfd:
+ def __init__(self, node):
+ self.node = node
+ self.isRunning = False
+
+ # Create home directory for a node
+ node.cmd("cd /tmp && mkdir %s" % node.name)
+ node.cmd("cd %s" % node.name)
+
+ self.homeFolder = "/tmp/%s" % node.name
+ self.confFile = "%s/%s.conf" % (self.homeFolder, node.name)
+ self.logFile = "%s/%s.log" % (self.homeFolder, node.name)
+ self.sockFile = "/var/run/%s.sock" % node.name
+ self.ndnFolder = "%s/.ndn" % self.homeFolder
+ self.clientConf = "%s/client.conf" % self.ndnFolder
+
+ # Copy file that checks FIB
+ node.cmd("sudo cp ~/mn-ndn/ndn_utils/checkFIB %s/checkFIB" % self.homeFolder)
+
+ # Copy nfd.conf file from mn-ndn/ndn_utils to the node's home
+ node.cmd("sudo cp ~/mn-ndn/ndn_utils/nfd.conf %s" % self.confFile)
+
+ # Open the conf file and change socket file name
+ node.cmd("sudo sed -i 's|nfd.sock|%s.sock|g' %s" % (node.name, self.confFile))
+
+ # Make NDN folder
+ node.cmd("sudo mkdir %s" % self.ndnFolder)
+
+ # Copy the client.conf file and change the unix socket
+ node.cmd("sudo cp ~/mn-ndn/ndn_utils/client.conf.sample %s" % self.clientConf)
+ node.cmd("sudo sed -i 's|nfd.sock|%s.sock|g' %s" % (node.name, self.clientConf))
+
+ # Change home folder
+ node.cmd("export HOME=%s" % self.homeFolder)
+
+ def start(self):
+ if self.isRunning is False:
+ self.node.cmd("sudo nfd --config %s 2>> %s &" % (self.confFile, self.logFile))
+ self.processId = self.node.cmd("echo $!")[:-1]
+
+ time.sleep(2)
+
+ self.isRunning = True
+
+ def stop(self):
+ if self.isRunning is True:
+ self.node.cmd("sudo kill %s" % self.processId)
+
+ self.isRunning = False
+
+ def setStrategy(self, name, strategy):
+ node.cmd("nfdc set-strategy %s ndn:/localhost/nfd/strategy/%s" % (name, strategy))
+ time.sleep(0.5)
diff --git a/ndn/nlsr.py b/ndn/nlsr.py
new file mode 100644
index 0000000..de9ec86
--- /dev/null
+++ b/ndn/nlsr.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+
+class Nlsr:
+ def __init__(self, node):
+ self.node = node
+ self.routerName = "/%sC1.Router/cs/%s" % ('%', node.name)
+ self.confFile = "/tmp/%s/nlsr.conf" % node.name
+
+ # Make directory for log file
+ self.logDir = "/tmp/%s/log" % node.name
+ node.cmd("mkdir %s" % self.logDir)
+
+ # Configure basic router information in nlsr.conf based on host name
+ node.cmd("sudo sed -i 's|router .*|router %s|g' %s" % (self.routerName, self.confFile))
+ node.cmd("sudo sed -i 's|log-dir .*|log-dir %s|g' %s" % (self.logDir, self.confFile))
+ node.cmd("sudo sed -i 's|seq-dir .*|seq-dir %s|g' %s" % (self.logDir, self.confFile))
+ node.cmd("sudo sed -i 's|prefix .*netlab|prefix /ndn/edu/%s|g' %s" % (node.name, self.confFile))
+
+ def start(self):
+ self.node.cmd("nlsr -d")
+
+
+class NlsrConfigGenerator:
+
+ ROUTING_LINK_STATE = "ls"
+ ROUTING_HYPERBOLIC = "hr"
+
+ def __init__(self, node, home):
+ node.cmd("sudo cp %s/mn-ndn/ndn_utils/nlsr.conf nlsr.conf" % home)
+ self.node = node
+
+ parameters = node.nlsrParameters
+
+ self.nFaces = parameters.get("max-faces-per-prefix", 3)
+ self.hyperbolicState = parameters.get("hyperbolic-state", "off")
+ self.hyperRadius = parameters.get("radius", 0.0)
+ self.hyperAngle = parameters.get("angle", 0.0)
+
+ def createConfigFile(self):
+
+ filePath = "/tmp/%s/nlsr.conf" % self.node.name
+
+ configFile = open(filePath, 'r')
+ oldContent = configFile.read()
+ configFile.close()
+
+ newContent = oldContent.replace("$GENERAL_SECTION", self.__getGeneralSection())
+ newContent = newContent.replace("$NEIGHBORS_SECTION", self.__getNeighborsSection())
+ newContent = newContent.replace("$HYPERBOLIC_SECTION", self.__getHyperbolicSection())
+ newContent = newContent.replace("$FIB_SECTION", self.__getFibSection())
+ newContent = newContent.replace("$ADVERTISING_SECTION", self.__getAdvertisingSection())
+
+ configFile = open(filePath, 'w')
+ configFile.write(newContent)
+ configFile.close()
+
+ def __getConfig(self):
+
+ config = self.__getGeneralSection()
+ config += self.__getNeighborsSection()
+ config += self.__getHyperbolicSection()
+ config += self.__getFibSection()
+ config += self.__getAdvertisingSection()
+ config += self.__getSecuritySection()
+
+ return config
+
+ def __getGeneralSection(self):
+
+ general = "general\n"
+ general += "{\n"
+ general += " network /ndn/\n"
+ general += " site /edu\n"
+ general += " router /%C1.Router/cs/" + self.node.name + "\n"
+ general += " log-level DEBUG\n"
+ general += " log-dir /tmp/" + self.node.name + "/log\n"
+ general += " seq-dir /tmp/" + self.node.name + "/log\n"
+ general += "}\n"
+
+ return general
+
+ def __getNeighborsSection(self):
+
+ neighbors = "neighbors\n"
+ neighbors += "{\n"
+
+ for intf in self.node.intfList():
+ link = intf.link
+ if link:
+ node1, node2 = link.intf1.node, link.intf2.node
+
+ if node1 == self.node:
+ other = node2
+ ip = other.IP(str(link.intf2))
+ else:
+ other = node1
+ ip = other.IP(str(link.intf1))
+
+ linkCost = intf.params.get("delay", "0ms").replace("ms", "")
+
+ neighbors += "neighbor\n"
+ neighbors += "{\n"
+ neighbors += " name /ndn/edu/%C1.Router/cs/" + other.name + "\n"
+ neighbors += " face-uri udp://" + str(ip) + "\n"
+ neighbors += " link-cost " + linkCost + "\n"
+ neighbors += "}\n"
+
+ neighbors += "}\n"
+
+ return neighbors
+
+ def __getHyperbolicSection(self):
+
+ hyper = "hyperbolic\n"
+ hyper += "{\n"
+ hyper += "state %s\n" % self.hyperbolicState
+ hyper += "radius " + str(self.hyperRadius) + "\n"
+ hyper += "angle " + str(self.hyperAngle) + "\n"
+ hyper += "}\n"
+
+ return hyper
+
+ def __getFibSection(self):
+
+ fib = "fib\n"
+ fib += "{\n"
+ fib += " max-faces-per-prefix " + str(self.nFaces) + "\n"
+ fib += "}\n"
+
+ return fib
+
+ def __getAdvertisingSection(self):
+
+ advertising = "advertising\n"
+ advertising += "{\n"
+ advertising += " prefix /ndn/edu/" + self.node.name + "\n"
+ advertising += "}\n"
+
+ return advertising
+
+ def __getSecuritySection(self):
+
+ security = "security\n"
+ security += "{\n"
+ security += " validator\n"
+ security += " {\n"
+ security += " trust-anchor\n"
+ security += " {\n"
+ security += " type any\n"
+ security += " }\n"
+ security += " }\n"
+ security += "}\n"
+
+ return security