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 (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
104 NS_ASSERT(m_ipv6->GetInterfaceForDevice(idev) >= 0);
105
106 // Check if input device supports IP forwarding
107 uint32_t iif = m_ipv6->GetInterfaceForDevice(idev);
108 if (!m_ipv6->IsForwarding(iif))
109 {
110 NS_LOG_LOGIC("Forwarding disabled for this interface");
111 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
112 return true;
113 }
114
115 // We disable error callback for the called protocols.
116 ErrorCallback nullEcb =
118
119 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
120 rprotoIter++)
121 {
122 if ((*rprotoIter).second->RouteInput(p, header, idev, ucb, mcb, lcb, nullEcb))
123 {
124 return true;
125 }
126 }
127
128 // No routing protocol has found a route.
129 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
130 return false;
131}
132
133void
135{
136 NS_LOG_FUNCTION(this << interface);
137 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
138 rprotoIter++)
139 {
140 (*rprotoIter).second->NotifyInterfaceUp(interface);
141 }
142}
143
144void
146{
147 NS_LOG_FUNCTION(this << interface);
148 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
149 rprotoIter++)
150 {
151 (*rprotoIter).second->NotifyInterfaceDown(interface);
152 }
153}
154
155void
157{
158 NS_LOG_FUNCTION(this << interface << address);
159 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
160 rprotoIter++)
161 {
162 (*rprotoIter).second->NotifyAddAddress(interface, address);
163 }
164}
165
166void
168{
169 NS_LOG_FUNCTION(this << interface << address);
170 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
171 rprotoIter++)
172 {
173 (*rprotoIter).second->NotifyRemoveAddress(interface, address);
174 }
175}
176
177void
179 Ipv6Prefix mask,
180 Ipv6Address nextHop,
181 uint32_t interface,
182 Ipv6Address prefixToUse)
183{
184 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
185 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
186 rprotoIter++)
187 {
188 (*rprotoIter).second->NotifyAddRoute(dst, mask, nextHop, interface, prefixToUse);
189 }
190}
191
192void
194 Ipv6Prefix mask,
195 Ipv6Address nextHop,
196 uint32_t interface,
197 Ipv6Address prefixToUse)
198{
199 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
200 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
201 rprotoIter++)
202 {
203 (*rprotoIter).second->NotifyRemoveRoute(dst, mask, nextHop, interface, prefixToUse);
204 }
205}
206
207void
209{
210 NS_LOG_FUNCTION(this);
211
212 *stream->GetStream() << "Node: " << m_ipv6->GetObject<Node>()->GetId()
213 << ", Time: " << Now().As(unit)
214 << ", Local time: " << m_ipv6->GetObject<Node>()->GetLocalTime().As(unit)
215 << ", Ipv6ListRouting table" << std::endl;
216 for (auto i = m_routingProtocols.begin(); i != m_routingProtocols.end(); i++)
217 {
218 *stream->GetStream() << " Priority: " << (*i).first
219 << " Protocol: " << (*i).second->GetInstanceTypeId() << std::endl;
220 (*i).second->PrintRoutingTable(stream, unit);
221 }
222}
223
224void
226{
227 NS_LOG_FUNCTION(this << ipv6);
229 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
230 rprotoIter++)
231 {
232 (*rprotoIter).second->SetIpv6(ipv6);
233 }
234 m_ipv6 = ipv6;
235}
236
237void
239{
240 NS_LOG_FUNCTION(this << routingProtocol->GetInstanceTypeId() << priority);
241 m_routingProtocols.emplace_back(priority, routingProtocol);
243 if (m_ipv6)
244 {
245 routingProtocol->SetIpv6(m_ipv6);
246 }
247}
248
251{
252 NS_LOG_FUNCTION(this);
253 return m_routingProtocols.size();
254}
255
257Ipv6ListRouting::GetRoutingProtocol(uint32_t index, int16_t& priority) const
258{
259 NS_LOG_FUNCTION(index);
260 if (index >= m_routingProtocols.size())
261 {
262 NS_FATAL_ERROR("Ipv6ListRouting::GetRoutingProtocol (): index " << index
263 << " out of range");
264 }
265 uint32_t i = 0;
266 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
267 rprotoIter++, i++)
268 {
269 if (i == index)
270 {
271 priority = (*rprotoIter).first;
272 return (*rprotoIter).second;
273 }
274 }
275 return nullptr;
276}
277
278bool
280{
281 return a.first > b.first;
282}
283
284} // 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:67
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:409
Unit
The unit to use to interpret a number representing time.
Definition nstime.h:102
a unique identifier for an interface.
Definition type-id.h:49
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.