blob: bbb5853fdf73506621c6d92aa4e5ae40e4b4c166 [file] [log] [blame]
Alexander Afanasyev08d984e2011-08-13 19:20:22 -07001// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
2//
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
21#include "ns3/packet.h"
22#include "ns3/log.h"
23#include "ns3/callback.h"
24#include "ns3/ccnx-address.h"
25#include "ns3/ccnx-route.h"
26#include "ns3/node.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070027#include "ns3/net-device.h"
28#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"
32//#include "ns3/ccnx-routing-table-entry.h"
33
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070034#include "ccnx-l3-protocol.h"
35#include "ccnx-interface.h"
36
37NS_LOG_COMPONENT_DEFINE ("CcnxL3Protocol");
38
39namespace ns3 {
40
41const uint16_t CcnxL3Protocol::PROT_NUMBER = 0x7777;
42
43NS_OBJECT_ENSURE_REGISTERED (CcnxL3Protocol);
44
45TypeId
46CcnxL3Protocol::GetTypeId (void)
47{
48 static TypeId tid = TypeId ("ns3::CcnxL3Protocol")
49 .SetParent<Ccnx> ()
50 .AddConstructor<CcnxL3Protocol> ()
51 .AddTraceSource ("Tx", "Send ccnx packet to outgoing interface.",
52 MakeTraceSourceAccessor (&CcnxL3Protocol::m_txTrace))
53 .AddTraceSource ("Rx", "Receive ccnx packet from incoming interface.",
54 MakeTraceSourceAccessor (&CcnxL3Protocol::m_rxTrace))
55 .AddTraceSource ("Drop", "Drop ccnx packet",
56 MakeTraceSourceAccessor (&CcnxL3Protocol::m_dropTrace))
57 .AddAttribute ("InterfaceList", "The set of Ccnx interfaces associated to this Ccnx stack.",
58 ObjectVectorValue (),
59 MakeObjectVectorAccessor (&CcnxL3Protocol::m_interfaces),
60 MakeObjectVectorChecker<CcnxInterface> ())
61
62 .AddTraceSource ("SendOutgoing", "A newly-generated packet by this node is about to be queued for transmission",
63 MakeTraceSourceAccessor (&CcnxL3Protocol::m_sendOutgoingTrace))
64
65 ;
66 return tid;
67}
68
69CcnxL3Protocol::CcnxL3Protocol()
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070070{
71 NS_LOG_FUNCTION (this);
72}
73
74CcnxL3Protocol::~CcnxL3Protocol ()
75{
76 NS_LOG_FUNCTION (this);
77}
78
79void
80CcnxL3Protocol::SetNode (Ptr<Node> node)
81{
82 m_node = node;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070083}
84
85/*
86 * This method is called by AddAgregate and completes the aggregation
87 * by setting the node in the ccnx stack
88 */
89void
90CcnxL3Protocol::NotifyNewAggregate ()
91{
92 if (m_node == 0)
93 {
94 Ptr<Node>node = this->GetObject<Node>();
95 // verify that it's a valid node and that
96 // the node has not been set before
97 if (node != 0)
98 {
99 this->SetNode (node);
100 }
101 }
102 Object::NotifyNewAggregate ();
103}
104
Alexander Afanasyev98256102011-08-14 01:00:02 -0700105void
106CcnxL3Protocol::SetForwardingProtocol (Ptr<CcnxForwardingProtocol> forwardingProtocol)
107{
108 NS_LOG_FUNCTION (this);
109 m_forwardingProtocol = forwardingProtocol;
110 m_forwardingProtocol->SetCcnx (this);
111}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700112
Alexander Afanasyev98256102011-08-14 01:00:02 -0700113Ptr<CcnxForwardingProtocol>
114CcnxL3Protocol::GetForwardingProtocol (void) const
115{
116 return m_forwardingProtocol;
117}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700118
119void
120CcnxL3Protocol::DoDispose (void)
121{
122 NS_LOG_FUNCTION (this);
123
Alexander Afanasyev98256102011-08-14 01:00:02 -0700124 for (CcnxInterfaceList::iterator i = m_faces.begin (); i != m_faces.end (); ++i)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700125 {
126 *i = 0;
127 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700128 m_faces.clear ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700129 m_node = 0;
Alexander Afanasyev98256102011-08-14 01:00:02 -0700130 // m_forwardingProtocol = 0;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700131 Object::DoDispose ();
132}
133
134uint32_t
Alexander Afanasyev98256102011-08-14 01:00:02 -0700135CcnxL3Protocol::AddFace (Ptr<CcnxFace> face)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700136{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700137 NS_LOG_FUNCTION (this << *face);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700138
Alexander Afanasyev98256102011-08-14 01:00:02 -0700139 // Ptr<Node> node = GetObject<Node> (); ///< \todo not sure why this thing should be called...
140 face->setNode (m_node);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700141
Alexander Afanasyev98256102011-08-14 01:00:02 -0700142 if (face->GetDevice() != 0)
143 {
144 m_node->RegisterProtocolHandler (MakeCallback (&CcnxL3Protocol::Receive, this),
145 CcnxL3Protocol::PROT_NUMBER, face->GetDevice(), true/*promiscuous mode*/);
146 }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700147
Alexander Afanasyev98256102011-08-14 01:00:02 -0700148 uint32_t index = m_faces.size ();
149 m_faces.push_back (interface);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700150 return index;
151}
152
Alexander Afanasyev98256102011-08-14 01:00:02 -0700153
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700154Ptr<CcnxInterface>
Alexander Afanasyev98256102011-08-14 01:00:02 -0700155CcnxL3Protocol::GetFace (uint32_t index) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700156{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700157 if (index < m_faces.size ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700158 {
Alexander Afanasyev98256102011-08-14 01:00:02 -0700159 return m_faces[index];
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700160 }
161 return 0;
162}
163
164uint32_t
Alexander Afanasyev98256102011-08-14 01:00:02 -0700165CcnxL3Protocol::GetNFaces (void) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700166{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700167 return m_faces.size ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700168}
169
Alexander Afanasyev98256102011-08-14 01:00:02 -0700170Ptr<CcnxFace>
171GetFaceForDevice (Ptr<const NetDevice> device) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700172{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700173 for (CcnxInterfaceList::const_iterator i = m_faces.begin ();
174 i != m_faces.end ();
175 i++, face++)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700176 {
177 if ((*i)->GetDevice () == device)
178 {
Alexander Afanasyev98256102011-08-14 01:00:02 -0700179 return *i;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700180 }
181 }
182
Alexander Afanasyev98256102011-08-14 01:00:02 -0700183 NS_ASSERT_MSG (false "Should never get to this place" );
184 return 0;
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700185}
186
Alexander Afanasyev98256102011-08-14 01:00:02 -0700187// Callback from lower layer
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700188void
189CcnxL3Protocol::Receive ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
190 const Address &to, NetDevice::PacketType packetType)
191{
192 NS_LOG_FUNCTION (this << &device << p << protocol << from);
193
Alexander Afanasyev98256102011-08-14 01:00:02 -0700194 NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700195
196 uint32_t interface = 0;
197 Ptr<Packet> packet = p->Copy ();
198
Alexander Afanasyev98256102011-08-14 01:00:02 -0700199 Ptr<CcnxFace> ccnxFace = GetFaceFromDevice (device);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700200
Alexander Afanasyev98256102011-08-14 01:00:02 -0700201 Receive (ccnxFace, p);
202}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700203
Alexander Afanasyev98256102011-08-14 01:00:02 -0700204// Callback from higher level
205void Receive (Ptr<CcnxFace> incomingFace, Ptr<const Packet> p)
206{
207 if ( incomingFace->IsUp ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700208 {
Alexander Afanasyev98256102011-08-14 01:00:02 -0700209 NS_LOG_LOGIC ("Dropping received packet -- interface is down");
210 m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700211 return;
212 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700213
214 m_rxTrace (packet, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700215
216 NS_ASSERT_MSG (m_routingProtocol != 0, "Need a routing protocol object to process packets");
Alexander Afanasyev98256102011-08-14 01:00:02 -0700217 if (!m_routingProtocol->RouteInput (packet, incomingFace,
218 MakeCallback (&CcnxL3Protocol::Send, this),
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700219 MakeCallback (&CcnxL3Protocol::RouteInputError, this)
220 ))
221 {
222 NS_LOG_WARN ("No route found for forwarding packet. Drop.");
Alexander Afanasyev98256102011-08-14 01:00:02 -0700223 m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700224 }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700225}
226
227
228void
Alexander Afanasyev98256102011-08-14 01:00:02 -0700229CcnxL3Protocol::Send (Ptr<Packet> packet, Ptr<CcnxRoute> route)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700230{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700231 NS_LOG_FUNCTION (this << "packet: " << packet << ", route: "<< route);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700232
Alexander Afanasyev98256102011-08-14 01:00:02 -0700233 if (route == 0)
234 {
235 NS_LOG_WARN ("No route to host. Drop.");
236 m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), 0);
237 return;
238 }
239 Ptr<CcnxFace> outFace = route->GetOutputFace ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700240
Alexander Afanasyev98256102011-08-14 01:00:02 -0700241 if (outFace->IsUp ())
242 {
243 NS_LOG_LOGIC ("Sending via face " << *outFace);
244 m_txTrace (packet, m_node->GetObject<Ccnx> (), outFace);
245 outFace->Send (packet);
246 }
247 else
248 {
249 NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << *outFace);
250 m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), outFace);
251 }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700252}
253
254
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700255void
256CcnxL3Protocol::SetMetric (uint32_t i, uint16_t metric)
257{
258 NS_LOG_FUNCTION (this << i << metric);
259 Ptr<CcnxInterface> interface = GetInterface (i);
260 interface->SetMetric (metric);
261}
262
263uint16_t
264CcnxL3Protocol::GetMetric (uint32_t i) const
265{
266 Ptr<CcnxInterface> interface = GetInterface (i);
267 return interface->GetMetric ();
268}
269
270uint16_t
271CcnxL3Protocol::GetMtu (uint32_t i) const
272{
273 Ptr<CcnxInterface> interface = GetInterface (i);
274 return interface->GetDevice ()->GetMtu ();
275}
276
277bool
278CcnxL3Protocol::IsUp (uint32_t i) const
279{
280 Ptr<CcnxInterface> interface = GetInterface (i);
281 return interface->IsUp ();
282}
283
284void
285CcnxL3Protocol::SetUp (uint32_t i)
286{
287 NS_LOG_FUNCTION (this << i);
288 Ptr<CcnxInterface> interface = GetInterface (i);
289 interface->SetUp ();
290
291 if (m_routingProtocol != 0)
292 {
293 m_routingProtocol->NotifyInterfaceUp (i);
294 }
295}
296
297void
298CcnxL3Protocol::SetDown (uint32_t ifaceIndex)
299{
300 NS_LOG_FUNCTION (this << ifaceIndex);
301 Ptr<CcnxInterface> interface = GetInterface (ifaceIndex);
302 interface->SetDown ();
303
304 if (m_routingProtocol != 0)
305 {
306 m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
307 }
308}
309
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700310void
311CcnxL3Protocol::RouteInputError (Ptr<const Packet> p, const CcnxHeader & ipHeader, Socket::SocketErrno sockErrno)
312{
313 NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
314 NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
315 m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, m_node->GetObject<Ccnx> (), 0);
316}
317
318} //namespace ns3