blob: 06dd368669e35549dc5af80b667ba929af9237a6 [file] [log] [blame]
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
Alexander Afanasyev45b92d42011-08-14 23:11:38 -07004 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08005 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
Alexander Afanasyev45b92d42011-08-14 23:11:38 -07007 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08008 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070011 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080012 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070015 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080016 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070019
Alexander Afanasyev0c395372014-12-20 15:54:02 -080020#include "ndn-stack-helper.hpp"
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -080021
22#include "ns3/log.h"
23#include "ns3/names.h"
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080024#include "ns3/string.h"
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -080025#include "ns3/point-to-point-net-device.h"
26
27#include "model/ndn-l3-protocol.hpp"
Alexander Afanasyeva91aab42016-09-08 15:47:38 -070028#include "model/ndn-net-device-link-service.hpp"
29#include "model/null-transport.hpp"
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -080030#include "utils/ndn-time.hpp"
Alexander Afanasyev34e13f32014-12-14 15:13:28 -080031#include "utils/dummy-keychain.hpp"
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080032#include "model/cs/ndn-content-store.hpp"
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070033
34#include <limits>
35#include <map>
Alexander Afanasyevb7626842012-01-12 13:43:33 -080036#include <boost/lexical_cast.hpp>
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -080037
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080038NS_LOG_COMPONENT_DEFINE("ndn.StackHelper");
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070039
40namespace ns3 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070041namespace ndn {
Alexander Afanasyev122f3782013-02-02 00:04:40 -080042
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080043StackHelper::StackHelper()
Alexander Afanasyeva91aab42016-09-08 15:47:38 -070044 : m_isRibManagerDisabled(false)
45 // , m_isFaceManagerDisabled(false)
46 , m_isForwarderStatusManagerDisabled(false)
spirosmastorakis0df15ba2015-11-14 08:46:24 -080047 , m_isStrategyChoiceManagerDisabled(false)
Alexander Afanasyeva91aab42016-09-08 15:47:38 -070048 , m_needSetDefaultRoutes(false)
49 , m_maxCsSize(100)
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070050{
Spyridon Mastorakis86edf6f2014-11-14 19:27:18 -080051 setCustomNdnCxxClocks();
52
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080053 m_ndnFactory.SetTypeId("ns3::ndn::L3Protocol");
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080054 m_contentStoreFactory.SetTypeId("ns3::ndn::cs::Lru");
Alexander Afanasyev122f3782013-02-02 00:04:40 -080055
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080056 m_netDeviceCallbacks.push_back(
57 std::make_pair(PointToPointNetDevice::GetTypeId(),
58 MakeCallback(&StackHelper::PointToPointNetDeviceCallback, this)));
Alexander Afanasyev122f3782013-02-02 00:04:40 -080059 // default callback will be fired if non of others callbacks fit or did the job
Ilya Moiseenko25f7d4d2011-09-29 18:41:06 -070060}
Alexander Afanasyev122f3782013-02-02 00:04:40 -080061
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080062StackHelper::~StackHelper()
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070063{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070064}
65
Alexander Afanasyev34e13f32014-12-14 15:13:28 -080066KeyChain&
67StackHelper::getKeyChain()
68{
Alexander Afanasyevdf26b5a2015-01-15 23:30:56 -080069 static ::ndn::KeyChain keyChain("pib-dummy", "tpm-dummy");
Alexander Afanasyev34e13f32014-12-14 15:13:28 -080070 return keyChain;
71}
72
Alexander Afanasyev3a4a0b32012-06-28 14:14:22 -070073void
Spyridon Mastorakis86edf6f2014-11-14 19:27:18 -080074StackHelper::setCustomNdnCxxClocks()
75{
76 ::ndn::time::setCustomClocks(make_shared<ns3::ndn::time::CustomSteadyClock>(),
77 make_shared<ns3::ndn::time::CustomSystemClock>());
78}
79
Spyridon Mastorakis588fd102014-11-20 19:50:02 -080080void
81StackHelper::SetDefaultRoutes(bool needSet)
82{
83 NS_LOG_FUNCTION(this << needSet);
84 m_needSetDefaultRoutes = needSet;
85}
86
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080087void
88StackHelper::SetStackAttributes(const std::string& attr1, const std::string& value1,
89 const std::string& attr2, const std::string& value2,
90 const std::string& attr3, const std::string& value3,
91 const std::string& attr4, const std::string& value4)
92{
93 if (attr1 != "")
94 m_ndnFactory.Set(attr1, StringValue(value1));
95 if (attr2 != "")
96 m_ndnFactory.Set(attr2, StringValue(value2));
97 if (attr3 != "")
98 m_ndnFactory.Set(attr3, StringValue(value3));
99 if (attr4 != "")
100 m_ndnFactory.Set(attr4, StringValue(value4));
101}
102
103void
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800104StackHelper::SetOldContentStore(const std::string& contentStore, const std::string& attr1,
105 const std::string& value1, const std::string& attr2,
106 const std::string& value2, const std::string& attr3,
107 const std::string& value3, const std::string& attr4,
108 const std::string& value4)
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800109{
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800110 m_maxCsSize = 0;
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800111
112 m_contentStoreFactory.SetTypeId(contentStore);
113 if (attr1 != "")
114 m_contentStoreFactory.Set(attr1, StringValue(value1));
115 if (attr2 != "")
116 m_contentStoreFactory.Set(attr2, StringValue(value2));
117 if (attr3 != "")
118 m_contentStoreFactory.Set(attr3, StringValue(value3));
119 if (attr4 != "")
120 m_contentStoreFactory.Set(attr4, StringValue(value4));
121}
122
123void
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800124StackHelper::setCsSize(size_t maxSize)
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800125{
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800126 m_maxCsSize = maxSize;
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800127}
128
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700129Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800130StackHelper::Install(const NodeContainer& c) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700131{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800132 Ptr<FaceContainer> faces = Create<FaceContainer>();
133 for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) {
134 faces->AddAll(Install(*i));
135 }
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700136 return faces;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700137}
138
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700139Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800140StackHelper::InstallAll() const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700141{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800142 return Install(NodeContainer::GetGlobal());
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700143}
144
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700145Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800146StackHelper::Install(Ptr<Node> node) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700147{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800148 Ptr<FaceContainer> faces = Create<FaceContainer>();
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800149
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800150 if (node->GetObject<L3Protocol>() != 0) {
Spyridon Mastorakis21226ae2015-03-31 18:03:11 -0700151 NS_FATAL_ERROR("Cannot re-install NDN stack on node "
152 << node->GetId());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800153 return 0;
154 }
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700155
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800156 Ptr<L3Protocol> ndn = m_ndnFactory.Create<L3Protocol>();
spirosmastorakis0df15ba2015-11-14 08:46:24 -0800157
158 if (m_isRibManagerDisabled) {
159 ndn->getConfig().put("ndnSIM.disable_rib_manager", true);
160 }
161
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700162 // if (m_isFaceManagerDisabled) {
163 // ndn->getConfig().put("ndnSIM.disable_face_manager", true);
164 // }
spirosmastorakis0df15ba2015-11-14 08:46:24 -0800165
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700166 if (m_isForwarderStatusManagerDisabled) {
167 ndn->getConfig().put("ndnSIM.disable_forwarder_status_manager", true);
spirosmastorakis0df15ba2015-11-14 08:46:24 -0800168 }
169
170 if (m_isStrategyChoiceManagerDisabled) {
171 ndn->getConfig().put("ndnSIM.disable_strategy_choice_manager", true);
172 }
173
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800174 ndn->getConfig().put("tables.cs_max_packets", (m_maxCsSize == 0) ? 1 : m_maxCsSize);
175
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800176 // Create and aggregate content store if NFD's contest store has been disabled
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800177 if (m_maxCsSize == 0) {
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800178 ndn->AggregateObject(m_contentStoreFactory.Create<ContentStore>());
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800179 }
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800180
181 // Aggregate L3Protocol on node (must be after setting ndnSIM CS)
182 node->AggregateObject(ndn);
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800183
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800184 for (uint32_t index = 0; index < node->GetNDevices(); index++) {
185 Ptr<NetDevice> device = node->GetDevice(index);
186 // This check does not make sense: LoopbackNetDevice is installed only if IP stack is installed,
187 // Normally, ndnSIM works without IP stack, so no reason to check
188 // if (DynamicCast<LoopbackNetDevice> (device) != 0)
189 // continue; // don't create face for a LoopbackNetDevice
Alexander Afanasyev11453142011-11-25 16:13:33 -0800190
Spyridon Mastorakis21226ae2015-03-31 18:03:11 -0700191 faces->Add(this->createAndRegisterFace(node, ndn, device));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800192 }
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800193
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700194 return faces;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700195}
196
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800197void
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700198StackHelper::AddFaceCreateCallback(TypeId netDeviceType,
199 StackHelper::FaceCreateCallback callback)
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800200{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800201 m_netDeviceCallbacks.push_back(std::make_pair(netDeviceType, callback));
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800202}
203
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700204void
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700205StackHelper::UpdateFaceCreateCallback(TypeId netDeviceType,
206 FaceCreateCallback callback)
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700207{
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800208 for (auto& i : m_netDeviceCallbacks) {
209 if (i.first == netDeviceType) {
210 i.second = callback;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800211 return;
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700212 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800213 }
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700214}
215
216void
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700217StackHelper::RemoveFaceCreateCallback(TypeId netDeviceType,
218 FaceCreateCallback callback)
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700219{
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700220 m_netDeviceCallbacks.remove_if([&] (const std::pair<TypeId, FaceCreateCallback>& i) {
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800221 return (i.first == netDeviceType);
222 });
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700223}
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800224
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700225shared_ptr<Face>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800226StackHelper::DefaultNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
227 Ptr<NetDevice> netDevice) const
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800228{
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700229 NS_LOG_DEBUG("Creating default Face on node " << node->GetId());
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800230
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700231 auto netDeviceLink = make_unique<NetDeviceLinkService>(node, netDevice);
232 auto transport = make_unique<NullTransport>("netDevice://", "netDevice://");
233 auto face = std::make_shared<Face>(std::move(netDeviceLink), std::move(transport));
234 face->setMetric(1);
235
236 // @TODO add netDevice ID
Alexander Afanasyevc17e4bd2013-02-17 14:31:56 -0800237
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800238 ndn->addFace(face);
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700239 NS_LOG_LOGIC("Node " << node->GetId() << ": added Face as face #"
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800240 << face->getLocalUri());
Alexander Afanasyevc17e4bd2013-02-17 14:31:56 -0800241
242 return face;
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800243}
244
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700245shared_ptr<Face>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800246StackHelper::PointToPointNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
247 Ptr<NetDevice> device) const
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800248{
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700249 NS_LOG_DEBUG("Creating point-to-point Face on node " << node->GetId());
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800250
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700251 auto netDeviceLink = make_unique<NetDeviceLinkService>(node, device);
252 auto transport = make_unique<NullTransport>("netDevice://", "netDevice://");
253 auto face = std::make_shared<Face>(std::move(netDeviceLink), std::move(transport));
254 face->setMetric(1);
255
256 // @TODO add netDevice ID
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800257
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800258 ndn->addFace(face);
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700259 NS_LOG_LOGIC("Node " << node->GetId() << ": added Face as face #"
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800260 << face->getLocalUri());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800261
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800262 return face;
263}
264
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700265Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800266StackHelper::Install(const std::string& nodeName) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700267{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800268 Ptr<Node> node = Names::Find<Node>(nodeName);
269 return Install(node);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700270}
271
Spyridon Mastorakis21226ae2015-03-31 18:03:11 -0700272void
273StackHelper::Update(Ptr<Node> node)
274{
275 if (node->GetObject<L3Protocol>() == 0) {
276 Install(node);
277 return;
278 }
279
280 Ptr<L3Protocol> ndn = node->GetObject<L3Protocol>();
281
282 for (uint32_t index = 0; index < node->GetNDevices(); index++) {
283
284 Ptr<NetDevice> device = node->GetDevice(index);
285
286 if (ndn->getFaceByNetDevice(device) == nullptr) {
287 this->createAndRegisterFace(node, ndn, device);
288 }
289 }
290}
291
292void
293StackHelper::Update(const NodeContainer& c)
294{
295 for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) {
296 Update(*i);
297 }
298}
299
300void
301StackHelper::Update(const std::string& nodeName)
302{
303 Ptr<Node> node = Names::Find<Node>(nodeName);
304 Update(node);
305}
306
307void
308StackHelper::UpdateAll()
309{
310 Update(NodeContainer::GetGlobal());
311}
312
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700313shared_ptr<Face>
Spyridon Mastorakis21226ae2015-03-31 18:03:11 -0700314StackHelper::createAndRegisterFace(Ptr<Node> node, Ptr<L3Protocol> ndn, Ptr<NetDevice> device) const
315{
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700316 shared_ptr<Face> face;
Spyridon Mastorakis21226ae2015-03-31 18:03:11 -0700317
318 for (const auto& item : m_netDeviceCallbacks) {
319 if (device->GetInstanceTypeId() == item.first ||
320 device->GetInstanceTypeId().IsChildOf(item.first)) {
321 face = item.second(node, ndn, device);
322 if (face != 0)
323 break;
324 }
325 }
326
327 if (face == 0) {
328 face = DefaultNetDeviceCallback(node, ndn, device);
329 }
330
331 if (m_needSetDefaultRoutes) {
332 // default route with lowest priority possible
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700333
334 // TODO: Restore when FibHelper is available
335 // FibHelper::AddRoute(node, "/", face, std::numeric_limits<int32_t>::max());
Spyridon Mastorakis21226ae2015-03-31 18:03:11 -0700336 }
337 return face;
338}
339
spirosmastorakis0df15ba2015-11-14 08:46:24 -0800340void
341StackHelper::disableRibManager()
342{
343 m_isRibManagerDisabled = true;
344}
345
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700346// void
347// StackHelper::disableFaceManager()
348// {
349// m_isFaceManagerDisabled = true;
350// }
spirosmastorakis0df15ba2015-11-14 08:46:24 -0800351
352void
353StackHelper::disableStrategyChoiceManager()
354{
355 m_isStrategyChoiceManagerDisabled = true;
356}
357
358void
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700359StackHelper::disableForwarderStatusManager()
spirosmastorakis0df15ba2015-11-14 08:46:24 -0800360{
Alexander Afanasyeva91aab42016-09-08 15:47:38 -0700361 m_isForwarderStatusManagerDisabled = true;
spirosmastorakis0df15ba2015-11-14 08:46:24 -0800362}
363
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700364} // namespace ndn
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700365} // namespace ns3