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
21NS_OBJECT_ENSURE_REGISTERED(Ipv4ListRouting);
22
23TypeId
25{
26 static TypeId tid = TypeId("ns3::Ipv4ListRouting")
28 .SetGroupName("Internet")
29 .AddConstructor<Ipv4ListRouting>();
30 return tid;
31}
32
34 : m_ipv4(nullptr)
35{
36 NS_LOG_FUNCTION(this);
37}
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 (route)
105 {
106 NS_LOG_LOGIC("Found route " << route);
107 sockerr = Socket::ERROR_NOTERROR;
108 return route;
109 }
110 }
111 NS_LOG_LOGIC("Done checking " << GetTypeId());
112 NS_LOG_LOGIC("");
114 return nullptr;
115}
116
117// Patterned after Linux ip_route_input and ip_route_input_slow
118bool
120 const Ipv4Header& header,
122 const UnicastForwardCallback& ucb,
123 const MulticastForwardCallback& mcb,
124 const LocalDeliverCallback& lcb,
125 const ErrorCallback& ecb)
126{
127 NS_LOG_FUNCTION(this << p << header << idev << &ucb << &mcb << &lcb << &ecb);
128 bool retVal = false;
129 NS_LOG_LOGIC("RouteInput logic for node: " << m_ipv4->GetObject<Node>()->GetId());
130
132 // Check if input device supports IP
135
136 retVal = m_ipv4->IsDestinationAddress(header.GetDestination(), iif);
137 if (retVal)
138 {
139 NS_LOG_LOGIC("Address " << header.GetDestination() << " is a match for local delivery");
140 if (header.GetDestination().IsMulticast())
141 {
142 Ptr<Packet> packetCopy = p->Copy();
143 lcb(packetCopy, header, iif);
144 retVal = true;
145 // Fall through
146 }
147 else
148 {
149 lcb(p, header, iif);
150 return true;
151 }
152 }
153 // Check if input device supports IP forwarding
154 if (!m_ipv4->IsForwarding(iif))
155 {
156 NS_LOG_LOGIC("Forwarding disabled for this interface");
157 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
158 return true;
159 }
160 // Next, try to find a route
161 // If we have already delivered a packet locally (e.g. multicast)
162 // we suppress further downstream local delivery by nulling the callback
163 LocalDeliverCallback downstreamLcb = lcb;
164 if (retVal)
165 {
167 }
168 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
169 rprotoIter++)
170 {
171 if ((*rprotoIter).second->RouteInput(p, header, idev, ucb, mcb, downstreamLcb, ecb))
172 {
173 NS_LOG_LOGIC("Route found to forward packet in protocol "
174 << (*rprotoIter).second->GetInstanceTypeId().GetName());
175 return true;
176 }
177 }
178 // No routing protocol has found a route.
179 return retVal;
180}
181
182void
184{
185 NS_LOG_FUNCTION(this << interface);
186 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
187 rprotoIter++)
188 {
189 (*rprotoIter).second->NotifyInterfaceUp(interface);
190 }
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->NotifyInterfaceDown(interface);
201 }
202}
203
204void
206{
207 NS_LOG_FUNCTION(this << interface << address);
208 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
209 rprotoIter++)
210 {
211 (*rprotoIter).second->NotifyAddAddress(interface, address);
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->NotifyRemoveAddress(interface, address);
223 }
224}
225
226void
228{
229 NS_LOG_FUNCTION(this << ipv4);
231 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
232 rprotoIter++)
233 {
234 (*rprotoIter).second->SetIpv4(ipv4);
235 }
236 m_ipv4 = ipv4;
237}
238
239void
241{
242 NS_LOG_FUNCTION(this << routingProtocol->GetInstanceTypeId() << priority);
243 m_routingProtocols.emplace_back(priority, routingProtocol);
245 if (m_ipv4)
246 {
247 routingProtocol->SetIpv4(m_ipv4);
248 }
249}
250
253{
254 NS_LOG_FUNCTION(this);
255 return m_routingProtocols.size();
256}
257
259Ipv4ListRouting::GetRoutingProtocol(uint32_t index, int16_t& priority) const
260{
261 NS_LOG_FUNCTION(this << index << priority);
262 if (index >= m_routingProtocols.size())
263 {
264 NS_FATAL_ERROR("Ipv4ListRouting::GetRoutingProtocol(): index " << index
265 << " out of range");
266 }
267 uint32_t i = 0;
268 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
269 rprotoIter++, i++)
270 {
271 if (i == index)
272 {
273 priority = (*rprotoIter).first;
274 return (*rprotoIter).second;
275 }
276 }
277 return nullptr;
278}
279
280bool
282{
283 NS_LOG_FUNCTION(a.first << a.second << b.first << b.second);
284 return a.first > b.first;
285}
286
287} // namespace ns3
bool IsMulticast() const
Packet header for IPv4.
Definition ipv4-header.h:23
Ipv4Address GetSource() const
Ipv4Address GetDestination() const
virtual bool IsForwarding(uint32_t interface) const =0
virtual bool IsDestinationAddress(Ipv4Address address, uint32_t iif) const =0
Determine whether address and interface corresponding to received packet can be accepted for local de...
virtual int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const =0
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:46
uint32_t GetId() const
Definition node.cc:106
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
virtual void DoInitialize()
Initialize() implementation.
Definition object.cc:440
Smart pointer class similar to boost::intrusive_ptr.
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:404
Unit
The unit to use to interpret a number representing time.
Definition nstime.h:100
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#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()
Definition callback.h:727
#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:191
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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:294
Every class exported by the ns3 library is enclosed in the ns3 namespace.