NS-3 based Named Data Networking (NDN) simulator
ndnSIM: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
ndn-l3-protocol.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2011 University of California, Los Angeles
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  *
18  * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19  * Ilya Moiseenko <iliamo@cs.ucla.edu>
20  */
21 
22 #include "ndn-l3-protocol.h"
23 
24 #include "ns3/packet.h"
25 #include "ns3/node.h"
26 #include "ns3/log.h"
27 #include "ns3/callback.h"
28 #include "ns3/uinteger.h"
29 #include "ns3/trace-source-accessor.h"
30 #include "ns3/object-vector.h"
31 #include "ns3/pointer.h"
32 #include "ns3/simulator.h"
33 #include "ns3/random-variable.h"
34 
35 #include "ns3/ndn-pit.h"
36 #include "ns3/ndn-interest.h"
37 #include "ns3/ndn-data.h"
38 
39 #include "ns3/ndn-face.h"
40 #include "ns3/ndn-forwarding-strategy.h"
41 
42 #include "ndn-net-device-face.h"
43 
44 #include <boost/foreach.hpp>
45 
46 NS_LOG_COMPONENT_DEFINE ("ndn.L3Protocol");
47 
48 namespace ns3 {
49 namespace ndn {
50 
51 const uint16_t L3Protocol::ETHERNET_FRAME_TYPE = 0x7777;
52 const uint16_t L3Protocol::IP_STACK_PORT = 9695;
53 
54 NS_OBJECT_ENSURE_REGISTERED (L3Protocol);
55 
56 TypeId
58 {
59  static TypeId tid = TypeId ("ns3::ndn::L3Protocol")
60  .SetGroupName ("ndn")
61  .SetParent<Object> ()
62  .AddConstructor<L3Protocol> ()
63  .AddAttribute ("FaceList", "List of faces associated with ndn stack",
64  ObjectVectorValue (),
65  MakeObjectVectorAccessor (&L3Protocol::m_faces),
66  MakeObjectVectorChecker<Face> ())
67  ;
68  return tid;
69 }
70 
72 : m_faceCounter (0)
73 {
74  NS_LOG_FUNCTION (this);
75 }
76 
77 L3Protocol::~L3Protocol ()
78 {
79  NS_LOG_FUNCTION (this);
80 }
81 
82 /*
83  * This method is called by AddAgregate and completes the aggregation
84  * by setting the node in the ndn stack
85  */
86 void
88 {
89  // not really efficient, but this will work only once
90  if (m_node == 0)
91  {
92  m_node = GetObject<Node> ();
93  if (m_node != 0)
94  {
95  NS_ASSERT_MSG (m_forwardingStrategy != 0,
96  "Forwarding strategy should be aggregated before L3Protocol");
97  }
98  }
99  if (m_forwardingStrategy == 0)
100  {
101  m_forwardingStrategy = GetObject<ForwardingStrategy> ();
102  }
103 
104  Object::NotifyNewAggregate ();
105 }
106 
107 void
109 {
110  NS_LOG_FUNCTION (this);
111 
112  // for (FaceList::iterator i = m_faces.begin (); i != m_faces.end (); ++i)
113  // {
114  // *i = 0;
115  // }
116  m_faces.clear ();
117  m_node = 0;
118 
119  // Force delete on objects
120  m_forwardingStrategy = 0; // there is a reference to PIT stored in here
121 
122  Object::DoDispose ();
123 }
124 
125 uint32_t
126 L3Protocol::AddFace (const Ptr<Face> &face)
127 {
128  NS_LOG_FUNCTION (this << &face);
129 
130  face->SetId (m_faceCounter); // sets a unique ID of the face. This ID serves only informational purposes
131 
132  // ask face to register in lower-layer stack
133  face->RegisterProtocolHandlers (MakeCallback (&ForwardingStrategy::OnInterest, m_forwardingStrategy),
134  MakeCallback (&ForwardingStrategy::OnData, m_forwardingStrategy));
135 
136  m_faces.push_back (face);
137  m_faceCounter++;
138 
139  m_forwardingStrategy->AddFace (face); // notify that face is added
140  return face->GetId ();
141 }
142 
143 void
144 L3Protocol::RemoveFace (Ptr<Face> face)
145 {
146  NS_LOG_FUNCTION (this << boost::cref (*face));
147  // ask face to register in lower-layer stack
148  face->UnRegisterProtocolHandlers ();
149  Ptr<Pit> pit = GetObject<Pit> ();
150 
151  // just to be on a safe side. Do the process in two steps
152  std::list< Ptr<pit::Entry> > entriesToRemoves;
153  for (Ptr<pit::Entry> pitEntry = pit->Begin (); pitEntry != 0; pitEntry = pit->Next (pitEntry))
154  {
155  pitEntry->RemoveAllReferencesToFace (face);
156 
157  // If this face is the only for the associated FIB entry, then FIB entry will be removed soon.
158  // Thus, we have to remove the whole PIT entry
159  if (pitEntry->GetFibEntry ()->m_faces.size () == 1 &&
160  pitEntry->GetFibEntry ()->m_faces.begin ()->GetFace () == face)
161  {
162  entriesToRemoves.push_back (pitEntry);
163  }
164  }
165  BOOST_FOREACH (Ptr<pit::Entry> removedEntry, entriesToRemoves)
166  {
167  pit->MarkErased (removedEntry);
168  }
169 
170  FaceList::iterator face_it = find (m_faces.begin(), m_faces.end(), face);
171  if (face_it == m_faces.end ())
172  {
173  return;
174  }
175  m_faces.erase (face_it);
176 
177  GetObject<Fib> ()->RemoveFromAll (face);
178  m_forwardingStrategy->RemoveFace (face); // notify that face is removed
179 }
180 
181 Ptr<Face>
182 L3Protocol::GetFace (uint32_t index) const
183 {
184  NS_ASSERT (0 <= index && index < m_faces.size ());
185  return m_faces[index];
186 }
187 
188 Ptr<Face>
189 L3Protocol::GetFaceById (uint32_t index) const
190 {
191  BOOST_FOREACH (const Ptr<Face> &face, m_faces) // this function is not supposed to be called often, so linear search is fine
192  {
193  if (face->GetId () == index)
194  return face;
195  }
196  return 0;
197 }
198 
199 Ptr<Face>
200 L3Protocol::GetFaceByNetDevice (Ptr<NetDevice> netDevice) const
201 {
202  BOOST_FOREACH (const Ptr<Face> &face, m_faces) // this function is not supposed to be called often, so linear search is fine
203  {
204  Ptr<NetDeviceFace> netDeviceFace = DynamicCast<NetDeviceFace> (face);
205  if (netDeviceFace == 0) continue;
206 
207  if (netDeviceFace->GetNetDevice () == netDevice)
208  return face;
209  }
210  return 0;
211 }
212 
213 uint32_t
215 {
216  return m_faces.size ();
217 }
218 
219 } //namespace ndn
220 } //namespace ns3
virtual uint32_t AddFace(const Ptr< Face > &face)
Add face to Ndn stack.
virtual Ptr< Face > GetFace(uint32_t face) const
Get face by face index.
virtual void OnInterest(Ptr< Face > face, Ptr< Interest > interest)
Actual processing of incoming Ndn interests.
virtual uint32_t GetNFaces() const
Get current number of faces added to Ndn stack.
virtual void RemoveFace(Ptr< Face > face)
Remove face from ndn stack (remove callbacks)
static TypeId GetTypeId()
Interface ID.
static const uint16_t ETHERNET_FRAME_TYPE
Ethernet Frame Type of Ndn.
static const uint16_t IP_STACK_PORT
TCP/UDP port for NDN stack.
virtual Ptr< Face > GetFaceByNetDevice(Ptr< NetDevice > netDevice) const
Get face for NetDevice.
virtual void OnData(Ptr< Face > face, Ptr< Data > data)
Actual processing of incoming Ndn content objects.
L3Protocol()
Default constructor.
virtual void NotifyNewAggregate()
This function will notify other components connected to the node that a new stack member is now conne...
virtual void DoDispose(void)
Do cleanup.
virtual Ptr< Face > GetFaceById(uint32_t face) const
Get face by face ID.