A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv6-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 "ipv6-list-routing.h"
9
10#include "ipv6-route.h"
11#include "ipv6.h"
12
13#include "ns3/log.h"
14#include "ns3/node.h"
15#include "ns3/simulator.h"
16
17namespace ns3
18{
19
20NS_LOG_COMPONENT_DEFINE("Ipv6ListRouting");
21
22NS_OBJECT_ENSURE_REGISTERED(Ipv6ListRouting);
23
24TypeId
26{
27 static TypeId tid = TypeId("ns3::Ipv6ListRouting")
29 .SetGroupName("Internet")
30 .AddConstructor<Ipv6ListRouting>();
31 return tid;
32}
33
35 : m_ipv6(nullptr)
36{
37 NS_LOG_FUNCTION(this);
38}
39
44
45void
47{
48 NS_LOG_FUNCTION(this);
49 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
50 rprotoIter++)
51 {
52 // Note: Calling dispose on these protocols causes memory leak
53 // The routing protocols should not maintain a pointer to
54 // this object, so Dispose () shouldn't be necessary.
55 (*rprotoIter).second = nullptr;
56 }
57 m_routingProtocols.clear();
58 m_ipv6 = nullptr;
59}
60
63 const Ipv6Header& header,
65 Socket::SocketErrno& sockerr)
66{
67 NS_LOG_FUNCTION(this << header.GetDestination() << header.GetSource() << oif);
68 Ptr<Ipv6Route> route;
69
70 for (auto i = m_routingProtocols.begin(); i != m_routingProtocols.end(); i++)
71 {
72 NS_LOG_LOGIC("Checking protocol " << (*i).second->GetInstanceTypeId() << " with priority "
73 << (*i).first);
74 NS_LOG_LOGIC("Requesting source address for destination " << header.GetDestination());
75 route = (*i).second->RouteOutput(p, header, oif, sockerr);
76 if (route)
77 {
78 NS_LOG_LOGIC("Found route " << route);
79 sockerr = Socket::ERROR_NOTERROR;
80 return route;
81 }
82 }
83 NS_LOG_LOGIC("Done checking " << GetTypeId());
84 NS_LOG_LOGIC("");
86 return nullptr;
87}
88
89// Patterned after Linux ip_route_input and ip_route_input_slow
90bool
92 const Ipv6Header& header,
94 const UnicastForwardCallback& ucb,
95 const MulticastForwardCallback& mcb,
96 const LocalDeliverCallback& lcb,
97 const ErrorCallback& ecb)
98{
99 NS_LOG_FUNCTION(p << header << idev);
100 NS_LOG_LOGIC("RouteInput logic for node: " << m_ipv6->GetObject<Node>()->GetId());
101
103 // Check if input device supports IP
105 Ipv6Address dst = header.GetDestination();
106
107 // Check if input device supports IP forwarding
109 if (!m_ipv6->IsForwarding(iif))
110 {
111 NS_LOG_LOGIC("Forwarding disabled for this interface");
112 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
113 return true;
114 }
115
116 // We disable error callback for the called protocols.
117 ErrorCallback nullEcb =
119
120 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
121 rprotoIter++)
122 {
123 if ((*rprotoIter).second->RouteInput(p, header, idev, ucb, mcb, lcb, nullEcb))
124 {
125 return true;
126 }
127 }
128
129 // No routing protocol has found a route.
130 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
131 return false;
132}
133
134void
136{
137 NS_LOG_FUNCTION(this << interface);
138 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
139 rprotoIter++)
140 {
141 (*rprotoIter).second->NotifyInterfaceUp(interface);
142 }
143}
144
145void
147{
148 NS_LOG_FUNCTION(this << interface);
149 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
150 rprotoIter++)
151 {
152 (*rprotoIter).second->NotifyInterfaceDown(interface);
153 }
154}
155
156void
158{
159 NS_LOG_FUNCTION(this << interface << address);
160 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
161 rprotoIter++)
162 {
163 (*rprotoIter).second->NotifyAddAddress(interface, address);
164 }
165}
166
167void
169{
170 NS_LOG_FUNCTION(this << interface << address);
171 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
172 rprotoIter++)
173 {
174 (*rprotoIter).second->NotifyRemoveAddress(interface, address);
175 }
176}
177
178void
180 Ipv6Prefix mask,
181 Ipv6Address nextHop,
182 uint32_t interface,
183 Ipv6Address prefixToUse)
184{
185 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
186 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
187 rprotoIter++)
188 {
189 (*rprotoIter).second->NotifyAddRoute(dst, mask, nextHop, interface, prefixToUse);
190 }
191}
192
193void
195 Ipv6Prefix mask,
196 Ipv6Address nextHop,
197 uint32_t interface,
198 Ipv6Address prefixToUse)
199{
200 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
201 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
202 rprotoIter++)
203 {
204 (*rprotoIter).second->NotifyRemoveRoute(dst, mask, nextHop, interface, prefixToUse);
205 }
206}
207
208void
210{
211 NS_LOG_FUNCTION(this);
212
213 *stream->GetStream() << "Node: " << m_ipv6->GetObject<Node>()->GetId()
214 << ", Time: " << Now().As(unit)
215 << ", Local time: " << m_ipv6->GetObject<Node>()->GetLocalTime().As(unit)
216 << ", Ipv6ListRouting table" << std::endl;
217 for (auto i = m_routingProtocols.begin(); i != m_routingProtocols.end(); i++)
218 {
219 *stream->GetStream() << " Priority: " << (*i).first
220 << " Protocol: " << (*i).second->GetInstanceTypeId() << std::endl;
221 (*i).second->PrintRoutingTable(stream, unit);
222 }
223}
224
225void
227{
228 NS_LOG_FUNCTION(this << ipv6);
230 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
231 rprotoIter++)
232 {
233 (*rprotoIter).second->SetIpv6(ipv6);
234 }
235 m_ipv6 = ipv6;
236}
237
238void
240{
241 NS_LOG_FUNCTION(this << routingProtocol->GetInstanceTypeId() << priority);
242 m_routingProtocols.emplace_back(priority, routingProtocol);
244 if (m_ipv6)
245 {
246 routingProtocol->SetIpv6(m_ipv6);
247 }
248}
249
252{
253 NS_LOG_FUNCTION(this);
254 return m_routingProtocols.size();
255}
256
258Ipv6ListRouting::GetRoutingProtocol(uint32_t index, int16_t& priority) const
259{
260 NS_LOG_FUNCTION(index);
261 if (index >= m_routingProtocols.size())
262 {
263 NS_FATAL_ERROR("Ipv6ListRouting::GetRoutingProtocol (): index " << index
264 << " out of range");
265 }
266 uint32_t i = 0;
267 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
268 rprotoIter++, i++)
269 {
270 if (i == index)
271 {
272 priority = (*rprotoIter).first;
273 return (*rprotoIter).second;
274 }
275 }
276 return nullptr;
277}
278
279bool
281{
282 return a.first > b.first;
283}
284
285} // namespace ns3
Describes an IPv6 address.
Packet header for IPv6.
Definition ipv6-header.h:24
Ipv6Address GetDestination() const
Get the "Destination address" field.
Ipv6Address GetSource() const
Get the "Source address" field.
virtual int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const =0
Get the interface index of the specified NetDevice.
virtual bool IsForwarding(uint32_t interface) const =0
If the specified IPv6 interface has forwarding enabled.
IPv6 address associated with an interface.
Hold list of Ipv6RoutingProtocol objects.
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
Print the Routing Table entries.
static TypeId GetTypeId()
Get the type ID of this class.
std::pair< int16_t, Ptr< Ipv6RoutingProtocol > > Ipv6RoutingProtocolEntry
Container identifying an IPv6 Routing Protocol entry in the list.
static bool Compare(const Ipv6RoutingProtocolEntry &a, const Ipv6RoutingProtocolEntry &b)
Compare two routing protocols.
void DoDispose() override
Dispose this object.
Ptr< Ipv6Route > RouteOutput(Ptr< Packet > p, const Ipv6Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr) override
Query routing cache for an existing route, for an outbound packet.
bool RouteInput(Ptr< const Packet > p, const Ipv6Header &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 uint32_t GetNRoutingProtocols() const
Get the number of routing protocols.
void SetIpv6(Ptr< Ipv6 > ipv6) override
Typically, invoked directly or indirectly from ns3::Ipv6::SetRoutingProtocol.
virtual Ptr< Ipv6RoutingProtocol > GetRoutingProtocol(uint32_t index, int16_t &priority) const
Get pointer to routing protocol stored at index,.
void NotifyAddAddress(uint32_t interface, Ipv6InterfaceAddress address) override
Notify when specified interface add an address.
Ipv6ListRouting()
Constructor.
void NotifyInterfaceDown(uint32_t interface) override
Notify when specified interface goes DOWN.
void NotifyRemoveAddress(uint32_t interface, Ipv6InterfaceAddress address) override
Notify when specified interface add an address.
void NotifyInterfaceUp(uint32_t interface) override
Notify when specified interface goes UP.
void NotifyAddRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero()) override
Notify a new route.
~Ipv6ListRouting() override
Destructor.
Ipv6RoutingProtocolList m_routingProtocols
List of routing protocols.
virtual void AddRoutingProtocol(Ptr< Ipv6RoutingProtocol > routingProtocol, int16_t priority)
Register a new routing protocol to be used in this IPv4 stack.
Ptr< Ipv6 > m_ipv6
Ipv6 this protocol is associated with.
void NotifyRemoveRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero()) override
Notify route removing.
Describes an IPv6 prefix.
Abstract base class for IPv6 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
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.