blob: 8b7cccd11d4f2043e94e0f08635bf812eb9fe938 [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"
Alexander Afanasyev070aa482011-08-20 00:38:25 -070040#include "ccnx-content-store.h"
Alexander Afanasyevc74a6022011-08-15 20:01:35 -070041
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -070042#include <boost/foreach.hpp>
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070043
44NS_LOG_COMPONENT_DEFINE ("CcnxL3Protocol");
45
46namespace ns3 {
47
Alexander Afanasyev7112f482011-08-17 14:05:57 -070048const uint16_t CcnxL3Protocol::ETHERNET_FRAME_TYPE = 0x7777;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070049
50NS_OBJECT_ENSURE_REGISTERED (CcnxL3Protocol);
51
52TypeId
53CcnxL3Protocol::GetTypeId (void)
54{
55 static TypeId tid = TypeId ("ns3::CcnxL3Protocol")
56 .SetParent<Ccnx> ()
Alexander Afanasyev070aa482011-08-20 00:38:25 -070057 .SetGroupName ("Ccnx")
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070058 .AddConstructor<CcnxL3Protocol> ()
Alexander Afanasyev7112f482011-08-17 14:05:57 -070059 // .AddTraceSource ("Tx", "Send ccnx packet to outgoing interface.",
60 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_txTrace))
61 // .AddTraceSource ("Rx", "Receive ccnx packet from incoming interface.",
62 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_rxTrace))
63 // .AddTraceSource ("Drop", "Drop ccnx packet",
64 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_dropTrace))
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070065 .AddAttribute ("InterfaceList", "The set of Ccnx interfaces associated to this Ccnx stack.",
66 ObjectVectorValue (),
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070067 MakeObjectVectorAccessor (&CcnxL3Protocol::m_faces),
68 MakeObjectVectorChecker<CcnxFace> ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070069
Alexander Afanasyev7112f482011-08-17 14:05:57 -070070 // .AddTraceSource ("SendOutgoing", "A newly-generated packet by this node is about to be queued for transmission",
71 // MakeTraceSourceAccessor (&CcnxL3Protocol::m_sendOutgoingTrace))
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070072
73 ;
74 return tid;
75}
76
77CcnxL3Protocol::CcnxL3Protocol()
Alexander Afanasyevab1d5602011-08-17 19:17:18 -070078: m_faceCounter (0)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070079{
80 NS_LOG_FUNCTION (this);
81}
82
83CcnxL3Protocol::~CcnxL3Protocol ()
84{
85 NS_LOG_FUNCTION (this);
86}
87
88void
89CcnxL3Protocol::SetNode (Ptr<Node> node)
90{
91 m_node = node;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070092}
93
94/*
95 * This method is called by AddAgregate and completes the aggregation
96 * by setting the node in the ccnx stack
97 */
98void
99CcnxL3Protocol::NotifyNewAggregate ()
100{
101 if (m_node == 0)
102 {
103 Ptr<Node>node = this->GetObject<Node>();
104 // verify that it's a valid node and that
105 // the node has not been set before
106 if (node != 0)
107 {
108 this->SetNode (node);
109 }
110 }
111 Object::NotifyNewAggregate ();
112}
113
Alexander Afanasyev98256102011-08-14 01:00:02 -0700114void
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700115CcnxL3Protocol::SetForwardingStrategy (Ptr<CcnxForwardingStrategy> forwardingStrategy)
Alexander Afanasyev98256102011-08-14 01:00:02 -0700116{
117 NS_LOG_FUNCTION (this);
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700118 m_forwardingStrategy = forwardingStrategy;
119 m_forwardingStrategy->SetCcnx (this);
Alexander Afanasyev98256102011-08-14 01:00:02 -0700120}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700121
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700122Ptr<CcnxForwardingStrategy>
123CcnxL3Protocol::GetForwardingStrategy (void) const
Alexander Afanasyev98256102011-08-14 01:00:02 -0700124{
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700125 return m_forwardingStrategy;
Alexander Afanasyev98256102011-08-14 01:00:02 -0700126}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700127
128void
129CcnxL3Protocol::DoDispose (void)
130{
131 NS_LOG_FUNCTION (this);
132
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700133 for (CcnxFaceList::iterator i = m_faces.begin (); i != m_faces.end (); ++i)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700134 {
135 *i = 0;
136 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700137 m_faces.clear ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700138 m_node = 0;
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700139 // m_forwardingStrategy = 0;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700140 Object::DoDispose ();
141}
142
143uint32_t
Alexander Afanasyev7112f482011-08-17 14:05:57 -0700144CcnxL3Protocol::AddFace (const Ptr<CcnxFace> &face)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700145{
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700146 NS_LOG_FUNCTION (this << &face);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700147
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700148 face->SetNode (m_node);
Alexander Afanasyevab1d5602011-08-17 19:17:18 -0700149 face->SetId (m_faceCounter); // sets a unique ID of the face. This ID serves only informational purposes
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700150
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700151 face->RegisterProtocolHandler (MakeCallback (&CcnxL3Protocol::Receive, this));
Alexander Afanasyevab1d5602011-08-17 19:17:18 -0700152 // if (face->GetDevice() != 0)
153 // {
154 // m_node->RegisterProtocolHandler (MakeCallback (&CcnxL3Protocol::ReceiveFromLower, this),
155 // CcnxL3Protocol::ETHERNET_FRAME_TYPE, face->GetDevice(), true/*promiscuous mode*/);
156 // }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700157
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700158 m_faces.push_back (face);
Alexander Afanasyevab1d5602011-08-17 19:17:18 -0700159 m_faceCounter ++;
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700160 return face->GetId ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700161}
162
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700163Ptr<CcnxFace>
Alexander Afanasyev98256102011-08-14 01:00:02 -0700164CcnxL3Protocol::GetFace (uint32_t index) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700165{
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700166 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 -0700167 {
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700168 if (face->GetId () == index)
169 return face;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700170 }
171 return 0;
172}
173
174uint32_t
Alexander Afanasyev98256102011-08-14 01:00:02 -0700175CcnxL3Protocol::GetNFaces (void) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700176{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700177 return m_faces.size ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700178}
179
Alexander Afanasyev98256102011-08-14 01:00:02 -0700180// Callback from lower layer
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700181void
Alexander Afanasyev0ab833e2011-08-18 15:49:13 -0700182CcnxL3Protocol::Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700183{
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700184 if (face->IsUp ())
185 {
186 NS_LOG_LOGIC ("Dropping received packet -- interface is down");
187 // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
188 return;
189 }
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700190 NS_LOG_LOGIC ("Packet from face " << &face << " received on node " << m_node->GetId ());
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700191
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700192 Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700193 try
194 {
195 Ptr<Header> header = CcnxHeaderHelper::CreateCorrectCcnxHeader (p);
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700196 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 -0700197 }
198 catch (CcnxUnknownHeaderException)
199 {
200 NS_ASSERT_MSG (false, "Unknown CCNx header. Should not happen");
201 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700202}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700203
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700204// Processing Interests
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700205void CcnxL3Protocol::ReceiveAndProcess (const Ptr<CcnxFace> &incomingFace,
206 const Ptr<CcnxInterestHeader> &header,
207 const Ptr<Packet> &packet)
Alexander Afanasyev98256102011-08-14 01:00:02 -0700208{
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700209 NS_LOG_LOGIC ("Receiving interest from " << &incomingFace);
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700210 // m_rxTrace (packet, m_node->GetObject<Ccnx> (), incomingFace);
211
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700212 /// \todo Processing of Interest packets
213
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700214 // NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
215 // if (!m_forwardingStrategy->RouteInput (packet, incomingFace,
216 // MakeCallback (&CcnxL3Protocol::Send, this),
217 // MakeCallback (&CcnxL3Protocol::RouteInputError, this)
218 // ))
219 // {
220 // NS_LOG_WARN ("No route found for forwarding packet. Drop.");
221 // m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), incomingFace);
222 // }
223}
224
225// Processing ContentObjects
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700226void CcnxL3Protocol::ReceiveAndProcess (const Ptr<CcnxFace> &incomingFace,
227 const Ptr<CcnxContentObjectHeader> &header,
228 const Ptr<Packet> &packet)
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700229{
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700230 NS_LOG_LOGIC ("Receiving contentObject from " << &incomingFace);
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700231
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700232 /// \todo Processing of ContentObject packets
Alexander Afanasyevc74a6022011-08-15 20:01:35 -0700233}
234
235// fake method
236void
237CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<Header> header, Ptr<Packet> p)
238{
239 NS_ASSERT_MSG (false, "This function should never be called");
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700240}
241
242
243void
Alexander Afanasyev56f79ea2011-08-17 23:54:27 -0700244CcnxL3Protocol::Send (const Ptr<CcnxFace> &face, const Ptr<Packet> &packet)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700245{
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700246 NS_LOG_FUNCTION (this << "packet: " << &packet << ", face: "<< &face); //
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700247
Alexander Afanasyev070aa482011-08-20 00:38:25 -0700248 NS_ASSERT_MSG (face != 0, "Face should never be NULL");
249
250 if (face->IsUp ())
251 {
252 NS_LOG_LOGIC ("Sending via face " << &face); //
253 m_txTrace (packet, m_node->GetObject<Ccnx> (), face);
254 face->Send (packet);
255 }
256 else
257 {
258 NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << &face);
259 m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), face);
260 }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700261}
262
263
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700264} //namespace ns3