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