A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv4-list-routing.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 University of Washington
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 */
18
19#include "ipv4-list-routing.h"
20
21#include "ipv4-route.h"
22#include "ipv4.h"
23
24#include "ns3/log.h"
25#include "ns3/node.h"
26
27namespace ns3
28{
29
30NS_LOG_COMPONENT_DEFINE("Ipv4ListRouting");
31
32NS_OBJECT_ENSURE_REGISTERED(Ipv4ListRouting);
33
34TypeId
36{
37 static TypeId tid = TypeId("ns3::Ipv4ListRouting")
39 .SetGroupName("Internet")
40 .AddConstructor<Ipv4ListRouting>();
41 return tid;
42}
43
45 : m_ipv4(nullptr)
46{
47 NS_LOG_FUNCTION(this);
48}
49
51{
52 NS_LOG_FUNCTION(this);
53}
54
55void
57{
58 NS_LOG_FUNCTION(this);
59 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
60 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 = nullptr;
66 }
67 m_routingProtocols.clear();
68 m_ipv4 = nullptr;
69}
70
71void
73{
74 NS_LOG_FUNCTION(this << stream);
75 *stream->GetStream() << "Node: " << m_ipv4->GetObject<Node>()->GetId()
76 << ", Time: " << Now().As(unit)
77 << ", Local time: " << m_ipv4->GetObject<Node>()->GetLocalTime().As(unit)
78 << ", Ipv4ListRouting table" << std::endl;
79 for (auto i = m_routingProtocols.begin(); i != m_routingProtocols.end(); i++)
80 {
81 *stream->GetStream() << " Priority: " << (*i).first
82 << " Protocol: " << (*i).second->GetInstanceTypeId() << std::endl;
83 (*i).second->PrintRoutingTable(stream, unit);
84 }
85}
86
87void
89{
90 NS_LOG_FUNCTION(this);
91 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
92 rprotoIter++)
93 {
94 Ptr<Ipv4RoutingProtocol> protocol = (*rprotoIter).second;
95 protocol->Initialize();
96 }
98}
99
102 const Ipv4Header& header,
103 Ptr<NetDevice> oif,
104 Socket::SocketErrno& sockerr)
105{
106 NS_LOG_FUNCTION(this << p << header.GetDestination() << header.GetSource() << oif << sockerr);
107 Ptr<Ipv4Route> route;
108
109 for (auto i = m_routingProtocols.begin(); i != m_routingProtocols.end(); i++)
110 {
111 NS_LOG_LOGIC("Checking protocol " << (*i).second->GetInstanceTypeId() << " with priority "
112 << (*i).first);
113 NS_LOG_LOGIC("Requesting source address for destination " << header.GetDestination());
114 route = (*i).second->RouteOutput(p, header, oif, sockerr);
115 if (route)
116 {
117 NS_LOG_LOGIC("Found route " << route);
118 sockerr = Socket::ERROR_NOTERROR;
119 return route;
120 }
121 }
122 NS_LOG_LOGIC("Done checking " << GetTypeId());
123 NS_LOG_LOGIC("");
125 return nullptr;
126}
127
128// Patterned after Linux ip_route_input and ip_route_input_slow
129bool
131 const Ipv4Header& header,
133 const UnicastForwardCallback& ucb,
134 const MulticastForwardCallback& mcb,
135 const LocalDeliverCallback& lcb,
136 const ErrorCallback& ecb)
137{
138 NS_LOG_FUNCTION(this << p << header << idev << &ucb << &mcb << &lcb << &ecb);
139 bool retVal = false;
140 NS_LOG_LOGIC("RouteInput logic for node: " << m_ipv4->GetObject<Node>()->GetId());
141
143 // Check if input device supports IP
144 NS_ASSERT(m_ipv4->GetInterfaceForDevice(idev) >= 0);
145 uint32_t iif = m_ipv4->GetInterfaceForDevice(idev);
146
147 retVal = m_ipv4->IsDestinationAddress(header.GetDestination(), iif);
148 if (retVal)
149 {
150 NS_LOG_LOGIC("Address " << header.GetDestination() << " is a match for local delivery");
151 if (header.GetDestination().IsMulticast())
152 {
153 Ptr<Packet> packetCopy = p->Copy();
154 lcb(packetCopy, header, iif);
155 retVal = true;
156 // Fall through
157 }
158 else
159 {
160 lcb(p, header, iif);
161 return true;
162 }
163 }
164 // Check if input device supports IP forwarding
165 if (!m_ipv4->IsForwarding(iif))
166 {
167 NS_LOG_LOGIC("Forwarding disabled for this interface");
168 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
169 return true;
170 }
171 // Next, try to find a route
172 // If we have already delivered a packet locally (e.g. multicast)
173 // we suppress further downstream local delivery by nulling the callback
174 LocalDeliverCallback downstreamLcb = lcb;
175 if (retVal)
176 {
177 downstreamLcb = MakeNullCallback<void, Ptr<const Packet>, const Ipv4Header&, uint32_t>();
178 }
179 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
180 rprotoIter++)
181 {
182 if ((*rprotoIter).second->RouteInput(p, header, idev, ucb, mcb, downstreamLcb, ecb))
183 {
184 NS_LOG_LOGIC("Route found to forward packet in protocol "
185 << (*rprotoIter).second->GetInstanceTypeId().GetName());
186 return true;
187 }
188 }
189 // No routing protocol has found a route.
190 return retVal;
191}
192
193void
195{
196 NS_LOG_FUNCTION(this << interface);
197 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
198 rprotoIter++)
199 {
200 (*rprotoIter).second->NotifyInterfaceUp(interface);
201 }
202}
203
204void
206{
207 NS_LOG_FUNCTION(this << interface);
208 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
209 rprotoIter++)
210 {
211 (*rprotoIter).second->NotifyInterfaceDown(interface);
212 }
213}
214
215void
217{
218 NS_LOG_FUNCTION(this << interface << address);
219 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
220 rprotoIter++)
221 {
222 (*rprotoIter).second->NotifyAddAddress(interface, address);
223 }
224}
225
226void
228{
229 NS_LOG_FUNCTION(this << interface << address);
230 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
231 rprotoIter++)
232 {
233 (*rprotoIter).second->NotifyRemoveAddress(interface, address);
234 }
235}
236
237void
239{
240 NS_LOG_FUNCTION(this << ipv4);
242 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
243 rprotoIter++)
244 {
245 (*rprotoIter).second->SetIpv4(ipv4);
246 }
247 m_ipv4 = ipv4;
248}
249
250void
252{
253 NS_LOG_FUNCTION(this << routingProtocol->GetInstanceTypeId() << priority);
254 m_routingProtocols.emplace_back(priority, routingProtocol);
256 if (m_ipv4)
257 {
258 routingProtocol->SetIpv4(m_ipv4);
259 }
260}
261
264{
265 NS_LOG_FUNCTION(this);
266 return m_routingProtocols.size();
267}
268
270Ipv4ListRouting::GetRoutingProtocol(uint32_t index, int16_t& priority) const
271{
272 NS_LOG_FUNCTION(this << index << priority);
273 if (index >= m_routingProtocols.size())
274 {
275 NS_FATAL_ERROR("Ipv4ListRouting::GetRoutingProtocol(): index " << index
276 << " out of range");
277 }
278 uint32_t i = 0;
279 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
280 rprotoIter++, i++)
281 {
282 if (i == index)
283 {
284 priority = (*rprotoIter).first;
285 return (*rprotoIter).second;
286 }
287 }
288 return nullptr;
289}
290
291bool
293{
294 NS_LOG_FUNCTION(a.first << a.second << b.first << b.second);
295 return a.first > b.first;
296}
297
298} // namespace ns3
bool IsMulticast() const
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetSource() const
Definition: ipv4-header.cc:302
Ipv4Address GetDestination() const
Definition: ipv4-header.cc:316
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.
static TypeId GetTypeId()
Get the type ID of this class.
void DoDispose() override
Destructor implementation.
Ipv4RoutingProtocolList m_routingProtocols
List of routing protocols.
void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address) override
Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr) override
Query routing cache for an existing route, for an outbound packet.
void SetIpv4(Ptr< Ipv4 > ipv4) override
virtual uint32_t GetNRoutingProtocols() const
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
Print the Routing Table entries.
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, const UnicastForwardCallback &ucb, const MulticastForwardCallback &mcb, const LocalDeliverCallback &lcb, const ErrorCallback &ecb) override
Route an input packet (to be forwarded or locally delivered)
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 bool Compare(const Ipv4RoutingProtocolEntry &a, const Ipv4RoutingProtocolEntry &b)
Compare two routing protocols.
void NotifyInterfaceDown(uint32_t interface) override
void DoInitialize() override
Initialize() implementation.
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...
void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address) override
void NotifyInterfaceUp(uint32_t interface) override
Abstract base class for IPv4 routing protocols.
A network Node.
Definition: node.h:57
uint32_t GetId() const
Definition: node.cc:117
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:451
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
@ ERROR_NOROUTETOHOST
Definition: socket.h:95
@ ERROR_NOTERROR
Definition: socket.h:85
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:111
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
Every class exported by the ns3 library is enclosed in the ns3 namespace.