A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 NS_LOG_COMPONENT_DEFINE ("Ipv6ListRouting");
29 
30 namespace ns3 {
31 
32 NS_OBJECT_ENSURE_REGISTERED (Ipv6ListRouting)
33  ;
34 
35 TypeId
37 {
38  static TypeId tid = TypeId ("ns3::Ipv6ListRouting")
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  bool retVal = false;
105  NS_LOG_FUNCTION (p << header << idev);
106  NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv6->GetObject<Node> ()->GetId ());
107 
108  NS_ASSERT (m_ipv6 != 0);
109  // Check if input device supports IP
110  NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
111  uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
112  Ipv6Address dst = header.GetDestinationAddress ();
113 
114  // Multicast recognition; handle local delivery here
115  //
116  if (dst.IsMulticast ())
117  {
118 #ifdef NOTYET
119  if (m_ipv6->MulticastCheckGroup (iif, dst))
120 #endif
121  if (true)
122  {
123  NS_LOG_LOGIC ("Multicast packet for me-- local deliver");
124  Ptr<Packet> packetCopy = p->Copy ();
125  // Here may want to disable lcb callback in recursive RouteInput
126  // call below
127  lcb (packetCopy, header, iif);
128  // Fall through-- we may also need to forward this
129  retVal = true;
130  }
131 
132  /* do not forward link-local multicast address */
134  {
135  return retVal;
136  }
137 
138  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
139  m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end ();
140  rprotoIter++)
141  {
142  NS_LOG_LOGIC ("Multicast packet for me-- trying to forward");
143  if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
144  {
145  retVal = true;
146  }
147  }
148  return retVal;
149  }
150 
152  // Right now, we will be permissive and allow a source to send us
153  // a packet to one of our other interface addresses; that is, the
154  // destination unicast address does not match one of the iif addresses,
155  // but we check our other interfaces. This could be an option
156  // (to remove the outer loop immediately below and just check iif).
157  for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
158  {
159  for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
160  {
161  Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
162  Ipv6Address addr = iaddr.GetAddress ();
163  if (addr.IsEqual (header.GetDestinationAddress ()))
164  {
165  if (j == iif)
166  {
167  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
168  }
169  else
170  {
171  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
172  }
173  lcb (p, header, iif);
174  return true;
175  }
176  NS_LOG_LOGIC ("Address " << addr << " not a match");
177  }
178  }
179  // Check if input device supports IP forwarding
180  if (m_ipv6->IsForwarding (iif) == false)
181  {
182  NS_LOG_LOGIC ("Forwarding disabled for this interface");
183  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
184  return false;
185  }
186  // Next, try to find a route
187  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
188  m_routingProtocols.begin ();
189  rprotoIter != m_routingProtocols.end ();
190  rprotoIter++)
191  {
192  if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
193  {
194  return true;
195  }
196  }
197  // No routing protocol has found a route.
198  return retVal;
199 }
200 
201 void
203 {
204  NS_LOG_FUNCTION (this << interface);
205  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
206  m_routingProtocols.begin ();
207  rprotoIter != m_routingProtocols.end ();
208  rprotoIter++)
209  {
210  (*rprotoIter).second->NotifyInterfaceUp (interface);
211  }
212 }
213 void
215 {
216  NS_LOG_FUNCTION (this << interface);
217  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
218  m_routingProtocols.begin ();
219  rprotoIter != m_routingProtocols.end ();
220  rprotoIter++)
221  {
222  (*rprotoIter).second->NotifyInterfaceDown (interface);
223  }
224 }
225 void
227 {
228  NS_LOG_FUNCTION (this << interface << address);
229  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
230  m_routingProtocols.begin ();
231  rprotoIter != m_routingProtocols.end ();
232  rprotoIter++)
233  {
234  (*rprotoIter).second->NotifyAddAddress (interface, address);
235  }
236 }
237 void
239 {
240  NS_LOG_FUNCTION (this << interface << address);
241  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
242  m_routingProtocols.begin ();
243  rprotoIter != m_routingProtocols.end ();
244  rprotoIter++)
245  {
246  (*rprotoIter).second->NotifyRemoveAddress (interface, address);
247  }
248 }
249 
250 void Ipv6ListRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
251 {
252  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
253  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
254  m_routingProtocols.begin ();
255  rprotoIter != m_routingProtocols.end ();
256  rprotoIter++)
257  {
258  (*rprotoIter).second->NotifyAddRoute (dst, mask, nextHop, interface, prefixToUse);
259  }
260 }
261 
262 void Ipv6ListRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
263 {
264  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
265  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
266  m_routingProtocols.begin ();
267  rprotoIter != m_routingProtocols.end ();
268  rprotoIter++)
269  {
270  (*rprotoIter).second->NotifyRemoveRoute (dst, mask, nextHop, interface, prefixToUse);
271  }
272 }
273 
274 void
276 {
277  NS_LOG_FUNCTION (this);
278 
279  *stream->GetStream () << "Node: " << m_ipv6->GetObject<Node> ()->GetId ()
280  << " Time: " << Simulator::Now ().GetSeconds () << "s "
281  << "Ipv6ListRouting table" << std::endl;
282  for (Ipv6RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
283  i != m_routingProtocols.end (); i++)
284  {
285  *stream->GetStream () << " Priority: " << (*i).first << " Protocol: " << (*i).second->GetInstanceTypeId () << std::endl;
286  (*i).second->PrintRoutingTable (stream);
287  }
288  *stream->GetStream () << std::endl;
289 }
290 
291 void
293 {
294  NS_LOG_FUNCTION (this << ipv6);
295  NS_ASSERT (m_ipv6 == 0);
296  for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
297  m_routingProtocols.begin ();
298  rprotoIter != m_routingProtocols.end ();
299  rprotoIter++)
300  {
301  (*rprotoIter).second->SetIpv6 (ipv6);
302  }
303  m_ipv6 = ipv6;
304 }
305 
306 void
308 {
309  NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
310  m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
311  m_routingProtocols.sort ( Compare );
312  if (m_ipv6 != 0)
313  {
314  routingProtocol->SetIpv6 (m_ipv6);
315  }
316 }
317 
318 uint32_t
320 {
321  NS_LOG_FUNCTION (this);
322  return m_routingProtocols.size ();
323 }
324 
326 Ipv6ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
327 {
328  NS_LOG_FUNCTION (index);
329  if (index > m_routingProtocols.size ())
330  {
331  NS_FATAL_ERROR ("Ipv6ListRouting::GetRoutingProtocol (): index " << index << " out of range");
332  }
333  uint32_t i = 0;
334  for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
335  rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
336  {
337  if (i == index)
338  {
339  priority = (*rprotoIter).first;
340  return (*rprotoIter).second;
341  }
342  }
343  return 0;
344 }
345 
346 bool
348 {
349  return a.first > b.first;
350 }
351 
352 
353 } // namespace ns3
354 
Doxygen introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
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:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
virtual uint32_t GetNRoutingProtocols(void) const
Get the number of routing protocols.
Callback template class.
Definition: callback.h:920
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)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
IPv6 address associated with an interface.
bool IsEqual(const Ipv6Address &other) const
Comparison operation between two Ipv6Addresses.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
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.
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
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.
double GetSeconds(void) const
Definition: nstime.h:274
Ipv6Address GetAddress() const
Get the IPv6 address.
virtual void NotifyInterfaceUp(uint32_t interface)
Notify when specified interface goes UP.
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
virtual void SetIpv6(Ptr< Ipv6 > ipv6)
Typically, invoked directly or indirectly from ns3::Ipv6::SetRoutingProtocol.
static Ipv6Address GetAllHostsMulticast()
Get the "all hosts multicast" address.
Ptr< Packet > Copy(void) const
Definition: packet.cc:122
Ipv6ListRouting()
Constructor.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
std::pair< int16_t, Ptr< Ipv6RoutingProtocol > > Ipv6RoutingProtocolEntry
Container identifying an IPv6 Routing Protocol entry in the list.
static Ipv6Address GetAllNodesMulticast()
Get the "all nodes multicast" address.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
virtual ~Ipv6ListRouting()
Destructor.
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
Describes an IPv6 address.
Definition: ipv6-address.h:46
static TypeId GetTypeId(void)
Get the type ID of this class.
uint32_t GetId(void) const
Definition: node.cc:104
virtual void NotifyInterfaceDown(uint32_t interface)
Notify when specified interface goes DOWN.
A network Node.
Definition: node.h:55
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:102
Describes an IPv6 prefix.
Definition: ipv6-address.h:387
virtual void DoDispose(void)
Dispose this object.
tuple address
Definition: first.py:37
Abstract base class for Ipv6 routing protocols.
a unique identifier for an interface.
Definition: type-id.h:49
virtual Ptr< Ipv6RoutingProtocol > GetRoutingProtocol(uint32_t index, int16_t &priority) const
Get pointer to routing protocol stored at index,.
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
Ipv6RoutingProtocolList m_routingProtocols
List of routing protocols.
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:112
NS_LOG_COMPONENT_DEFINE("Ipv6ListRouting")
static Ipv6Address GetAllRoutersMulticast()
Get the "all routers multicast" address.
virtual void NotifyAddAddress(uint32_t interface, Ipv6InterfaceAddress address)
Notify when specified interface add an address.