A Discrete-Event Network Simulator
API
ipv4-list-routing.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 University of Washington
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  */
19 
20 #include "ns3/log.h"
21 #include "ns3/ipv4.h"
22 #include "ns3/ipv4-route.h"
23 #include "ns3/node.h"
24 #include "ns3/ipv4-static-routing.h"
25 #include "ipv4-list-routing.h"
26 
27 namespace ns3 {
28 
29 NS_LOG_COMPONENT_DEFINE ("Ipv4ListRouting");
30 
31 NS_OBJECT_ENSURE_REGISTERED (Ipv4ListRouting);
32 
33 TypeId
35 {
36  static TypeId tid = TypeId ("ns3::Ipv4ListRouting")
38  .SetGroupName ("Internet")
39  .AddConstructor<Ipv4ListRouting> ()
40  ;
41  return tid;
42 }
43 
44 
46  : m_ipv4 (0)
47 {
48  NS_LOG_FUNCTION (this);
49 }
50 
52 {
53  NS_LOG_FUNCTION (this);
54 }
55 
56 void
58 {
59  NS_LOG_FUNCTION (this);
60  for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
61  rprotoIter != m_routingProtocols.end (); rprotoIter++)
62  {
63  // Note: Calling dispose on these protocols causes memory leak
64  // The routing protocols should not maintain a pointer to
65  // this object, so Dispose() shouldn't be necessary.
66  (*rprotoIter).second = 0;
67  }
68  m_routingProtocols.clear ();
69  m_ipv4 = 0;
70 }
71 
72 void
74 {
75  NS_LOG_FUNCTION (this << stream);
76  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId ()
77  << ", Time: " << Now().As (unit)
78  << ", Local time: " << m_ipv4->GetObject<Node> ()->GetLocalTime ().As (unit)
79  << ", Ipv4ListRouting table" << std::endl;
80  for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
81  i != m_routingProtocols.end (); i++)
82  {
83  *stream->GetStream () << " Priority: " << (*i).first << " Protocol: " << (*i).second->GetInstanceTypeId () << std::endl;
84  (*i).second->PrintRoutingTable (stream, unit);
85  }
86 }
87 
88 void
90 {
91  NS_LOG_FUNCTION (this);
92  for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
93  rprotoIter != m_routingProtocols.end (); rprotoIter++)
94  {
95  Ptr<Ipv4RoutingProtocol> protocol = (*rprotoIter).second;
96  protocol->Initialize ();
97  }
99 }
100 
101 
104 {
105  NS_LOG_FUNCTION (this << p << header.GetDestination () << header.GetSource () << oif << sockerr);
106  Ptr<Ipv4Route> route;
107 
108  for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
109  i != m_routingProtocols.end (); i++)
110  {
111  NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first);
112  NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestination ());
113  route = (*i).second->RouteOutput (p, header, oif, sockerr);
114  if (route)
115  {
116  NS_LOG_LOGIC ("Found route " << route);
117  sockerr = Socket::ERROR_NOTERROR;
118  return route;
119  }
120  }
121  NS_LOG_LOGIC ("Done checking " << GetTypeId ());
122  NS_LOG_LOGIC ("");
123  sockerr = Socket::ERROR_NOROUTETOHOST;
124  return 0;
125 }
126 
127 // Patterned after Linux ip_route_input and ip_route_input_slow
128 bool
132 {
133  NS_LOG_FUNCTION (this << p << header << idev << &ucb << &mcb << &lcb << &ecb);
134  bool retVal = false;
135  NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv4->GetObject<Node> ()->GetId ());
136 
137  NS_ASSERT (m_ipv4 != 0);
138  // Check if input device supports IP
139  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
140  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
141 
142  retVal = m_ipv4->IsDestinationAddress (header.GetDestination (), iif);
143  if (retVal == true)
144  {
145  NS_LOG_LOGIC ("Address "<< header.GetDestination () << " is a match for local delivery");
146  if (header.GetDestination ().IsMulticast ())
147  {
148  Ptr<Packet> packetCopy = p->Copy ();
149  lcb (packetCopy, header, iif);
150  retVal = true;
151  // Fall through
152  }
153  else
154  {
155  lcb (p, header, iif);
156  return true;
157  }
158  }
159  // Check if input device supports IP forwarding
160  if (m_ipv4->IsForwarding (iif) == false)
161  {
162  NS_LOG_LOGIC ("Forwarding disabled for this interface");
163  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
164  return true;
165  }
166  // Next, try to find a route
167  // If we have already delivered a packet locally (e.g. multicast)
168  // we suppress further downstream local delivery by nulling the callback
169  LocalDeliverCallback downstreamLcb = lcb;
170  if (retVal == true)
171  {
172  downstreamLcb = MakeNullCallback<void, Ptr<const Packet>, const Ipv4Header &, uint32_t > ();
173  }
174  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
175  m_routingProtocols.begin ();
176  rprotoIter != m_routingProtocols.end ();
177  rprotoIter++)
178  {
179  if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, downstreamLcb, ecb))
180  {
181  NS_LOG_LOGIC ("Route found to forward packet in protocol " << (*rprotoIter).second->GetInstanceTypeId ().GetName ());
182  return true;
183  }
184  }
185  // No routing protocol has found a route.
186  return retVal;
187 }
188 
189 void
191 {
192  NS_LOG_FUNCTION (this << interface);
193  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
194  m_routingProtocols.begin ();
195  rprotoIter != m_routingProtocols.end ();
196  rprotoIter++)
197  {
198  (*rprotoIter).second->NotifyInterfaceUp (interface);
199  }
200 }
201 void
203 {
204  NS_LOG_FUNCTION (this << interface);
205  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
206  m_routingProtocols.begin ();
207  rprotoIter != m_routingProtocols.end ();
208  rprotoIter++)
209  {
210  (*rprotoIter).second->NotifyInterfaceDown (interface);
211  }
212 }
213 void
215 {
216  NS_LOG_FUNCTION (this << interface << address);
217  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
218  m_routingProtocols.begin ();
219  rprotoIter != m_routingProtocols.end ();
220  rprotoIter++)
221  {
222  (*rprotoIter).second->NotifyAddAddress (interface, address);
223  }
224 }
225 void
227 {
228  NS_LOG_FUNCTION (this << interface << address);
229  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
230  m_routingProtocols.begin ();
231  rprotoIter != m_routingProtocols.end ();
232  rprotoIter++)
233  {
234  (*rprotoIter).second->NotifyRemoveAddress (interface, address);
235  }
236 }
237 void
239 {
240  NS_LOG_FUNCTION (this << ipv4);
241  NS_ASSERT (m_ipv4 == 0);
242  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
243  m_routingProtocols.begin ();
244  rprotoIter != m_routingProtocols.end ();
245  rprotoIter++)
246  {
247  (*rprotoIter).second->SetIpv4 (ipv4);
248  }
249  m_ipv4 = ipv4;
250 }
251 
252 void
254 {
255  NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
256  m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
257  m_routingProtocols.sort ( Compare );
258  if (m_ipv4 != 0)
259  {
260  routingProtocol->SetIpv4 (m_ipv4);
261  }
262 }
263 
264 uint32_t
266 {
267  NS_LOG_FUNCTION (this);
268  return m_routingProtocols.size ();
269 }
270 
272 Ipv4ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
273 {
274  NS_LOG_FUNCTION (this << index << priority);
275  if (index > m_routingProtocols.size ())
276  {
277  NS_FATAL_ERROR ("Ipv4ListRouting::GetRoutingProtocol(): index " << index << " out of range");
278  }
279  uint32_t i = 0;
280  for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
281  rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
282  {
283  if (i == index)
284  {
285  priority = (*rprotoIter).first;
286  return (*rprotoIter).second;
287  }
288  }
289  return 0;
290 }
291 
292 bool
294 {
296  return a.first > b.first;
297 }
298 
299 
300 } // namespace ns3
301 
virtual void DoInitialize(void)
Initialize() implementation.
Definition: object.cc:353
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Callback template class.
Definition: callback.h:1176
uint32_t GetId(void) const
Definition: node.cc:107
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
virtual void DoInitialize(void)
Initialize() implementation.
virtual void AddRoutingProtocol(Ptr< Ipv4RoutingProtocol > routingProtocol, int16_t priority)
Register a new routing protocol to be used in this IPv4 stack.
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
static TypeId GetTypeId(void)
Get the type ID of this class.
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
Ptr< Ipv4 > m_ipv4
Ipv4 this protocol is associated with.
Packet header for IPv4.
Definition: ipv4-header.h:33
bool IsMulticast(void) const
static bool Compare(const Ipv4RoutingProtocolEntry &a, const Ipv4RoutingProtocolEntry &b)
Compare two routing protocols.
std::pair< int16_t, Ptr< Ipv4RoutingProtocol > > Ipv4RoutingProtocolEntry
Container identifying an IPv4 Routing Protocol entry in the list.
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:108
IPv4 list routing.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
address
Definition: first.py:37
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
virtual void DoDispose(void)
Destructor implementation.
virtual void NotifyInterfaceUp(uint32_t interface)
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
virtual bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
virtual Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
a class to store IPv4 address information on an interface
Ipv4RoutingProtocolList m_routingProtocols
List of routing protocols.
A network Node.
Definition: node.h:56
virtual void NotifyInterfaceDown(uint32_t interface)
Abstract base class for IPv4 routing protocols.
virtual Ptr< Ipv4RoutingProtocol > GetRoutingProtocol(uint32_t index, int16_t &priority) const
Return pointer to routing protocol stored at index, with the first protocol (index 0) the highest pri...
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:309
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
virtual uint32_t GetNRoutingProtocols(void) const
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)