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
23
26{
27 static TypeId tid = TypeId("ns3::Ipv6ListRouting")
29 .SetGroupName("Internet")
30 .AddConstructor<Ipv6ListRouting>();
31 return tid;
32}
33
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 (oif)
77 {
78 if (route && route->GetOutputDevice() != oif)
79 {
80 NS_LOG_LOGIC("Not on requested interface, skipping");
81 continue;
82 }
83 }
84 if (route)
85 {
86 NS_LOG_LOGIC("Found route " << route);
87 sockerr = Socket::ERROR_NOTERROR;
88 return route;
89 }
90 }
91 NS_LOG_LOGIC("Done checking " << GetTypeId());
92 NS_LOG_LOGIC("");
94 return nullptr;
95}
96
97// Patterned after Linux ip_route_input and ip_route_input_slow
98bool
100 const Ipv6Header& header,
102 const UnicastForwardCallback& ucb,
103 const MulticastForwardCallback& mcb,
104 const LocalDeliverCallback& lcb,
105 const ErrorCallback& ecb)
106{
107 NS_LOG_FUNCTION(p << header << idev);
108 NS_LOG_LOGIC("RouteInput logic for node: " << m_ipv6->GetObject<Node>()->GetId());
109
111 // Check if input device supports IP
112 NS_ASSERT(m_ipv6->GetInterfaceForDevice(idev) >= 0);
113
114 // Check if input device supports IP forwarding
115 uint32_t iif = m_ipv6->GetInterfaceForDevice(idev);
116 if (!m_ipv6->IsForwarding(iif))
117 {
118 NS_LOG_LOGIC("Forwarding disabled for this interface");
119 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
120 return true;
121 }
122
123 // We disable error callback for the called protocols.
124 ErrorCallback nullEcb =
126
127 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
128 rprotoIter++)
129 {
130 if ((*rprotoIter).second->RouteInput(p, header, idev, ucb, mcb, lcb, nullEcb))
131 {
132 return true;
133 }
134 }
135
136 // No routing protocol has found a route.
137 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
138 return false;
139}
140
141void
143{
144 NS_LOG_FUNCTION(this << interface);
145 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
146 rprotoIter++)
147 {
148 (*rprotoIter).second->NotifyInterfaceUp(interface);
149 }
150}
151
152void
154{
155 NS_LOG_FUNCTION(this << interface);
156 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
157 rprotoIter++)
158 {
159 (*rprotoIter).second->NotifyInterfaceDown(interface);
160 }
161}
162
163void
165{
166 NS_LOG_FUNCTION(this << interface << address);
167 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
168 rprotoIter++)
169 {
170 (*rprotoIter).second->NotifyAddAddress(interface, address);
171 }
172}
173
174void
176{
177 NS_LOG_FUNCTION(this << interface << address);
178 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
179 rprotoIter++)
180 {
181 (*rprotoIter).second->NotifyRemoveAddress(interface, address);
182 }
183}
184
185void
187 Ipv6Prefix mask,
188 Ipv6Address nextHop,
189 uint32_t interface,
190 Ipv6Address prefixToUse)
191{
192 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
193 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
194 rprotoIter++)
195 {
196 (*rprotoIter).second->NotifyAddRoute(dst, mask, nextHop, interface, prefixToUse);
197 }
198}
199
200void
202 Ipv6Prefix mask,
203 Ipv6Address nextHop,
204 uint32_t interface,
205 Ipv6Address prefixToUse)
206{
207 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
208 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
209 rprotoIter++)
210 {
211 (*rprotoIter).second->NotifyRemoveRoute(dst, mask, nextHop, interface, prefixToUse);
212 }
213}
214
215void
217{
218 NS_LOG_FUNCTION(this);
219
220 *stream->GetStream() << "Node: " << m_ipv6->GetObject<Node>()->GetId()
221 << ", Time: " << Now().As(unit)
222 << ", Local time: " << m_ipv6->GetObject<Node>()->GetLocalTime().As(unit)
223 << ", Ipv6ListRouting table" << std::endl;
224 for (auto i = m_routingProtocols.begin(); i != m_routingProtocols.end(); i++)
225 {
226 *stream->GetStream() << " Priority: " << (*i).first
227 << " Protocol: " << (*i).second->GetInstanceTypeId() << std::endl;
228 (*i).second->PrintRoutingTable(stream, unit);
229 }
230}
231
232void
234{
235 NS_LOG_FUNCTION(this << ipv6);
237 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
238 rprotoIter++)
239 {
240 (*rprotoIter).second->SetIpv6(ipv6);
241 }
242 m_ipv6 = ipv6;
243}
244
245void
247{
248 NS_LOG_FUNCTION(this << routingProtocol->GetInstanceTypeId() << priority);
249 m_routingProtocols.emplace_back(priority, routingProtocol);
251 if (m_ipv6)
252 {
253 routingProtocol->SetIpv6(m_ipv6);
254 }
255}
256
259{
260 NS_LOG_FUNCTION(this);
261 return m_routingProtocols.size();
262}
263
265Ipv6ListRouting::GetRoutingProtocol(uint32_t index, int16_t& priority) const
266{
267 NS_LOG_FUNCTION(index);
268 if (index >= m_routingProtocols.size())
269 {
270 NS_FATAL_ERROR("Ipv6ListRouting::GetRoutingProtocol (): index " << index
271 << " out of range");
272 }
273 uint32_t i = 0;
274 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
275 rprotoIter++, i++)
276 {
277 if (i == index)
278 {
279 priority = (*rprotoIter).first;
280 return (*rprotoIter).second;
281 }
282 }
283 return nullptr;
284}
285
286bool
288{
289 return a.first > b.first;
290}
291
292} // 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.
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.
Callback< void, Ptr< const Packet >, const Ipv6Header &, Socket::SocketErrno > ErrorCallback
Callback for routing errors (e.g., no route found).
Callback< void, Ptr< const NetDevice >, Ptr< Ipv6MulticastRoute >, Ptr< const Packet >, const Ipv6Header & > MulticastForwardCallback
Callback for multicast packets to be forwarded.
Callback< void, Ptr< const Packet >, const Ipv6Header &, uint32_t > LocalDeliverCallback
Callback for packets to be locally delivered.
Callback< void, Ptr< const NetDevice >, Ptr< Ipv6Route >, Ptr< const Packet >, const Ipv6Header & > UnicastForwardCallback
Callback for unicast packets to be forwarded.
A network Node.
Definition node.h:46
uint32_t GetId() const
Definition node.cc:106
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.