A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 NS_LOG_COMPONENT_DEFINE ("Ipv4ListRouting");
28 
29 namespace ns3 {
30 
31 NS_OBJECT_ENSURE_REGISTERED (Ipv4ListRouting);
32 
33 TypeId
35 {
36  static TypeId tid = TypeId ("ns3::Ipv4ListRouting")
38  .AddConstructor<Ipv4ListRouting> ()
39  ;
40  return tid;
41 }
42 
43 
45  : m_ipv4 (0)
46 {
47  NS_LOG_FUNCTION (this);
48 }
49 
51 {
52  NS_LOG_FUNCTION (this);
53 }
54 
55 void
57 {
58  NS_LOG_FUNCTION (this);
59  for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
60  rprotoIter != m_routingProtocols.end (); rprotoIter++)
61  {
62  // Note: Calling dispose on these protocols causes memory leak
63  // The routing protocols should not maintain a pointer to
64  // this object, so Dispose() shouldn't be necessary.
65  (*rprotoIter).second = 0;
66  }
67  m_routingProtocols.clear ();
68  m_ipv4 = 0;
69 }
70 
71 void
73 {
74  NS_LOG_FUNCTION (this << stream);
75  *stream->GetStream () << "Node: " << m_ipv4->GetObject<Node> ()->GetId ()
76  << " Time: " << Simulator::Now ().GetSeconds () << "s "
77  << "Ipv4ListRouting table" << std::endl;
78  for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
79  i != m_routingProtocols.end (); i++)
80  {
81  *stream->GetStream () << " Priority: " << (*i).first << " Protocol: " << (*i).second->GetInstanceTypeId () << std::endl;
82  (*i).second->PrintRoutingTable (stream);
83  }
84  *stream->GetStream () << std::endl;
85 }
86 
87 void
89 {
90  NS_LOG_FUNCTION (this);
91  for (Ipv4RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
92  rprotoIter != m_routingProtocols.end (); rprotoIter++)
93  {
94  Ptr<Ipv4RoutingProtocol> protocol = (*rprotoIter).second;
95  protocol->Initialize ();
96  }
98 }
99 
100 
103 {
104  NS_LOG_FUNCTION (this << p << header.GetDestination () << header.GetSource () << oif << sockerr);
105  Ptr<Ipv4Route> route;
106 
107  for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
108  i != m_routingProtocols.end (); i++)
109  {
110  NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first);
111  NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestination ());
112  route = (*i).second->RouteOutput (p, header, oif, sockerr);
113  if (route)
114  {
115  NS_LOG_LOGIC ("Found route " << route);
116  sockerr = Socket::ERROR_NOTERROR;
117  return route;
118  }
119  }
120  NS_LOG_LOGIC ("Done checking " << GetTypeId ());
121  NS_LOG_LOGIC ("");
122  sockerr = Socket::ERROR_NOROUTETOHOST;
123  return 0;
124 }
125 
126 // Patterned after Linux ip_route_input and ip_route_input_slow
127 bool
131 {
132  NS_LOG_FUNCTION (this << p << header << idev << &ucb << &mcb << &lcb << &ecb);
133  bool retVal = false;
134  NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv4->GetObject<Node> ()->GetId ());
135 
136  NS_ASSERT (m_ipv4 != 0);
137  // Check if input device supports IP
138  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
139  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
140 
141  retVal = m_ipv4->IsDestinationAddress (header.GetDestination (), iif);
142  if (retVal == true)
143  {
144  NS_LOG_LOGIC ("Address "<< header.GetDestination () << " is a match for local delivery");
145  if (header.GetDestination ().IsMulticast ())
146  {
147  Ptr<Packet> packetCopy = p->Copy ();
148  lcb (packetCopy, header, iif);
149  retVal = true;
150  // Fall through
151  }
152  else
153  {
154  lcb (p, header, iif);
155  return true;
156  }
157  }
158  // Check if input device supports IP forwarding
159  if (m_ipv4->IsForwarding (iif) == false)
160  {
161  NS_LOG_LOGIC ("Forwarding disabled for this interface");
162  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
163  return false;
164  }
165  // Next, try to find a route
166  // If we have already delivered a packet locally (e.g. multicast)
167  // we suppress further downstream local delivery by nulling the callback
168  LocalDeliverCallback downstreamLcb = lcb;
169  if (retVal == true)
170  {
171  downstreamLcb = MakeNullCallback<void, Ptr<const Packet>, const Ipv4Header &, uint32_t > ();
172  }
173  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
174  m_routingProtocols.begin ();
175  rprotoIter != m_routingProtocols.end ();
176  rprotoIter++)
177  {
178  if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, downstreamLcb, ecb))
179  {
180  NS_LOG_LOGIC ("Route found to forward packet in protocol " << (*rprotoIter).second->GetInstanceTypeId ().GetName ());
181  return true;
182  }
183  }
184  // No routing protocol has found a route.
185  return retVal;
186 }
187 
188 void
190 {
191  NS_LOG_FUNCTION (this << interface);
192  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
193  m_routingProtocols.begin ();
194  rprotoIter != m_routingProtocols.end ();
195  rprotoIter++)
196  {
197  (*rprotoIter).second->NotifyInterfaceUp (interface);
198  }
199 }
200 void
202 {
203  NS_LOG_FUNCTION (this << interface);
204  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
205  m_routingProtocols.begin ();
206  rprotoIter != m_routingProtocols.end ();
207  rprotoIter++)
208  {
209  (*rprotoIter).second->NotifyInterfaceDown (interface);
210  }
211 }
212 void
214 {
215  NS_LOG_FUNCTION (this << interface << address);
216  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
217  m_routingProtocols.begin ();
218  rprotoIter != m_routingProtocols.end ();
219  rprotoIter++)
220  {
221  (*rprotoIter).second->NotifyAddAddress (interface, address);
222  }
223 }
224 void
226 {
227  NS_LOG_FUNCTION (this << interface << address);
228  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
229  m_routingProtocols.begin ();
230  rprotoIter != m_routingProtocols.end ();
231  rprotoIter++)
232  {
233  (*rprotoIter).second->NotifyRemoveAddress (interface, address);
234  }
235 }
236 void
238 {
239  NS_LOG_FUNCTION (this << ipv4);
240  NS_ASSERT (m_ipv4 == 0);
241  for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
242  m_routingProtocols.begin ();
243  rprotoIter != m_routingProtocols.end ();
244  rprotoIter++)
245  {
246  (*rprotoIter).second->SetIpv4 (ipv4);
247  }
248  m_ipv4 = ipv4;
249 }
250 
251 void
253 {
254  NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
255  m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
256  m_routingProtocols.sort ( Compare );
257  if (m_ipv4 != 0)
258  {
259  routingProtocol->SetIpv4 (m_ipv4);
260  }
261 }
262 
263 uint32_t
265 {
266  NS_LOG_FUNCTION (this);
267  return m_routingProtocols.size ();
268 }
269 
271 Ipv4ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
272 {
273  NS_LOG_FUNCTION (this << index << priority);
274  if (index > m_routingProtocols.size ())
275  {
276  NS_FATAL_ERROR ("Ipv4ListRouting::GetRoutingProtocol(): index " << index << " out of range");
277  }
278  uint32_t i = 0;
279  for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
280  rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
281  {
282  if (i == index)
283  {
284  priority = (*rprotoIter).first;
285  return (*rprotoIter).second;
286  }
287  }
288  return 0;
289 }
290 
291 bool
293 {
295  return a.first > b.first;
296 }
297 
298 
299 } // namespace ns3
300 
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
Callback template class.
Definition: callback.h:972
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...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
void DoInitialize(void)
This method is called only once by Object::Initialize.
virtual void AddRoutingProtocol(Ptr< Ipv4RoutingProtocol > routingProtocol, int16_t priority)
Register a new routing protocol to be used in this IPv4 stack.
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
bool IsMulticast(void) const
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
static TypeId GetTypeId(void)
Get the type ID of this class.
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
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:31
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:322
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.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
virtual uint32_t GetNRoutingProtocols(void) const
void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
virtual void NotifyInterfaceUp(uint32_t interface)
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
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)
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.
uint32_t GetId(void) const
Definition: node.cc:106
a class to store IPv4 address information on an interface
Ipv4RoutingProtocolList m_routingProtocols
List of routing protocols.
A network Node.
Definition: node.h:55
virtual void NotifyInterfaceDown(uint32_t interface)
Abstract base class for IPv4 routing protocols.
tuple address
Definition: first.py:37
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
virtual void DoInitialize(void)
This method is called only once by Object::Initialize.
Definition: object.cc:342
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)