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