A Discrete-Event Network Simulator
API
ipv6-static-routing.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007-2009 Strasbourg University
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  * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
19  */
20 
21 #include <iomanip>
22 #include "ns3/log.h"
23 #include "ns3/node.h"
24 #include "ns3/packet.h"
25 #include "ns3/simulator.h"
26 #include "ns3/ipv6-route.h"
27 #include "ns3/net-device.h"
28 #include "ns3/names.h"
29 
30 #include "ipv6-static-routing.h"
32 
33 namespace ns3 {
34 
35 NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRouting");
36 
37 NS_OBJECT_ENSURE_REGISTERED (Ipv6StaticRouting);
38 
40 {
41  static TypeId tid = TypeId ("ns3::Ipv6StaticRouting")
43  .SetGroupName ("Internet")
44  .AddConstructor<Ipv6StaticRouting> ()
45  ;
46  return tid;
47 }
48 
50  : m_ipv6 (0)
51 {
52  NS_LOG_FUNCTION (this);
53 }
54 
56 {
57  NS_LOG_FUNCTION (this);
58 }
59 
61 {
62  NS_LOG_FUNCTION (this << ipv6);
63  NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
64  uint32_t i = 0;
65  m_ipv6 = ipv6;
66 
67  for (i = 0; i < m_ipv6->GetNInterfaces (); i++)
68  {
69  if (m_ipv6->IsUp (i))
70  {
72  }
73  else
74  {
76  }
77  }
78 }
79 
80 // Formatted like output of "route -n" command
81 void
83 {
84  NS_LOG_FUNCTION (this << stream);
85  std::ostream* os = stream->GetStream ();
86 
87  *os << "Node: " << m_ipv6->GetObject<Node> ()->GetId ()
88  << ", Time: " << Now().As (unit)
89  << ", Local time: " << m_ipv6->GetObject<Node> ()->GetLocalTime ().As (unit)
90  << ", Ipv6StaticRouting table" << std::endl;
91 
92  if (GetNRoutes () > 0)
93  {
94  *os << "Destination Next Hop Flag Met Ref Use If" << std::endl;
95  for (uint32_t j = 0; j < GetNRoutes (); j++)
96  {
97  std::ostringstream dest, gw, mask, flags;
98  Ipv6RoutingTableEntry route = GetRoute (j);
99  dest << route.GetDest () << "/" << int(route.GetDestNetworkPrefix ().GetPrefixLength ());
100  *os << std::setiosflags (std::ios::left) << std::setw (31) << dest.str ();
101  gw << route.GetGateway ();
102  *os << std::setiosflags (std::ios::left) << std::setw (27) << gw.str ();
103  flags << "U";
104  if (route.IsHost ())
105  {
106  flags << "H";
107  }
108  else if (route.IsGateway ())
109  {
110  flags << "G";
111  }
112  *os << std::setiosflags (std::ios::left) << std::setw (5) << flags.str ();
113  *os << std::setiosflags (std::ios::left) << std::setw (4) << GetMetric (j);
114  // Ref ct not implemented
115  *os << "-" << " ";
116  // Use not implemented
117  *os << "-" << " ";
118  if (Names::FindName (m_ipv6->GetNetDevice (route.GetInterface ())) != "")
119  {
120  *os << Names::FindName (m_ipv6->GetNetDevice (route.GetInterface ()));
121  }
122  else
123  {
124  *os << route.GetInterface ();
125  }
126  *os << std::endl;
127  }
128  }
129  *os << std::endl;
130 }
131 
132 void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
133 {
134  NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse << metric);
135  if (nextHop.IsLinkLocal())
136  {
137  NS_LOG_WARN ("Ipv6StaticRouting::AddHostRouteTo - Next hop should be link-local");
138  }
139 
140  AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse, metric);
141 }
142 
143 void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, uint32_t interface, uint32_t metric)
144 {
145  NS_LOG_FUNCTION (this << dst << interface << metric);
146  AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), interface, metric);
147 }
148 
149 void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric)
150 {
151  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << metric);
152 
153  Ipv6RoutingTableEntry route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface);
154 
155  if (!LookupRoute (route, metric))
156  {
157  Ipv6RoutingTableEntry* routePtr = new Ipv6RoutingTableEntry (route);
158  m_networkRoutes.push_back (std::make_pair (routePtr, metric));
159  }
160 }
161 
162 void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
163 {
164  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse << metric);
165  if (nextHop.IsLinkLocal())
166  {
167  NS_LOG_WARN ("Ipv6StaticRouting::AddNetworkRouteTo - Next hop should be link-local");
168  }
169 
170  Ipv6RoutingTableEntry route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);
171  if (!LookupRoute (route, metric))
172  {
173  Ipv6RoutingTableEntry* routePtr = new Ipv6RoutingTableEntry (route);
174  m_networkRoutes.push_back (std::make_pair (routePtr, metric));
175  }
176 }
177 
178 void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric)
179 {
180  NS_LOG_FUNCTION (this << network << networkPrefix << interface);
181 
182  Ipv6RoutingTableEntry route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface);
183  if (!LookupRoute (route, metric))
184  {
185  Ipv6RoutingTableEntry* routePtr = new Ipv6RoutingTableEntry (route);
186  m_networkRoutes.push_back (std::make_pair (routePtr, metric));
187  }
188 }
189 
190 void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
191 {
192  NS_LOG_FUNCTION (this << nextHop << interface << prefixToUse);
193  AddNetworkRouteTo (Ipv6Address ("::"), Ipv6Prefix::GetZero (), nextHop, interface, prefixToUse, metric);
194 }
195 
196 void Ipv6StaticRouting::AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
197 {
198  NS_LOG_FUNCTION (this << origin << group << inputInterface);
200  *route = Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (origin, group, inputInterface, outputInterfaces);
201  m_multicastRoutes.push_back (route);
202 }
203 
204 void Ipv6StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface)
205 {
206  NS_LOG_FUNCTION (this << outputInterface);
208  Ipv6Address network = Ipv6Address ("ff00::"); /* RFC 3513 */
209  Ipv6Prefix networkMask = Ipv6Prefix (8);
210  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkMask, outputInterface);
211  m_networkRoutes.push_back (std::make_pair (route, 0));
212 }
213 
215 {
216  NS_LOG_FUNCTION (this);
217  return m_multicastRoutes.size ();
218 }
219 
221 {
222  NS_LOG_FUNCTION (this << index);
223  NS_ASSERT_MSG (index < m_multicastRoutes.size (), "Ipv6StaticRouting::GetMulticastRoute () : Index out of range");
224 
225  if (index < m_multicastRoutes.size ())
226  {
227  uint32_t tmp = 0;
228  for (MulticastRoutesCI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
229  {
230  if (tmp == index)
231  {
232  return *i;
233  }
234  tmp++;
235  }
236  }
237  return 0;
238 }
239 
240 bool Ipv6StaticRouting::RemoveMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface)
241 {
242  NS_LOG_FUNCTION (this << origin << group << inputInterface);
243  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
244  {
245  Ipv6MulticastRoutingTableEntry *route = *i;
246  if (origin == route->GetOrigin ()
247  && group == route->GetGroup ()
248  && inputInterface == route->GetInputInterface ())
249  {
250  delete *i;
251  m_multicastRoutes.erase (i);
252  return true;
253  }
254  }
255  return false;
256 }
257 
259 {
260  NS_LOG_FUNCTION (this << index);
261  uint32_t tmp = 0;
262 
263  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
264  {
265  if (tmp == index)
266  {
267  delete *i;
268  m_multicastRoutes.erase (i);
269  return;
270  }
271  tmp++;
272  }
273 }
274 
275 bool Ipv6StaticRouting::HasNetworkDest (Ipv6Address network, uint32_t interfaceIndex)
276 {
277  NS_LOG_FUNCTION (this << network << interfaceIndex);
278 
279  /* in the network table */
280  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end (); j++)
281  {
282  Ipv6RoutingTableEntry* rtentry = j->first;
283  Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
284  Ipv6Address entry = rtentry->GetDestNetwork ();
285 
286  if (prefix.IsMatch (network, entry) && rtentry->GetInterface () == interfaceIndex)
287  {
288  return true;
289  }
290  }
291 
292  /* beuh!!! not route at all */
293  return false;
294 }
295 
296 bool Ipv6StaticRouting::LookupRoute (const Ipv6RoutingTableEntry &route, uint32_t metric)
297 {
298  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end (); j++)
299  {
300  Ipv6RoutingTableEntry* rtentry = j->first;
301 
302  if (rtentry->GetDest () == route.GetDest () &&
303  rtentry->GetDestNetworkPrefix () == route.GetDestNetworkPrefix () &&
304  rtentry->GetGateway () == route.GetGateway () &&
305  rtentry->GetInterface () == route.GetInterface () &&
306  rtentry->GetPrefixToUse () == route.GetPrefixToUse () &&
307  j->second == metric)
308  {
309  return true;
310  }
311  }
312  return false;
313 }
314 
316 {
317  NS_LOG_FUNCTION (this << dst << interface);
318  Ptr<Ipv6Route> rtentry = 0;
319  uint16_t longestMask = 0;
320  uint32_t shortestMetric = 0xffffffff;
321 
322  /* when sending on link-local multicast, there have to be interface specified */
323  if (dst.IsLinkLocalMulticast ())
324  {
325  NS_ASSERT_MSG (interface, "Try to send on link-local multicast address, and no interface index is given!");
326  rtentry = Create<Ipv6Route> ();
327  rtentry->SetSource (m_ipv6->SourceAddressSelection (m_ipv6->GetInterfaceForDevice (interface), dst));
328  rtentry->SetDestination (dst);
329  rtentry->SetGateway (Ipv6Address::GetZero ());
330  rtentry->SetOutputDevice (interface);
331  return rtentry;
332  }
333 
334  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
335  {
336  Ipv6RoutingTableEntry* j = it->first;
337  uint32_t metric = it->second;
338  Ipv6Prefix mask = j->GetDestNetworkPrefix ();
339  uint16_t maskLen = mask.GetPrefixLength ();
340  Ipv6Address entry = j->GetDestNetwork ();
341 
342  NS_LOG_LOGIC ("Searching for route to " << dst << ", mask length " << maskLen << ", metric " << metric);
343 
344  if (mask.IsMatch (dst, entry))
345  {
346  NS_LOG_LOGIC ("Found global network route " << *j << ", mask length " << maskLen << ", metric " << metric);
347 
348  /* if interface is given, check the route will output on this interface */
349  if (!interface || interface == m_ipv6->GetNetDevice (j->GetInterface ()))
350  {
351  if (maskLen < longestMask)
352  {
353  NS_LOG_LOGIC ("Previous match longer, skipping");
354  continue;
355  }
356 
357  if (maskLen > longestMask)
358  {
359  shortestMetric = 0xffffffff;
360  }
361 
362  longestMask = maskLen;
363  if (metric > shortestMetric)
364  {
365  NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
366  continue;
367  }
368 
369  shortestMetric = metric;
370  Ipv6RoutingTableEntry* route = j;
371  uint32_t interfaceIdx = route->GetInterface ();
372  rtentry = Create<Ipv6Route> ();
373 
374  if (route->GetGateway ().IsAny ())
375  {
376  rtentry->SetSource (m_ipv6->SourceAddressSelection (interfaceIdx, route->GetDest ()));
377  }
378  else if (route->GetDest ().IsAny ()) /* default route */
379  {
380  rtentry->SetSource (m_ipv6->SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? dst : route->GetPrefixToUse ()));
381  }
382  else
383  {
384  rtentry->SetSource (m_ipv6->SourceAddressSelection (interfaceIdx, route->GetGateway ()));
385  }
386 
387  rtentry->SetDestination (route->GetDest ());
388  rtentry->SetGateway (route->GetGateway ());
389  rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
390  if (maskLen == 128)
391  {
392  break;
393  }
394  }
395  }
396  }
397 
398  if (rtentry)
399  {
400  NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (Through " << rtentry->GetGateway () << ") at the end");
401  }
402  return rtentry;
403 }
404 
406 {
407  NS_LOG_FUNCTION (this);
408 
409  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end (); j = m_networkRoutes.erase (j))
410  {
411  delete j->first;
412  }
413  m_networkRoutes.clear ();
414 
415  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i = m_multicastRoutes.erase (i))
416  {
417  delete (*i);
418  }
419  m_multicastRoutes.clear ();
420 
421  m_ipv6 = 0;
423 }
424 
426 {
427  NS_LOG_FUNCTION (this << origin << group << interface);
428  Ptr<Ipv6MulticastRoute> mrtentry = 0;
429 
430  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
431  {
432  Ipv6MulticastRoutingTableEntry* route = *i;
433 
434  /*
435  We've been passed an origin address, a multicast group address and an
436  interface index. We have to decide if the current route in the list is
437  a match.
438 
439  The first case is the restrictive case where the origin, group and index
440  matches. This picks up exact routes during forwarded and exact routes from
441  the local node (in which case the ifIndex is a wildcard).
442  */
443 
444  if (origin == route->GetOrigin () && group == route->GetGroup ())
445  {
446  /* skipping SSM case */
447  NS_LOG_LOGIC ("Find source specific multicast route" << *i);
448  }
449 
450  if (group == route->GetGroup ())
451  {
452  if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
453  {
454  NS_LOG_LOGIC ("Found multicast route" << *i);
455  mrtentry = Create<Ipv6MulticastRoute> ();
456  mrtentry->SetGroup (route->GetGroup ());
457  mrtentry->SetOrigin (route->GetOrigin ());
458  mrtentry->SetParent (route->GetInputInterface ());
459  for (uint32_t j = 0; j < route->GetNOutputInterfaces (); j++)
460  {
461  if (route->GetOutputInterface (j))
462  {
463  NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
464  mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
465  }
466  }
467  return mrtentry;
468  }
469  }
470  }
471  return mrtentry;
472 }
473 
475 {
476  return m_networkRoutes.size ();
477 }
478 
480 {
481  NS_LOG_FUNCTION (this);
482  Ipv6Address dst ("::");
483  uint32_t shortestMetric = 0xffffffff;
484  Ipv6RoutingTableEntry* result = 0;
485 
486  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
487  {
488  Ipv6RoutingTableEntry* j = it->first;
489  uint32_t metric = it->second;
490  Ipv6Prefix mask = j->GetDestNetworkPrefix ();
491  uint16_t maskLen = mask.GetPrefixLength ();
492  Ipv6Address entry = j->GetDestNetwork ();
493 
494  if (maskLen)
495  {
496  continue;
497  }
498 
499  if (metric > shortestMetric)
500  {
501  continue;
502  }
503  shortestMetric = metric;
504  result = j;
505  }
506 
507  if (result)
508  {
509  return result;
510  }
511  else
512  {
513  return Ipv6RoutingTableEntry ();
514  }
515 }
516 
518 {
519  NS_LOG_FUNCTION (this << index);
520  uint32_t tmp = 0;
521 
522  for (NetworkRoutesCI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
523  {
524  if (tmp == index)
525  {
526  return it->first;
527  }
528  tmp++;
529  }
530  NS_ASSERT (false);
531  // quiet compiler.
532  return 0;
533 }
534 
535 uint32_t Ipv6StaticRouting::GetMetric (uint32_t index) const
536 {
537  NS_LOG_FUNCTION (this << index);
538  uint32_t tmp = 0;
539 
540  for (NetworkRoutesCI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
541  {
542  if (tmp == index)
543  {
544  return it->second;
545  }
546  tmp++;
547  }
548  NS_ASSERT (false);
549  // quiet compiler.
550  return 0;
551 }
552 
553 void Ipv6StaticRouting::RemoveRoute (uint32_t index)
554 {
555  NS_LOG_FUNCTION (this << index);
556  uint32_t tmp = 0;
557 
558  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
559  {
560  if (tmp == index)
561  {
562  delete it->first;
563  m_networkRoutes.erase (it);
564  return;
565  }
566  tmp++;
567  }
568  NS_ASSERT (false);
569 }
570 
571 void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse)
572 {
573  NS_LOG_FUNCTION (this << network << prefix << ifIndex);
574 
575  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
576  {
577  Ipv6RoutingTableEntry* rtentry = it->first;
578  if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex
579  && rtentry->GetPrefixToUse () == prefixToUse)
580  {
581  delete it->first;
582  m_networkRoutes.erase (it);
583  return;
584  }
585  }
586 }
587 
589 {
590  NS_LOG_FUNCTION (this << header << oif);
591  Ipv6Address destination = header.GetDestinationAddress ();
592  Ptr<Ipv6Route> rtentry = 0;
593 
594  if (destination.IsMulticast ())
595  {
596  // Note: Multicast routes for outbound packets are stored in the
597  // normal unicast table. An implication of this is that it is not
598  // possible to source multicast datagrams on multiple interfaces.
599  // This is a well-known property of sockets implementation on
600  // many Unix variants.
601  // So, we just log it and fall through to LookupStatic ()
602  NS_LOG_LOGIC ("RouteOutput ()::Multicast destination");
603  }
604 
605  rtentry = LookupStatic (destination, oif);
606  if (rtentry)
607  {
608  sockerr = Socket::ERROR_NOTERROR;
609  }
610  else
611  {
612  sockerr = Socket::ERROR_NOROUTETOHOST;
613  }
614  return rtentry;
615 }
616 
620 {
621  NS_LOG_FUNCTION (this << p << header << header.GetSourceAddress () << header.GetDestinationAddress () << idev);
622  NS_ASSERT (m_ipv6 != 0);
623  // Check if input device supports IP
624  NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
625  uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
626  Ipv6Address dst = header.GetDestinationAddress ();
627 
628  // Multicast recognition; handle local delivery here
629  if (dst.IsMulticast ())
630  {
631  NS_LOG_LOGIC ("Multicast destination");
633  header.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev));
634 
635  // \todo check if we want to forward up the packet
636  if (mrtentry)
637  {
638  NS_LOG_LOGIC ("Multicast route found");
639  mcb (idev, mrtentry, p, header); // multicast forwarding callback
640  return true;
641  }
642  else
643  {
644  NS_LOG_LOGIC ("Multicast route not found");
645  return false; // Let other routing protocols try to handle this
646  }
647  }
648 
649  // Check if input device supports IP forwarding
650  if (m_ipv6->IsForwarding (iif) == false)
651  {
652  NS_LOG_LOGIC ("Forwarding disabled for this interface");
653  if (!ecb.IsNull ())
654  {
655  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
656  }
657  return true;
658  }
659  // Next, try to find a route
660  NS_LOG_LOGIC ("Unicast destination");
661  Ptr<Ipv6Route> rtentry = LookupStatic (header.GetDestinationAddress ());
662 
663  if (rtentry != 0)
664  {
665  NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
666  ucb (idev, rtentry, p, header); // unicast forwarding callback
667  return true;
668  }
669  else
670  {
671  NS_LOG_LOGIC ("Did not find unicast destination- returning false");
672  return false; // Let other routing protocols try to handle this
673  }
674 }
675 
677 {
678  for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
679  {
680  if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address ()
681  && m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
682  {
683  if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
684  {
685  /* host route */
686  AddHostRouteTo (m_ipv6->GetAddress (i, j).GetAddress (), i);
687  }
688  else
689  {
690  AddNetworkRouteTo (m_ipv6->GetAddress (i, j).GetAddress ().CombinePrefix (m_ipv6->GetAddress (i, j).GetPrefix ()),
691  m_ipv6->GetAddress (i, j).GetPrefix (), i);
692  }
693  }
694  }
695 }
696 
698 {
699  NS_LOG_FUNCTION (this << i);
700 
701  /* remove all static routes that are going through this interface */
702  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); )
703  {
704  if (it->first->GetInterface () == i)
705  {
706  delete it->first;
707  it = m_networkRoutes.erase (it);
708  }
709  else
710  {
711  it++;
712  }
713  }
714 }
715 
717 {
718  if (!m_ipv6->IsUp (interface))
719  {
720  return;
721  }
722 
723  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
724  Ipv6Prefix networkMask = address.GetPrefix ();
725 
726  if (address.GetAddress () != Ipv6Address () && address.GetPrefix () != Ipv6Prefix ())
727  {
728  AddNetworkRouteTo (networkAddress, networkMask, interface);
729  }
730 }
731 
733 {
734  if (!m_ipv6->IsUp (interface))
735  {
736  return;
737  }
738 
739  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
740  Ipv6Prefix networkMask = address.GetPrefix ();
741 
742  // Remove all static routes that are going through this interface
743  // which reference this network
744  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); )
745  {
746  if (it->first->GetInterface () == interface
747  && it->first->IsNetwork ()
748  && it->first->GetDestNetwork () == networkAddress
749  && it->first->GetDestNetworkPrefix () == networkMask)
750  {
751  delete it->first;
752  it = m_networkRoutes.erase (it);
753  }
754  else
755  {
756  it++;
757  }
758  }
759 }
760 
761 void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
762 {
763  NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
764  if (dst != Ipv6Address::GetZero ())
765  {
766  AddNetworkRouteTo (dst, mask, nextHop, interface);
767  }
768  else /* default route */
769  {
770  /* this case is mainly used by configuring default route following RA processing,
771  * in case of multiple prefix in RA, the first will configured default route
772  */
773 
774  /* for the moment, all default route has the same metric
775  * so according to the longest prefix algorithm,
776  * the default route chosen will be the last added
777  */
778  SetDefaultRoute (nextHop, interface, prefixToUse);
779  }
780 }
781 
782 void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
783 {
784  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
785  if (dst != Ipv6Address::GetZero ())
786  {
787  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end ();)
788  {
789  Ipv6RoutingTableEntry* rtentry = j->first;
790  Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
791  Ipv6Address entry = rtentry->GetDestNetwork ();
792 
793  if (dst == entry && prefix == mask && rtentry->GetInterface () == interface)
794  {
795  delete j->first;
796  j = m_networkRoutes.erase (j);
797  }
798  else
799  {
800  ++j;
801  }
802  }
803  }
804  else
805  {
806  /* default route case */
807  RemoveRoute (dst, mask, interface, prefixToUse);
808  }
809 }
810 
811 } /* namespace ns3 */
812 
static const uint32_t MAX_TTL
Maximum Time-To-Live (TTL).
Definition: ipv6-route.h:150
bool IsGateway() const
Is it the gateway ?
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:429
Packet header for IPv6.
Definition: ipv6-header.h:34
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 "...
NetworkRoutes m_networkRoutes
the forwarding table for network.
Ipv6Address GetGroup() const
Get the group.
Callback template class.
Definition: callback.h:1278
bool RemoveMulticastRoute(Ipv6Address origin, Ipv6Address group, uint32_t inputInterface)
Remove a static multicast route.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Ipv6Address GetPrefixToUse() const
Get the prefix to use (for multihomed link).
static Ipv6RoutingTableEntry CreateNetworkRouteTo(Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface)
Create a route to a network.
virtual void NotifyRemoveRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero())
Notify route removing.
virtual void NotifyAddRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero())
Notify a new route.
A record of an IPv6 multicast route.
virtual void SetIpv6(Ptr< Ipv6 > ipv6)
Typically, invoked directly or indirectly from ns3::Ipv6::SetRoutingProtocol.
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.
Ipv6MulticastRoutingTableEntry GetMulticastRoute(uint32_t i) const
Get the specified multicast route.
std::list< Ipv6MulticastRoutingTableEntry * >::const_iterator MulticastRoutesCI
Const Iterator for container for the multicast routes.
#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:205
IPv6 address associated with an interface.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
std::list< std::pair< Ipv6RoutingTableEntry *, uint32_t > >::iterator NetworkRoutesI
Iterator for container for the network routes.
Ipv6RoutingTableEntry GetRoute(uint32_t i) const
Get a specified route.
static Ipv6MulticastRoutingTableEntry CreateMulticastRoute(Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector< uint32_t > outputInterfaces)
Create a multicast route.
static Ipv6Prefix GetZero()
Get the zero prefix ( /0).
uint32_t GetNMulticastRoutes() const
Get the number of entries in the multicast routing table.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
Ipv6Address GetDestNetwork() const
Get the destination network.
bool IsMatch(Ipv6Address a, Ipv6Address b) const
If the Address match the type.
void AddHostRouteTo(Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address("::"), uint32_t metric=0)
Add route to host.
Ipv6Address GetOrigin() const
Get the source of this route.
static TypeId GetTypeId()
The interface Id associated with this class.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
A record of an IPv6 route.
Ipv6Address GetDest() const
Get the destination.
Ptr< Ipv6 > m_ipv6
Ipv6 reference.
virtual void NotifyInterfaceDown(uint32_t interface)
Notify when specified interface goes DOWN.
bool IsHost() const
Is the route entry correspond to a host ?
Ptr< Ipv6Route > LookupStatic(Ipv6Address dest, Ptr< NetDevice >=0)
Lookup in the forwarding table for destination.
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
void AddMulticastRoute(Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector< uint32_t > outputInterfaces)
Add a multicast route for a given multicast source and group.
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:109
virtual void NotifyRemoveAddress(uint32_t interface, Ipv6InterfaceAddress address)
Notify when specified interface add an address.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
void AddNetworkRouteTo(Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric=0)
Add route to network.
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)
Ipv6Address GetGateway() const
Get the gateway.
virtual void NotifyInterfaceUp(uint32_t interface)
Notify when specified interface goes UP.
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:100
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
Static routing protocol for IP version 6 stacks.
uint32_t GetNRoutes() const
Get the number or entries in the routing table.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const uint32_t IF_ANY
Any interface magic number.
Definition: ipv6.h:390
address
Definition: first.py:44
Ipv6RoutingTableEntry GetDefaultRoute()
Get the default route.
uint8_t GetPrefixLength() const
Get prefix length.
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
Describes an IPv6 address.
Definition: ipv6-address.h:49
void RemoveRoute(uint32_t i)
Remove a route from the routing table.
void SetDefaultRoute(Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address("::"), uint32_t metric=0)
Set the default route.
static Ipv6Prefix GetOnes()
Get the "all-1" IPv6 mask (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
uint32_t GetInputInterface() const
Get the input interface address.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
uint32_t GetMetric(uint32_t index) const
Get a metric for route from the static unicast routing table.
A network Node.
Definition: node.h:56
virtual void DoDispose()
Dispose this object.
void SetDefaultMulticastRoute(uint32_t outputInterface)
Set the default multicast route.
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and...
Definition: names.cc:817
virtual void NotifyAddAddress(uint32_t interface, Ipv6InterfaceAddress address)
Notify when specified interface add an address.
std::list< std::pair< Ipv6RoutingTableEntry *, uint32_t > >::const_iterator NetworkRoutesCI
Const Iterator for container for the network routes.
Describes an IPv6 prefix.
Definition: ipv6-address.h:467
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
MulticastRoutes m_multicastRoutes
the forwarding table for multicast.
Ipv6Prefix GetDestNetworkPrefix() const
Get the destination prefix.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
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:923
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
bool HasNetworkDest(Ipv6Address dest, uint32_t interfaceIndex)
If the destination is already present in network destination list.
uint32_t GetNOutputInterfaces() const
Get the number of output interfaces of this route.
bool LookupRoute(const Ipv6RoutingTableEntry &route, uint32_t metric)
Checks if a route is already present in the forwarding table.
bool IsAny() const
If the IPv6 address is the "Any" address.
std::list< Ipv6MulticastRoutingTableEntry * >::iterator MulticastRoutesI
Iterator for container for the multicast routes.
uint32_t GetInterface() const
Get the interface index.
uint32_t GetOutputInterface(uint32_t n) const
Get a specified output interface.