A Discrete-Event Network Simulator
API
ipv6-list-routing.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2009 University of Washington
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19
20#include "ns3/log.h"
21#include "ns3/ipv6.h"
22#include "ns3/ipv6-route.h"
23#include "ns3/node.h"
24#include "ns3/ipv6-static-routing.h"
25#include "ipv6-list-routing.h"
26#include "ns3/simulator.h"
27
28namespace ns3 {
29
30NS_LOG_COMPONENT_DEFINE ("Ipv6ListRouting");
31
32NS_OBJECT_ENSURE_REGISTERED (Ipv6ListRouting);
33
34TypeId
36{
37 static TypeId tid = TypeId ("ns3::Ipv6ListRouting")
39 .SetGroupName ("Internet")
40 .AddConstructor<Ipv6ListRouting> ()
41 ;
42 return tid;
43}
44
45
47 : m_ipv6 (0)
48{
49 NS_LOG_FUNCTION (this);
50}
51
53{
54 NS_LOG_FUNCTION (this);
55}
56
57void
59{
60 NS_LOG_FUNCTION (this);
61 for (Ipv6RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
62 rprotoIter != m_routingProtocols.end (); rprotoIter++)
63 {
64 // Note: Calling dispose on these protocols causes memory leak
65 // The routing protocols should not maintain a pointer to
66 // this object, so Dispose () shouldn't be necessary.
67 (*rprotoIter).second = 0;
68 }
69 m_routingProtocols.clear ();
70 m_ipv6 = 0;
71}
72
75{
76 NS_LOG_FUNCTION (this << header.GetDestination () << header.GetSource () << oif);
77 Ptr<Ipv6Route> route;
78
79 for (Ipv6RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
80 i != m_routingProtocols.end (); i++)
81 {
82 NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first);
83 NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestination ());
84 route = (*i).second->RouteOutput (p, header, oif, sockerr);
85 if (route)
86 {
87 NS_LOG_LOGIC ("Found route " << route);
88 sockerr = Socket::ERROR_NOTERROR;
89 return route;
90 }
91 }
92 NS_LOG_LOGIC ("Done checking " << GetTypeId ());
93 NS_LOG_LOGIC ("");
95 return 0;
96}
97
98// Patterned after Linux ip_route_input and ip_route_input_slow
99bool
103{
104 NS_LOG_FUNCTION (p << header << idev);
105 NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv6->GetObject<Node> ()->GetId ());
106
107 NS_ASSERT (m_ipv6 != 0);
108 // Check if input device supports IP
109 NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
110 Ipv6Address dst = header.GetDestination ();
111
112 // Check if input device supports IP forwarding
113 uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
114 if (m_ipv6->IsForwarding (iif) == false)
115 {
116 NS_LOG_LOGIC ("Forwarding disabled for this interface");
117 ecb (p, header, Socket::ERROR_NOROUTETOHOST);
118 return true;
119 }
120
121 // We disable error callback for the called protocols.
122 ErrorCallback nullEcb = MakeNullCallback<void, Ptr<const Packet>, const Ipv6Header &, Socket::SocketErrno > ();
123
124 for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
125 rprotoIter != m_routingProtocols.end ();
126 rprotoIter++)
127 {
128 if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, nullEcb))
129 {
130 return true;
131 }
132 }
133
134 // No routing protocol has found a route.
135 ecb (p, header, Socket::ERROR_NOROUTETOHOST);
136 return false;
137}
138
139void
141{
142 NS_LOG_FUNCTION (this << interface);
143 for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
144 m_routingProtocols.begin ();
145 rprotoIter != m_routingProtocols.end ();
146 rprotoIter++)
147 {
148 (*rprotoIter).second->NotifyInterfaceUp (interface);
149 }
150}
151void
153{
154 NS_LOG_FUNCTION (this << interface);
155 for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
156 m_routingProtocols.begin ();
157 rprotoIter != m_routingProtocols.end ();
158 rprotoIter++)
159 {
160 (*rprotoIter).second->NotifyInterfaceDown (interface);
161 }
162}
163void
165{
166 NS_LOG_FUNCTION (this << interface << address);
167 for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
168 m_routingProtocols.begin ();
169 rprotoIter != m_routingProtocols.end ();
170 rprotoIter++)
171 {
172 (*rprotoIter).second->NotifyAddAddress (interface, address);
173 }
174}
175void
177{
178 NS_LOG_FUNCTION (this << interface << address);
179 for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
180 m_routingProtocols.begin ();
181 rprotoIter != m_routingProtocols.end ();
182 rprotoIter++)
183 {
184 (*rprotoIter).second->NotifyRemoveAddress (interface, address);
185 }
186}
187
189{
190 NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
191 for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
192 m_routingProtocols.begin ();
193 rprotoIter != m_routingProtocols.end ();
194 rprotoIter++)
195 {
196 (*rprotoIter).second->NotifyAddRoute (dst, mask, nextHop, interface, prefixToUse);
197 }
198}
199
201{
202 NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
203 for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
204 m_routingProtocols.begin ();
205 rprotoIter != m_routingProtocols.end ();
206 rprotoIter++)
207 {
208 (*rprotoIter).second->NotifyRemoveRoute (dst, mask, nextHop, interface, prefixToUse);
209 }
210}
211
212void
214{
215 NS_LOG_FUNCTION (this);
216
217 *stream->GetStream () << "Node: " << m_ipv6->GetObject<Node> ()->GetId ()
218 << ", Time: " << Now().As (unit)
219 << ", Local time: " << m_ipv6->GetObject<Node> ()->GetLocalTime ().As (unit)
220 << ", Ipv6ListRouting table" << std::endl;
221 for (Ipv6RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
222 i != m_routingProtocols.end (); i++)
223 {
224 *stream->GetStream () << " Priority: " << (*i).first << " Protocol: " << (*i).second->GetInstanceTypeId () << std::endl;
225 (*i).second->PrintRoutingTable (stream, unit);
226 }
227}
228
229void
231{
232 NS_LOG_FUNCTION (this << ipv6);
233 NS_ASSERT (m_ipv6 == 0);
234 for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
235 m_routingProtocols.begin ();
236 rprotoIter != m_routingProtocols.end ();
237 rprotoIter++)
238 {
239 (*rprotoIter).second->SetIpv6 (ipv6);
240 }
241 m_ipv6 = ipv6;
242}
243
244void
246{
247 NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
248 m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
250 if (m_ipv6 != 0)
251 {
252 routingProtocol->SetIpv6 (m_ipv6);
253 }
254}
255
258{
259 NS_LOG_FUNCTION (this);
260 return m_routingProtocols.size ();
261}
262
264Ipv6ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
265{
266 NS_LOG_FUNCTION (index);
267 if (index > m_routingProtocols.size ())
268 {
269 NS_FATAL_ERROR ("Ipv6ListRouting::GetRoutingProtocol (): index " << index << " out of range");
270 }
271 uint32_t i = 0;
272 for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
273 rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
274 {
275 if (i == index)
276 {
277 priority = (*rprotoIter).first;
278 return (*rprotoIter).second;
279 }
280 }
281 return 0;
282}
283
284bool
286{
287 return a.first > b.first;
288}
289
290
291} // namespace ns3
292
Callback template class.
Definition: callback.h:1279
Describes an IPv6 address.
Definition: ipv6-address.h:50
Packet header for IPv6.
Definition: ipv6-header.h:36
Ipv6Address GetSource(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:105
Ipv6Address GetDestination(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:125
IPv6 address associated with an interface.
Hold list of Ipv6RoutingProtocol objects.
virtual ~Ipv6ListRouting()
Destructor.
virtual void NotifyRemoveRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero())
Notify route removing.
virtual Ptr< Ipv6Route > RouteOutput(Ptr< Packet > p, const Ipv6Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
virtual bool RouteInput(Ptr< const Packet > p, const Ipv6Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
virtual void NotifyInterfaceDown(uint32_t interface)
Notify when specified interface goes DOWN.
static TypeId GetTypeId(void)
Get the type ID of this class.
std::pair< int16_t, Ptr< Ipv6RoutingProtocol > > Ipv6RoutingProtocolEntry
Container identifying an IPv6 Routing Protocol entry in the list.
virtual void NotifyAddRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero())
Notify a new route.
static bool Compare(const Ipv6RoutingProtocolEntry &a, const Ipv6RoutingProtocolEntry &b)
Compare two routing protocols.
virtual void NotifyRemoveAddress(uint32_t interface, Ipv6InterfaceAddress address)
Notify when specified interface add an address.
virtual void NotifyAddAddress(uint32_t interface, Ipv6InterfaceAddress address)
Notify when specified interface add an address.
virtual void DoDispose(void)
Dispose this object.
virtual Ptr< Ipv6RoutingProtocol > GetRoutingProtocol(uint32_t index, int16_t &priority) const
Get pointer to routing protocol stored at index,.
virtual uint32_t GetNRoutingProtocols(void) const
Get the number of routing protocols.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
Ipv6ListRouting()
Constructor.
virtual void SetIpv6(Ptr< Ipv6 > ipv6)
Typically, invoked directly or indirectly from ns3::Ipv6::SetRoutingProtocol.
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.
virtual void NotifyInterfaceUp(uint32_t interface)
Notify when specified interface goes UP.
Describes an IPv6 prefix.
Definition: ipv6-address.h:456
Abstract base class for IPv6 routing protocols.
A network Node.
Definition: node.h:57
uint32_t GetId(void) const
Definition: node.cc:109
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
@ ERROR_NOROUTETOHOST
Definition: socket.h:93
@ ERROR_NOTERROR
Definition: socket.h:83
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:109
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:432
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#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:45
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
address
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.