blob: d6983569eb38afd0d28dc6a1acf44031c4917dab [file] [log] [blame]
Alexander Afanasyevc74a6022011-08-15 20:01:35 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Alexander Afanasyevab1d5602011-08-17 19:17:18 -07002/*
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 */
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070020
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 Afanasyevab1d5602011-08-17 19:17:18 -070075: m_faceCounter (0)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070076{
77 NS_LOG_FUNCTION (this);
78}
79
80CcnxL3Protocol::~CcnxL3Protocol ()
81{
82 NS_LOG_FUNCTION (this);
83}
84
85void
86CcnxL3Protocol::SetNode (Ptr<Node> node)
87{
88 m_node = node;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070089}
90
91/*
92 * This method is called by AddAgregate and completes the aggregation
93 * by setting the node in the ccnx stack
94 */
95void
96CcnxL3Protocol::NotifyNewAggregate ()
97{
98 if (m_node == 0)
99 {
100 Ptr<Node>node = this->GetObject<Node>();
101 // verify that it's a valid node and that
102 // the node has not been set before
103 if (node != 0)
104 {
105 this->SetNode (node);
106 }
107 }
108 Object::NotifyNewAggregate ();
109}
110
Alexander Afanasyev98256102011-08-14 01:00:02 -0700111void
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700112CcnxL3Protocol::SetForwardingStrategy (Ptr<CcnxForwardingStrategy> forwardingStrategy)
Alexander Afanasyev98256102011-08-14 01:00:02 -0700113{
114 NS_LOG_FUNCTION (this);
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700115 m_forwardingStrategy = forwardingStrategy;
116 m_forwardingStrategy->SetCcnx (this);
Alexander Afanasyev98256102011-08-14 01:00:02 -0700117}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700118
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700119Ptr<CcnxForwardingStrategy>
120CcnxL3Protocol::GetForwardingStrategy (void) const
Alexander Afanasyev98256102011-08-14 01:00:02 -0700121{
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700122 return m_forwardingStrategy;
Alexander Afanasyev98256102011-08-14 01:00:02 -0700123}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700124
125void
126CcnxL3Protocol::DoDispose (void)
127{
128 NS_LOG_FUNCTION (this);
129
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700130 for (CcnxFaceList::iterator i = m_faces.begin (); i != m_faces.end (); ++i)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700131 {
132 *i = 0;
133 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700134 m_faces.clear ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700135 m_node = 0;
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700136 // m_forwardingStrategy = 0;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700137 Object::DoDispose ();
138}
139
140uint32_t
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700141CcnxL3Protocol::AddFace (const Ptr<CcnxFace> &face)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700142{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700143 NS_LOG_FUNCTION (this << *face);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700144
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700145 face->SetNode (m_node);
Alexander Afanasyevab1d5602011-08-17 19:17:18 -0700146 face->SetId (m_faceCounter); // sets a unique ID of the face. This ID serves only informational purposes
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700147
Alexander Afanasyevab1d5602011-08-17 19:17:18 -0700148 face->RegisterProtocolHandler (MakeCallback (&CcnxL3Protocol::ReceiveFromLower, this));
149 // if (face->GetDevice() != 0)
150 // {
151 // m_node->RegisterProtocolHandler (MakeCallback (&CcnxL3Protocol::ReceiveFromLower, this),
152 // CcnxL3Protocol::ETHERNET_FRAME_TYPE, face->GetDevice(), true/*promiscuous mode*/);
153 // }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700154
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700155 m_faces.push_back (face);
Alexander Afanasyevab1d5602011-08-17 19:17:18 -0700156 m_faceCounter ++;
157 return m_faceCounter;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700158}
159
Alexander Afanasyev98256102011-08-14 01:00:02 -0700160
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700161Ptr<CcnxFace>
Alexander Afanasyev98256102011-08-14 01:00:02 -0700162CcnxL3Protocol::GetFace (uint32_t index) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700163{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700164 if (index < m_faces.size ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700165 {
Alexander Afanasyev98256102011-08-14 01:00:02 -0700166 return m_faces[index];
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700167 }
168 return 0;
169}
170
171uint32_t
Alexander Afanasyev98256102011-08-14 01:00:02 -0700172CcnxL3Protocol::GetNFaces (void) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700173{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700174 return m_faces.size ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700175}
176
Alexander Afanasyev98256102011-08-14 01:00:02 -0700177Ptr<CcnxFace>
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700178CcnxL3Protocol::GetFaceForDevice (Ptr<const NetDevice> device) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700179{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700180 for (CcnxFaceList::const_iterator i = m_faces.begin ();
Alexander Afanasyev98256102011-08-14 01:00:02 -0700181 i != m_faces.end ();
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700182 i++)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700183 {
184 if ((*i)->GetDevice () == device)
185 {
Alexander Afanasyev98256102011-08-14 01:00:02 -0700186 return *i;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700187 }
188 }
189
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700190 NS_ASSERT_MSG (false, "Should never get to this place" );
Alexander Afanasyev98256102011-08-14 01:00:02 -0700191 return 0;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700192}
193
Alexander Afanasyev98256102011-08-14 01:00:02 -0700194// Callback from lower layer
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700195void
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700196CcnxL3Protocol::ReceiveFromLower ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700197 const Address &to, NetDevice::PacketType packetType)
198{
199 NS_LOG_FUNCTION (this << &device << p << protocol << from);
200
Alexander Afanasyev98256102011-08-14 01:00:02 -0700201 NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700202
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700203 Ptr<CcnxFace> ccnxFace = GetFaceForDevice (device);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700204
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700205 Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700206 try
207 {
208 Ptr<Header> header = CcnxHeaderHelper::CreateCorrectCcnxHeader (p);
209 ReceiveAndProcess (ccnxFace, header, packet); // header should serve as overloaded method selector... not sure whether it works with this "smart" pointers...
210 }
211 catch (CcnxUnknownHeaderException)
212 {
213 NS_ASSERT_MSG (false, "Unknown CCNx header. Should not happen");
214 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700215}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700216
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700217// Processing Interests
218void CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> incomingFace, Ptr<CcnxInterestHeader> header, Ptr<Packet> packet)
Alexander Afanasyev98256102011-08-14 01:00:02 -0700219{
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700220 if (incomingFace->IsUp ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700221 {
Alexander Afanasyev98256102011-08-14 01:00:02 -0700222 NS_LOG_LOGIC ("Dropping received packet -- interface is down");
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700223 // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700224 return;
225 }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700226
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700227 NS_LOG_LOGIC ("Receiving interest from " << incomingFace);
228 // m_rxTrace (packet, m_node->GetObject<Ccnx> (), incomingFace);
229
230 // NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
231 // if (!m_forwardingStrategy->RouteInput (packet, incomingFace,
232 // MakeCallback (&CcnxL3Protocol::Send, this),
233 // MakeCallback (&CcnxL3Protocol::RouteInputError, this)
234 // ))
235 // {
236 // NS_LOG_WARN ("No route found for forwarding packet. Drop.");
237 // m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), incomingFace);
238 // }
239}
240
241// Processing ContentObjects
242void CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> incomingFace, Ptr<CcnxContentObjectHeader> header, Ptr<Packet> packet)
243{
244 if (incomingFace->IsUp ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700245 {
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700246 NS_LOG_LOGIC ("Dropping received packet -- interface is down");
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700247 // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700248 return;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700249 }
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700250
251 NS_LOG_LOGIC ("Receiving contentObject from " << incomingFace);
252}
253
254// fake method
255void
256CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<Header> header, Ptr<Packet> p)
257{
258 NS_ASSERT_MSG (false, "This function should never be called");
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700259}
260
261
262void
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700263CcnxL3Protocol::Send (Ptr<Packet> packet, const Ptr<CcnxFace> &face)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700264{
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700265 // NS_LOG_FUNCTION (this << "packet: " << packet << ", route: "<< route);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700266
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700267 // if (route == 0)
268 // {
269 // NS_LOG_WARN ("No route to host. Drop.");
270 // // m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), 0);
271 // return;
272 // }
273 // Ptr<CcnxFace> outFace = route->GetOutputFace ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700274
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700275 // if (outFace->IsUp ())
276 // {
277 // NS_LOG_LOGIC ("Sending via face " << *outFace);
278 // // m_txTrace (packet, m_node->GetObject<Ccnx> (), outFace);
279 // outFace->Send (packet);
280 // }
281 // else
282 // {
283 // NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << *outFace);
284 // // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), outFace);
285 // }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700286}
287
288
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700289void
290CcnxL3Protocol::SetMetric (uint32_t i, uint16_t metric)
291{
292 NS_LOG_FUNCTION (this << i << metric);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700293 Ptr<CcnxFace> face = GetFace (i);
294 face->SetMetric (metric);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700295}
296
297uint16_t
298CcnxL3Protocol::GetMetric (uint32_t i) const
299{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700300 Ptr<const CcnxFace> face = GetFace (i);
301 return face->GetMetric ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700302}
303
304uint16_t
305CcnxL3Protocol::GetMtu (uint32_t i) const
306{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700307 Ptr<CcnxFace> face = GetFace (i);
308 return face->GetDevice ()->GetMtu ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700309}
310
311bool
312CcnxL3Protocol::IsUp (uint32_t i) const
313{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700314 Ptr<CcnxFace> interface = GetFace (i);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700315 return interface->IsUp ();
316}
317
318void
319CcnxL3Protocol::SetUp (uint32_t i)
320{
321 NS_LOG_FUNCTION (this << i);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700322 Ptr<CcnxFace> interface = GetFace (i);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700323 interface->SetUp ();
324
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700325 if (m_forwardingStrategy != 0)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700326 {
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700327 m_forwardingStrategy->NotifyInterfaceUp (i);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700328 }
329}
330
331void
332CcnxL3Protocol::SetDown (uint32_t ifaceIndex)
333{
334 NS_LOG_FUNCTION (this << ifaceIndex);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700335 Ptr<CcnxFace> interface = GetFace (ifaceIndex);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700336 interface->SetDown ();
337
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700338 if (m_forwardingStrategy != 0)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700339 {
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700340 m_forwardingStrategy->NotifyInterfaceDown (ifaceIndex);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700341 }
342}
343
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700344} //namespace ns3