A Discrete-Event Network Simulator
API
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 "ns3/ipv6-route.h"
22 #include "ns3/ipv6-static-routing.h"
23 #include "ns3/ipv6.h"
24 #include "ns3/log.h"
25 #include "ns3/node.h"
26 #include "ns3/simulator.h"
27 
28 namespace ns3
29 {
30 
31 NS_LOG_COMPONENT_DEFINE("Ipv6ListRouting");
32 
33 NS_OBJECT_ENSURE_REGISTERED(Ipv6ListRouting);
34 
35 TypeId
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 
56 void
58 {
59  NS_LOG_FUNCTION(this);
60  for (Ipv6RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin();
61  rprotoIter != m_routingProtocols.end();
62  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 = nullptr;
68  }
69  m_routingProtocols.clear();
70  m_ipv6 = nullptr;
71 }
72 
75  const Ipv6Header& header,
76  Ptr<NetDevice> oif,
77  enum Socket::SocketErrno& sockerr)
78 {
79  NS_LOG_FUNCTION(this << header.GetDestination() << header.GetSource() << oif);
80  Ptr<Ipv6Route> route;
81 
82  for (Ipv6RoutingProtocolList::const_iterator i = m_routingProtocols.begin();
83  i != m_routingProtocols.end();
84  i++)
85  {
86  NS_LOG_LOGIC("Checking protocol " << (*i).second->GetInstanceTypeId() << " with priority "
87  << (*i).first);
88  NS_LOG_LOGIC("Requesting source address for destination " << header.GetDestination());
89  route = (*i).second->RouteOutput(p, header, oif, sockerr);
90  if (route)
91  {
92  NS_LOG_LOGIC("Found route " << route);
93  sockerr = Socket::ERROR_NOTERROR;
94  return route;
95  }
96  }
97  NS_LOG_LOGIC("Done checking " << GetTypeId());
98  NS_LOG_LOGIC("");
100  return nullptr;
101 }
102 
103 // Patterned after Linux ip_route_input and ip_route_input_slow
104 bool
106  const Ipv6Header& header,
111  ErrorCallback ecb)
112 {
113  NS_LOG_FUNCTION(p << header << idev);
114  NS_LOG_LOGIC("RouteInput logic for node: " << m_ipv6->GetObject<Node>()->GetId());
115 
116  NS_ASSERT(m_ipv6);
117  // Check if input device supports IP
118  NS_ASSERT(m_ipv6->GetInterfaceForDevice(idev) >= 0);
119  Ipv6Address dst = header.GetDestination();
120 
121  // Check if input device supports IP forwarding
122  uint32_t iif = m_ipv6->GetInterfaceForDevice(idev);
123  if (m_ipv6->IsForwarding(iif) == false)
124  {
125  NS_LOG_LOGIC("Forwarding disabled for this interface");
126  ecb(p, header, Socket::ERROR_NOROUTETOHOST);
127  return true;
128  }
129 
130  // We disable error callback for the called protocols.
131  ErrorCallback nullEcb =
132  MakeNullCallback<void, Ptr<const Packet>, const Ipv6Header&, Socket::SocketErrno>();
133 
134  for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin();
135  rprotoIter != m_routingProtocols.end();
136  rprotoIter++)
137  {
138  if ((*rprotoIter).second->RouteInput(p, header, idev, ucb, mcb, lcb, nullEcb))
139  {
140  return true;
141  }
142  }
143 
144  // No routing protocol has found a route.
145  ecb(p, header, Socket::ERROR_NOROUTETOHOST);
146  return false;
147 }
148 
149 void
151 {
152  NS_LOG_FUNCTION(this << interface);
153  for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin();
154  rprotoIter != m_routingProtocols.end();
155  rprotoIter++)
156  {
157  (*rprotoIter).second->NotifyInterfaceUp(interface);
158  }
159 }
160 
161 void
163 {
164  NS_LOG_FUNCTION(this << interface);
165  for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin();
166  rprotoIter != m_routingProtocols.end();
167  rprotoIter++)
168  {
169  (*rprotoIter).second->NotifyInterfaceDown(interface);
170  }
171 }
172 
173 void
175 {
176  NS_LOG_FUNCTION(this << interface << address);
177  for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin();
178  rprotoIter != m_routingProtocols.end();
179  rprotoIter++)
180  {
181  (*rprotoIter).second->NotifyAddAddress(interface, address);
182  }
183 }
184 
185 void
187 {
188  NS_LOG_FUNCTION(this << interface << address);
189  for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin();
190  rprotoIter != m_routingProtocols.end();
191  rprotoIter++)
192  {
193  (*rprotoIter).second->NotifyRemoveAddress(interface, address);
194  }
195 }
196 
197 void
199  Ipv6Prefix mask,
200  Ipv6Address nextHop,
201  uint32_t interface,
202  Ipv6Address prefixToUse)
203 {
204  NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
205  for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin();
206  rprotoIter != m_routingProtocols.end();
207  rprotoIter++)
208  {
209  (*rprotoIter).second->NotifyAddRoute(dst, mask, nextHop, interface, prefixToUse);
210  }
211 }
212 
213 void
215  Ipv6Prefix mask,
216  Ipv6Address nextHop,
217  uint32_t interface,
218  Ipv6Address prefixToUse)
219 {
220  NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
221  for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin();
222  rprotoIter != m_routingProtocols.end();
223  rprotoIter++)
224  {
225  (*rprotoIter).second->NotifyRemoveRoute(dst, mask, nextHop, interface, prefixToUse);
226  }
227 }
228 
229 void
231 {
232  NS_LOG_FUNCTION(this);
233 
234  *stream->GetStream() << "Node: " << m_ipv6->GetObject<Node>()->GetId()
235  << ", Time: " << Now().As(unit)
236  << ", Local time: " << m_ipv6->GetObject<Node>()->GetLocalTime().As(unit)
237  << ", Ipv6ListRouting table" << std::endl;
238  for (Ipv6RoutingProtocolList::const_iterator i = m_routingProtocols.begin();
239  i != m_routingProtocols.end();
240  i++)
241  {
242  *stream->GetStream() << " Priority: " << (*i).first
243  << " Protocol: " << (*i).second->GetInstanceTypeId() << std::endl;
244  (*i).second->PrintRoutingTable(stream, unit);
245  }
246 }
247 
248 void
250 {
251  NS_LOG_FUNCTION(this << ipv6);
252  NS_ASSERT(!m_ipv6);
253  for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin();
254  rprotoIter != m_routingProtocols.end();
255  rprotoIter++)
256  {
257  (*rprotoIter).second->SetIpv6(ipv6);
258  }
259  m_ipv6 = ipv6;
260 }
261 
262 void
264 {
265  NS_LOG_FUNCTION(this << routingProtocol->GetInstanceTypeId() << priority);
266  m_routingProtocols.emplace_back(priority, routingProtocol);
268  if (m_ipv6)
269  {
270  routingProtocol->SetIpv6(m_ipv6);
271  }
272 }
273 
274 uint32_t
276 {
277  NS_LOG_FUNCTION(this);
278  return m_routingProtocols.size();
279 }
280 
282 Ipv6ListRouting::GetRoutingProtocol(uint32_t index, int16_t& priority) const
283 {
284  NS_LOG_FUNCTION(index);
285  if (index >= m_routingProtocols.size())
286  {
287  NS_FATAL_ERROR("Ipv6ListRouting::GetRoutingProtocol (): index " << index
288  << " out of range");
289  }
290  uint32_t i = 0;
291  for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin();
292  rprotoIter != m_routingProtocols.end();
293  rprotoIter++, i++)
294  {
295  if (i == index)
296  {
297  priority = (*rprotoIter).first;
298  return (*rprotoIter).second;
299  }
300  }
301  return nullptr;
302 }
303 
304 bool
306 {
307  return a.first > b.first;
308 }
309 
310 } // namespace ns3
Callback template class.
Definition: callback.h:443
Describes an IPv6 address.
Definition: ipv6-address.h:50
Packet header for IPv6.
Definition: ipv6-header.h:36
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.
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.
bool RouteInput(Ptr< const Packet > p, const Ipv6Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb) override
Route an input packet (to be forwarded or locally delivered)
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:456
Abstract base class for IPv6 routing protocols.
A network Node.
Definition: node.h:56
uint32_t GetId() const
Definition: node.cc:117
std::ostream * GetStream()
Return a pointer to an ostream previously set in the wrapper.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
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:417
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:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
#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:296
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.