blob: b906a4ca90aa6c88584d52b9a63284069cb3e341 [file] [log] [blame]
Alexander Afanasyev45b92d42011-08-14 23:11:38 -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 Afanasyev45b92d42011-08-14 23:11:38 -070033#include "ccnx-face.h"
34#include "ccnx-route.h"
35#include "ccnx-forwarding-protocol.h"
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070036
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 (),
Alexander Afanasyev45b92d42011-08-14 23:11:38 -070059 MakeObjectVectorAccessor (&CcnxL3Protocol::m_faces),
60 MakeObjectVectorChecker<CcnxFace> ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -070061
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 Afanasyev45b92d42011-08-14 23:11:38 -0700124 for (CcnxFaceList::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...
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700140 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 {
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700144 m_node->RegisterProtocolHandler (MakeCallback (&CcnxL3Protocol::ReceiveFromLower, this),
Alexander Afanasyev98256102011-08-14 01:00:02 -0700145 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 ();
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700149 m_faces.push_back (face);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700150 return index;
151}
152
Alexander Afanasyev98256102011-08-14 01:00:02 -0700153
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700154Ptr<CcnxFace>
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>
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700171CcnxL3Protocol::GetFaceForDevice (Ptr<const NetDevice> device) const
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700172{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700173 for (CcnxFaceList::const_iterator i = m_faces.begin ();
Alexander Afanasyev98256102011-08-14 01:00:02 -0700174 i != m_faces.end ();
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700175 i++)
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 Afanasyev45b92d42011-08-14 23:11:38 -0700183 NS_ASSERT_MSG (false, "Should never get to this place" );
Alexander Afanasyev98256102011-08-14 01:00:02 -0700184 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
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700189CcnxL3Protocol::ReceiveFromLower ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700190 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
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700196 Ptr<CcnxFace> ccnxFace = GetFaceForDevice (device);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700197
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700198 Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
199 ReceiveAndProcess (ccnxFace, packet);
Alexander Afanasyev98256102011-08-14 01:00:02 -0700200}
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700201
Alexander Afanasyev98256102011-08-14 01:00:02 -0700202// Callback from higher level
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700203void CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> incomingFace, Ptr<Packet> packet)
Alexander Afanasyev98256102011-08-14 01:00:02 -0700204{
205 if ( incomingFace->IsUp ())
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700206 {
Alexander Afanasyev98256102011-08-14 01:00:02 -0700207 NS_LOG_LOGIC ("Dropping received packet -- interface is down");
208 m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700209 return;
210 }
Alexander Afanasyev98256102011-08-14 01:00:02 -0700211
212 m_rxTrace (packet, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700213
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700214 NS_ASSERT_MSG (m_forwardingProtocol != 0, "Need a forwarding protocol object to process packets");
215 if (!m_forwardingProtocol->RouteInput (packet, incomingFace,
Alexander Afanasyev98256102011-08-14 01:00:02 -0700216 MakeCallback (&CcnxL3Protocol::Send, this),
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700217 MakeCallback (&CcnxL3Protocol::RouteInputError, this)
218 ))
219 {
220 NS_LOG_WARN ("No route found for forwarding packet. Drop.");
Alexander Afanasyev98256102011-08-14 01:00:02 -0700221 m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), incomingFace);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700222 }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700223}
224
225
226void
Alexander Afanasyev98256102011-08-14 01:00:02 -0700227CcnxL3Protocol::Send (Ptr<Packet> packet, Ptr<CcnxRoute> route)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700228{
Alexander Afanasyev98256102011-08-14 01:00:02 -0700229 NS_LOG_FUNCTION (this << "packet: " << packet << ", route: "<< route);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700230
Alexander Afanasyev98256102011-08-14 01:00:02 -0700231 if (route == 0)
232 {
233 NS_LOG_WARN ("No route to host. Drop.");
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700234 m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), 0);
Alexander Afanasyev98256102011-08-14 01:00:02 -0700235 return;
236 }
237 Ptr<CcnxFace> outFace = route->GetOutputFace ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700238
Alexander Afanasyev98256102011-08-14 01:00:02 -0700239 if (outFace->IsUp ())
240 {
241 NS_LOG_LOGIC ("Sending via face " << *outFace);
242 m_txTrace (packet, m_node->GetObject<Ccnx> (), outFace);
243 outFace->Send (packet);
244 }
245 else
246 {
247 NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << *outFace);
248 m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), outFace);
249 }
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700250}
251
252
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700253void
254CcnxL3Protocol::SetMetric (uint32_t i, uint16_t metric)
255{
256 NS_LOG_FUNCTION (this << i << metric);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700257 Ptr<CcnxFace> face = GetFace (i);
258 face->SetMetric (metric);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700259}
260
261uint16_t
262CcnxL3Protocol::GetMetric (uint32_t i) const
263{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700264 Ptr<const CcnxFace> face = GetFace (i);
265 return face->GetMetric ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700266}
267
268uint16_t
269CcnxL3Protocol::GetMtu (uint32_t i) const
270{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700271 Ptr<CcnxFace> face = GetFace (i);
272 return face->GetDevice ()->GetMtu ();
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700273}
274
275bool
276CcnxL3Protocol::IsUp (uint32_t i) const
277{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700278 Ptr<CcnxFace> interface = GetFace (i);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700279 return interface->IsUp ();
280}
281
282void
283CcnxL3Protocol::SetUp (uint32_t i)
284{
285 NS_LOG_FUNCTION (this << i);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700286 Ptr<CcnxFace> interface = GetFace (i);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700287 interface->SetUp ();
288
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700289 if (m_forwardingProtocol != 0)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700290 {
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700291 m_forwardingProtocol->NotifyInterfaceUp (i);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700292 }
293}
294
295void
296CcnxL3Protocol::SetDown (uint32_t ifaceIndex)
297{
298 NS_LOG_FUNCTION (this << ifaceIndex);
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700299 Ptr<CcnxFace> interface = GetFace (ifaceIndex);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700300 interface->SetDown ();
301
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700302 if (m_forwardingProtocol != 0)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700303 {
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700304 m_forwardingProtocol->NotifyInterfaceDown (ifaceIndex);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700305 }
306}
307
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700308void
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700309CcnxL3Protocol::RouteInputError (Ptr<Packet> p)//, Socket::SocketErrno sockErrno)
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700310{
Alexander Afanasyev45b92d42011-08-14 23:11:38 -0700311 // NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
312 // NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
313 m_dropTrace (p, DROP_ROUTE_ERROR, m_node->GetObject<Ccnx> (), 0);
Alexander Afanasyev08d984e2011-08-13 19:20:22 -0700314}
315
316} //namespace ns3