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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8#include "ipv4-list-routing.h"
9
10#include "ipv4-route.h"
11#include "ipv4.h"
12
13#include "ns3/log.h"
14#include "ns3/node.h"
15
16namespace ns3
17{
18
19NS_LOG_COMPONENT_DEFINE("Ipv4ListRouting");
20
22
25{
26 static TypeId tid = TypeId("ns3::Ipv4ListRouting")
28 .SetGroupName("Internet")
29 .AddConstructor<Ipv4ListRouting>();
30 return tid;
31}
32
38
43
44void
46{
47 NS_LOG_FUNCTION(this);
48 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
49 rprotoIter++)
50 {
51 // Note: Calling dispose on these protocols causes memory leak
52 // The routing protocols should not maintain a pointer to
53 // this object, so Dispose() shouldn't be necessary.
54 (*rprotoIter).second = nullptr;
55 }
56 m_routingProtocols.clear();
57 m_ipv4 = nullptr;
58}
59
60void
62{
63 NS_LOG_FUNCTION(this << stream);
64 *stream->GetStream() << "Node: " << m_ipv4->GetObject<Node>()->GetId()
65 << ", Time: " << Now().As(unit)
66 << ", Local time: " << m_ipv4->GetObject<Node>()->GetLocalTime().As(unit)
67 << ", Ipv4ListRouting table" << std::endl;
68 for (auto i = m_routingProtocols.begin(); i != m_routingProtocols.end(); i++)
69 {
70 *stream->GetStream() << " Priority: " << (*i).first
71 << " Protocol: " << (*i).second->GetInstanceTypeId() << std::endl;
72 (*i).second->PrintRoutingTable(stream, unit);
73 }
74}
75
76void
78{
79 NS_LOG_FUNCTION(this);
80 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
81 rprotoIter++)
82 {
83 Ptr<Ipv4RoutingProtocol> protocol = (*rprotoIter).second;
84 protocol->Initialize();
85 }
87}
88
91 const Ipv4Header& header,
93 Socket::SocketErrno& sockerr)
94{
95 NS_LOG_FUNCTION(this << p << header.GetDestination() << header.GetSource() << oif << sockerr);
96 Ptr<Ipv4Route> route;
97
98 for (auto i = m_routingProtocols.begin(); i != m_routingProtocols.end(); i++)
99 {
100 NS_LOG_LOGIC("Checking protocol " << (*i).second->GetInstanceTypeId() << " with priority "
101 << (*i).first);
102 NS_LOG_LOGIC("Requesting source address for destination " << header.GetDestination());
103 route = (*i).second->RouteOutput(p, header, oif, sockerr);
104 if (oif)
105 {
106 if (route && route->GetOutputDevice() != oif)
107 {
108 NS_LOG_LOGIC("Not on requested interface, skipping");
109 continue;
110 }
111 }
112 if (route)
113 {
114 NS_LOG_LOGIC("Found route " << route);
115 sockerr = Socket::ERROR_NOTERROR;
116 return route;
117 }
118 }
119 NS_LOG_LOGIC("Done checking " << GetTypeId());
120 NS_LOG_LOGIC("");
122 return nullptr;
123}
124
125// Patterned after Linux ip_route_input and ip_route_input_slow
126bool
128 const Ipv4Header& header,
130 const UnicastForwardCallback& ucb,
131 const MulticastForwardCallback& mcb,
132 const LocalDeliverCallback& lcb,
133 const ErrorCallback& ecb)
134{
135 NS_LOG_FUNCTION(this << p << header << idev << &ucb << &mcb << &lcb << &ecb);
136 bool retVal = false;
137 NS_LOG_LOGIC("RouteInput logic for node: " << m_ipv4->GetObject<Node>()->GetId());
138
140 // Check if input device supports IP
141 NS_ASSERT(m_ipv4->GetInterfaceForDevice(idev) >= 0);
142 uint32_t iif = m_ipv4->GetInterfaceForDevice(idev);
143
144 retVal = m_ipv4->IsDestinationAddress(header.GetDestination(), iif);
145 if (retVal)
146 {
147 NS_LOG_LOGIC("Address " << header.GetDestination() << " is a match for local delivery");
148 if (header.GetDestination().IsMulticast())
149 {
150 Ptr<Packet> packetCopy = p->Copy();
151 lcb(packetCopy, header, iif);
152 retVal = true;
153 // Fall through
154 }
155 else
156 {
157 lcb(p, header, iif);
158 return true;
159 }
160 }
161 // Check if input device supports IP forwarding
162 if (!m_ipv4->IsForwarding(iif))
163 {
164 NS_LOG_LOGIC("Forwarding disabled for this interface");
165 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
166 return true;
167 }
168 // Next, try to find a route
169 // If we have already delivered a packet locally (e.g. multicast)
170 // we suppress further downstream local delivery by nulling the callback
171 LocalDeliverCallback downstreamLcb = lcb;
172 if (retVal)
173 {
175 }
176 for (auto rprotoIter = m_routingProtocols.begin(); 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 "
182 << (*rprotoIter).second->GetInstanceTypeId().GetName());
183 return true;
184 }
185 }
186 // No routing protocol has found a route.
187 return retVal;
188}
189
190void
192{
193 NS_LOG_FUNCTION(this << interface);
194 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
195 rprotoIter++)
196 {
197 (*rprotoIter).second->NotifyInterfaceUp(interface);
198 }
199}
200
201void
203{
204 NS_LOG_FUNCTION(this << interface);
205 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
206 rprotoIter++)
207 {
208 (*rprotoIter).second->NotifyInterfaceDown(interface);
209 }
210}
211
212void
214{
215 NS_LOG_FUNCTION(this << interface << address);
216 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
217 rprotoIter++)
218 {
219 (*rprotoIter).second->NotifyAddAddress(interface, address);
220 }
221}
222
223void
225{
226 NS_LOG_FUNCTION(this << interface << address);
227 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
228 rprotoIter++)
229 {
230 (*rprotoIter).second->NotifyRemoveAddress(interface, address);
231 }
232}
233
234void
236{
237 NS_LOG_FUNCTION(this << ipv4);
239 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
240 rprotoIter++)
241 {
242 (*rprotoIter).second->SetIpv4(ipv4);
243 }
244 m_ipv4 = ipv4;
245}
246
247void
249{
250 NS_LOG_FUNCTION(this << routingProtocol->GetInstanceTypeId() << priority);
251 m_routingProtocols.emplace_back(priority, routingProtocol);
253 if (m_ipv4)
254 {
255 routingProtocol->SetIpv4(m_ipv4);
256 }
257}
258
261{
262 NS_LOG_FUNCTION(this);
263 return m_routingProtocols.size();
264}
265
267Ipv4ListRouting::GetRoutingProtocol(uint32_t index, int16_t& priority) const
268{
269 NS_LOG_FUNCTION(this << index << priority);
270 if (index >= m_routingProtocols.size())
271 {
272 NS_FATAL_ERROR("Ipv4ListRouting::GetRoutingProtocol(): index " << index
273 << " out of range");
274 }
275 uint32_t i = 0;
276 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
277 rprotoIter++, i++)
278 {
279 if (i == index)
280 {
281 priority = (*rprotoIter).first;
282 return (*rprotoIter).second;
283 }
284 }
285 return nullptr;
286}
287
288bool
290{
291 NS_LOG_FUNCTION(a.first << a.second << b.first << b.second);
292 return a.first > b.first;
293}
294
295} // namespace ns3
bool IsMulticast() const
Packet header for IPv4.
Definition ipv4-header.h:23
Ipv4Address GetSource() const
Ipv4Address GetDestination() const
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.
Callback< void, Ptr< Ipv4MulticastRoute >, Ptr< const Packet >, const Ipv4Header & > MulticastForwardCallback
Callback for multicast packets to be forwarded.
Callback< void, Ptr< const Packet >, const Ipv4Header &, uint32_t > LocalDeliverCallback
Callback for packets to be locally delivered.
Callback< void, Ptr< Ipv4Route >, Ptr< const Packet >, const Ipv4Header & > UnicastForwardCallback
Callback for unicast packets to be forwarded.
Callback< void, Ptr< const Packet >, const Ipv4Header &, Socket::SocketErrno > ErrorCallback
Callback for routing errors (e.g., no route found).
A network Node.
Definition node.h:46
uint32_t GetId() const
Definition node.cc:106
virtual void DoInitialize()
Initialize() implementation.
Definition object.cc:437
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition socket.h:73
@ ERROR_NOROUTETOHOST
Definition socket.h:84
@ ERROR_NOTERROR
Definition socket.h:74
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:408
Unit
The unit to use to interpret a number representing time.
Definition nstime.h:101
a unique identifier for an interface.
Definition type-id.h:50
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
Callback< R, Args... > MakeNullCallback()
Build null Callbacks which take no arguments, for varying number of template arguments,...
Definition callback.h:734
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:274
#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:35
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition simulator.cc:288
Every class exported by the ns3 library is enclosed in the ns3 namespace.