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