blob: 08aeccf66f1f3926254bbc9f8baee0f6aa0a43c9 [file] [log] [blame]
Alexander Lane6f7a64f2018-05-17 15:01:14 -05001# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2#
Saurab Dulal576a4192020-08-25 00:55:22 -05003# Copyright (C) 2015-2020, The University of Memphis,
Alexander Lane6f7a64f2018-05-17 15:01:14 -05004# Arizona Board of Regents,
5# Regents of the University of California.
6#
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
tylerliu86647792023-03-03 15:18:48 -080024from mininet.log import debug, warn
Ashlesh Gawande6c86e302019-09-17 22:27:05 -050025from minindn.minindn import Minindn
awlane21acd052024-06-13 21:12:51 -050026from minindn.util import MACToEther
Saurab Dulal8ae870a2018-07-31 05:17:49 +000027
Varun Patil63a330d2022-05-18 14:23:13 -070028# If needed (e.g. to speed up the process), use a smaller (or larger value)
29# based on your machines resource (CPU, memory)
tylerliu86647792023-03-03 15:18:48 -080030SLEEP_TIME = 0.0015
Alexander Lane6f7a64f2018-05-17 15:01:14 -050031
Ashlesh Gawande6c86e302019-09-17 22:27:05 -050032class Nfdc(object):
33 STRATEGY_ASF = 'asf'
34 STRATEGY_BEST_ROUTE = 'best-route'
35 STRATEGY_MULTICAST = 'multicast'
36 STRATEGY_NCC = 'ncc'
37 PROTOCOL_UDP = 'udp'
38 PROTOCOL_TCP = 'tcp'
39 PROTOCOL_ETHER = 'ether'
Alexander Lane6f7a64f2018-05-17 15:01:14 -050040
41 @staticmethod
Alex Lane1d3c0a82021-07-22 17:28:16 -050042 def registerRoute(node, namePrefix, remoteNode, protocol=PROTOCOL_UDP, origin=255,
Ashlesh Gawande6651a742019-01-03 18:13:06 -060043 cost=0, inheritFlag=True, captureFlag=False, expirationInMillis=None):
Alex Lane1d3c0a82021-07-22 17:28:16 -050044 cmd = ""
45 if remoteNode.isdigit() and not protocol == "fd":
46 cmd = ('nfdc route add {} {} origin {} cost {} {}{}{}').format(
47 namePrefix,
48 remoteNode,
49 origin,
50 cost,
51 'no-inherit ' if not inheritFlag else '',
52 'capture ' if captureFlag else '',
53 'expires {}'.format(expirationInMillis) if expirationInMillis else ''
54 )
55 else:
awlane21acd052024-06-13 21:12:51 -050056 if protocol == "ether":
57 remoteNode = MACToEther(remoteNode)
Alex Lane1d3c0a82021-07-22 17:28:16 -050058 cmd = ('nfdc route add {} {}://{} origin {} cost {} {}{}{}').format(
59 namePrefix,
60 protocol,
61 remoteNode,
62 origin,
63 cost,
64 'no-inherit ' if not inheritFlag else '',
65 'capture ' if captureFlag else '',
66 'expires {}'.format(expirationInMillis) if expirationInMillis else ''
67 )
dulalsaurab2b899532018-10-25 18:02:15 +000068 debug(node.cmd(cmd))
Ashlesh Gawande6c86e302019-09-17 22:27:05 -050069 Minindn.sleep(SLEEP_TIME)
Alexander Lane6f7a64f2018-05-17 15:01:14 -050070
71 @staticmethod
awlane21acd052024-06-13 21:12:51 -050072 def unregisterRoute(node, namePrefix, remoteNode, protocol=PROTOCOL_UDP, origin=255):
Alex Lane1d3c0a82021-07-22 17:28:16 -050073 cmd = ""
74 if remoteNode.isdigit() and not protocol == "fd":
awlane21acd052024-06-13 21:12:51 -050075 cmd = 'nfdc route remove {} {} origin {}'.format(namePrefix, remoteNode, origin)
Alex Lane1d3c0a82021-07-22 17:28:16 -050076 else:
awlane21acd052024-06-13 21:12:51 -050077 if protocol == "ether":
78 remoteNode = MACToEther(remoteNode)
79 cmd = 'nfdc route remove {} {}://{} origin {}'.format(namePrefix, protocol, remoteNode, origin)
dulalsaurab0dcdb322018-08-15 20:39:07 +000080 debug(node.cmd(cmd))
Ashlesh Gawande6c86e302019-09-17 22:27:05 -050081 Minindn.sleep(SLEEP_TIME)
Alexander Lane6f7a64f2018-05-17 15:01:14 -050082
83 @staticmethod
awlane21acd052024-06-13 21:12:51 -050084 def createFace(node, remoteNodeAddress, protocol=PROTOCOL_UDP, isPermanent=False, localInterface='', allowExisting=True):
Alex Lane1d3c0a82021-07-22 17:28:16 -050085 '''Create face in node's NFD instance. Returns FaceID of created face or -1 if failed.'''
awlane21acd052024-06-13 21:12:51 -050086 if protocol == "ether" and not localInterface:
87 warn("Cannot create ethernet face without local interface!")
88 return
89 elif protocol != "ether" and localInterface:
90 warn("Cannot create non-ethernet face with local interface specified!")
91 return
92 elif protocol == "ether" and localInterface:
93 remoteNodeAddress = MACToEther(remoteNodeAddress)
94 cmd = ('nfdc face create {}://{} {}{}'.format(
Alexander Lane6f7a64f2018-05-17 15:01:14 -050095 protocol,
Ashlesh Gawande6651a742019-01-03 18:13:06 -060096 remoteNodeAddress,
awlane21acd052024-06-13 21:12:51 -050097 'local dev://{} '.format(localInterface) if localInterface else '',
98 'persistency permanent' if isPermanent else 'persistency persistent'
Alexander Lane6f7a64f2018-05-17 15:01:14 -050099 ))
Alex Lane1d3c0a82021-07-22 17:28:16 -0500100 output = node.cmd(cmd)
101 debug(output)
Ashlesh Gawande6c86e302019-09-17 22:27:05 -0500102 Minindn.sleep(SLEEP_TIME)
awlanea43c2412024-04-02 14:14:45 -0500103 if "face-created" in output or (allowExisting and ("face-exists" in output or "face-updated" in output)):
Varun Patilc69041f2022-05-18 14:17:54 -0700104 faceID = output.split(" ")[1][3:]
awlanea43c2412024-04-02 14:14:45 -0500105 if "face-exists" in output or "face-updated" in output:
106 debug("[{}] Existing face found: {}\n".format(node.name, faceID))
Varun Patilc69041f2022-05-18 14:17:54 -0700107 return faceID
awlanea43c2412024-04-02 14:14:45 -0500108 warn("[{}] Face register failed: {}\n".format(node.name, output))
Varun Patilc69041f2022-05-18 14:17:54 -0700109 return -1
Alexander Lane6f7a64f2018-05-17 15:01:14 -0500110
111 @staticmethod
awlane21acd052024-06-13 21:12:51 -0500112 def destroyFace(node, remoteNode, protocol=PROTOCOL_UDP):
Alex Lane1d3c0a82021-07-22 17:28:16 -0500113 if remoteNode.isdigit() and not protocol == "fd":
awlane21acd052024-06-13 21:12:51 -0500114 debug(node.cmd('nfdc face destroy {}'.format(remoteNode)))
Alex Lane1d3c0a82021-07-22 17:28:16 -0500115 else:
awlane21acd052024-06-13 21:12:51 -0500116 if protocol == "ether":
117 remoteNode = MACToEther(remoteNode)
Alex Lane1d3c0a82021-07-22 17:28:16 -0500118 debug(node.cmd('nfdc face destroy {}://{}'.format(protocol, remoteNode)))
Ashlesh Gawande6c86e302019-09-17 22:27:05 -0500119 Minindn.sleep(SLEEP_TIME)
Alexander Lane6f7a64f2018-05-17 15:01:14 -0500120
121 @staticmethod
122 def setStrategy(node, namePrefix, strategy):
Ashlesh Gawande6c86e302019-09-17 22:27:05 -0500123 cmd = 'nfdc strategy set {} ndn:/localhost/nfd/strategy/{}'.format(namePrefix, strategy)
tylerliu86647792023-03-03 15:18:48 -0800124 out = node.cmd(cmd)
125 if out.find('error') != -1:
126 warn("[" + node.name + "] Error on strategy set out: " + out)
Ashlesh Gawande6c86e302019-09-17 22:27:05 -0500127 Minindn.sleep(SLEEP_TIME)
Alexander Lane6f7a64f2018-05-17 15:01:14 -0500128
129 @staticmethod
130 def unsetStrategy(node, namePrefix):
dulalsaurab2b899532018-10-25 18:02:15 +0000131 debug(node.cmd("nfdc strategy unset {}".format(namePrefix)))
Ashlesh Gawande6c86e302019-09-17 22:27:05 -0500132 Minindn.sleep(SLEEP_TIME)
Alex Lane1d3c0a82021-07-22 17:28:16 -0500133
134 @staticmethod
awlane21acd052024-06-13 21:12:51 -0500135 def getFaceId(node, remoteNodeAddress, localEndpoint=None, protocol=PROTOCOL_UDP, portNum="6363"):
Alex Lane1d3c0a82021-07-22 17:28:16 -0500136 '''Returns the faceId for a remote node based on FaceURI, or -1 if a face is not found'''
137 #Should this be cached or is the hit not worth it?
138 local = ""
139 if localEndpoint:
140 local = " local {}".format(localEndpoint)
awlane21acd052024-06-13 21:12:51 -0500141 if protocol == "ether":
142 remoteNodeAddress = MACToEther(remoteNodeAddress)
143 output = node.cmd("nfdc face list remote {}://{}{}".format(protocol, remoteNodeAddress, local))
144 else:
145 output = node.cmd("nfdc face list remote {}://{}:{}{}".format(protocol, remoteNodeAddress, portNum, local))
Alex Lane1d3c0a82021-07-22 17:28:16 -0500146 debug(output)
147 Minindn.sleep(SLEEP_TIME)
148 # This is fragile but we don't have that many better options
149 if "faceid=" not in output:
150 return -1
151 faceId = output.split(" ")[0][7:]
tylerliu86647792023-03-03 15:18:48 -0800152 return faceId