This documentation is not the Latest Release.
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 {
53 }
54 
56 {
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 (Time::S)
89  << ", Local time: " << GetObject<Node> ()->GetLocalTime ().As (Time::S)
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);
153  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface);
154  m_networkRoutes.push_back (std::make_pair (route, metric));
155 }
156 
157 void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
158 {
159  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse << metric);
160  if (nextHop.IsLinkLocal())
161  {
162  NS_LOG_WARN ("Ipv6StaticRouting::AddNetworkRouteTo - Next hop should be link-local");
163  }
164 
166  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);
167  m_networkRoutes.push_back (std::make_pair (route, metric));
168 }
169 
170 void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric)
171 {
172  NS_LOG_FUNCTION (this << network << networkPrefix << interface);
174  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface);
175  m_networkRoutes.push_back (std::make_pair (route, metric));
176 }
177 
178 void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
179 {
180  NS_LOG_FUNCTION (this << nextHop << interface << prefixToUse);
181  AddNetworkRouteTo (Ipv6Address ("::"), Ipv6Prefix::GetZero (), nextHop, interface, prefixToUse, metric);
182 }
183 
184 void Ipv6StaticRouting::AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
185 {
186  NS_LOG_FUNCTION (this << origin << group << inputInterface);
188  *route = Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (origin, group, inputInterface, outputInterfaces);
189  m_multicastRoutes.push_back (route);
190 }
191 
192 void Ipv6StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface)
193 {
194  NS_LOG_FUNCTION (this << outputInterface);
196  Ipv6Address network = Ipv6Address ("ff00::"); /* RFC 3513 */
197  Ipv6Prefix networkMask = Ipv6Prefix (8);
198  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkMask, outputInterface);
199  m_networkRoutes.push_back (std::make_pair (route, 0));
200 }
201 
203 {
205  return m_multicastRoutes.size ();
206 }
207 
209 {
210  NS_LOG_FUNCTION (this << index);
211  NS_ASSERT_MSG (index < m_multicastRoutes.size (), "Ipv6StaticRouting::GetMulticastRoute () : Index out of range");
212 
213  if (index < m_multicastRoutes.size ())
214  {
215  uint32_t tmp = 0;
216  for (MulticastRoutesCI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
217  {
218  if (tmp == index)
219  {
220  return *i;
221  }
222  tmp++;
223  }
224  }
225  return 0;
226 }
227 
229 {
230  NS_LOG_FUNCTION (this << origin << group << inputInterface);
231  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
232  {
233  Ipv6MulticastRoutingTableEntry *route = *i;
234  if (origin == route->GetOrigin ()
235  && group == route->GetGroup ()
236  && inputInterface == route->GetInputInterface ())
237  {
238  delete *i;
239  m_multicastRoutes.erase (i);
240  return true;
241  }
242  }
243  return false;
244 }
245 
247 {
248  NS_LOG_FUNCTION (this << index);
249  uint32_t tmp = 0;
250 
251  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
252  {
253  if (tmp == index)
254  {
255  delete *i;
256  m_multicastRoutes.erase (i);
257  return;
258  }
259  tmp++;
260  }
261 }
262 
263 bool Ipv6StaticRouting::HasNetworkDest (Ipv6Address network, uint32_t interfaceIndex)
264 {
265  NS_LOG_FUNCTION (this << network << interfaceIndex);
266 
267  /* in the network table */
268  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end (); j++)
269  {
270  Ipv6RoutingTableEntry* rtentry = j->first;
271  Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
272  Ipv6Address entry = rtentry->GetDestNetwork ();
273 
274  if (prefix.IsMatch (network, entry) && rtentry->GetInterface () == interfaceIndex)
275  {
276  return true;
277  }
278  }
279 
280  /* beuh!!! not route at all */
281  return false;
282 }
283 
285 {
286  NS_LOG_FUNCTION (this << dst << interface);
287  Ptr<Ipv6Route> rtentry = 0;
288  uint16_t longestMask = 0;
289  uint32_t shortestMetric = 0xffffffff;
290 
291  /* when sending on link-local multicast, there have to be interface specified */
292  if (dst.IsLinkLocalMulticast ())
293  {
294  NS_ASSERT_MSG (interface, "Try to send on link-local multicast address, and no interface index is given!");
295  rtentry = Create<Ipv6Route> ();
296  rtentry->SetSource (m_ipv6->SourceAddressSelection (m_ipv6->GetInterfaceForDevice (interface), dst));
297  rtentry->SetDestination (dst);
298  rtentry->SetGateway (Ipv6Address::GetZero ());
299  rtentry->SetOutputDevice (interface);
300  return rtentry;
301  }
302 
303  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
304  {
305  Ipv6RoutingTableEntry* j = it->first;
306  uint32_t metric = it->second;
307  Ipv6Prefix mask = j->GetDestNetworkPrefix ();
308  uint16_t maskLen = mask.GetPrefixLength ();
309  Ipv6Address entry = j->GetDestNetwork ();
310 
311  NS_LOG_LOGIC ("Searching for route to " << dst << ", mask length " << maskLen << ", metric " << metric);
312 
313  if (mask.IsMatch (dst, entry))
314  {
315  NS_LOG_LOGIC ("Found global network route " << *j << ", mask length " << maskLen << ", metric " << metric);
316 
317  /* if interface is given, check the route will output on this interface */
318  if (!interface || interface == m_ipv6->GetNetDevice (j->GetInterface ()))
319  {
320  if (maskLen < longestMask)
321  {
322  NS_LOG_LOGIC ("Previous match longer, skipping");
323  continue;
324  }
325 
326  if (maskLen > longestMask)
327  {
328  shortestMetric = 0xffffffff;
329  }
330 
331  longestMask = maskLen;
332  if (metric > shortestMetric)
333  {
334  NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
335  continue;
336  }
337 
338  shortestMetric = metric;
339  Ipv6RoutingTableEntry* route = j;
340  uint32_t interfaceIdx = route->GetInterface ();
341  rtentry = Create<Ipv6Route> ();
342 
343  if (route->GetGateway ().IsAny ())
344  {
345  rtentry->SetSource (m_ipv6->SourceAddressSelection (interfaceIdx, route->GetDest ()));
346  }
347  else if (route->GetDest ().IsAny ()) /* default route */
348  {
349  rtentry->SetSource (m_ipv6->SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? dst : route->GetPrefixToUse ()));
350  }
351  else
352  {
353  rtentry->SetSource (m_ipv6->SourceAddressSelection (interfaceIdx, route->GetGateway ()));
354  }
355 
356  rtentry->SetDestination (route->GetDest ());
357  rtentry->SetGateway (route->GetGateway ());
358  rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
359  }
360  }
361  }
362 
363  if (rtentry)
364  {
365  NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (Through " << rtentry->GetGateway () << ") at the end");
366  }
367  return rtentry;
368 }
369 
371 {
373 
374  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end (); j = m_networkRoutes.erase (j))
375  {
376  delete j->first;
377  }
378  m_networkRoutes.clear ();
379 
380  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i = m_multicastRoutes.erase (i))
381  {
382  delete (*i);
383  }
384  m_multicastRoutes.clear ();
385 
386  m_ipv6 = 0;
388 }
389 
391 {
392  NS_LOG_FUNCTION (this << origin << group << interface);
393  Ptr<Ipv6MulticastRoute> mrtentry = 0;
394 
395  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
396  {
397  Ipv6MulticastRoutingTableEntry* route = *i;
398 
399  /*
400  We've been passed an origin address, a multicast group address and an
401  interface index. We have to decide if the current route in the list is
402  a match.
403 
404  The first case is the restrictive case where the origin, group and index
405  matches. This picks up exact routes during forwarded and exact routes from
406  the local node (in which case the ifIndex is a wildcard).
407  */
408 
409  if (origin == route->GetOrigin () && group == route->GetGroup ())
410  {
411  /* skipping SSM case */
412  NS_LOG_LOGIC ("Find source specific multicast route" << *i);
413  }
414 
415  if (group == route->GetGroup ())
416  {
417  if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
418  {
419  NS_LOG_LOGIC ("Found multicast route" << *i);
420  mrtentry = Create<Ipv6MulticastRoute> ();
421  mrtentry->SetGroup (route->GetGroup ());
422  mrtentry->SetOrigin (route->GetOrigin ());
423  mrtentry->SetParent (route->GetInputInterface ());
424  for (uint32_t j = 0; j < route->GetNOutputInterfaces (); j++)
425  {
426  if (route->GetOutputInterface (j))
427  {
428  NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
429  mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
430  }
431  }
432  return mrtentry;
433  }
434  }
435  }
436  return mrtentry;
437 }
438 
440 {
441  return m_networkRoutes.size ();
442 }
443 
445 {
447  Ipv6Address dst ("::");
448  uint32_t shortestMetric = 0xffffffff;
449  Ipv6RoutingTableEntry* result = 0;
450 
451  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
452  {
453  Ipv6RoutingTableEntry* j = it->first;
454  uint32_t metric = it->second;
455  Ipv6Prefix mask = j->GetDestNetworkPrefix ();
456  uint16_t maskLen = mask.GetPrefixLength ();
457  Ipv6Address entry = j->GetDestNetwork ();
458 
459  if (maskLen)
460  {
461  continue;
462  }
463 
464  if (metric > shortestMetric)
465  {
466  continue;
467  }
468  shortestMetric = metric;
469  result = j;
470  }
471 
472  if (result)
473  {
474  return result;
475  }
476  else
477  {
478  return Ipv6RoutingTableEntry ();
479  }
480 }
481 
483 {
484  NS_LOG_FUNCTION (this << index);
485  uint32_t tmp = 0;
486 
487  for (NetworkRoutesCI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
488  {
489  if (tmp == index)
490  {
491  return it->first;
492  }
493  tmp++;
494  }
495  NS_ASSERT (false);
496  // quiet compiler.
497  return 0;
498 }
499 
500 uint32_t Ipv6StaticRouting::GetMetric (uint32_t index) const
501 {
503  uint32_t tmp = 0;
504 
505  for (NetworkRoutesCI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
506  {
507  if (tmp == index)
508  {
509  return it->second;
510  }
511  tmp++;
512  }
513  NS_ASSERT (false);
514  // quiet compiler.
515  return 0;
516 }
517 
518 void Ipv6StaticRouting::RemoveRoute (uint32_t index)
519 {
520  NS_LOG_FUNCTION (this << index);
521  uint32_t tmp = 0;
522 
523  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
524  {
525  if (tmp == index)
526  {
527  delete it->first;
528  m_networkRoutes.erase (it);
529  return;
530  }
531  tmp++;
532  }
533  NS_ASSERT (false);
534 }
535 
536 void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse)
537 {
538  NS_LOG_FUNCTION (this << network << prefix << ifIndex);
539 
540  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
541  {
542  Ipv6RoutingTableEntry* rtentry = it->first;
543  if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex
544  && rtentry->GetPrefixToUse () == prefixToUse)
545  {
546  delete it->first;
547  m_networkRoutes.erase (it);
548  return;
549  }
550  }
551 }
552 
554 {
555  NS_LOG_FUNCTION (this << header << oif);
556  Ipv6Address destination = header.GetDestinationAddress ();
557  Ptr<Ipv6Route> rtentry = 0;
558 
559  if (destination.IsMulticast ())
560  {
561  // Note: Multicast routes for outbound packets are stored in the
562  // normal unicast table. An implication of this is that it is not
563  // possible to source multicast datagrams on multiple interfaces.
564  // This is a well-known property of sockets implementation on
565  // many Unix variants.
566  // So, we just log it and fall through to LookupStatic ()
567  NS_LOG_LOGIC ("RouteOutput ()::Multicast destination");
568  }
569 
570  rtentry = LookupStatic (destination, oif);
571  if (rtentry)
572  {
573  sockerr = Socket::ERROR_NOTERROR;
574  }
575  else
576  {
577  sockerr = Socket::ERROR_NOROUTETOHOST;
578  }
579  return rtentry;
580 }
581 
585 {
586  NS_LOG_FUNCTION (this << p << header << header.GetSourceAddress () << header.GetDestinationAddress () << idev);
587  NS_ASSERT (m_ipv6 != 0);
588  // Check if input device supports IP
589  NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
590  uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
591  Ipv6Address dst = header.GetDestinationAddress ();
592 
593  if (dst.IsMulticast ())
594  {
595  NS_LOG_LOGIC ("Multicast destination");
597  header.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev));
598 
599  if (mrtentry)
600  {
601  NS_LOG_LOGIC ("Multicast route found");
602  mcb (idev, mrtentry, p, header); // multicast forwarding callback
603  return true;
604  }
605  else
606  {
607  NS_LOG_LOGIC ("Multicast route not found");
608  return false; // Let other routing protocols try to handle this
609  }
610  }
611 
613  // Right now, we will be permissive and allow a source to send us
614  // a packet to one of our other interface addresses; that is, the
615  // destination unicast address does not match one of the iif addresses,
616  // but we check our other interfaces. This could be an option
617  // (to remove the outer loop immediately below and just check iif).
618  for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
619  {
620  for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
621  {
622  Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
623  Ipv6Address addr = iaddr.GetAddress ();
624  if (addr.IsEqual (header.GetDestinationAddress ()))
625  {
626  if (j == iif)
627  {
628  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
629  }
630  else
631  {
632  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
633  }
634  lcb (p, header, iif);
635  return true;
636  }
637  NS_LOG_LOGIC ("Address " << addr << " not a match");
638  }
639  }
640  // Check if input device supports IP forwarding
641  if (m_ipv6->IsForwarding (iif) == false)
642  {
643  NS_LOG_LOGIC ("Forwarding disabled for this interface");
644  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
645  return false;
646  }
647  // Next, try to find a route
648  NS_LOG_LOGIC ("Unicast destination");
649  Ptr<Ipv6Route> rtentry = LookupStatic (header.GetDestinationAddress ());
650 
651  if (rtentry != 0)
652  {
653  NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
654  ucb (idev, rtentry, p, header); // unicast forwarding callback
655  return true;
656  }
657  else
658  {
659  NS_LOG_LOGIC ("Did not find unicast destination- returning false");
660  return false; // Let other routing protocols try to handle this
661  }
662 }
663 
665 {
666  for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
667  {
668  if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address ()
669  && m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
670  {
671  if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
672  {
673  /* host route */
674  AddHostRouteTo (m_ipv6->GetAddress (i, j).GetAddress (), i);
675  }
676  else
677  {
678  AddNetworkRouteTo (m_ipv6->GetAddress (i, j).GetAddress ().CombinePrefix (m_ipv6->GetAddress (i, j).GetPrefix ()),
679  m_ipv6->GetAddress (i, j).GetPrefix (), i);
680  }
681  }
682  }
683 }
684 
686 {
687  NS_LOG_FUNCTION (this << i);
688 
689  /* remove all static routes that are going through this interface */
690  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); )
691  {
692  if (it->first->GetInterface () == i)
693  {
694  delete it->first;
695  it = m_networkRoutes.erase (it);
696  }
697  else
698  {
699  it++;
700  }
701  }
702 }
703 
705 {
706  if (!m_ipv6->IsUp (interface))
707  {
708  return;
709  }
710 
711  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
712  Ipv6Prefix networkMask = address.GetPrefix ();
713 
714  if (address.GetAddress () != Ipv6Address () && address.GetPrefix () != Ipv6Prefix ())
715  {
716  AddNetworkRouteTo (networkAddress, networkMask, interface);
717  }
718 }
719 
721 {
722  if (!m_ipv6->IsUp (interface))
723  {
724  return;
725  }
726 
727  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
728  Ipv6Prefix networkMask = address.GetPrefix ();
729 
730  // Remove all static routes that are going through this interface
731  // which reference this network
732  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); )
733  {
734  if (it->first->GetInterface () == interface
735  && it->first->IsNetwork ()
736  && it->first->GetDestNetwork () == networkAddress
737  && it->first->GetDestNetworkPrefix () == networkMask)
738  {
739  delete it->first;
740  it = m_networkRoutes.erase (it);
741  }
742  else
743  {
744  it++;
745  }
746  }
747 }
748 
749 void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
750 {
751  NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
752  if (dst != Ipv6Address::GetZero ())
753  {
754  AddNetworkRouteTo (dst, mask, nextHop, interface);
755  }
756  else /* default route */
757  {
758  /* this case is mainly used by configuring default route following RA processing,
759  * in case of multiple prefix in RA, the first will configured default route
760  */
761 
762  /* for the moment, all default route has the same metric
763  * so according to the longest prefix algorithm,
764  * the default route chosen will be the last added
765  */
766  SetDefaultRoute (nextHop, interface, prefixToUse);
767  }
768 }
769 
770 void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
771 {
772  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
773  if (dst != Ipv6Address::GetZero ())
774  {
775  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end ();)
776  {
777  Ipv6RoutingTableEntry* rtentry = j->first;
778  Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
779  Ipv6Address entry = rtentry->GetDestNetwork ();
780 
781  if (dst == entry && prefix == mask && rtentry->GetInterface () == interface)
782  {
783  delete j->first;
784  j = m_networkRoutes.erase (j);
785  }
786  else
787  {
788  ++j;
789  }
790  }
791  }
792  else
793  {
794  /* default route case */
795  RemoveRoute (dst, mask, interface, prefixToUse);
796  }
797 }
798 
799 } /* namespace ns3 */
800 
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:150
Introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
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 "...
Ipv6Address GetPrefixToUse() const
Get the prefix to use (for multihomed link).
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
NetworkRoutes m_networkRoutes
the forwarding table for network.
Callback template class.
Definition: callback.h:1164
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 an Object subclass with the TypeId system.
Definition: object-base.h:44
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:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
IPv6 address associated with an interface.
second
Definition: nstime.h:114
bool IsEqual(const Ipv6Address &other) const
Comparison operation between two Ipv6Addresses.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:339
#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).
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.
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:252
Introspection did not find any typical Config paths.
uint32_t GetOutputInterface(uint32_t n) const
Get a specified output interface.
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:335
Ipv6RoutingTableEntry GetDefaultRoute()
Get the default route.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
Ipv6Address GetGateway() const
Get the gateway.
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:90
Describes an IPv6 address.
Definition: ipv6-address.h:47
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).
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
Ipv6Address GetDest() const
Get the destination.
A network Node.
Definition: node.h:56
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:743
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:389
bool IsGateway() const
Is it the gateway ?
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:330
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:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:826
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.