blob: ff3f926c1ef9bd47235531cad3a32756041b904f [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 Afanasyev56f79ea2011-08-17 23:54:27 -070041#include <boost/foreach.hpp>
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070042
43NS_LOG_COMPONENT_DEFINE ("CcnxL3Protocol");
44
45namespace ns3 {
46
Alexander Afanasyev7112f482011-08-17 14:05:57 -070047const uint16_t CcnxL3Protocol::ETHERNET_FRAME_TYPE = 0x7777;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070048
49NS_OBJECT_ENSURE_REGISTERED (CcnxL3Protocol);
50
51TypeId
52CcnxL3Protocol::GetTypeId (void)
53{
54 static TypeId tid = TypeId ("ns3::CcnxL3Protocol")
55 .SetParent<Ccnx> ()
56 .AddConstructor<CcnxL3Protocol> ()
Alexander Afanasyev7112f482011-08-17 14:05:57 -070057 // .AddTraceSource ("Tx", "Send ccnx packet to outgoing interface.",
58 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_txTrace))
59 // .AddTraceSource ("Rx", "Receive ccnx packet from incoming interface.",
60 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_rxTrace))
61 // .AddTraceSource ("Drop", "Drop ccnx packet",
62 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_dropTrace))
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070063 .AddAttribute ("InterfaceList", "The set of Ccnx interfaces associated to this Ccnx stack.",
64 ObjectVectorValue (),
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070065 MakeObjectVectorAccessor (&CcnxL3Protocol::m_faces),
66 MakeObjectVectorChecker<CcnxFace> ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070067
Alexander Afanasyev7112f482011-08-17 14:05:57 -070068 // .AddTraceSource ("SendOutgoing", "A newly-generated packet by this node is about to be queued for transmission",
69 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_sendOutgoingTrace))
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070070
71 ;
72 return tid;
73}
74
75CcnxL3Protocol::CcnxL3Protocol()
Alexander Afanasyevab1d5602011-08-17 19:17:18 -070076: m_faceCounter (0)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070077{
78 NS_LOG_FUNCTION (this);
79}
80
81CcnxL3Protocol::~CcnxL3Protocol ()
82{
83 NS_LOG_FUNCTION (this);
84}
85
86void
87CcnxL3Protocol::SetNode (Ptr<Node> node)
88{
89 m_node = node;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070090}
91
92/*
93 * This method is called by AddAgregate and completes the aggregation
94 * by setting the node in the ccnx stack
95 */
96void
97CcnxL3Protocol::NotifyNewAggregate ()
98{
99 if (m_node == 0)
100 {
101 Ptr<Node>node = this->GetObject<Node>();
102 // verify that it's a valid node and that
103 // the node has not been set before
104 if (node != 0)
105 {
106 this->SetNode (node);
107 }
108 }
109 Object::NotifyNewAggregate ();
110}
111
Alexander Afanasyev98256102011-08-14 01:00:02 -0700112void
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700113CcnxL3Protocol::SetForwardingStrategy (Ptr<CcnxForwardingStrategy> forwardingStrategy)
Alexander Afanasyev98256102011-08-14 01:00:02 -0700114{
115 NS_LOG_FUNCTION (this);
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700116 m_forwardingStrategy = forwardingStrategy;
117 m_forwardingStrategy->SetCcnx (this);
Alexander Afanasyev98256102011-08-14 01:00:02 -0700118}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700119
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700120Ptr<CcnxForwardingStrategy>
121CcnxL3Protocol::GetForwardingStrategy (void) const
Alexander Afanasyev98256102011-08-14 01:00:02 -0700122{
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700123 return m_forwardingStrategy;
Alexander Afanasyev98256102011-08-14 01:00:02 -0700124}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700125
126void
127CcnxL3Protocol::DoDispose (void)
128{
129 NS_LOG_FUNCTION (this);
130
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700131 for (CcnxFaceList::iterator i = m_faces.begin (); i != m_faces.end (); ++i)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700132 {
133 *i = 0;
134 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700135 m_faces.clear ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700136 m_node = 0;
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700137 // m_forwardingStrategy = 0;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700138 Object::DoDispose ();
139}
140
141uint32_t
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700142CcnxL3Protocol::AddFace (const Ptr<CcnxFace> &face)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700143{
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700144 NS_LOG_FUNCTION (this << &face);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700145
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700146 face->SetNode (m_node);
Alexander Afanasyevab1d5602011-08-17 19:17:18 -0700147 face->SetId (m_faceCounter); // sets a unique ID of the face. This ID serves only informational purposes
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700148
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700149 face->RegisterProtocolHandler (MakeCallback (&CcnxL3Protocol::Receive, this));
Alexander Afanasyevab1d5602011-08-17 19:17:18 -0700150 // if (face->GetDevice() != 0)
151 // {
152 // m_node->RegisterProtocolHandler (MakeCallback (&CcnxL3Protocol::ReceiveFromLower, this),
153 // CcnxL3Protocol::ETHERNET_FRAME_TYPE, face->GetDevice(), true/*promiscuous mode*/);
154 // }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700155
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700156 m_faces.push_back (face);
Alexander Afanasyevab1d5602011-08-17 19:17:18 -0700157 m_faceCounter ++;
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700158 return face->GetId ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700159}
160
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 Afanasyev56f79ea2011-08-17 23:54:27 -0700164 BOOST_FOREACH (const Ptr<CcnxFace> &face, m_faces) // this function is not supposed to be called often, so linear search is fine
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700165 {
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700166 if (face->GetId () == index)
167 return face;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700168 }
169 return 0;
170}
171
172uint32_t
Alexander Afanasyev98256102011-08-14 01:00:02 -0700173CcnxL3Protocol::GetNFaces (void) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700174{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700175 return m_faces.size ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700176}
177
Alexander Afanasyev98256102011-08-14 01:00:02 -0700178// Callback from lower layer
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700179void
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700180CcnxL3Protocol::Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700181{
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700182 NS_LOG_LOGIC ("Packet from face " << &face << " received on node " << m_node->GetId ());
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700183
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700184 Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700185 try
186 {
187 Ptr<Header> header = CcnxHeaderHelper::CreateCorrectCcnxHeader (p);
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700188 ReceiveAndProcess (face, header, packet); // header should serve as overloaded method selector... not sure whether it works with this "smart" pointers...
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700189 }
190 catch (CcnxUnknownHeaderException)
191 {
192 NS_ASSERT_MSG (false, "Unknown CCNx header. Should not happen");
193 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700194}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700195
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700196// Processing Interests
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700197void CcnxL3Protocol::ReceiveAndProcess (const Ptr<CcnxFace> &incomingFace,
198 const Ptr<CcnxInterestHeader> &header,
199 const Ptr<Packet> &packet)
Alexander Afanasyev98256102011-08-14 01:00:02 -0700200{
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700201 if (incomingFace->IsUp ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700202 {
Alexander Afanasyev98256102011-08-14 01:00:02 -0700203 NS_LOG_LOGIC ("Dropping received packet -- interface is down");
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700204 // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700205 return;
206 }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700207
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700208 NS_LOG_LOGIC ("Receiving interest from " << incomingFace);
209 // m_rxTrace (packet, m_node->GetObject<Ccnx> (), incomingFace);
210
211 // NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
212 // if (!m_forwardingStrategy->RouteInput (packet, incomingFace,
213 // MakeCallback (&CcnxL3Protocol::Send, this),
214 // MakeCallback (&CcnxL3Protocol::RouteInputError, this)
215 // ))
216 // {
217 // NS_LOG_WARN ("No route found for forwarding packet. Drop.");
218 // m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), incomingFace);
219 // }
220}
221
222// Processing ContentObjects
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700223void CcnxL3Protocol::ReceiveAndProcess (const Ptr<CcnxFace> &incomingFace,
224 const Ptr<CcnxContentObjectHeader> &header,
225 const Ptr<Packet> &packet)
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700226{
227 if (incomingFace->IsUp ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700228 {
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700229 NS_LOG_LOGIC ("Dropping received packet -- interface is down");
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700230 // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700231 return;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700232 }
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700233
234 NS_LOG_LOGIC ("Receiving contentObject from " << incomingFace);
235}
236
237// fake method
238void
239CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<Header> header, Ptr<Packet> p)
240{
241 NS_ASSERT_MSG (false, "This function should never be called");
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700242}
243
244
245void
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700246CcnxL3Protocol::Send (const Ptr<CcnxFace> &face, const Ptr<Packet> &packet)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700247{
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700248 // NS_LOG_FUNCTION (this << "packet: " << packet << ", route: "<< route);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700249
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700250 // if (route == 0)
251 // {
252 // NS_LOG_WARN ("No route to host. Drop.");
253 // // m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), 0);
254 // return;
255 // }
256 // Ptr<CcnxFace> outFace = route->GetOutputFace ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700257
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700258 // if (outFace->IsUp ())
259 // {
260 // NS_LOG_LOGIC ("Sending via face " << *outFace);
261 // // m_txTrace (packet, m_node->GetObject<Ccnx> (), outFace);
262 // outFace->Send (packet);
263 // }
264 // else
265 // {
266 // NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << *outFace);
267 // // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), outFace);
268 // }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700269}
270
271
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700272} //namespace ns3