blob: 2a13f4c9641ae7034c15778a9924bbba37befb10 [file] [log] [blame]
Alexander Afanasyevc74a6022011-08-15 20:01:35 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Alexander Afanasyev08d984e2011-08-13 19:20:22 -07002//
3// Copyright (c) 2006 Georgia Tech Research Corporation
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//
Alexander Afanasyev98256102011-08-14 01:00:02 -070018// Author:
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070019//
20
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070021#include "ccnx-l3-protocol.h"
22
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070023#include "ns3/packet.h"
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070024#include "ns3/net-device.h"
25#include "ns3/node.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070026#include "ns3/log.h"
27#include "ns3/callback.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070028#include "ns3/uinteger.h"
29#include "ns3/trace-source-accessor.h"
30#include "ns3/object-vector.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070031#include "ns3/boolean.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070032
Alexander Afanasyevc74a6022011-08-15 20:01:35 -070033#include "ns3/ccnx-header-helper.h"
34
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070035#include "ccnx-face.h"
36#include "ccnx-route.h"
Alexander Afanasyevc74a6022011-08-15 20:01:35 -070037#include "ccnx-forwarding-strategy.h"
38#include "ccnx-interest-header.h"
39#include "ccnx-content-object-header.h"
40
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070041
42NS_LOG_COMPONENT_DEFINE ("CcnxL3Protocol");
43
44namespace ns3 {
45
Alexander Afanasyev7112f482011-08-17 14:05:57 -070046const uint16_t CcnxL3Protocol::ETHERNET_FRAME_TYPE = 0x7777;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070047
48NS_OBJECT_ENSURE_REGISTERED (CcnxL3Protocol);
49
50TypeId
51CcnxL3Protocol::GetTypeId (void)
52{
53 static TypeId tid = TypeId ("ns3::CcnxL3Protocol")
54 .SetParent<Ccnx> ()
55 .AddConstructor<CcnxL3Protocol> ()
Alexander Afanasyev7112f482011-08-17 14:05:57 -070056 // .AddTraceSource ("Tx", "Send ccnx packet to outgoing interface.",
57 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_txTrace))
58 // .AddTraceSource ("Rx", "Receive ccnx packet from incoming interface.",
59 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_rxTrace))
60 // .AddTraceSource ("Drop", "Drop ccnx packet",
61 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_dropTrace))
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070062 .AddAttribute ("InterfaceList", "The set of Ccnx interfaces associated to this Ccnx stack.",
63 ObjectVectorValue (),
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070064 MakeObjectVectorAccessor (&CcnxL3Protocol::m_faces),
65 MakeObjectVectorChecker<CcnxFace> ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070066
Alexander Afanasyev7112f482011-08-17 14:05:57 -070067 // .AddTraceSource ("SendOutgoing", "A newly-generated packet by this node is about to be queued for transmission",
68 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_sendOutgoingTrace))
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070069
70 ;
71 return tid;
72}
73
74CcnxL3Protocol::CcnxL3Protocol()
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070075{
76 NS_LOG_FUNCTION (this);
77}
78
79CcnxL3Protocol::~CcnxL3Protocol ()
80{
81 NS_LOG_FUNCTION (this);
82}
83
84void
85CcnxL3Protocol::SetNode (Ptr<Node> node)
86{
87 m_node = node;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070088}
89
90/*
91 * This method is called by AddAgregate and completes the aggregation
92 * by setting the node in the ccnx stack
93 */
94void
95CcnxL3Protocol::NotifyNewAggregate ()
96{
97 if (m_node == 0)
98 {
99 Ptr<Node>node = this->GetObject<Node>();
100 // verify that it's a valid node and that
101 // the node has not been set before
102 if (node != 0)
103 {
104 this->SetNode (node);
105 }
106 }
107 Object::NotifyNewAggregate ();
108}
109
Alexander Afanasyev98256102011-08-14 01:00:02 -0700110void
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700111CcnxL3Protocol::SetForwardingStrategy (Ptr<CcnxForwardingStrategy> forwardingStrategy)
Alexander Afanasyev98256102011-08-14 01:00:02 -0700112{
113 NS_LOG_FUNCTION (this);
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700114 m_forwardingStrategy = forwardingStrategy;
115 m_forwardingStrategy->SetCcnx (this);
Alexander Afanasyev98256102011-08-14 01:00:02 -0700116}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700117
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700118Ptr<CcnxForwardingStrategy>
119CcnxL3Protocol::GetForwardingStrategy (void) const
Alexander Afanasyev98256102011-08-14 01:00:02 -0700120{
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700121 return m_forwardingStrategy;
Alexander Afanasyev98256102011-08-14 01:00:02 -0700122}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700123
124void
125CcnxL3Protocol::DoDispose (void)
126{
127 NS_LOG_FUNCTION (this);
128
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700129 for (CcnxFaceList::iterator i = m_faces.begin (); i != m_faces.end (); ++i)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700130 {
131 *i = 0;
132 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700133 m_faces.clear ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700134 m_node = 0;
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700135 // m_forwardingStrategy = 0;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700136 Object::DoDispose ();
137}
138
139uint32_t
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700140CcnxL3Protocol::AddFace (const Ptr<CcnxFace> &face)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700141{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700142 NS_LOG_FUNCTION (this << *face);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700143
Alexander Afanasyev98256102011-08-14 01:00:02 -0700144 // Ptr<Node> node = GetObject<Node> (); ///< \todo not sure why this thing should be called...
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700145 face->SetNode (m_node);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700146
Alexander Afanasyev98256102011-08-14 01:00:02 -0700147 if (face->GetDevice() != 0)
148 {
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700149 m_node->RegisterProtocolHandler (MakeCallback (&CcnxL3Protocol::ReceiveFromLower, this),
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700150 CcnxL3Protocol::ETHERNET_FRAME_TYPE, face->GetDevice(), true/*promiscuous mode*/);
Alexander Afanasyev98256102011-08-14 01:00:02 -0700151 }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700152
Alexander Afanasyev98256102011-08-14 01:00:02 -0700153 uint32_t index = m_faces.size ();
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700154 m_faces.push_back (face);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700155 return index;
156}
157
Alexander Afanasyev98256102011-08-14 01:00:02 -0700158
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700159Ptr<CcnxFace>
Alexander Afanasyev98256102011-08-14 01:00:02 -0700160CcnxL3Protocol::GetFace (uint32_t index) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700161{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700162 if (index < m_faces.size ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700163 {
Alexander Afanasyev98256102011-08-14 01:00:02 -0700164 return m_faces[index];
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700165 }
166 return 0;
167}
168
169uint32_t
Alexander Afanasyev98256102011-08-14 01:00:02 -0700170CcnxL3Protocol::GetNFaces (void) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700171{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700172 return m_faces.size ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700173}
174
Alexander Afanasyev98256102011-08-14 01:00:02 -0700175Ptr<CcnxFace>
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700176CcnxL3Protocol::GetFaceForDevice (Ptr<const NetDevice> device) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700177{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700178 for (CcnxFaceList::const_iterator i = m_faces.begin ();
Alexander Afanasyev98256102011-08-14 01:00:02 -0700179 i != m_faces.end ();
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700180 i++)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700181 {
182 if ((*i)->GetDevice () == device)
183 {
Alexander Afanasyev98256102011-08-14 01:00:02 -0700184 return *i;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700185 }
186 }
187
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700188 NS_ASSERT_MSG (false, "Should never get to this place" );
Alexander Afanasyev98256102011-08-14 01:00:02 -0700189 return 0;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700190}
191
Alexander Afanasyev98256102011-08-14 01:00:02 -0700192// Callback from lower layer
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700193void
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700194CcnxL3Protocol::ReceiveFromLower ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700195 const Address &to, NetDevice::PacketType packetType)
196{
197 NS_LOG_FUNCTION (this << &device << p << protocol << from);
198
Alexander Afanasyev98256102011-08-14 01:00:02 -0700199 NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700200
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700201 Ptr<CcnxFace> ccnxFace = GetFaceForDevice (device);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700202
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700203 Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700204 try
205 {
206 Ptr<Header> header = CcnxHeaderHelper::CreateCorrectCcnxHeader (p);
207 ReceiveAndProcess (ccnxFace, header, packet); // header should serve as overloaded method selector... not sure whether it works with this "smart" pointers...
208 }
209 catch (CcnxUnknownHeaderException)
210 {
211 NS_ASSERT_MSG (false, "Unknown CCNx header. Should not happen");
212 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700213}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700214
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700215// Processing Interests
216void CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> incomingFace, Ptr<CcnxInterestHeader> header, Ptr<Packet> packet)
Alexander Afanasyev98256102011-08-14 01:00:02 -0700217{
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700218 if (incomingFace->IsUp ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700219 {
Alexander Afanasyev98256102011-08-14 01:00:02 -0700220 NS_LOG_LOGIC ("Dropping received packet -- interface is down");
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700221 // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700222 return;
223 }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700224
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700225 NS_LOG_LOGIC ("Receiving interest from " << incomingFace);
226 // m_rxTrace (packet, m_node->GetObject<Ccnx> (), incomingFace);
227
228 // NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
229 // if (!m_forwardingStrategy->RouteInput (packet, incomingFace,
230 // MakeCallback (&CcnxL3Protocol::Send, this),
231 // MakeCallback (&CcnxL3Protocol::RouteInputError, this)
232 // ))
233 // {
234 // NS_LOG_WARN ("No route found for forwarding packet. Drop.");
235 // m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), incomingFace);
236 // }
237}
238
239// Processing ContentObjects
240void CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> incomingFace, Ptr<CcnxContentObjectHeader> header, Ptr<Packet> packet)
241{
242 if (incomingFace->IsUp ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700243 {
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700244 NS_LOG_LOGIC ("Dropping received packet -- interface is down");
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700245 // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700246 return;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700247 }
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700248
249 NS_LOG_LOGIC ("Receiving contentObject from " << incomingFace);
250}
251
252// fake method
253void
254CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<Header> header, Ptr<Packet> p)
255{
256 NS_ASSERT_MSG (false, "This function should never be called");
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700257}
258
259
260void
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700261CcnxL3Protocol::Send (Ptr<Packet> packet, const Ptr<CcnxFace> &face)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700262{
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700263 // NS_LOG_FUNCTION (this << "packet: " << packet << ", route: "<< route);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700264
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700265 // if (route == 0)
266 // {
267 // NS_LOG_WARN ("No route to host. Drop.");
268 // // m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), 0);
269 // return;
270 // }
271 // Ptr<CcnxFace> outFace = route->GetOutputFace ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700272
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700273 // if (outFace->IsUp ())
274 // {
275 // NS_LOG_LOGIC ("Sending via face " << *outFace);
276 // // m_txTrace (packet, m_node->GetObject<Ccnx> (), outFace);
277 // outFace->Send (packet);
278 // }
279 // else
280 // {
281 // NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << *outFace);
282 // // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), outFace);
283 // }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700284}
285
286
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700287void
288CcnxL3Protocol::SetMetric (uint32_t i, uint16_t metric)
289{
290 NS_LOG_FUNCTION (this << i << metric);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700291 Ptr<CcnxFace> face = GetFace (i);
292 face->SetMetric (metric);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700293}
294
295uint16_t
296CcnxL3Protocol::GetMetric (uint32_t i) const
297{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700298 Ptr<const CcnxFace> face = GetFace (i);
299 return face->GetMetric ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700300}
301
302uint16_t
303CcnxL3Protocol::GetMtu (uint32_t i) const
304{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700305 Ptr<CcnxFace> face = GetFace (i);
306 return face->GetDevice ()->GetMtu ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700307}
308
309bool
310CcnxL3Protocol::IsUp (uint32_t i) const
311{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700312 Ptr<CcnxFace> interface = GetFace (i);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700313 return interface->IsUp ();
314}
315
316void
317CcnxL3Protocol::SetUp (uint32_t i)
318{
319 NS_LOG_FUNCTION (this << i);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700320 Ptr<CcnxFace> interface = GetFace (i);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700321 interface->SetUp ();
322
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700323 if (m_forwardingStrategy != 0)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700324 {
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700325 m_forwardingStrategy->NotifyInterfaceUp (i);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700326 }
327}
328
329void
330CcnxL3Protocol::SetDown (uint32_t ifaceIndex)
331{
332 NS_LOG_FUNCTION (this << ifaceIndex);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700333 Ptr<CcnxFace> interface = GetFace (ifaceIndex);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700334 interface->SetDown ();
335
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700336 if (m_forwardingStrategy != 0)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700337 {
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700338 m_forwardingStrategy->NotifyInterfaceDown (ifaceIndex);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700339 }
340}
341
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700342} //namespace ns3