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 (unit)
89  << ", Local time: " << m_ipv6->GetObject<Node> ()->GetLocalTime ().As (unit)
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 
228 bool Ipv6StaticRouting::RemoveMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface)
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  if (maskLen == 128)
360  {
361  break;
362  }
363  }
364  }
365  }
366 
367  if (rtentry)
368  {
369  NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (Through " << rtentry->GetGateway () << ") at the end");
370  }
371  return rtentry;
372 }
373 
375 {
377 
378  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end (); j = m_networkRoutes.erase (j))
379  {
380  delete j->first;
381  }
382  m_networkRoutes.clear ();
383 
384  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i = m_multicastRoutes.erase (i))
385  {
386  delete (*i);
387  }
388  m_multicastRoutes.clear ();
389 
390  m_ipv6 = 0;
392 }
393 
395 {
396  NS_LOG_FUNCTION (this << origin << group << interface);
397  Ptr<Ipv6MulticastRoute> mrtentry = 0;
398 
399  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
400  {
401  Ipv6MulticastRoutingTableEntry* route = *i;
402 
403  /*
404  We've been passed an origin address, a multicast group address and an
405  interface index. We have to decide if the current route in the list is
406  a match.
407 
408  The first case is the restrictive case where the origin, group and index
409  matches. This picks up exact routes during forwarded and exact routes from
410  the local node (in which case the ifIndex is a wildcard).
411  */
412 
413  if (origin == route->GetOrigin () && group == route->GetGroup ())
414  {
415  /* skipping SSM case */
416  NS_LOG_LOGIC ("Find source specific multicast route" << *i);
417  }
418 
419  if (group == route->GetGroup ())
420  {
421  if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
422  {
423  NS_LOG_LOGIC ("Found multicast route" << *i);
424  mrtentry = Create<Ipv6MulticastRoute> ();
425  mrtentry->SetGroup (route->GetGroup ());
426  mrtentry->SetOrigin (route->GetOrigin ());
427  mrtentry->SetParent (route->GetInputInterface ());
428  for (uint32_t j = 0; j < route->GetNOutputInterfaces (); j++)
429  {
430  if (route->GetOutputInterface (j))
431  {
432  NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
433  mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
434  }
435  }
436  return mrtentry;
437  }
438  }
439  }
440  return mrtentry;
441 }
442 
444 {
445  return m_networkRoutes.size ();
446 }
447 
449 {
451  Ipv6Address dst ("::");
452  uint32_t shortestMetric = 0xffffffff;
453  Ipv6RoutingTableEntry* result = 0;
454 
455  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
456  {
457  Ipv6RoutingTableEntry* j = it->first;
458  uint32_t metric = it->second;
459  Ipv6Prefix mask = j->GetDestNetworkPrefix ();
460  uint16_t maskLen = mask.GetPrefixLength ();
461  Ipv6Address entry = j->GetDestNetwork ();
462 
463  if (maskLen)
464  {
465  continue;
466  }
467 
468  if (metric > shortestMetric)
469  {
470  continue;
471  }
472  shortestMetric = metric;
473  result = j;
474  }
475 
476  if (result)
477  {
478  return result;
479  }
480  else
481  {
482  return Ipv6RoutingTableEntry ();
483  }
484 }
485 
487 {
488  NS_LOG_FUNCTION (this << index);
489  uint32_t tmp = 0;
490 
491  for (NetworkRoutesCI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
492  {
493  if (tmp == index)
494  {
495  return it->first;
496  }
497  tmp++;
498  }
499  NS_ASSERT (false);
500  // quiet compiler.
501  return 0;
502 }
503 
504 uint32_t Ipv6StaticRouting::GetMetric (uint32_t index) const
505 {
507  uint32_t tmp = 0;
508 
509  for (NetworkRoutesCI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
510  {
511  if (tmp == index)
512  {
513  return it->second;
514  }
515  tmp++;
516  }
517  NS_ASSERT (false);
518  // quiet compiler.
519  return 0;
520 }
521 
522 void Ipv6StaticRouting::RemoveRoute (uint32_t index)
523 {
524  NS_LOG_FUNCTION (this << index);
525  uint32_t tmp = 0;
526 
527  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
528  {
529  if (tmp == index)
530  {
531  delete it->first;
532  m_networkRoutes.erase (it);
533  return;
534  }
535  tmp++;
536  }
537  NS_ASSERT (false);
538 }
539 
540 void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse)
541 {
542  NS_LOG_FUNCTION (this << network << prefix << ifIndex);
543 
544  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
545  {
546  Ipv6RoutingTableEntry* rtentry = it->first;
547  if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex
548  && rtentry->GetPrefixToUse () == prefixToUse)
549  {
550  delete it->first;
551  m_networkRoutes.erase (it);
552  return;
553  }
554  }
555 }
556 
558 {
559  NS_LOG_FUNCTION (this << header << oif);
560  Ipv6Address destination = header.GetDestinationAddress ();
561  Ptr<Ipv6Route> rtentry = 0;
562 
563  if (destination.IsMulticast ())
564  {
565  // Note: Multicast routes for outbound packets are stored in the
566  // normal unicast table. An implication of this is that it is not
567  // possible to source multicast datagrams on multiple interfaces.
568  // This is a well-known property of sockets implementation on
569  // many Unix variants.
570  // So, we just log it and fall through to LookupStatic ()
571  NS_LOG_LOGIC ("RouteOutput ()::Multicast destination");
572  }
573 
574  rtentry = LookupStatic (destination, oif);
575  if (rtentry)
576  {
577  sockerr = Socket::ERROR_NOTERROR;
578  }
579  else
580  {
581  sockerr = Socket::ERROR_NOROUTETOHOST;
582  }
583  return rtentry;
584 }
585 
589 {
590  NS_LOG_FUNCTION (this << p << header << header.GetSourceAddress () << header.GetDestinationAddress () << idev);
591  NS_ASSERT (m_ipv6 != 0);
592  // Check if input device supports IP
593  NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
594  uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
595  Ipv6Address dst = header.GetDestinationAddress ();
596 
597  // Multicast recognition; handle local delivery here
598  if (dst.IsMulticast ())
599  {
600  NS_LOG_LOGIC ("Multicast destination");
602  header.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev));
603 
604  // \todo check if we want to forward up the packet
605  if (mrtentry)
606  {
607  NS_LOG_LOGIC ("Multicast route found");
608  mcb (idev, mrtentry, p, header); // multicast forwarding callback
609  return true;
610  }
611  else
612  {
613  NS_LOG_LOGIC ("Multicast route not found");
614  return false; // Let other routing protocols try to handle this
615  }
616  }
617 
618  // Check if input device supports IP forwarding
619  if (m_ipv6->IsForwarding (iif) == false)
620  {
621  NS_LOG_LOGIC ("Forwarding disabled for this interface");
622  if (!ecb.IsNull ())
623  {
624  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
625  }
626  return true;
627  }
628  // Next, try to find a route
629  NS_LOG_LOGIC ("Unicast destination");
630  Ptr<Ipv6Route> rtentry = LookupStatic (header.GetDestinationAddress ());
631 
632  if (rtentry != 0)
633  {
634  NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
635  ucb (idev, rtentry, p, header); // unicast forwarding callback
636  return true;
637  }
638  else
639  {
640  NS_LOG_LOGIC ("Did not find unicast destination- returning false");
641  return false; // Let other routing protocols try to handle this
642  }
643 }
644 
646 {
647  for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
648  {
649  if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address ()
650  && m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
651  {
652  if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
653  {
654  /* host route */
655  AddHostRouteTo (m_ipv6->GetAddress (i, j).GetAddress (), i);
656  }
657  else
658  {
659  AddNetworkRouteTo (m_ipv6->GetAddress (i, j).GetAddress ().CombinePrefix (m_ipv6->GetAddress (i, j).GetPrefix ()),
660  m_ipv6->GetAddress (i, j).GetPrefix (), i);
661  }
662  }
663  }
664 }
665 
667 {
668  NS_LOG_FUNCTION (this << i);
669 
670  /* remove all static routes that are going through this interface */
671  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); )
672  {
673  if (it->first->GetInterface () == i)
674  {
675  delete it->first;
676  it = m_networkRoutes.erase (it);
677  }
678  else
679  {
680  it++;
681  }
682  }
683 }
684 
686 {
687  if (!m_ipv6->IsUp (interface))
688  {
689  return;
690  }
691 
692  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
693  Ipv6Prefix networkMask = address.GetPrefix ();
694 
695  if (address.GetAddress () != Ipv6Address () && address.GetPrefix () != Ipv6Prefix ())
696  {
697  AddNetworkRouteTo (networkAddress, networkMask, interface);
698  }
699 }
700 
702 {
703  if (!m_ipv6->IsUp (interface))
704  {
705  return;
706  }
707 
708  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
709  Ipv6Prefix networkMask = address.GetPrefix ();
710 
711  // Remove all static routes that are going through this interface
712  // which reference this network
713  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); )
714  {
715  if (it->first->GetInterface () == interface
716  && it->first->IsNetwork ()
717  && it->first->GetDestNetwork () == networkAddress
718  && it->first->GetDestNetworkPrefix () == networkMask)
719  {
720  delete it->first;
721  it = m_networkRoutes.erase (it);
722  }
723  else
724  {
725  it++;
726  }
727  }
728 }
729 
730 void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
731 {
732  NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
733  if (dst != Ipv6Address::GetZero ())
734  {
735  AddNetworkRouteTo (dst, mask, nextHop, interface);
736  }
737  else /* default route */
738  {
739  /* this case is mainly used by configuring default route following RA processing,
740  * in case of multiple prefix in RA, the first will configured default route
741  */
742 
743  /* for the moment, all default route has the same metric
744  * so according to the longest prefix algorithm,
745  * the default route chosen will be the last added
746  */
747  SetDefaultRoute (nextHop, interface, prefixToUse);
748  }
749 }
750 
751 void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
752 {
753  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
754  if (dst != Ipv6Address::GetZero ())
755  {
756  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end ();)
757  {
758  Ipv6RoutingTableEntry* rtentry = j->first;
759  Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
760  Ipv6Address entry = rtentry->GetDestNetwork ();
761 
762  if (dst == entry && prefix == mask && rtentry->GetInterface () == interface)
763  {
764  delete j->first;
765  j = m_networkRoutes.erase (j);
766  }
767  else
768  {
769  ++j;
770  }
771  }
772  }
773  else
774  {
775  /* default route case */
776  RemoveRoute (dst, mask, interface, prefixToUse);
777  }
778 }
779 
780 } /* namespace ns3 */
781 
static const uint32_t MAX_TTL
Maximum Time-To-Live (TTL).
Definition: ipv6-route.h:150
bool IsGateway() const
Is it the gateway ?
Packet header for IPv6.
Definition: ipv6-header.h:34
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 "...
NetworkRoutes m_networkRoutes
the forwarding table for network.
Ipv6Address GetGroup() const
Get the group.
Callback template class.
Definition: callback.h:1176
bool RemoveMulticastRoute(Ipv6Address origin, Ipv6Address group, uint32_t inputInterface)
Remove a static multicast route.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Ipv6Address GetPrefixToUse() const
Get the prefix to use (for multihomed link).
static Ipv6RoutingTableEntry CreateNetworkRouteTo(Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface)
Create a route to a network.
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
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.
Ipv6MulticastRoutingTableEntry GetMulticastRoute(uint32_t i) const
Get the specified multicast route.
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:204
IPv6 address associated with an interface.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:280
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
#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.
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
Ipv6RoutingTableEntry GetRoute(uint32_t i) const
Get a specified 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).
uint32_t GetNMulticastRoutes() const
Get the number of entries in the multicast routing table.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
Ipv6Address GetDestNetwork() const
Get the destination network.
bool IsMatch(Ipv6Address a, Ipv6Address b) const
If the Address match the type.
void AddHostRouteTo(Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address("::"), uint32_t metric=0)
Add route to host.
Ipv6Address GetOrigin() const
Get the source of this route.
static TypeId GetTypeId()
The interface Id associated with this class.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
A record of an IPv6 route.
Ipv6Address GetDest() const
Get the destination.
Ptr< Ipv6 > m_ipv6
Ipv6 reference.
virtual void NotifyInterfaceDown(uint32_t interface)
Notify when specified interface goes DOWN.
bool IsHost() const
Is the route entry correspond to a host ?
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.
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:108
virtual void NotifyRemoveAddress(uint32_t interface, Ipv6InterfaceAddress address)
Notify when specified interface add an address.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
void AddNetworkRouteTo(Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric=0)
Add route to network.
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)
Ipv6Address GetGateway() const
Get the gateway.
virtual void NotifyInterfaceUp(uint32_t interface)
Notify when specified interface goes UP.
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:100
Static routing protocol for IP version 6 stacks.
uint32_t GetNRoutes() const
Get the number or entries in the routing table.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
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:390
address
Definition: first.py:37
Ipv6RoutingTableEntry GetDefaultRoute()
Get the default route.
uint8_t GetPrefixLength() const
Get prefix length.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
Describes an IPv6 address.
Definition: ipv6-address.h:49
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.
static Ipv6Prefix GetOnes()
Get the "all-1" IPv6 mask (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
uint32_t GetInputInterface() const
Get the input interface address.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:264
uint32_t GetMetric(uint32_t index) const
Get a metric for route from the static unicast routing table.
A network Node.
Definition: node.h:56
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:819
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:449
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:309
MulticastRoutes m_multicastRoutes
the forwarding table for multicast.
Ipv6Prefix GetDestNetworkPrefix() const
Get the destination prefix.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:110
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:915
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.
uint32_t GetNOutputInterfaces() const
Get the number of output interfaces of this route.
bool IsAny() const
If the IPv6 address is the "Any" address.
std::list< Ipv6MulticastRoutingTableEntry * >::iterator MulticastRoutesI
Iterator for container for the multicast routes.
uint32_t GetInterface() const
Get the interface index.
uint32_t GetOutputInterface(uint32_t n) const
Get a specified output interface.