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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 */
18
19#include "ipv6-list-routing.h"
20
21#include "ipv6-route.h"
22#include "ipv6.h"
23
24#include "ns3/log.h"
25#include "ns3/node.h"
26#include "ns3/simulator.h"
27
28namespace ns3
29{
30
31NS_LOG_COMPONENT_DEFINE("Ipv6ListRouting");
32
33NS_OBJECT_ENSURE_REGISTERED(Ipv6ListRouting);
34
35TypeId
37{
38 static TypeId tid = TypeId("ns3::Ipv6ListRouting")
40 .SetGroupName("Internet")
41 .AddConstructor<Ipv6ListRouting>();
42 return tid;
43}
44
46 : m_ipv6(nullptr)
47{
48 NS_LOG_FUNCTION(this);
49}
50
52{
53 NS_LOG_FUNCTION(this);
54}
55
56void
58{
59 NS_LOG_FUNCTION(this);
60 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
61 rprotoIter++)
62 {
63 // Note: Calling dispose on these protocols causes memory leak
64 // The routing protocols should not maintain a pointer to
65 // this object, so Dispose () shouldn't be necessary.
66 (*rprotoIter).second = nullptr;
67 }
68 m_routingProtocols.clear();
69 m_ipv6 = nullptr;
70}
71
74 const Ipv6Header& header,
76 Socket::SocketErrno& sockerr)
77{
78 NS_LOG_FUNCTION(this << header.GetDestination() << header.GetSource() << oif);
79 Ptr<Ipv6Route> route;
80
81 for (auto i = m_routingProtocols.begin(); i != m_routingProtocols.end(); i++)
82 {
83 NS_LOG_LOGIC("Checking protocol " << (*i).second->GetInstanceTypeId() << " with priority "
84 << (*i).first);
85 NS_LOG_LOGIC("Requesting source address for destination " << header.GetDestination());
86 route = (*i).second->RouteOutput(p, header, oif, sockerr);
87 if (route)
88 {
89 NS_LOG_LOGIC("Found route " << route);
90 sockerr = Socket::ERROR_NOTERROR;
91 return route;
92 }
93 }
94 NS_LOG_LOGIC("Done checking " << GetTypeId());
95 NS_LOG_LOGIC("");
97 return nullptr;
98}
99
100// Patterned after Linux ip_route_input and ip_route_input_slow
101bool
103 const Ipv6Header& header,
105 const UnicastForwardCallback& ucb,
106 const MulticastForwardCallback& mcb,
107 const LocalDeliverCallback& lcb,
108 const ErrorCallback& ecb)
109{
110 NS_LOG_FUNCTION(p << header << idev);
111 NS_LOG_LOGIC("RouteInput logic for node: " << m_ipv6->GetObject<Node>()->GetId());
112
114 // Check if input device supports IP
115 NS_ASSERT(m_ipv6->GetInterfaceForDevice(idev) >= 0);
116 Ipv6Address dst = header.GetDestination();
117
118 // Check if input device supports IP forwarding
119 uint32_t iif = m_ipv6->GetInterfaceForDevice(idev);
120 if (!m_ipv6->IsForwarding(iif))
121 {
122 NS_LOG_LOGIC("Forwarding disabled for this interface");
123 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
124 return true;
125 }
126
127 // We disable error callback for the called protocols.
128 ErrorCallback nullEcb =
129 MakeNullCallback<void, Ptr<const Packet>, const Ipv6Header&, Socket::SocketErrno>();
130
131 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
132 rprotoIter++)
133 {
134 if ((*rprotoIter).second->RouteInput(p, header, idev, ucb, mcb, lcb, nullEcb))
135 {
136 return true;
137 }
138 }
139
140 // No routing protocol has found a route.
141 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
142 return false;
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->NotifyInterfaceUp(interface);
153 }
154}
155
156void
158{
159 NS_LOG_FUNCTION(this << interface);
160 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
161 rprotoIter++)
162 {
163 (*rprotoIter).second->NotifyInterfaceDown(interface);
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->NotifyAddAddress(interface, address);
175 }
176}
177
178void
180{
181 NS_LOG_FUNCTION(this << interface << address);
182 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
183 rprotoIter++)
184 {
185 (*rprotoIter).second->NotifyRemoveAddress(interface, address);
186 }
187}
188
189void
191 Ipv6Prefix mask,
192 Ipv6Address nextHop,
193 uint32_t interface,
194 Ipv6Address prefixToUse)
195{
196 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
197 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
198 rprotoIter++)
199 {
200 (*rprotoIter).second->NotifyAddRoute(dst, mask, nextHop, interface, prefixToUse);
201 }
202}
203
204void
206 Ipv6Prefix mask,
207 Ipv6Address nextHop,
208 uint32_t interface,
209 Ipv6Address prefixToUse)
210{
211 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
212 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
213 rprotoIter++)
214 {
215 (*rprotoIter).second->NotifyRemoveRoute(dst, mask, nextHop, interface, prefixToUse);
216 }
217}
218
219void
221{
222 NS_LOG_FUNCTION(this);
223
224 *stream->GetStream() << "Node: " << m_ipv6->GetObject<Node>()->GetId()
225 << ", Time: " << Now().As(unit)
226 << ", Local time: " << m_ipv6->GetObject<Node>()->GetLocalTime().As(unit)
227 << ", Ipv6ListRouting table" << std::endl;
228 for (auto i = m_routingProtocols.begin(); i != m_routingProtocols.end(); i++)
229 {
230 *stream->GetStream() << " Priority: " << (*i).first
231 << " Protocol: " << (*i).second->GetInstanceTypeId() << std::endl;
232 (*i).second->PrintRoutingTable(stream, unit);
233 }
234}
235
236void
238{
239 NS_LOG_FUNCTION(this << ipv6);
241 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
242 rprotoIter++)
243 {
244 (*rprotoIter).second->SetIpv6(ipv6);
245 }
246 m_ipv6 = ipv6;
247}
248
249void
251{
252 NS_LOG_FUNCTION(this << routingProtocol->GetInstanceTypeId() << priority);
253 m_routingProtocols.emplace_back(priority, routingProtocol);
255 if (m_ipv6)
256 {
257 routingProtocol->SetIpv6(m_ipv6);
258 }
259}
260
263{
264 NS_LOG_FUNCTION(this);
265 return m_routingProtocols.size();
266}
267
269Ipv6ListRouting::GetRoutingProtocol(uint32_t index, int16_t& priority) const
270{
271 NS_LOG_FUNCTION(index);
272 if (index >= m_routingProtocols.size())
273 {
274 NS_FATAL_ERROR("Ipv6ListRouting::GetRoutingProtocol (): index " << index
275 << " out of range");
276 }
277 uint32_t i = 0;
278 for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
279 rprotoIter++, i++)
280 {
281 if (i == index)
282 {
283 priority = (*rprotoIter).first;
284 return (*rprotoIter).second;
285 }
286 }
287 return nullptr;
288}
289
290bool
292{
293 return a.first > b.first;
294}
295
296} // namespace ns3
Describes an IPv6 address.
Definition: ipv6-address.h:49
Packet header for IPv6.
Definition: ipv6-header.h:35
Ipv6Address GetDestination() const
Get the "Destination address" field.
Definition: ipv6-header.cc:124
Ipv6Address GetSource() const
Get the "Source address" field.
Definition: ipv6-header.cc:112
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.
Definition: ipv6-address.h:455
Abstract base class for IPv6 routing protocols.
A network Node.
Definition: node.h:57
uint32_t GetId() const
Definition: node.cc:117
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
@ ERROR_NOROUTETOHOST
Definition: socket.h:95
@ ERROR_NOTERROR
Definition: socket.h:85
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:111
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
Every class exported by the ns3 library is enclosed in the ns3 namespace.