blob: 7d55a21c01e00f3eec2e2561a102b7c758049019 [file] [log] [blame]
Vince Lehmanb8b18062015-07-14 13:07:22 -05001# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2#
Alexander Lane9944cf52018-05-17 12:16:50 -05003# Copyright (C) 2015-2018, The University of Memphis,
Vince Lehman5d5a5662015-12-02 12:33:12 -06004# Arizona Board of Regents,
5# Regents of the University of California.
Vince Lehmanb8b18062015-07-14 13:07:22 -05006#
7# This file is part of Mini-NDN.
8# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
9#
10# Mini-NDN is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# Mini-NDN is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with Mini-NDN, e.g., in COPYING.md file.
22# If not, see <http://www.gnu.org/licenses/>.
23
Vince Lehman5d5a5662015-12-02 12:33:12 -060024from mininet.clean import sh
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -050025from mininet.examples.cluster import RemoteMixin
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050026from mininet.log import info
Vince Lehman5d5a5662015-12-02 12:33:12 -060027
Ashlesh Gawande792c6aa2015-07-10 12:18:36 -050028from ndn.ndn_application import NdnApplication
Alexander Lane4fa88812018-05-23 12:56:52 -050029from ndn.util import ssh, scp, copyExistentFile
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050030from ndn.apps.nfdc import Nfdc
ashuef3490b2015-02-17 11:01:04 -060031
Vince Lehman5d5a5662015-12-02 12:33:12 -060032import shutil
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -050033import os
Vince Lehman5d5a5662015-12-02 12:33:12 -060034import textwrap
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -050035from subprocess import call
Ashlesh Gawande59f86242017-05-05 09:45:18 -050036import time
Vince Lehman5d5a5662015-12-02 12:33:12 -060037
Ashlesh Gawandef6a610b2017-02-21 14:48:08 -060038NETWORK="/ndn/"
39
Ashlesh Gawande792c6aa2015-07-10 12:18:36 -050040class Nlsr(NdnApplication):
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050041 def __init__(self, node, options):
Ashlesh Gawande792c6aa2015-07-10 12:18:36 -050042 NdnApplication.__init__(self, node)
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050043 self.config = NlsrConfigGenerator(node, options)
44
Ashlesh Gawande708fcca2017-06-23 14:04:12 -050045 self.node = node
Alexander Lane6f7a64f2018-05-17 15:01:14 -050046 self.routerName = "/{}C1.Router/cs/{}".format('%', node.name)
47 self.confFile = "{}/nlsr.conf".format(node.homeFolder)
ashuef3490b2015-02-17 11:01:04 -060048
49 # Make directory for log file
Saurab Dulal7a6978e2017-11-29 10:50:09 -060050 self.logDir = "{}/log".format(node.homeFolder)
51 self.node.cmd("mkdir {}".format(self.logDir))
Ashlesh Gawande708fcca2017-06-23 14:04:12 -050052
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050053 def start(self, sleepTime = 1):
54 self.node.cmd("export NDN_LOG=nlsr.*={}".format(self.node.params["params"].get("nlsr-log-level", "DEBUG")))
dmcoomes73caa522018-01-15 16:33:32 -060055 NdnApplication.start(self, "nlsr -f {} > log/nlsr.log 2>&1 &".format(self.confFile))
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050056 time.sleep(sleepTime)
ashuef3490b2015-02-17 11:01:04 -060057
Ashlesh Gawande708fcca2017-06-23 14:04:12 -050058 def createFaces(self):
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -050059 for ip in self.config.neighborIPs:
60 Nfdc.createFace(self.node, ip, self.config.faceType, isPermanent=True)
Ashlesh Gawande708fcca2017-06-23 14:04:12 -050061
Vince Lehman5d5a5662015-12-02 12:33:12 -060062 @staticmethod
63 def createKey(host, name, outputFile):
64 host.cmd("ndnsec-keygen {} > {}".format(name, outputFile))
65
66 @staticmethod
Ashlesh Gawandea80484e2017-10-17 15:52:23 -050067 def createCertificate(host, signer, keyFile, outputFile):
68 host.cmd("ndnsec-certgen -s {} -r {} > {}".format(signer, keyFile, outputFile))
Vince Lehman5d5a5662015-12-02 12:33:12 -060069
70 @staticmethod
71 def createKeysAndCertificates(net, workDir):
72 securityDir = "{}/security".format(workDir)
73
74 if not os.path.exists(securityDir):
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -050075 os.mkdir(securityDir)
Vince Lehman5d5a5662015-12-02 12:33:12 -060076
77 # Create root certificate
Ashlesh Gawandef6a610b2017-02-21 14:48:08 -060078 rootName = NETWORK
Ashlesh Gawandea80484e2017-10-17 15:52:23 -050079 sh("ndnsec-keygen {}".format(rootName)) # Installs a self-signed cert into the system
Alexander Lane4fa88812018-05-23 12:56:52 -050080 sh("ndnsec-cert-dump -i {} > {}/root.cert".format(rootName, securityDir))
Vince Lehman5d5a5662015-12-02 12:33:12 -060081
82 # Create necessary certificates for each site
83 for host in net.hosts:
84 nodeSecurityFolder = "{}/security".format(host.homeFolder)
85
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -050086 host.cmd("mkdir -p %s" % nodeSecurityFolder)
87
88 # Create temp folders for remote nodes on this machine (localhost) to store site.key file
89 # from RemoteNodes
90 if not os.path.exists(nodeSecurityFolder) and isinstance(host, RemoteMixin) and host.isRemote:
91 os.makedirs(nodeSecurityFolder)
Vince Lehman5d5a5662015-12-02 12:33:12 -060092
93 shutil.copyfile("{}/root.cert".format(securityDir), "{}/root.cert".format(nodeSecurityFolder))
94
95 # Create site certificate
Ashlesh Gawandef6a610b2017-02-21 14:48:08 -060096 siteName = "{}{}-site".format(NETWORK, host.name)
Vince Lehman5d5a5662015-12-02 12:33:12 -060097 siteKeyFile = "{}/site.keys".format(nodeSecurityFolder)
98 siteCertFile = "{}/site.cert".format(nodeSecurityFolder)
99 Nlsr.createKey(host, siteName, siteKeyFile)
100
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500101 # Copy siteKeyFile from remote for ndnsec-certgen
102 if isinstance(host, RemoteMixin) and host.isRemote:
103 login = "mininet@{}".format(host.server)
104 src = "{}:{}".format(login, siteKeyFile)
105 dst = siteKeyFile
106 scp(src, dst)
107
Vince Lehman5d5a5662015-12-02 12:33:12 -0600108 # Root key is in root namespace, must sign site key and then install on host
Ashlesh Gawandea80484e2017-10-17 15:52:23 -0500109 sh("ndnsec-certgen -s {} -r {} > {}".format(rootName, siteKeyFile, siteCertFile))
Ashlesh Gawandef5f304b2016-06-16 16:42:41 -0500110
111 # Copy root.cert and site.cert from localhost to remote host
112 if isinstance(host, RemoteMixin) and host.isRemote:
113 login = "mininet@{}".format(host.server)
114 src = "{}/site.cert".format(nodeSecurityFolder)
115 src2 = "{}/root.cert".format(nodeSecurityFolder)
116 dst = "{}:/tmp/".format(login)
117 scp(src, src2, dst)
118 host.cmd("mv /tmp/*.cert {}".format(nodeSecurityFolder))
119
Vince Lehman5d5a5662015-12-02 12:33:12 -0600120 host.cmd("ndnsec-cert-install -f {}".format(siteCertFile))
121
Ashlesh Gawande3bed4832017-02-08 18:17:31 -0600122 # Create and install operator certificate
Vince Lehman5d5a5662015-12-02 12:33:12 -0600123 opName = "{}/%C1.Operator/op".format(siteName)
124 opKeyFile = "{}/op.keys".format(nodeSecurityFolder)
125 opCertFile = "{}/op.cert".format(nodeSecurityFolder)
126 Nlsr.createKey(host, opName, opKeyFile)
Ashlesh Gawandea80484e2017-10-17 15:52:23 -0500127 Nlsr.createCertificate(host, siteName, opKeyFile, opCertFile)
Ashlesh Gawande3bed4832017-02-08 18:17:31 -0600128 host.cmd("ndnsec-cert-install -f {}".format(opCertFile))
Vince Lehman5d5a5662015-12-02 12:33:12 -0600129
Ashlesh Gawande3bed4832017-02-08 18:17:31 -0600130 # Create and install router certificate
Vince Lehman5d5a5662015-12-02 12:33:12 -0600131 routerName = "{}/%C1.Router/cs/{}".format(siteName, host.name)
132 routerKeyFile = "{}/router.keys".format(nodeSecurityFolder)
133 routerCertFile = "{}/router.cert".format(nodeSecurityFolder)
134 Nlsr.createKey(host, routerName, routerKeyFile)
Ashlesh Gawandea80484e2017-10-17 15:52:23 -0500135 Nlsr.createCertificate(host, opName, routerKeyFile, routerCertFile)
Ashlesh Gawande3bed4832017-02-08 18:17:31 -0600136 host.cmd("ndnsec-cert-install -f {}".format(routerCertFile))
Vince Lehman5d5a5662015-12-02 12:33:12 -0600137
ashuef3490b2015-02-17 11:01:04 -0600138class NlsrConfigGenerator:
139
140 ROUTING_LINK_STATE = "ls"
141 ROUTING_HYPERBOLIC = "hr"
142
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500143 def __init__(self, node, options):
ashuef3490b2015-02-17 11:01:04 -0600144 self.node = node
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500145 self.isSecurityEnabled = options.nlsrSecurity
146 self.faceType = options.faceType
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600147 self.infocmd = "infoedit -f nlsr.conf"
ashuef3490b2015-02-17 11:01:04 -0600148
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500149 parameters = node.params["params"]
ashuef3490b2015-02-17 11:01:04 -0600150
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500151 self.nFaces = options.nFaces
152 if options.routingType == "hr":
153 self.hyperbolicState = "on"
154 elif options.routingType == "dry":
155 self.hyperbolicState = "dry-run"
156 else:
157 self.hyperbolicState = "off"
ashuef3490b2015-02-17 11:01:04 -0600158 self.hyperRadius = parameters.get("radius", 0.0)
159 self.hyperAngle = parameters.get("angle", 0.0)
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500160
161 if ((self.hyperbolicState == "on" or self.hyperbolicState == "dry-run") and
162 (self.hyperRadius == 0.0 or self.hyperAngle == 0.0)):
163 info('Hyperbolic coordinates in topology file are either missing or misconfigured.')
164 info('Check that each node has one radius value and one or two angle value(s).')
165 sys.exit(1)
166
Ashlesh Gawande708fcca2017-06-23 14:04:12 -0500167 self.neighborIPs = []
Alexander Lane4fa88812018-05-23 12:56:52 -0500168 possibleConfPaths = ["/usr/local/etc/ndn/nlsr.conf.sample", "/etc/ndn/nlsr.conf.sample"]
169 copyExistentFile(node, possibleConfPaths, "{}/nlsr.conf".format(self.node.homeFolder))
ashuef3490b2015-02-17 11:01:04 -0600170
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500171 self.createConfigFile()
172
ashuef3490b2015-02-17 11:01:04 -0600173 def createConfigFile(self):
174
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600175 self.__editGeneralSection()
176 self.__editNeighborsSection()
177 self.__editHyperbolicSection()
178 self.__editFibSection()
179 self.__editAdvertisingSection()
180 self.__editSecuritySection()
ashuef3490b2015-02-17 11:01:04 -0600181
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600182 def __editGeneralSection(self):
ashuef3490b2015-02-17 11:01:04 -0600183
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600184 self.node.cmd("{} -s general.network -v {}".format(self.infocmd, NETWORK))
185 self.node.cmd("{} -s general.site -v /{}-site".format(self.infocmd, self.node.name))
186 self.node.cmd("{} -s general.router -v /%C1.Router/cs/{}".format(self.infocmd, self.node.name))
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600187 self.node.cmd("{} -s general.log-dir -v {}/log".format(self.infocmd, self.node.homeFolder))
188 self.node.cmd("{} -s general.seq-dir -v {}/log".format(self.infocmd, self.node.homeFolder))
ashuef3490b2015-02-17 11:01:04 -0600189
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600190 def __editNeighborsSection(self):
ashuef3490b2015-02-17 11:01:04 -0600191
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600192 self.node.cmd("{} -d neighbors.neighbor".format(self.infocmd))
ashuef3490b2015-02-17 11:01:04 -0600193 for intf in self.node.intfList():
194 link = intf.link
195 if link:
196 node1, node2 = link.intf1.node, link.intf2.node
197
198 if node1 == self.node:
199 other = node2
200 ip = other.IP(str(link.intf2))
201 else:
202 other = node1
203 ip = other.IP(str(link.intf1))
204
ashu7b6ba182015-04-17 15:02:37 -0500205 linkCost = intf.params.get("delay", "10ms").replace("ms", "")
ashuef3490b2015-02-17 11:01:04 -0600206
Ashlesh Gawande27b5e1b2018-08-06 17:47:15 -0500207 Nfdc.createFace(self.node, ip, self.faceType, isPermanent=True)
Ashlesh Gawande708fcca2017-06-23 14:04:12 -0500208 self.neighborIPs.append(ip)
209
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600210 self.node.cmd("{} -a neighbors.neighbor \
Saurab Dulal5f8c7962018-03-09 12:54:38 -0600211 <<<\'name {}{}-site/%C1.Router/cs/{} face-uri {}://{}\n link-cost {}\'"
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600212 .format(self.infocmd, NETWORK, other.name, other.name, self.faceType, ip, linkCost))
ashuef3490b2015-02-17 11:01:04 -0600213
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600214 def __editHyperbolicSection(self):
ashuef3490b2015-02-17 11:01:04 -0600215
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600216 self.node.cmd("{} -s hyperbolic.state -v {}".format(self.infocmd, self.hyperbolicState))
217 self.node.cmd("{} -s hyperbolic.radius -v {}".format(self.infocmd, self.hyperRadius))
218 self.node.cmd("{} -s hyperbolic.angle -v {}".format(self.infocmd, self.hyperAngle))
ashuef3490b2015-02-17 11:01:04 -0600219
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600220 def __editFibSection(self):
ashuef3490b2015-02-17 11:01:04 -0600221
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600222 self.node.cmd("{} -s fib.max-faces-per-prefix -v {}".format(self.infocmd, self.nFaces))
ashuef3490b2015-02-17 11:01:04 -0600223
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600224 def __editAdvertisingSection(self):
ashuef3490b2015-02-17 11:01:04 -0600225
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600226 self.node.cmd("{} -d advertising.prefix".format(self.infocmd))
227 self.node.cmd("{} -s advertising.prefix -v {}{}-site/{}"
228 .format(self.infocmd, NETWORK, self.node.name, self.node.name))
ashuef3490b2015-02-17 11:01:04 -0600229
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600230 def __editSecuritySection(self):
ashuef3490b2015-02-17 11:01:04 -0600231
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600232 self.node.cmd("{} -d security.cert-to-publish".format(self.infocmd))
Vince Lehman5d5a5662015-12-02 12:33:12 -0600233 if self.isSecurityEnabled is False:
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600234 self.node.cmd("{} -s security.validator.trust-anchor.type -v any".format(self.infocmd))
235 self.node.cmd("{} -d security.validator.trust-anchor.file-name".format(self.infocmd))
236 self.node.cmd("{} -s security.prefix-update-validator.trust-anchor.type -v any".format(self.infocmd))
237 self.node.cmd("{} -d security.prefix-update-validator.trust-anchor.file-name".format(self.infocmd))
Vince Lehman5d5a5662015-12-02 12:33:12 -0600238 else:
Saurab Dulal7a6978e2017-11-29 10:50:09 -0600239 self.node.cmd("{} -s security.validator.trust-anchor.file-name -v security/root.cert".format(self.infocmd))
240 self.node.cmd("{} -s security.prefix-update-validator.trust-anchor.file-name -v security/site.cert".format(self.infocmd))
241 self.node.cmd("{} -p security.cert-to-publish -v security/site.cert".format(self.infocmd))
242 self.node.cmd("{} -p security.cert-to-publish -v security/op.cert".format(self.infocmd))
dmcoomes73caa522018-01-15 16:33:32 -0600243 self.node.cmd("{} -p security.cert-to-publish -v security/router.cert".format(self.infocmd))