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 
28 namespace ns3 {
29 
30 NS_LOG_COMPONENT_DEFINE ("Ipv6ListRouting");
31 
32 NS_OBJECT_ENSURE_REGISTERED (Ipv6ListRouting);
33 
34 TypeId
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 {
50 }
51 
53 {
55 }
56 
57 void
59 {
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.GetDestinationAddress () << header.GetSourceAddress () << 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.GetDestinationAddress ());
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
99 bool
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.GetDestinationAddress ();
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 
139 void
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 }
151 void
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 }
163 void
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 }
175 void
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 
188 void Ipv6ListRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
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 
200 void Ipv6ListRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
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 
212 void
214 {
215  NS_LOG_FUNCTION (this);
216 
217  *stream->GetStream () << "Node: " << m_ipv6->GetObject<Node> ()->GetId ()
218  << ", Time: " << Now().As (unit)
219  << ", Local time: " << 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 
229 void
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 
244 void
246 {
247  NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
248  m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
249  m_routingProtocols.sort ( Compare );
250  if (m_ipv6 != 0)
251  {
252  routingProtocol->SetIpv6 (m_ipv6);
253  }
254 }
255 
256 uint32_t
258 {
259  NS_LOG_FUNCTION (this);
260  return m_routingProtocols.size ();
261 }
262 
264 Ipv6ListRouting::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 
284 bool
286 {
287  return a.first > b.first;
288 }
289 
290 
291 } // namespace ns3
292 
Packet header for IPv6.
Definition: ipv6-header.h:34
virtual void NotifyRemoveAddress(uint32_t interface, Ipv6InterfaceAddress address)
Notify when specified interface add an address.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Callback template class.
Definition: callback.h:1176
uint32_t GetId(void) const
Definition: node.cc:107
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
virtual Ptr< Ipv6RoutingProtocol > GetRoutingProtocol(uint32_t index, int16_t &priority) const
Get pointer to routing protocol stored at index,.
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.
#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_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
IPv6 address associated with an interface.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
virtual void AddRoutingProtocol(Ptr< Ipv6RoutingProtocol > routingProtocol, int16_t priority)
Register a new routing protocol to be used in this IPv4 stack.
virtual void NotifyAddRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero())
Notify a new route.
Ptr< Ipv6 > m_ipv6
Ipv6 this protocol is associated with.
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)
static bool Compare(const Ipv6RoutingProtocolEntry &a, const Ipv6RoutingProtocolEntry &b)
Compare two routing protocols.
virtual void NotifyRemoveRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero())
Notify route removing.
virtual void NotifyInterfaceUp(uint32_t interface)
Notify when specified interface goes UP.
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:108
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:100
virtual void SetIpv6(Ptr< Ipv6 > ipv6)
Typically, invoked directly or indirectly from ns3::Ipv6::SetRoutingProtocol.
Ipv6ListRouting()
Constructor.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
address
Definition: first.py:37
std::pair< int16_t, Ptr< Ipv6RoutingProtocol > > Ipv6RoutingProtocolEntry
Container identifying an IPv6 Routing Protocol entry in the list.
virtual ~Ipv6ListRouting()
Destructor.
virtual uint32_t GetNRoutingProtocols(void) const
Get the number of routing protocols.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
Describes an IPv6 address.
Definition: ipv6-address.h:49
static TypeId GetTypeId(void)
Get the type ID of this class.
virtual void NotifyInterfaceDown(uint32_t interface)
Notify when specified interface goes DOWN.
A network Node.
Definition: node.h:56
Describes an IPv6 prefix.
Definition: ipv6-address.h:428
Hold list of Ipv6RoutingProtocol objects.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:365
virtual void DoDispose(void)
Dispose this object.
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:110
Abstract base class for IPv6 routing protocols.
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
Ipv6RoutingProtocolList m_routingProtocols
List of routing protocols.
virtual void NotifyAddAddress(uint32_t interface, Ipv6InterfaceAddress address)
Notify when specified interface add an address.