A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ipv4-list-routing.cc
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
34 Ipv4ListRouting::GetTypeId (void)
35 {
36  static TypeId tid = TypeId ("ns3::Ipv4ListRouting")
37  .SetParent<Ipv4RoutingProtocol> ()
38  .AddConstructor<Ipv4ListRouting> ()
39  ;
40  return tid;
41 }
42 
43 
44 Ipv4ListRouting::Ipv4ListRouting ()
45  : m_ipv4 (0)
46 {
47  NS_LOG_FUNCTION (this);
48 }
49 
50 Ipv4ListRouting::~Ipv4ListRouting ()
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 
102 Ipv4ListRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, enum Socket::SocketErrno &sockerr)
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
292 Ipv4ListRouting::Compare (const Ipv4RoutingProtocolEntry& a, const Ipv4RoutingProtocolEntry& b)
293 {
295  return a.first > b.first;
296 }
297 
298 
299 } // namespace ns3
300 
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
Callback template class.
Definition: callback.h:369
virtual Ptr< Ipv4RoutingProtocol > GetRoutingProtocol(uint32_t index, int16_t &priority) const
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
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:303
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
bool IsMulticast(void) const
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:290
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
Packet header for IPv4.
Definition: ipv4-header.h:31
double GetSeconds(void) const
Definition: nstime.h:262
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
virtual uint32_t GetNRoutingProtocols(void) const
virtual void NotifyInterfaceUp(uint32_t interface)
static Time Now(void)
Definition: simulator.cc:179
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:105
a class to store IPv4 address information on an interface
A network Node.
Definition: node.h:56
virtual void NotifyInterfaceDown(uint32_t interface)
std::ostream * GetStream(void)
virtual void DoInitialize(void)
Definition: object.cc:342
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)