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
27namespace ns3 {
28
29NS_LOG_COMPONENT_DEFINE ("Ipv4ListRouting");
30
31NS_OBJECT_ENSURE_REGISTERED (Ipv4ListRouting);
32
33TypeId
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
56void
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
72void
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
88void
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 ("");
124 return 0;
125}
126
127// Patterned after Linux ip_route_input and ip_route_input_slow
128bool
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
189void
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}
201void
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}
213void
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}
225void
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}
237void
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
252void
254{
255 NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
256 m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
258 if (m_ipv4 != 0)
259 {
260 routingProtocol->SetIpv4 (m_ipv4);
261 }
262}
263
266{
267 NS_LOG_FUNCTION (this);
268 return m_routingProtocols.size ();
269}
270
272Ipv4ListRouting::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
292bool
294{
295 NS_LOG_FUNCTION (a.first << a.second << b.first << b.second);
296 return a.first > b.first;
297}
298
299
300} // namespace ns3
301
Callback template class.
Definition: callback.h:1279
bool IsMulticast(void) const
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
a class to store IPv4 address information on an interface
IPv4 list routing.
std::pair< int16_t, Ptr< Ipv4RoutingProtocol > > Ipv4RoutingProtocolEntry
Container identifying an IPv4 Routing Protocol entry in the list.
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
virtual void NotifyInterfaceUp(uint32_t interface)
virtual void NotifyInterfaceDown(uint32_t interface)
virtual void DoInitialize(void)
Initialize() implementation.
Ipv4RoutingProtocolList m_routingProtocols
List of routing protocols.
virtual uint32_t GetNRoutingProtocols(void) const
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
virtual void AddRoutingProtocol(Ptr< Ipv4RoutingProtocol > routingProtocol, int16_t priority)
Register a new routing protocol to be used in this IPv4 stack.
Ptr< Ipv4 > m_ipv4
Ipv4 this protocol is associated with.
static TypeId GetTypeId(void)
Get the type ID of this class.
static bool Compare(const Ipv4RoutingProtocolEntry &a, const Ipv4RoutingProtocolEntry &b)
Compare two 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...
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.
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 void DoDispose(void)
Destructor implementation.
Abstract base class for IPv4 routing protocols.
A network Node.
Definition: node.h:57
uint32_t GetId(void) const
Definition: node.cc:109
virtual void DoInitialize(void)
Initialize() implementation.
Definition: object.cc:353
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
@ ERROR_NOROUTETOHOST
Definition: socket.h:93
@ ERROR_NOTERROR
Definition: socket.h:83
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:109
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:432
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
#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_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
address
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.