blob: 074bdde5b9b576d3bebda690acae5001e32e7860 [file] [log] [blame]
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Alexander Afanasyev45b92d42011-08-14 23:11:38 -07002/*
3 * Copyright (c) 2011 UCLA
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
Ilya Moiseenko25f7d4d2011-09-29 18:41:06 -070018 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
Ilya Moiseenkofbd0a8b2011-10-28 13:07:16 -070019 * Ilya Moiseenko <iliamo@cs.ucla.edu>
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070020 */
21
22/**
23 * \ingroup ccnx
24 * \defgroup CcnxStackModel Ccnx Stack Model
25 *
26 * \section CcnxStackTracingModel Tracing in the Ccnx Stack
27 *
28 * The ccnx stack provides a number of trace sources in its various
29 * protocol implementations. These trace sources can be hooked using your own
30 * custom trace code, or you can use our helper functions in some cases to
31 * arrange for tracing to be enabled.
32 *
33 * \subsection CcnxStackCcnxTracingModel Tracing in Ccnx
34 *
35 * The Ccnx layer three protocol provides three trace hooks. These are the
36 * "Tx" (ns3::CcnxL3Protocol::m_txTrace), "Rx" (ns3::CcnxL3Protocol::m_rxTrace)
37 * and "Drop" (ns3::CcnxL3Protocol::m_dropTrace) trace sources.
38 *
39 * The "Tx" trace is fired in a number of situations, all of which indicate that
40 * a given packet is about to be sent down to a given ns3::CcnxFace.
41 *
42 * - \todo list Tx trace events
43 *
44 * The "Rx" trace is fired when a packet is passed from the device up to the
45 * ns3::CcnxL3Protocol::Receive function.
46 *
47 * - In the receive function, the CcnxFaceList is iterated, and if the
48 * CcnxFace corresponding to the receiving device is found to be in the
49 * UP state, the trace is fired.
50 *
51 * The "Drop" trace is fired in any case where the packet is dropped (in both
52 * the transmit and receive paths).
53 *
54 * - \todo list Drop trace events
55 */
56
57#include "ns3/assert.h"
58#include "ns3/log.h"
59#include "ns3/object.h"
60#include "ns3/names.h"
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070061#include "ns3/packet-socket-factory.h"
62#include "ns3/config.h"
63#include "ns3/simulator.h"
64#include "ns3/string.h"
65#include "ns3/net-device.h"
66#include "ns3/callback.h"
67#include "ns3/node.h"
68#include "ns3/core-config.h"
Alexander Afanasyevc74a6022011-08-15 20:01:35 -070069#include "ns3/ccnx-forwarding-strategy.h"
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -070070#include "ns3/ccnx-net-device-face.h"
71#include "ns3/ccnx-l3-protocol.h"
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -070072#include "ns3/ccnx-fib.h"
Alexander Afanasyev52e9aa92011-11-15 20:23:20 -080073#include "ns3/node-list.h"
Alexander Afanasyev11453142011-11-25 16:13:33 -080074#include "ns3/loopback-net-device.h"
Alexander Afanasyev52e9aa92011-11-15 20:23:20 -080075#include "ns3/global-router-interface.h"
Alexander Afanasyev11453142011-11-25 16:13:33 -080076#include "ns3/ipv4.h"
77#include "ns3/ipv4-global-routing.h"
78#include "ns3/ipv4-global-routing-ordered-nexthops.h"
79#include "ns3/ipv4-routing-helper.h"
Alexander Afanasyev52e9aa92011-11-15 20:23:20 -080080#include "ns3/ipv4-global-routing-helper.h"
Alexander Afanasyev11453142011-11-25 16:13:33 -080081#include "ns3/data-rate.h"
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070082
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -070083#include "ccnx-face-container.h"
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070084#include "ccnx-stack-helper.h"
85#include "ccnx-forwarding-helper.h"
86
87#include <limits>
88#include <map>
Alexander Afanasyev52e9aa92011-11-15 20:23:20 -080089#include <boost/foreach.hpp>
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070090
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -080091#define NDN_DEFAULT_DATA_SIZE 1024
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -080092
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070093NS_LOG_COMPONENT_DEFINE ("CcnxStackHelper");
94
95namespace ns3 {
96
97// Things are going to work differently here with respect to trace
98// file handling than in most places because the Tx and Rx trace
99// sources we are interested in are going to multiplex receive and
100// transmit callbacks for all Ccnx and face pairs through one
101// callback. We want packets to or from each distinct pair to go to
102// an individual file, so we have got to demultiplex the Ccnx and face
103// pair into a corresponding Ptr<PcapFileWrapper> at the callback.
104//
105// A complication in this situation is that the trace sources are
106// hooked on a protocol basis. There is no trace source hooked by an
107// Ccnx and face pair. This means that if we naively proceed to hook,
108// say, a drop trace for a given Ccnx with face 0, and then hook for
109// Ccnx with face 1 we will hook the drop trace twice and get two
110// callbacks per event. What we need to do is to hook the event once,
111// and that will result in a single callback per drop event, and the
112// trace source will provide the face which we filter on in the trace
113// sink.
114//
115// This has got to continue to work properly after the helper has been
116// destroyed; but must be cleaned up at the end of time to avoid
117// leaks. Global maps of protocol/face pairs to file objects seems to
118// fit the bill.
119//
Alexander Afanasyev11453142011-11-25 16:13:33 -0800120// typedef std::pair<Ptr<Ccnx>, uint32_t> FacePairCcnx;
121// typedef std::map<FacePairCcnx, Ptr<PcapFileWrapper> > FaceFileMapCcnx;
122// typedef std::map<FacePairCcnx, Ptr<OutputStreamWrapper> > FaceStreamMapCcnx;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700123
Alexander Afanasyev11453142011-11-25 16:13:33 -0800124// static FaceFileMapCcnx g_faceFileMapCcnx; /**< A mapping of Ccnx/face pairs to pcap files */
125// static FaceStreamMapCcnx g_faceStreamMapCcnx; /**< A mapping of Ccnx/face pairs to ascii streams */
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700126
Ilya Moiseenko25f7d4d2011-09-29 18:41:06 -0700127
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700128CcnxStackHelper::CcnxStackHelper ()
Alexander Afanasyev4a5c2c12011-12-12 18:50:57 -0800129 : m_limitsEnabled (false)
130 , m_needSetDefaultRoutes (false)
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700131{
Alexander Afanasyev11453142011-11-25 16:13:33 -0800132 m_strategyFactory.SetTypeId ("ns3::CcnxFloodingStrategy");
Ilya Moiseenko25f7d4d2011-09-29 18:41:06 -0700133}
134
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700135CcnxStackHelper::~CcnxStackHelper ()
136{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700137}
138
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700139void
Alexander Afanasyev11453142011-11-25 16:13:33 -0800140CcnxStackHelper::SetForwardingStrategy (std::string strategy)
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700141{
Alexander Afanasyev11453142011-11-25 16:13:33 -0800142 m_strategyFactory.SetTypeId (strategy);
143}
144
Alexander Afanasyev4a5c2c12011-12-12 18:50:57 -0800145
146void
147CcnxStackHelper::SetDefaultRoutes (bool needSet)
148{
149 NS_LOG_FUNCTION (this << needSet);
150 m_needSetDefaultRoutes = needSet;
151}
152
Alexander Afanasyev11453142011-11-25 16:13:33 -0800153void
Alexander Afanasyevc39f0b42011-11-28 12:51:12 -0800154CcnxStackHelper::EnableLimits (bool enable/* = true*/, Time avgRtt/*=Seconds(0.1)*/, uint32_t avgContentObject/*=1100*/, uint32_t avgInterest/*=40*/)
Alexander Afanasyev11453142011-11-25 16:13:33 -0800155{
Alexander Afanasyevc39f0b42011-11-28 12:51:12 -0800156 NS_LOG_INFO ("EnableLimits: " << enable);
Alexander Afanasyev11453142011-11-25 16:13:33 -0800157 m_limitsEnabled = enable;
Alexander Afanasyevc39f0b42011-11-28 12:51:12 -0800158 m_avgContentObjectSize = avgContentObject;
159 m_avgInterestSize = avgInterest;
160 m_avgRtt = avgRtt;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700161}
162
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700163Ptr<CcnxFaceContainer>
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700164CcnxStackHelper::Install (NodeContainer c) const
165{
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700166 Ptr<CcnxFaceContainer> faces = Create<CcnxFaceContainer> ();
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700167 for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
168 {
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700169 faces->AddAll (Install (*i));
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700170 }
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700171 return faces;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700172}
173
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700174Ptr<CcnxFaceContainer>
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700175CcnxStackHelper::InstallAll (void) const
176{
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700177 return Install (NodeContainer::GetGlobal ());
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700178}
179
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700180Ptr<CcnxFaceContainer>
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700181CcnxStackHelper::Install (Ptr<Node> node) const
182{
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700183 // NS_ASSERT_MSG (m_forwarding, "SetForwardingHelper() should be set prior calling Install() method");
184 Ptr<CcnxFaceContainer> faces = Create<CcnxFaceContainer> ();
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700185
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700186 if (node->GetObject<Ccnx> () != 0)
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700187 {
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700188 NS_FATAL_ERROR ("CcnxStackHelper::Install (): Installing "
189 "a CcnxStack to a node with an existing Ccnx object");
190 return 0;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700191 }
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700192
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700193 Ptr<CcnxFib> fib = CreateObject<CcnxFib> ();
194 node->AggregateObject (fib);
195
Ilya Moiseenkofbd0a8b2011-10-28 13:07:16 -0700196 Ptr<CcnxL3Protocol> ccnx = CreateObject<CcnxL3Protocol> ();
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700197 node->AggregateObject (ccnx);
198
Alexander Afanasyev11453142011-11-25 16:13:33 -0800199 ccnx->SetForwardingStrategy
200 (DynamicCast<CcnxForwardingStrategy> (m_strategyFactory.Create<Object> ()));
201
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700202 for (uint32_t index=0; index < node->GetNDevices (); index++)
203 {
Alexander Afanasyev11453142011-11-25 16:13:33 -0800204 Ptr<NetDevice> device = node->GetDevice (index);
205 if (DynamicCast<LoopbackNetDevice> (device) != 0)
206 continue; // don't create face for a LoopbackNetDevice
207
208 Ptr<CcnxNetDeviceFace> face = Create<CcnxNetDeviceFace> (node, device);
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800209
Alexander Afanasyev4a5c2c12011-12-12 18:50:57 -0800210 ccnx->AddFace (face);
211 NS_LOG_LOGIC ("Node " << node->GetId () << ": added CcnxNetDeviceFace as face #" << *face);
Alexander Afanasyev11453142011-11-25 16:13:33 -0800212
Alexander Afanasyev4a5c2c12011-12-12 18:50:57 -0800213 if (m_needSetDefaultRoutes)
214 {
215 // default route with lowest priority possible
216 AddRoute (node, "/", face, std::numeric_limits<int32_t>::max ());
217 }
218
Alexander Afanasyev11453142011-11-25 16:13:33 -0800219 if (m_limitsEnabled)
220 {
Alexander Afanasyevc39f0b42011-11-28 12:51:12 -0800221 NS_LOG_INFO ("Limits are enabled");
Alexander Afanasyev11453142011-11-25 16:13:33 -0800222 Ptr<PointToPointNetDevice> p2p = DynamicCast<PointToPointNetDevice> (device);
223 if (p2p == 0)
Alexander Afanasyevc39f0b42011-11-28 12:51:12 -0800224 {
225 NS_LOG_INFO ("Non p2p interface");
226 continue; // only PointToPointNetDevice supports limits
227 }
Alexander Afanasyev11453142011-11-25 16:13:33 -0800228
229 // Setup bucket filtering
230 // Assume that we know average data packet size, and this size is equal default size
231 // Set maximum buckets (averaging over 1 second)
Ilya Moiseenkoc9266042011-11-02 17:49:21 -0700232
Alexander Afanasyev11453142011-11-25 16:13:33 -0800233 DataRateValue dataRate; device->GetAttribute ("DataRate", dataRate);
234
235 NS_LOG_INFO("DataRate for this link is " << dataRate.Get());
Alexander Afanasyevc39f0b42011-11-28 12:51:12 -0800236
237 double maxInterestPackets = 1.0 * dataRate.Get ().GetBitRate () / 8.0 / m_avgContentObjectSize;
238 NS_LOG_INFO ("BucketMax: " << maxInterestPackets);
239
240 // Set bucket max to BDP
241 face->SetBucketMax (m_avgRtt.ToDouble (Time::S) * maxInterestPackets); // number of interests allowed
242 face->SetBucketLeak (maxInterestPackets);
Alexander Afanasyev11453142011-11-25 16:13:33 -0800243 }
Ilya Moiseenkoc9266042011-11-02 17:49:21 -0700244
Ilya Moiseenko25f7d4d2011-09-29 18:41:06 -0700245 face->SetUp ();
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700246 faces->Add (face);
247 }
Ilya Moiseenko25f7d4d2011-09-29 18:41:06 -0700248
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700249 return faces;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700250}
251
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700252Ptr<CcnxFaceContainer>
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700253CcnxStackHelper::Install (std::string nodeName) const
254{
255 Ptr<Node> node = Names::Find<Node> (nodeName);
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700256 return Install (node);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700257}
258
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700259
260void
Alexander Afanasyev4a5c2c12011-12-12 18:50:57 -0800261CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric) const
Alexander Afanasyev52e9aa92011-11-15 20:23:20 -0800262{
Alexander Afanasyev4a5c2c12011-12-12 18:50:57 -0800263 NS_LOG_LOGIC ("[" << node->GetId () << "]$ route add " << prefix << " via " << *face << " metric " << metric);
264
Alexander Afanasyev52e9aa92011-11-15 20:23:20 -0800265 Ptr<CcnxFib> fib = node->GetObject<CcnxFib> ();
266
267 CcnxNameComponentsValue prefixValue;
268 prefixValue.DeserializeFromString (prefix, MakeCcnxNameComponentsChecker ());
269 fib->Add (prefixValue.Get (), face, metric);
270}
271
272void
Alexander Afanasyev4a5c2c12011-12-12 18:50:57 -0800273CcnxStackHelper::AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric) const
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700274{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700275 Ptr<Node> node = Names::Find<Node> (nodeName);
276 NS_ASSERT_MSG (node != 0, "Node [" << nodeName << "] does not exist");
Alexander Afanasyeva4e3f852011-11-15 20:39:33 -0800277
Alexander Afanasyev52e9aa92011-11-15 20:23:20 -0800278 Ptr<Ccnx> ccnx = node->GetObject<Ccnx> ();
279 NS_ASSERT_MSG (ccnx != 0, "Ccnx stack should be installed on the node");
280
281 Ptr<CcnxFace> face = ccnx->GetFace (faceId);
282 NS_ASSERT_MSG (face != 0, "Face with ID [" << faceId << "] does not exist on node [" << nodeName << "]");
283
284 AddRoute (node, prefix, face, metric);
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700285}
Alexander Afanasyev4a5c2c12011-12-12 18:50:57 -0800286
Ilya Moiseenkoc9266042011-11-02 17:49:21 -0700287/*
Alexander Afanasyev11453142011-11-25 16:13:33 -0800288 void
289 CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, uint32_t faceId, int32_t metric)
290 {
291 NS_LOG_LOGIC ("[" << nodeName << "]$ route add " << prefix << " via " << faceId << " metric " << metric);
Ilya Moiseenkoc9266042011-11-02 17:49:21 -0700292
293 NS_ASSERT_MSG (node != 0, "Node does not exist");
294
295 Ptr<Ccnx> ccnx = node->GetObject<Ccnx> ();
296 Ptr<CcnxFib> fib = node->GetObject<CcnxFib> ();
297 Ptr<CcnxFace> face = ccnx->GetFace (faceId);
298 NS_ASSERT_MSG (node != 0, "Face with ID [" << faceId << "] does not exist on node [" << nodeName << "]");
299
300 CcnxNameComponentsValue prefixValue;
301 prefixValue.DeserializeFromString (prefix, MakeCcnxNameComponentsChecker ());
302 fib->Add (prefixValue.Get (), face, metric);
Alexander Afanasyev11453142011-11-25 16:13:33 -0800303 }
Ilya Moiseenkoc9266042011-11-02 17:49:21 -0700304*/
Ilya Moiseenkoae394872011-11-15 17:56:36 -0800305
Alexander Afanasyev11453142011-11-25 16:13:33 -0800306// static void
307// CcnxL3ProtocolRxTxSink (Ptr<const Packet> p, Ptr<Ccnx> ccnx, uint32_t face)
308// {
309// NS_LOG_FUNCTION (p << ccnx << face);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700310
Alexander Afanasyev11453142011-11-25 16:13:33 -0800311// //
312// // Since trace sources are independent of face, if we hook a source
313// // on a particular protocol we will get traces for all of its faces.
314// // We need to filter this to only report faces for which the user
315// // has expressed interest.
316// //
317// FacePairCcnx pair = std::make_pair (ccnx, face);
318// if (g_faceFileMapCcnx.find (pair) == g_faceFileMapCcnx.end ())
319// {
320// NS_LOG_INFO ("Ignoring packet to/from face " << face);
321// return;
322// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700323
Alexander Afanasyev11453142011-11-25 16:13:33 -0800324// Ptr<PcapFileWrapper> file = g_faceFileMapCcnx[pair];
325// file->Write (Simulator::Now (), p);
326// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700327
Alexander Afanasyev11453142011-11-25 16:13:33 -0800328// bool
329// CcnxStackHelper::PcapHooked (Ptr<Ccnx> ccnx)
330// {
331// for (FaceFileMapCcnx::const_iterator i = g_faceFileMapCcnx.begin ();
332// i != g_faceFileMapCcnx.end ();
333// ++i)
334// {
335// if ((*i).first.first == ccnx)
336// {
337// return true;
338// }
339// }
340// return false;
341// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700342
Alexander Afanasyev11453142011-11-25 16:13:33 -0800343// void
344// CcnxStackHelper::EnablePcapCcnxInternal (std::string prefix, Ptr<Ccnx> ccnx, uint32_t face, bool explicitFilename)
345// {
346// NS_LOG_FUNCTION (prefix << ccnx << face);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700347
Alexander Afanasyev11453142011-11-25 16:13:33 -0800348// //
349// // We have to create a file and a mapping from protocol/face to file
350// // irrespective of how many times we want to trace a particular protocol.
351// //
352// PcapHelper pcapHelper;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700353
Alexander Afanasyev11453142011-11-25 16:13:33 -0800354// std::string filename;
355// if (explicitFilename)
356// {
357// filename = prefix;
358// }
359// else
360// {
361// filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
362// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700363
Alexander Afanasyev11453142011-11-25 16:13:33 -0800364// Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_RAW);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700365
Alexander Afanasyev11453142011-11-25 16:13:33 -0800366// //
367// // However, we only hook the trace source once to avoid multiple trace sink
368// // calls per event (connect is independent of face).
369// //
370// if (!PcapHooked (ccnx))
371// {
372// //
373// // Ptr<Ccnx> is aggregated to node and CcnxL3Protocol is aggregated to
374// // node so we can get to CcnxL3Protocol through Ccnx.
375// //
376// Ptr<CcnxL3Protocol> ccnxL3Protocol = ccnx->GetObject<CcnxL3Protocol> ();
377// NS_ASSERT_MSG (ccnxL3Protocol, "CcnxStackHelper::EnablePcapCcnxInternal(): "
378// "m_ccnxEnabled and ccnxL3Protocol inconsistent");
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700379
Alexander Afanasyev11453142011-11-25 16:13:33 -0800380// bool result = ccnxL3Protocol->TraceConnectWithoutContext ("Tx", MakeCallback (&CcnxL3ProtocolRxTxSink));
381// NS_ASSERT_MSG (result == true, "CcnxStackHelper::EnablePcapCcnxInternal(): "
382// "Unable to connect ccnxL3Protocol \"Tx\"");
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700383
Alexander Afanasyev11453142011-11-25 16:13:33 -0800384// result = ccnxL3Protocol->TraceConnectWithoutContext ("Rx", MakeCallback (&CcnxL3ProtocolRxTxSink));
385// NS_ASSERT_MSG (result == true, "CcnxStackHelper::EnablePcapCcnxInternal(): "
386// "Unable to connect ccnxL3Protocol \"Rx\"");
387// // cast result to void, to suppress ‘result’ set but not used compiler-warning
388// // for optimized builds
389// (void) result;
390// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700391
Alexander Afanasyev11453142011-11-25 16:13:33 -0800392// g_faceFileMapCcnx[std::make_pair (ccnx, face)] = file;
393// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700394
Alexander Afanasyev11453142011-11-25 16:13:33 -0800395// static void
396// CcnxL3ProtocolDropSinkWithoutContext (
397// Ptr<OutputStreamWrapper> stream,
398// Ptr<const Packet> packet,
399// CcnxL3Protocol::DropReason reason,
400// Ptr<Ccnx> ccnx,
401// uint32_t face)
402// {
403// //
404// // Since trace sources are independent of face, if we hook a source
405// // on a particular protocol we will get traces for all of its faces.
406// // We need to filter this to only report faces for which the user
407// // has expressed interest.
408// //
409// FacePairCcnx pair = std::make_pair (ccnx, face);
410// if (g_faceStreamMapCcnx.find (pair) == g_faceStreamMapCcnx.end ())
411// {
412// NS_LOG_INFO ("Ignoring packet to/from face " << face);
413// return;
414// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700415
Alexander Afanasyev11453142011-11-25 16:13:33 -0800416// *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
417// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700418
Alexander Afanasyev11453142011-11-25 16:13:33 -0800419// static void
420// CcnxL3ProtocolDropSinkWithContext (
421// Ptr<OutputStreamWrapper> stream,
422// std::string context,
423// Ptr<const Packet> packet,
424// CcnxL3Protocol::DropReason reason,
425// Ptr<Ccnx> ccnx,
426// uint32_t face)
427// {
428// //
429// // Since trace sources are independent of face, if we hook a source
430// // on a particular protocol we will get traces for all of its faces.
431// // We need to filter this to only report faces for which the user
432// // has expressed interest.
433// //
434// FacePairCcnx pair = std::make_pair (ccnx, face);
435// if (g_faceStreamMapCcnx.find (pair) == g_faceStreamMapCcnx.end ())
436// {
437// NS_LOG_INFO ("Ignoring packet to/from face " << face);
438// return;
439// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700440
Alexander Afanasyev11453142011-11-25 16:13:33 -0800441// *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << "(" << face << ") "
442// << *packet << std::endl;
443// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700444
Alexander Afanasyev11453142011-11-25 16:13:33 -0800445// bool
446// CcnxStackHelper::AsciiHooked (Ptr<Ccnx> ccnx)
447// {
448// for ( FaceStreamMapCcnx::const_iterator i = g_faceStreamMapCcnx.begin ();
449// i != g_faceStreamMapCcnx.end ();
450// ++i)
451// {
452// if ((*i).first.first == ccnx)
453// {
454// return true;
455// }
456// }
457// return false;
458// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700459
Alexander Afanasyev11453142011-11-25 16:13:33 -0800460// void
461// CcnxStackHelper::EnableAsciiCcnxInternal (
462// Ptr<OutputStreamWrapper> stream,
463// std::string prefix,
464// Ptr<Ccnx> ccnx,
465// uint32_t face,
466// bool explicitFilename)
467// {
468// //
469// // Our trace sinks are going to use packet printing, so we have to
470// // make sure that is turned on.
471// //
472// Packet::EnablePrinting ();
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700473
Alexander Afanasyev11453142011-11-25 16:13:33 -0800474// //
475// // If we are not provided an OutputStreamWrapper, we are expected to create
476// // one using the usual trace filename conventions and hook WithoutContext
477// // since there will be one file per context and therefore the context would
478// // be redundant.
479// //
480// if (stream == 0)
481// {
482// //
483// // Set up an output stream object to deal with private ofstream copy
484// // constructor and lifetime issues. Let the helper decide the actual
485// // name of the file given the prefix.
486// //
487// // We have to create a stream and a mapping from protocol/face to
488// // stream irrespective of how many times we want to trace a particular
489// // protocol.
490// //
491// AsciiTraceHelper asciiTraceHelper;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700492
Alexander Afanasyev11453142011-11-25 16:13:33 -0800493// std::string filename;
494// if (explicitFilename)
495// {
496// filename = prefix;
497// }
498// else
499// {
500// filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
501// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700502
Alexander Afanasyev11453142011-11-25 16:13:33 -0800503// Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700504
Alexander Afanasyev11453142011-11-25 16:13:33 -0800505// //
506// // However, we only hook the trace sources once to avoid multiple trace sink
507// // calls per event (connect is independent of face).
508// //
509// if (!AsciiHooked (ccnx))
510// {
511// //
512// // The drop sink for the CcnxL3Protocol uses a different signature than
513// // the default sink, so we have to cook one up for ourselves. We can get
514// // to the Ptr<CcnxL3Protocol> through our Ptr<Ccnx> since they must both
515// // be aggregated to the same node.
516// //
517// Ptr<CcnxL3Protocol> ccnxL3Protocol = ccnx->GetObject<CcnxL3Protocol> ();
518// bool __attribute__ ((unused)) result = ccnxL3Protocol->TraceConnectWithoutContext ("Drop",
519// MakeBoundCallback (&CcnxL3ProtocolDropSinkWithoutContext, theStream));
520// NS_ASSERT_MSG (result == true, "CcnxStackHelper::EanableAsciiCcnxInternal(): "
521// "Unable to connect ccnxL3Protocol \"Drop\"");
522// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700523
Alexander Afanasyev11453142011-11-25 16:13:33 -0800524// g_faceStreamMapCcnx[std::make_pair (ccnx, face)] = theStream;
525// return;
526// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700527
Alexander Afanasyev11453142011-11-25 16:13:33 -0800528// //
529// // If we are provided an OutputStreamWrapper, we are expected to use it, and
530// // to provide a context. We are free to come up with our own context if we
531// // want, and use the AsciiTraceHelper Hook*WithContext functions, but for
532// // compatibility and simplicity, we just use Config::Connect and let it deal
533// // with the context.
534// //
535// // We need to associate the ccnx/face with a stream to express interest
536// // in tracing events on that pair, however, we only hook the trace sources
537// // once to avoid multiple trace sink calls per event (connect is independent
538// // of face).
539// //
540// if (!AsciiHooked (ccnx))
541// {
542// Ptr<Node> node = ccnx->GetObject<Node> ();
543// std::ostringstream oss;
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700544
Alexander Afanasyev11453142011-11-25 16:13:33 -0800545// //
546// // This has all kinds of parameters coming with, so we have to cook up our
547// // own sink.
548// //
549// oss.str ("");
550// oss << "/NodeList/" << node->GetId () << "/$ns3::CcnxL3Protocol/Drop";
551// Config::Connect (oss.str (), MakeBoundCallback (&CcnxL3ProtocolDropSinkWithContext, stream));
552// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700553
Alexander Afanasyev11453142011-11-25 16:13:33 -0800554// g_faceStreamMapCcnx[std::make_pair (ccnx, face)] = stream;
555// }
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700556
Alexander Afanasyev52e9aa92011-11-15 20:23:20 -0800557void
558CcnxStackHelper::InstallFakeGlobalRoutes ()
559{
560 for (NodeList::Iterator node = NodeList::Begin ();
561 node != NodeList::End ();
562 node ++)
563 {
564 NS_ASSERT_MSG ((*node)->GetObject<Ipv4> () != 0,
565 "InternetStack should be installed on all nodes");
566
567 NS_ASSERT_MSG (Ipv4RoutingHelper::GetRouting<Ipv4GlobalRoutingOrderedNexthops>
568 (
569 (*node)->GetObject<Ipv4> ()->GetRoutingProtocol ()
Alexander Afanasyev11453142011-11-25 16:13:33 -0800570 ),
Alexander Afanasyev52e9aa92011-11-15 20:23:20 -0800571 "InternetStack should have Ipv4GlobalRoutingOrderedNexthops as routing protocol");
572 // Example:
573 //
574 // Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingUnorderedNexthops");
575 // stack.SetRoutingHelper (ipv4RoutingHelper);
576 //
577
578 Ptr<GlobalRouter> globalRouter = (*node)->GetObject<GlobalRouter> ();
579 if (globalRouter == 0) continue;
580
581 globalRouter->InjectRoute (Ipv4Address((*node)->GetId ()), Ipv4Mask("255.255.255.255"));
582 }
583
584 Ipv4GlobalRoutingHelper::PopulateAllPossibleRoutingTables ();
585}
586
587void
588CcnxStackHelper::InstallRouteTo (Ptr<Node> destNode)
589{
590 std::ostringstream destPrefix;
591 destPrefix << "/" << destNode->GetId ();
592
593 Ipv4Address destIpv4 = Ipv4Address(destNode->GetId ());
594
595 for (NodeList::Iterator node = NodeList::Begin ();
596 node != NodeList::End ();
597 node ++)
598 {
599 if (destNode == *node) continue;
600
601 Ptr<Ccnx> ccnx = (*node)->GetObject<Ccnx> ();
602 NS_ASSERT_MSG (ccnx != 0, "CCNx stack should be installed on all nodes");
603
604 Ptr<Ipv4> ipv4 = (*node)->GetObject<Ipv4> ();
605 NS_ASSERT_MSG (ipv4 != 0,
606 "InternetStack should be installed on all nodes");
607
608 Ptr<Ipv4GlobalRoutingOrderedNexthops> routing =
609 Ipv4RoutingHelper::GetRouting<Ipv4GlobalRoutingOrderedNexthops> (ipv4->GetRoutingProtocol ());
610 NS_ASSERT_MSG (routing != 0, "Ipv4GlobalRoutingOrderedNexthops should be used in InternetStack");
611
612 Ptr<Ipv4GlobalRoutingOrderedNexthops::EntryContainer>
613 routes = routing->Lookup (destIpv4);
614
615 NS_ASSERT_MSG (routes != 0, "Should not happen... Call the developer");
616
617 BOOST_FOREACH (const Ipv4RoutingTableEntry &entry, *routes)
618 {
619 Ptr<NetDevice> netDevice = ipv4->GetNetDevice (entry.GetInterface ());
620 NS_ASSERT_MSG (netDevice != 0, "Should never happen. Call the popos");
621
622 Ptr<CcnxFace> face = ccnx->GetFaceByNetDevice (netDevice);
623 NS_ASSERT_MSG (face != 0, "Definitely should never happen. Call the president");
624
625 AddRoute (*node, destPrefix.str(), face, entry.GetMetric ());
626 }
627 }
628}
629
630void
631CcnxStackHelper::InstallRoutesToAll ()
632{
633 for (NodeList::Iterator node = NodeList::Begin ();
634 node != NodeList::End ();
635 node ++)
636 {
637 InstallRouteTo (*node);
638 }
639}
640
641
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700642} // namespace ns3