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