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