blob: 72116396f0844c7941fdea570157e930fbbe1ba9 [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"
28#include "model/ndn-net-device-face.hpp"
29#include "utils/ndn-time.hpp"
Alexander Afanasyev34e13f32014-12-14 15:13:28 -080030#include "utils/dummy-keychain.hpp"
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080031#include "model/cs/ndn-content-store.hpp"
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070032
33#include <limits>
34#include <map>
Alexander Afanasyevb7626842012-01-12 13:43:33 -080035#include <boost/lexical_cast.hpp>
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -080036
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080037NS_LOG_COMPONENT_DEFINE("ndn.StackHelper");
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070038
39namespace ns3 {
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070040namespace ndn {
Alexander Afanasyev122f3782013-02-02 00:04:40 -080041
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080042StackHelper::StackHelper()
Spyridon Mastorakis588fd102014-11-20 19:50:02 -080043 : m_needSetDefaultRoutes(false)
Alexander Afanasyevdde1e812015-01-06 14:26:09 -080044 , m_maxCsSize(100)
spirosmastorakis0df15ba2015-11-14 08:46:24 -080045 , m_isRibManagerDisabled(false)
46 , m_isFaceManagerDisabled(false)
47 , m_isStatusServerDisabled(false)
48 , m_isStrategyChoiceManagerDisabled(false)
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070049{
Spyridon Mastorakis86edf6f2014-11-14 19:27:18 -080050 setCustomNdnCxxClocks();
51
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080052 m_ndnFactory.SetTypeId("ns3::ndn::L3Protocol");
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080053 m_contentStoreFactory.SetTypeId("ns3::ndn::cs::Lru");
Alexander Afanasyev122f3782013-02-02 00:04:40 -080054
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080055 m_netDeviceCallbacks.push_back(
56 std::make_pair(PointToPointNetDevice::GetTypeId(),
57 MakeCallback(&StackHelper::PointToPointNetDeviceCallback, this)));
Alexander Afanasyev122f3782013-02-02 00:04:40 -080058 // default callback will be fired if non of others callbacks fit or did the job
Ilya Moiseenko25f7d4d2011-09-29 18:41:06 -070059}
Alexander Afanasyev122f3782013-02-02 00:04:40 -080060
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080061StackHelper::~StackHelper()
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070062{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070063}
64
Alexander Afanasyev34e13f32014-12-14 15:13:28 -080065KeyChain&
66StackHelper::getKeyChain()
67{
Alexander Afanasyevdf26b5a2015-01-15 23:30:56 -080068 static ::ndn::KeyChain keyChain("pib-dummy", "tpm-dummy");
Alexander Afanasyev34e13f32014-12-14 15:13:28 -080069 return keyChain;
70}
71
Alexander Afanasyev3a4a0b32012-06-28 14:14:22 -070072void
Spyridon Mastorakis86edf6f2014-11-14 19:27:18 -080073StackHelper::setCustomNdnCxxClocks()
74{
75 ::ndn::time::setCustomClocks(make_shared<ns3::ndn::time::CustomSteadyClock>(),
76 make_shared<ns3::ndn::time::CustomSystemClock>());
77}
78
Spyridon Mastorakis588fd102014-11-20 19:50:02 -080079void
80StackHelper::SetDefaultRoutes(bool needSet)
81{
82 NS_LOG_FUNCTION(this << needSet);
83 m_needSetDefaultRoutes = needSet;
84}
85
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -080086void
87StackHelper::SetStackAttributes(const std::string& attr1, const std::string& value1,
88 const std::string& attr2, const std::string& value2,
89 const std::string& attr3, const std::string& value3,
90 const std::string& attr4, const std::string& value4)
91{
92 if (attr1 != "")
93 m_ndnFactory.Set(attr1, StringValue(value1));
94 if (attr2 != "")
95 m_ndnFactory.Set(attr2, StringValue(value2));
96 if (attr3 != "")
97 m_ndnFactory.Set(attr3, StringValue(value3));
98 if (attr4 != "")
99 m_ndnFactory.Set(attr4, StringValue(value4));
100}
101
102void
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800103StackHelper::SetOldContentStore(const std::string& contentStore, const std::string& attr1,
104 const std::string& value1, const std::string& attr2,
105 const std::string& value2, const std::string& attr3,
106 const std::string& value3, const std::string& attr4,
107 const std::string& value4)
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800108{
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800109 m_maxCsSize = 0;
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800110
111 m_contentStoreFactory.SetTypeId(contentStore);
112 if (attr1 != "")
113 m_contentStoreFactory.Set(attr1, StringValue(value1));
114 if (attr2 != "")
115 m_contentStoreFactory.Set(attr2, StringValue(value2));
116 if (attr3 != "")
117 m_contentStoreFactory.Set(attr3, StringValue(value3));
118 if (attr4 != "")
119 m_contentStoreFactory.Set(attr4, StringValue(value4));
120}
121
122void
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800123StackHelper::setCsSize(size_t maxSize)
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800124{
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800125 m_maxCsSize = maxSize;
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800126}
127
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700128Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800129StackHelper::Install(const NodeContainer& c) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700130{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800131 Ptr<FaceContainer> faces = Create<FaceContainer>();
132 for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) {
133 faces->AddAll(Install(*i));
134 }
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700135 return faces;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700136}
137
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700138Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800139StackHelper::InstallAll() const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700140{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800141 return Install(NodeContainer::GetGlobal());
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700142}
143
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700144Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800145StackHelper::Install(Ptr<Node> node) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700146{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800147 Ptr<FaceContainer> faces = Create<FaceContainer>();
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800148
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800149 if (node->GetObject<L3Protocol>() != 0) {
Spyridon Mastorakis21226ae2015-03-31 18:03:11 -0700150 NS_FATAL_ERROR("Cannot re-install NDN stack on node "
151 << node->GetId());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800152 return 0;
153 }
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700154
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800155 Ptr<L3Protocol> ndn = m_ndnFactory.Create<L3Protocol>();
spirosmastorakis0df15ba2015-11-14 08:46:24 -0800156
157 if (m_isRibManagerDisabled) {
158 ndn->getConfig().put("ndnSIM.disable_rib_manager", true);
159 }
160
161 if (m_isFaceManagerDisabled) {
162 ndn->getConfig().put("ndnSIM.disable_face_manager", true);
163 }
164
165 if (m_isStatusServerDisabled) {
166 ndn->getConfig().put("ndnSIM.disable_status_server", true);
167 }
168
169 if (m_isStrategyChoiceManagerDisabled) {
170 ndn->getConfig().put("ndnSIM.disable_strategy_choice_manager", true);
171 }
172
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800173 ndn->getConfig().put("tables.cs_max_packets", (m_maxCsSize == 0) ? 1 : m_maxCsSize);
174
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800175 // Create and aggregate content store if NFD's contest store has been disabled
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800176 if (m_maxCsSize == 0) {
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800177 ndn->AggregateObject(m_contentStoreFactory.Create<ContentStore>());
Alexander Afanasyevdde1e812015-01-06 14:26:09 -0800178 }
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800179
180 // Aggregate L3Protocol on node (must be after setting ndnSIM CS)
181 node->AggregateObject(ndn);
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800182
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800183 for (uint32_t index = 0; index < node->GetNDevices(); index++) {
184 Ptr<NetDevice> device = node->GetDevice(index);
185 // This check does not make sense: LoopbackNetDevice is installed only if IP stack is installed,
186 // Normally, ndnSIM works without IP stack, so no reason to check
187 // if (DynamicCast<LoopbackNetDevice> (device) != 0)
188 // continue; // don't create face for a LoopbackNetDevice
Alexander Afanasyev11453142011-11-25 16:13:33 -0800189
Spyridon Mastorakis21226ae2015-03-31 18:03:11 -0700190 faces->Add(this->createAndRegisterFace(node, ndn, device));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800191 }
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800192
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700193 return faces;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700194}
195
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800196void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800197StackHelper::AddNetDeviceFaceCreateCallback(TypeId netDeviceType,
198 StackHelper::NetDeviceFaceCreateCallback callback)
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800199{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800200 m_netDeviceCallbacks.push_back(std::make_pair(netDeviceType, callback));
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800201}
202
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700203void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800204StackHelper::UpdateNetDeviceFaceCreateCallback(TypeId netDeviceType,
205 NetDeviceFaceCreateCallback callback)
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700206{
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800207 for (auto& i : m_netDeviceCallbacks) {
208 if (i.first == netDeviceType) {
209 i.second = callback;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800210 return;
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700211 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800212 }
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700213}
214
215void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800216StackHelper::RemoveNetDeviceFaceCreateCallback(TypeId netDeviceType,
217 NetDeviceFaceCreateCallback callback)
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700218{
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800219 m_netDeviceCallbacks.remove_if([&] (const std::pair<TypeId, NetDeviceFaceCreateCallback>& i) {
220 return (i.first == netDeviceType);
221 });
Alexander Afanasyev2a269f72013-06-06 22:59:33 -0700222}
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800223
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700224shared_ptr<NetDeviceFace>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800225StackHelper::DefaultNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
226 Ptr<NetDevice> netDevice) const
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800227{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800228 NS_LOG_DEBUG("Creating default NetDeviceFace on node " << node->GetId());
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800229
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800230 shared_ptr<NetDeviceFace> face = std::make_shared<NetDeviceFace>(node, netDevice);
Alexander Afanasyevc17e4bd2013-02-17 14:31:56 -0800231
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800232 ndn->addFace(face);
233 NS_LOG_LOGIC("Node " << node->GetId() << ": added NetDeviceFace as face #"
234 << face->getLocalUri());
Alexander Afanasyevc17e4bd2013-02-17 14:31:56 -0800235
236 return face;
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800237}
238
Spyridon Mastorakise4f0d3c2014-10-29 13:20:03 -0700239shared_ptr<NetDeviceFace>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800240StackHelper::PointToPointNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn,
241 Ptr<NetDevice> device) const
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800242{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800243 NS_LOG_DEBUG("Creating point-to-point NetDeviceFace on node " << node->GetId());
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800244
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800245 shared_ptr<NetDeviceFace> face = std::make_shared<NetDeviceFace>(node, device);
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800246
Spyridon Mastorakis9760bd02014-11-12 13:32:55 -0800247 ndn->addFace(face);
248 NS_LOG_LOGIC("Node " << node->GetId() << ": added NetDeviceFace as face #"
249 << face->getLocalUri());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800250
Alexander Afanasyev122f3782013-02-02 00:04:40 -0800251 return face;
252}
253
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700254Ptr<FaceContainer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800255StackHelper::Install(const std::string& nodeName) const
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700256{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800257 Ptr<Node> node = Names::Find<Node>(nodeName);
258 return Install(node);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700259}
260
Spyridon Mastorakis21226ae2015-03-31 18:03:11 -0700261void
262StackHelper::Update(Ptr<Node> node)
263{
264 if (node->GetObject<L3Protocol>() == 0) {
265 Install(node);
266 return;
267 }
268
269 Ptr<L3Protocol> ndn = node->GetObject<L3Protocol>();
270
271 for (uint32_t index = 0; index < node->GetNDevices(); index++) {
272
273 Ptr<NetDevice> device = node->GetDevice(index);
274
275 if (ndn->getFaceByNetDevice(device) == nullptr) {
276 this->createAndRegisterFace(node, ndn, device);
277 }
278 }
279}
280
281void
282StackHelper::Update(const NodeContainer& c)
283{
284 for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) {
285 Update(*i);
286 }
287}
288
289void
290StackHelper::Update(const std::string& nodeName)
291{
292 Ptr<Node> node = Names::Find<Node>(nodeName);
293 Update(node);
294}
295
296void
297StackHelper::UpdateAll()
298{
299 Update(NodeContainer::GetGlobal());
300}
301
302shared_ptr<NetDeviceFace>
303StackHelper::createAndRegisterFace(Ptr<Node> node, Ptr<L3Protocol> ndn, Ptr<NetDevice> device) const
304{
305 shared_ptr<NetDeviceFace> face;
306
307 for (const auto& item : m_netDeviceCallbacks) {
308 if (device->GetInstanceTypeId() == item.first ||
309 device->GetInstanceTypeId().IsChildOf(item.first)) {
310 face = item.second(node, ndn, device);
311 if (face != 0)
312 break;
313 }
314 }
315
316 if (face == 0) {
317 face = DefaultNetDeviceCallback(node, ndn, device);
318 }
319
320 if (m_needSetDefaultRoutes) {
321 // default route with lowest priority possible
322 FibHelper::AddRoute(node, "/", face, std::numeric_limits<int32_t>::max());
323 }
324 return face;
325}
326
spirosmastorakis0df15ba2015-11-14 08:46:24 -0800327void
328StackHelper::disableRibManager()
329{
330 m_isRibManagerDisabled = true;
331}
332
333void
334StackHelper::disableFaceManager()
335{
336 m_isFaceManagerDisabled = true;
337}
338
339void
340StackHelper::disableStrategyChoiceManager()
341{
342 m_isStrategyChoiceManagerDisabled = true;
343}
344
345void
346StackHelper::disableStatusServer()
347{
348 m_isStatusServerDisabled = true;
349}
350
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700351} // namespace ndn
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700352} // namespace ns3