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