A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
29 #include "ipv6-static-routing.h"
31 
32 namespace ns3 {
33 
34 NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRouting");
35 NS_OBJECT_ENSURE_REGISTERED (Ipv6StaticRouting);
36 
38 {
39  static TypeId tid = TypeId ("ns3::Ipv6StaticRouting")
41  .AddConstructor<Ipv6StaticRouting> ()
42  ;
43  return tid;
44 }
45 
47  : m_ipv6 (0)
48 {
50 }
51 
53 {
55 }
56 
58 {
59  NS_LOG_FUNCTION (this << ipv6);
60  NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
61  uint32_t i = 0;
62  m_ipv6 = ipv6;
63 
64  for (i = 0; i < m_ipv6->GetNInterfaces (); i++)
65  {
66  if (m_ipv6->IsUp (i))
67  {
69  }
70  else
71  {
73  }
74  }
75 }
76 
77 // Formatted like output of "route -n" command
78 void
80 {
81  NS_LOG_FUNCTION (this);
82  std::ostream* os = stream->GetStream ();
83  if (GetNRoutes () > 0)
84  {
85  *os << "Node: " << m_ipv6->GetObject<Node> ()->GetId ()
86  << " Time: " << Simulator::Now ().GetSeconds () << "s "
87  << "Ipv6StaticRouting table" << std::endl;
88 
89  for (uint32_t j = 0; j < GetNRoutes (); j++)
90  {
91  Ipv6RoutingTableEntry route = GetRoute (j);
92  *os << route << std::endl;
93  }
94  }
95 }
96 
97 void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
98 {
99  NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse << metric);
100  if (nextHop.IsLinkLocal())
101  {
102  NS_LOG_WARN ("Ipv6StaticRouting::AddHostRouteTo - Next hop should be link-local");
103  }
104 
105  AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse, metric);
106 }
107 
108 void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, uint32_t interface, uint32_t metric)
109 {
110  NS_LOG_FUNCTION (this << dst << interface << metric);
111  AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), interface, metric);
112 }
113 
114 void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric)
115 {
116  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << metric);
118  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface);
119  m_networkRoutes.push_back (std::make_pair (route, metric));
120 }
121 
122 void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
123 {
124  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse << metric);
125  if (nextHop.IsLinkLocal())
126  {
127  NS_LOG_WARN ("Ipv6StaticRouting::AddNetworkRouteTo - Next hop should be link-local");
128  }
129 
131  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);
132  m_networkRoutes.push_back (std::make_pair (route, metric));
133 }
134 
135 void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric)
136 {
137  NS_LOG_FUNCTION (this << network << networkPrefix << interface);
139  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface);
140  m_networkRoutes.push_back (std::make_pair (route, metric));
141 }
142 
143 void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
144 {
145  NS_LOG_FUNCTION (this << nextHop << interface << prefixToUse);
146  AddNetworkRouteTo (Ipv6Address ("::"), Ipv6Prefix::GetZero (), nextHop, interface, prefixToUse, metric);
147 }
148 
149 void Ipv6StaticRouting::AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
150 {
151  NS_LOG_FUNCTION (this << origin << group << inputInterface);
153  *route = Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (origin, group, inputInterface, outputInterfaces);
154  m_multicastRoutes.push_back (route);
155 }
156 
157 void Ipv6StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface)
158 {
159  NS_LOG_FUNCTION (this << outputInterface);
161  Ipv6Address network = Ipv6Address ("ff00::"); /* RFC 3513 */
162  Ipv6Prefix networkMask = Ipv6Prefix (8);
163  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkMask, outputInterface);
164  m_networkRoutes.push_back (std::make_pair (route, 0));
165 }
166 
168 {
170  return m_multicastRoutes.size ();
171 }
172 
174 {
175  NS_LOG_FUNCTION (this << index);
176  NS_ASSERT_MSG (index < m_multicastRoutes.size (), "Ipv6StaticRouting::GetMulticastRoute () : Index out of range");
177 
178  if (index < m_multicastRoutes.size ())
179  {
180  uint32_t tmp = 0;
181  for (MulticastRoutesCI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
182  {
183  if (tmp == index)
184  {
185  return *i;
186  }
187  tmp++;
188  }
189  }
190  return 0;
191 }
192 
194 {
195  NS_LOG_FUNCTION (this << origin << group << inputInterface);
196  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
197  {
198  Ipv6MulticastRoutingTableEntry *route = *i;
199  if (origin == route->GetOrigin ()
200  && group == route->GetGroup ()
201  && inputInterface == route->GetInputInterface ())
202  {
203  delete *i;
204  m_multicastRoutes.erase (i);
205  return true;
206  }
207  }
208  return false;
209 }
210 
212 {
213  NS_LOG_FUNCTION (this << index);
214  uint32_t tmp = 0;
215 
216  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
217  {
218  if (tmp == index)
219  {
220  delete *i;
221  m_multicastRoutes.erase (i);
222  return;
223  }
224  tmp++;
225  }
226 }
227 
228 bool Ipv6StaticRouting::HasNetworkDest (Ipv6Address network, uint32_t interfaceIndex)
229 {
230  NS_LOG_FUNCTION (this << network << interfaceIndex);
231 
232  /* in the network table */
233  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end (); j++)
234  {
235  Ipv6RoutingTableEntry* rtentry = j->first;
236  Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
237  Ipv6Address entry = rtentry->GetDestNetwork ();
238 
239  if (prefix.IsMatch (network, entry) && rtentry->GetInterface () == interfaceIndex)
240  {
241  return true;
242  }
243  }
244 
245  /* beuh!!! not route at all */
246  return false;
247 }
248 
250 {
251  NS_LOG_FUNCTION (this << dst << interface);
252  Ptr<Ipv6Route> rtentry = 0;
253  uint16_t longestMask = 0;
254  uint32_t shortestMetric = 0xffffffff;
255 
256  /* when sending on link-local multicast, there have to be interface specified */
259  {
260  NS_ASSERT_MSG (interface, "Try to send on link-local multicast address, and no interface index is given!");
261  rtentry = Create<Ipv6Route> ();
262  rtentry->SetSource (SourceAddressSelection (m_ipv6->GetInterfaceForDevice (interface), dst));
263  rtentry->SetDestination (dst);
264  rtentry->SetGateway (Ipv6Address::GetZero ());
265  rtentry->SetOutputDevice (interface);
266  return rtentry;
267  }
268 
269  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
270  {
271  Ipv6RoutingTableEntry* j = it->first;
272  uint32_t metric = it->second;
273  Ipv6Prefix mask = j->GetDestNetworkPrefix ();
274  uint16_t maskLen = mask.GetPrefixLength ();
275  Ipv6Address entry = j->GetDestNetwork ();
276 
277  NS_LOG_LOGIC ("Searching for route to " << dst << ", mask length " << maskLen << ", metric " << metric);
278 
279  if (mask.IsMatch (dst, entry))
280  {
281  NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << maskLen << ", metric " << metric);
282 
283  /* if interface is given, check the route will output on this interface */
284  if (!interface || interface == m_ipv6->GetNetDevice (j->GetInterface ()))
285  {
286  if (maskLen < longestMask)
287  {
288  NS_LOG_LOGIC ("Previous match longer, skipping");
289  continue;
290  }
291 
292  if (maskLen > longestMask)
293  {
294  shortestMetric = 0xffffffff;
295  }
296 
297  longestMask = maskLen;
298  if (metric > shortestMetric)
299  {
300  NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
301  continue;
302  }
303 
304  shortestMetric = metric;
305  Ipv6RoutingTableEntry* route = j;
306  uint32_t interfaceIdx = route->GetInterface ();
307  rtentry = Create<Ipv6Route> ();
308 
309  if (route->GetGateway ().IsAny ())
310  {
311  rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
312  }
313  else if (route->GetDest ().IsAny ()) /* default route */
314  {
315  rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? dst : route->GetPrefixToUse ()));
316  }
317  else
318  {
319  rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetGateway ()));
320  }
321 
322  rtentry->SetDestination (route->GetDest ());
323  rtentry->SetGateway (route->GetGateway ());
324  rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
325  }
326  }
327  }
328 
329  if (rtentry)
330  {
331  NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (throught " << rtentry->GetGateway () << ") at the end");
332  }
333  return rtentry;
334 }
335 
337 {
339 
340  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end (); j = m_networkRoutes.erase (j))
341  {
342  delete j->first;
343  }
344  m_networkRoutes.clear ();
345 
346  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i = m_multicastRoutes.erase (i))
347  {
348  delete (*i);
349  }
350  m_multicastRoutes.clear ();
351 
352  m_ipv6 = 0;
354 }
355 
357 {
358  NS_LOG_FUNCTION (this << origin << group << interface);
359  Ptr<Ipv6MulticastRoute> mrtentry = 0;
360 
361  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
362  {
363  Ipv6MulticastRoutingTableEntry* route = *i;
364 
365  /*
366  We've been passed an origin address, a multicast group address and an
367  interface index. We have to decide if the current route in the list is
368  a match.
369 
370  The first case is the restrictive case where the origin, group and index
371  matches. This picks up exact routes during forwarded and exact routes from
372  the local node (in which case the ifIndex is a wildcard).
373  */
374 
375  if (origin == route->GetOrigin () && group == route->GetGroup ())
376  {
377  /* skipping SSM case */
378  NS_LOG_LOGIC ("Find source specific multicast route" << *i);
379  }
380 
381  if (group == route->GetGroup ())
382  {
383  if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
384  {
385  NS_LOG_LOGIC ("Found multicast route" << *i);
386  mrtentry = Create<Ipv6MulticastRoute> ();
387  mrtentry->SetGroup (route->GetGroup ());
388  mrtentry->SetOrigin (route->GetOrigin ());
389  mrtentry->SetParent (route->GetInputInterface ());
390  for (uint32_t j = 0; j < route->GetNOutputInterfaces (); j++)
391  {
392  if (route->GetOutputInterface (j))
393  {
394  NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
395  mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
396  }
397  }
398  return mrtentry;
399  }
400  }
401  }
402  return mrtentry;
403 }
404 
406 {
407  return m_networkRoutes.size ();
408 }
409 
411 {
413  Ipv6Address dst ("::");
414  uint32_t shortestMetric = 0xffffffff;
415  Ipv6RoutingTableEntry* result = 0;
416 
417  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
418  {
419  Ipv6RoutingTableEntry* j = it->first;
420  uint32_t metric = it->second;
421  Ipv6Prefix mask = j->GetDestNetworkPrefix ();
422  uint16_t maskLen = mask.GetPrefixLength ();
423  Ipv6Address entry = j->GetDestNetwork ();
424 
425  if (maskLen)
426  {
427  continue;
428  }
429 
430  if (metric > shortestMetric)
431  {
432  continue;
433  }
434  shortestMetric = metric;
435  result = j;
436  }
437 
438  if (result)
439  {
440  return result;
441  }
442  else
443  {
444  return Ipv6RoutingTableEntry ();
445  }
446 }
447 
449 {
450  NS_LOG_FUNCTION (this << index);
451  uint32_t tmp = 0;
452 
453  for (NetworkRoutesCI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
454  {
455  if (tmp == index)
456  {
457  return it->first;
458  }
459  tmp++;
460  }
461  NS_ASSERT (false);
462  // quiet compiler.
463  return 0;
464 }
465 
466 uint32_t Ipv6StaticRouting::GetMetric (uint32_t index) const
467 {
469  uint32_t tmp = 0;
470 
471  for (NetworkRoutesCI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
472  {
473  if (tmp == index)
474  {
475  return it->second;
476  }
477  tmp++;
478  }
479  NS_ASSERT (false);
480  // quiet compiler.
481  return 0;
482 }
483 
484 void Ipv6StaticRouting::RemoveRoute (uint32_t index)
485 {
486  NS_LOG_FUNCTION (this << index);
487  uint32_t tmp = 0;
488 
489  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
490  {
491  if (tmp == index)
492  {
493  delete it->first;
494  m_networkRoutes.erase (it);
495  return;
496  }
497  tmp++;
498  }
499  NS_ASSERT (false);
500 }
501 
502 void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse)
503 {
504  NS_LOG_FUNCTION (this << network << prefix << ifIndex);
505 
506  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
507  {
508  Ipv6RoutingTableEntry* rtentry = it->first;
509  if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex
510  && rtentry->GetPrefixToUse () == prefixToUse)
511  {
512  delete it->first;
513  m_networkRoutes.erase (it);
514  return;
515  }
516  }
517 }
518 
520 {
521  NS_LOG_FUNCTION (this << header << oif);
522  Ipv6Address destination = header.GetDestinationAddress ();
523  Ptr<Ipv6Route> rtentry = 0;
524 
525  if (destination.IsMulticast ())
526  {
527  // Note: Multicast routes for outbound packets are stored in the
528  // normal unicast table. An implication of this is that it is not
529  // possible to source multicast datagrams on multiple interfaces.
530  // This is a well-known property of sockets implementation on
531  // many Unix variants.
532  // So, we just log it and fall through to LookupStatic ()
533  NS_LOG_LOGIC ("RouteOutput ()::Multicast destination");
534  }
535 
536  rtentry = LookupStatic (destination, oif);
537  if (rtentry)
538  {
539  sockerr = Socket::ERROR_NOTERROR;
540  }
541  else
542  {
543  sockerr = Socket::ERROR_NOROUTETOHOST;
544  }
545  return rtentry;
546 }
547 
551 {
552  NS_LOG_FUNCTION (this << p << header << header.GetSourceAddress () << header.GetDestinationAddress () << idev);
553  NS_ASSERT (m_ipv6 != 0);
554  // Check if input device supports IP
555  NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
556  uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
557  Ipv6Address dst = header.GetDestinationAddress ();
558 
559  if (dst.IsMulticast ())
560  {
561  NS_LOG_LOGIC ("Multicast destination");
563  header.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev));
564 
565  if (mrtentry)
566  {
567  NS_LOG_LOGIC ("Multicast route found");
568  mcb (idev, mrtentry, p, header); // multicast forwarding callback
569  return true;
570  }
571  else
572  {
573  NS_LOG_LOGIC ("Multicast route not found");
574  return false; // Let other routing protocols try to handle this
575  }
576  }
577 
579  // Right now, we will be permissive and allow a source to send us
580  // a packet to one of our other interface addresses; that is, the
581  // destination unicast address does not match one of the iif addresses,
582  // but we check our other interfaces. This could be an option
583  // (to remove the outer loop immediately below and just check iif).
584  for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
585  {
586  for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
587  {
588  Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
589  Ipv6Address addr = iaddr.GetAddress ();
590  if (addr.IsEqual (header.GetDestinationAddress ()))
591  {
592  if (j == iif)
593  {
594  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
595  }
596  else
597  {
598  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
599  }
600  lcb (p, header, iif);
601  return true;
602  }
603  NS_LOG_LOGIC ("Address " << addr << " not a match");
604  }
605  }
606  // Check if input device supports IP forwarding
607  if (m_ipv6->IsForwarding (iif) == false)
608  {
609  NS_LOG_LOGIC ("Forwarding disabled for this interface");
610  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
611  return false;
612  }
613  // Next, try to find a route
614  NS_LOG_LOGIC ("Unicast destination");
615  Ptr<Ipv6Route> rtentry = LookupStatic (header.GetDestinationAddress ());
616 
617  if (rtentry != 0)
618  {
619  NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
620  ucb (idev, rtentry, p, header); // unicast forwarding callback
621  return true;
622  }
623  else
624  {
625  NS_LOG_LOGIC ("Did not find unicast destination- returning false");
626  return false; // Let other routing protocols try to handle this
627  }
628 }
629 
631 {
632  for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
633  {
634  if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address ()
635  && m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
636  {
637  if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
638  {
639  /* host route */
640  AddHostRouteTo (m_ipv6->GetAddress (i, j).GetAddress (), i);
641  }
642  else
643  {
644  AddNetworkRouteTo (m_ipv6->GetAddress (i, j).GetAddress ().CombinePrefix (m_ipv6->GetAddress (i, j).GetPrefix ()),
645  m_ipv6->GetAddress (i, j).GetPrefix (), i);
646  }
647  }
648  }
649 }
650 
652 {
653  NS_LOG_FUNCTION (this << i);
654  uint32_t j = 0;
655  uint32_t max = GetNRoutes ();
656 
657  /* remove all static routes that are going through this interface */
658  while (j < max)
659  {
660  Ipv6RoutingTableEntry route = GetRoute (j);
661 
662  if (route.GetInterface () == i)
663  {
664  RemoveRoute (j);
665  }
666  else
667  {
668  j++;
669  }
670  }
671 }
672 
674 {
675  if (!m_ipv6->IsUp (interface))
676  {
677  return;
678  }
679 
680  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
681  Ipv6Prefix networkMask = address.GetPrefix ();
682 
683  if (address.GetAddress () != Ipv6Address () && address.GetPrefix () != Ipv6Prefix ())
684  {
685  AddNetworkRouteTo (networkAddress, networkMask, interface);
686  }
687 }
688 
690 {
691  if (!m_ipv6->IsUp (interface))
692  {
693  return;
694  }
695 
696  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
697  Ipv6Prefix networkMask = address.GetPrefix ();
698 
699  // Remove all static routes that are going through this interface
700  // which reference this network
701  for (uint32_t j = 0; j < GetNRoutes (); j++)
702  {
703  Ipv6RoutingTableEntry route = GetRoute (j);
704 
705  if (route.GetInterface () == interface
706  && route.IsNetwork ()
707  && route.GetDestNetwork () == networkAddress
708  && route.GetDestNetworkPrefix () == networkMask)
709  {
710  RemoveRoute (j);
711  }
712  }
713 }
714 
715 void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
716 {
717  NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
718  if (dst != Ipv6Address::GetZero ())
719  {
720  AddNetworkRouteTo (dst, mask, nextHop, interface);
721  }
722  else /* default route */
723  {
724  /* this case is mainly used by configuring default route following RA processing,
725  * in case of multipe prefix in RA, the first will configured default route
726  */
727 
728  /* for the moment, all default route has the same metric
729  * so according to the longest prefix algorithm,
730  * the default route choosen will be the last added
731  */
732  SetDefaultRoute (nextHop, interface, prefixToUse);
733  }
734 }
735 
736 void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
737 {
738  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
739  if (dst != Ipv6Address::GetZero ())
740  {
741  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end ();)
742  {
743  Ipv6RoutingTableEntry* rtentry = j->first;
744  Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
745  Ipv6Address entry = rtentry->GetDestNetwork ();
746 
747  if (dst == entry && prefix == mask && rtentry->GetInterface () == interface)
748  {
749  delete j->first;
750  j = m_networkRoutes.erase (j);
751  }
752  else
753  {
754  ++j;
755  }
756  }
757  }
758  else
759  {
760  /* default route case */
761  RemoveRoute (dst, mask, interface, prefixToUse);
762  }
763 }
764 
766 {
767  NS_LOG_FUNCTION (this << interface << dest);
768  Ipv6Address ret;
769 
770  /* first address of an IPv6 interface is link-local ones */
771  ret = m_ipv6->GetAddress (interface, 0).GetAddress ();
772 
774  {
775  return ret;
776  }
777 
778  /* usually IPv6 interfaces have one link-local address and one global address */
779 
780  for (uint32_t i = 1; i < m_ipv6->GetNAddresses (interface); i++)
781  {
782  Ipv6InterfaceAddress test = m_ipv6->GetAddress (interface, i);
783  Ipv6InterfaceAddress dst(dest);
784 
785  if (test.GetScope() == dst.GetScope())
786  {
787  return test.GetAddress ();
788  }
789  }
790 
791  return ret;
792 }
793 
794 } /* namespace ns3 */
795 
bool IsMatch(Ipv6Address a, Ipv6Address b) const
If the Address match the type.
bool IsAny() const
If the IPv6 address is the "Any" address.
static const uint32_t MAX_TTL
Maximum Time-To-Live (TTL).
Definition: ipv6-route.h:144
Packet header for IPv6.
Definition: ipv6-header.h:33
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
Ipv6Address GetPrefixToUse() const
Get the prefix to use (for multihomed link).
virtual ~Ipv6StaticRouting()
Destructor.
NetworkRoutes m_networkRoutes
the forwarding table for network.
Callback template class.
Definition: callback.h:920
bool RemoveMulticastRoute(Ipv6Address origin, Ipv6Address group, uint32_t inputInterface)
Remove a static multicast route.
Ipv6Prefix GetDestNetworkPrefix() const
Get the destination prefix.
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.
Ipv6Address SourceAddressSelection(uint32_t interface, Ipv6Address dest)
Choose the source address to use with destination address.
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.
uint32_t GetInputInterface() const
Get the input interface address.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
std::list< Ipv6MulticastRoutingTableEntry * >::const_iterator MulticastRoutesCI
#define NS_ASSERT(condition)
Definition: assert.h:64
IPv6 address associated with an interface.
bool IsEqual(const Ipv6Address &other) const
Comparison operation between two Ipv6Addresses.
virtual void DoDispose(void)
Definition: object.cc:335
#define NS_LOG_INFO(msg)
Definition: log.h:264
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
std::list< std::pair< Ipv6RoutingTableEntry *, uint32_t > >::iterator NetworkRoutesI
uint32_t GetNOutputInterfaces() const
Get the number of output interfaces of this 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).
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
uint32_t GetNMulticastRoutes() const
Get the number of entries in the multicast routing table.
void AddHostRouteTo(Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address("::"), uint32_t metric=0)
Add route to host.
static TypeId GetTypeId()
The interface Id associated with this class.
double GetSeconds(void) const
Definition: nstime.h:266
Ipv6Address GetDestNetwork() const
Get the destination network.
Ipv6Address GetAddress() const
Get the IPv6 address.
A record of an IPv6 route.
Ptr< Ipv6 > m_ipv6
Ipv6 reference.
uint32_t GetMetric(uint32_t index) const
Get a metric for route from the static unicast routing table.
virtual void NotifyInterfaceDown(uint32_t interface)
Notify when specified interface goes DOWN.
Ptr< Ipv6Route > LookupStatic(Ipv6Address dest, Ptr< NetDevice >=0)
Lookup in the forwarding table for destination.
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
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.
virtual void NotifyRemoveAddress(uint32_t interface, Ipv6InterfaceAddress address)
Notify when specified interface add an address.
Ipv6Address GetOrigin() const
Get the source of this route.
void AddNetworkRouteTo(Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric=0)
Add route to network.
Ipv6Prefix GetPrefix() const
Get the IPv6 prefix.
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 NotifyInterfaceUp(uint32_t interface)
Notify when specified interface goes UP.
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
static Ipv6Address GetAllHostsMulticast()
Get the "all hosts multicast" address.
uint32_t GetOutputInterface(uint32_t n) const
Get a specified output interface.
static const uint32_t IF_ANY
Any interface magic number.
Definition: ipv6.h:315
Ipv6RoutingTableEntry GetDefaultRoute()
Get the default route.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
static Ipv6Address GetAllNodesMulticast()
Get the "all nodes multicast" address.
Ipv6Address GetGateway() const
Get the gateway.
static Time Now(void)
Definition: simulator.cc:180
uint32_t GetInterface() const
Get the interface index.
Ipv6StaticRouting()
Constructor.
Ipv6RoutingTableEntry GetRoute(uint32_t i) const
Get a specified route.
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Describes an IPv6 address.
Definition: ipv6-address.h:46
void RemoveRoute(uint32_t i)
Remove a route from the routing table.
bool IsSolicitedMulticast() const
If the IPv6 address is a Solicited multicast address.
void SetDefaultRoute(Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address("::"), uint32_t metric=0)
Set the default route.
Ipv6Address GetGroup() const
Get the group.
Ipv6InterfaceAddress::Scope_e GetScope() const
Get address scope.
static Ipv6Prefix GetOnes()
Get the "all-1" IPv6 mask (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
NS_LOG_COMPONENT_DEFINE("PacketLossCounter")
#define NS_LOG_WARN(msg)
Definition: log.h:246
Ipv6Address GetDest() const
Get the destination.
A network Node.
Definition: node.h:55
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:101
virtual void DoDispose()
Dispose this object.
void SetDefaultMulticastRoute(uint32_t outputInterface)
Set the default multicast route.
bool IsNetwork() const
Is the route entry correspond to a network ?
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
Describes an IPv6 prefix. It is just a bitmask like Ipv4Mask.
Definition: ipv6-address.h:364
uint8_t GetPrefixLength() const
Get prefix length.
MulticastRoutes m_multicastRoutes
the forwarding table for multicast.
tuple address
Definition: first.py:37
uint32_t GetNRoutes() const
Get the number or entries in the routing table.
Ipv6MulticastRoutingTableEntry GetMulticastRoute(uint32_t i) const
Get the specified multicast route.
Ipv6Address CombinePrefix(Ipv6Prefix const &prefix)
Combine this address with a prefix.
Abstract base class for Ipv6 routing protocols.
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
void test(void)
std::ostream * GetStream(void)
bool HasNetworkDest(Ipv6Address dest, uint32_t interfaceIndex)
If the destination is already present in network destination list.
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:111
std::list< Ipv6MulticastRoutingTableEntry * >::iterator MulticastRoutesI
static Ipv6Address GetAllRoutersMulticast()
Get the "all routers multicast" address.