A Discrete-Event Network Simulator
API
ipv6-static-routing.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007-2009 Strasbourg University
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
19  */
20 
21 #include <iomanip>
22 #include "ns3/log.h"
23 #include "ns3/node.h"
24 #include "ns3/packet.h"
25 #include "ns3/simulator.h"
26 #include "ns3/ipv6-route.h"
27 #include "ns3/net-device.h"
28 #include "ns3/names.h"
29 
30 #include "ipv6-static-routing.h"
32 
33 namespace ns3 {
34 
35 NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRouting");
36 
37 NS_OBJECT_ENSURE_REGISTERED (Ipv6StaticRouting);
38 
40 {
41  static TypeId tid = TypeId ("ns3::Ipv6StaticRouting")
43  .SetGroupName ("Internet")
44  .AddConstructor<Ipv6StaticRouting> ()
45  ;
46  return tid;
47 }
48 
50  : m_ipv6 (0)
51 {
53 }
54 
56 {
58 }
59 
61 {
62  NS_LOG_FUNCTION (this << ipv6);
63  NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
64  uint32_t i = 0;
65  m_ipv6 = ipv6;
66 
67  for (i = 0; i < m_ipv6->GetNInterfaces (); i++)
68  {
69  if (m_ipv6->IsUp (i))
70  {
72  }
73  else
74  {
76  }
77  }
78 }
79 
80 // Formatted like output of "route -n" command
81 void
83 {
84  NS_LOG_FUNCTION (this << stream);
85  std::ostream* os = stream->GetStream ();
86 
87  *os << "Node: " << m_ipv6->GetObject<Node> ()->GetId ()
88  << " Time: " << Simulator::Now ().GetSeconds () << "s "
89  << "Ipv6StaticRouting table" << std::endl;
90 
91  if (GetNRoutes () > 0)
92  {
93  *os << "Destination Next Hop Flag Met Ref Use If" << std::endl;
94  for (uint32_t j = 0; j < GetNRoutes (); j++)
95  {
96  std::ostringstream dest, gw, mask, flags;
97  Ipv6RoutingTableEntry route = GetRoute (j);
98  dest << route.GetDest () << "/" << int(route.GetDestNetworkPrefix ().GetPrefixLength ());
99  *os << std::setiosflags (std::ios::left) << std::setw (31) << dest.str ();
100  gw << route.GetGateway ();
101  *os << std::setiosflags (std::ios::left) << std::setw (27) << gw.str ();
102  flags << "U";
103  if (route.IsHost ())
104  {
105  flags << "H";
106  }
107  else if (route.IsGateway ())
108  {
109  flags << "G";
110  }
111  *os << std::setiosflags (std::ios::left) << std::setw (5) << flags.str ();
112  *os << std::setiosflags (std::ios::left) << std::setw (4) << GetMetric (j);
113  // Ref ct not implemented
114  *os << "-" << " ";
115  // Use not implemented
116  *os << "-" << " ";
117  if (Names::FindName (m_ipv6->GetNetDevice (route.GetInterface ())) != "")
118  {
119  *os << Names::FindName (m_ipv6->GetNetDevice (route.GetInterface ()));
120  }
121  else
122  {
123  *os << route.GetInterface ();
124  }
125  *os << std::endl;
126  }
127  }
128 }
129 
130 void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
131 {
132  NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse << metric);
133  if (nextHop.IsLinkLocal())
134  {
135  NS_LOG_WARN ("Ipv6StaticRouting::AddHostRouteTo - Next hop should be link-local");
136  }
137 
138  AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse, metric);
139 }
140 
141 void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, uint32_t interface, uint32_t metric)
142 {
143  NS_LOG_FUNCTION (this << dst << interface << metric);
144  AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), interface, metric);
145 }
146 
147 void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric)
148 {
149  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << metric);
151  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface);
152  m_networkRoutes.push_back (std::make_pair (route, metric));
153 }
154 
155 void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
156 {
157  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse << metric);
158  if (nextHop.IsLinkLocal())
159  {
160  NS_LOG_WARN ("Ipv6StaticRouting::AddNetworkRouteTo - Next hop should be link-local");
161  }
162 
164  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);
165  m_networkRoutes.push_back (std::make_pair (route, metric));
166 }
167 
168 void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric)
169 {
170  NS_LOG_FUNCTION (this << network << networkPrefix << interface);
172  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface);
173  m_networkRoutes.push_back (std::make_pair (route, metric));
174 }
175 
176 void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
177 {
178  NS_LOG_FUNCTION (this << nextHop << interface << prefixToUse);
179  AddNetworkRouteTo (Ipv6Address ("::"), Ipv6Prefix::GetZero (), nextHop, interface, prefixToUse, metric);
180 }
181 
182 void Ipv6StaticRouting::AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
183 {
184  NS_LOG_FUNCTION (this << origin << group << inputInterface);
186  *route = Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (origin, group, inputInterface, outputInterfaces);
187  m_multicastRoutes.push_back (route);
188 }
189 
190 void Ipv6StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface)
191 {
192  NS_LOG_FUNCTION (this << outputInterface);
194  Ipv6Address network = Ipv6Address ("ff00::"); /* RFC 3513 */
195  Ipv6Prefix networkMask = Ipv6Prefix (8);
196  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkMask, outputInterface);
197  m_networkRoutes.push_back (std::make_pair (route, 0));
198 }
199 
201 {
203  return m_multicastRoutes.size ();
204 }
205 
207 {
208  NS_LOG_FUNCTION (this << index);
209  NS_ASSERT_MSG (index < m_multicastRoutes.size (), "Ipv6StaticRouting::GetMulticastRoute () : Index out of range");
210 
211  if (index < m_multicastRoutes.size ())
212  {
213  uint32_t tmp = 0;
214  for (MulticastRoutesCI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
215  {
216  if (tmp == index)
217  {
218  return *i;
219  }
220  tmp++;
221  }
222  }
223  return 0;
224 }
225 
227 {
228  NS_LOG_FUNCTION (this << origin << group << inputInterface);
229  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
230  {
231  Ipv6MulticastRoutingTableEntry *route = *i;
232  if (origin == route->GetOrigin ()
233  && group == route->GetGroup ()
234  && inputInterface == route->GetInputInterface ())
235  {
236  delete *i;
237  m_multicastRoutes.erase (i);
238  return true;
239  }
240  }
241  return false;
242 }
243 
245 {
246  NS_LOG_FUNCTION (this << index);
247  uint32_t tmp = 0;
248 
249  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
250  {
251  if (tmp == index)
252  {
253  delete *i;
254  m_multicastRoutes.erase (i);
255  return;
256  }
257  tmp++;
258  }
259 }
260 
261 bool Ipv6StaticRouting::HasNetworkDest (Ipv6Address network, uint32_t interfaceIndex)
262 {
263  NS_LOG_FUNCTION (this << network << interfaceIndex);
264 
265  /* in the network table */
266  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end (); j++)
267  {
268  Ipv6RoutingTableEntry* rtentry = j->first;
269  Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
270  Ipv6Address entry = rtentry->GetDestNetwork ();
271 
272  if (prefix.IsMatch (network, entry) && rtentry->GetInterface () == interfaceIndex)
273  {
274  return true;
275  }
276  }
277 
278  /* beuh!!! not route at all */
279  return false;
280 }
281 
283 {
284  NS_LOG_FUNCTION (this << dst << interface);
285  Ptr<Ipv6Route> rtentry = 0;
286  uint16_t longestMask = 0;
287  uint32_t shortestMetric = 0xffffffff;
288 
289  /* when sending on link-local multicast, there have to be interface specified */
290  if (dst.IsLinkLocalMulticast ())
291  {
292  NS_ASSERT_MSG (interface, "Try to send on link-local multicast address, and no interface index is given!");
293  rtentry = Create<Ipv6Route> ();
294  rtentry->SetSource (m_ipv6->SourceAddressSelection (m_ipv6->GetInterfaceForDevice (interface), dst));
295  rtentry->SetDestination (dst);
296  rtentry->SetGateway (Ipv6Address::GetZero ());
297  rtentry->SetOutputDevice (interface);
298  return rtentry;
299  }
300 
301  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
302  {
303  Ipv6RoutingTableEntry* j = it->first;
304  uint32_t metric = it->second;
305  Ipv6Prefix mask = j->GetDestNetworkPrefix ();
306  uint16_t maskLen = mask.GetPrefixLength ();
307  Ipv6Address entry = j->GetDestNetwork ();
308 
309  NS_LOG_LOGIC ("Searching for route to " << dst << ", mask length " << maskLen << ", metric " << metric);
310 
311  if (mask.IsMatch (dst, entry))
312  {
313  NS_LOG_LOGIC ("Found global network route " << *j << ", mask length " << maskLen << ", metric " << metric);
314 
315  /* if interface is given, check the route will output on this interface */
316  if (!interface || interface == m_ipv6->GetNetDevice (j->GetInterface ()))
317  {
318  if (maskLen < longestMask)
319  {
320  NS_LOG_LOGIC ("Previous match longer, skipping");
321  continue;
322  }
323 
324  if (maskLen > longestMask)
325  {
326  shortestMetric = 0xffffffff;
327  }
328 
329  longestMask = maskLen;
330  if (metric > shortestMetric)
331  {
332  NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
333  continue;
334  }
335 
336  shortestMetric = metric;
337  Ipv6RoutingTableEntry* route = j;
338  uint32_t interfaceIdx = route->GetInterface ();
339  rtentry = Create<Ipv6Route> ();
340 
341  if (route->GetGateway ().IsAny ())
342  {
343  rtentry->SetSource (m_ipv6->SourceAddressSelection (interfaceIdx, route->GetDest ()));
344  }
345  else if (route->GetDest ().IsAny ()) /* default route */
346  {
347  rtentry->SetSource (m_ipv6->SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? dst : route->GetPrefixToUse ()));
348  }
349  else
350  {
351  rtentry->SetSource (m_ipv6->SourceAddressSelection (interfaceIdx, route->GetGateway ()));
352  }
353 
354  rtentry->SetDestination (route->GetDest ());
355  rtentry->SetGateway (route->GetGateway ());
356  rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
357  }
358  }
359  }
360 
361  if (rtentry)
362  {
363  NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (Through " << rtentry->GetGateway () << ") at the end");
364  }
365  return rtentry;
366 }
367 
369 {
371 
372  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end (); j = m_networkRoutes.erase (j))
373  {
374  delete j->first;
375  }
376  m_networkRoutes.clear ();
377 
378  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i = m_multicastRoutes.erase (i))
379  {
380  delete (*i);
381  }
382  m_multicastRoutes.clear ();
383 
384  m_ipv6 = 0;
386 }
387 
389 {
390  NS_LOG_FUNCTION (this << origin << group << interface);
391  Ptr<Ipv6MulticastRoute> mrtentry = 0;
392 
393  for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
394  {
395  Ipv6MulticastRoutingTableEntry* route = *i;
396 
397  /*
398  We've been passed an origin address, a multicast group address and an
399  interface index. We have to decide if the current route in the list is
400  a match.
401 
402  The first case is the restrictive case where the origin, group and index
403  matches. This picks up exact routes during forwarded and exact routes from
404  the local node (in which case the ifIndex is a wildcard).
405  */
406 
407  if (origin == route->GetOrigin () && group == route->GetGroup ())
408  {
409  /* skipping SSM case */
410  NS_LOG_LOGIC ("Find source specific multicast route" << *i);
411  }
412 
413  if (group == route->GetGroup ())
414  {
415  if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
416  {
417  NS_LOG_LOGIC ("Found multicast route" << *i);
418  mrtentry = Create<Ipv6MulticastRoute> ();
419  mrtentry->SetGroup (route->GetGroup ());
420  mrtentry->SetOrigin (route->GetOrigin ());
421  mrtentry->SetParent (route->GetInputInterface ());
422  for (uint32_t j = 0; j < route->GetNOutputInterfaces (); j++)
423  {
424  if (route->GetOutputInterface (j))
425  {
426  NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
427  mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
428  }
429  }
430  return mrtentry;
431  }
432  }
433  }
434  return mrtentry;
435 }
436 
438 {
439  return m_networkRoutes.size ();
440 }
441 
443 {
445  Ipv6Address dst ("::");
446  uint32_t shortestMetric = 0xffffffff;
447  Ipv6RoutingTableEntry* result = 0;
448 
449  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
450  {
451  Ipv6RoutingTableEntry* j = it->first;
452  uint32_t metric = it->second;
453  Ipv6Prefix mask = j->GetDestNetworkPrefix ();
454  uint16_t maskLen = mask.GetPrefixLength ();
455  Ipv6Address entry = j->GetDestNetwork ();
456 
457  if (maskLen)
458  {
459  continue;
460  }
461 
462  if (metric > shortestMetric)
463  {
464  continue;
465  }
466  shortestMetric = metric;
467  result = j;
468  }
469 
470  if (result)
471  {
472  return result;
473  }
474  else
475  {
476  return Ipv6RoutingTableEntry ();
477  }
478 }
479 
481 {
482  NS_LOG_FUNCTION (this << index);
483  uint32_t tmp = 0;
484 
485  for (NetworkRoutesCI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
486  {
487  if (tmp == index)
488  {
489  return it->first;
490  }
491  tmp++;
492  }
493  NS_ASSERT (false);
494  // quiet compiler.
495  return 0;
496 }
497 
498 uint32_t Ipv6StaticRouting::GetMetric (uint32_t index) const
499 {
501  uint32_t tmp = 0;
502 
503  for (NetworkRoutesCI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
504  {
505  if (tmp == index)
506  {
507  return it->second;
508  }
509  tmp++;
510  }
511  NS_ASSERT (false);
512  // quiet compiler.
513  return 0;
514 }
515 
516 void Ipv6StaticRouting::RemoveRoute (uint32_t index)
517 {
518  NS_LOG_FUNCTION (this << index);
519  uint32_t tmp = 0;
520 
521  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
522  {
523  if (tmp == index)
524  {
525  delete it->first;
526  m_networkRoutes.erase (it);
527  return;
528  }
529  tmp++;
530  }
531  NS_ASSERT (false);
532 }
533 
534 void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse)
535 {
536  NS_LOG_FUNCTION (this << network << prefix << ifIndex);
537 
538  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); it++)
539  {
540  Ipv6RoutingTableEntry* rtentry = it->first;
541  if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex
542  && rtentry->GetPrefixToUse () == prefixToUse)
543  {
544  delete it->first;
545  m_networkRoutes.erase (it);
546  return;
547  }
548  }
549 }
550 
552 {
553  NS_LOG_FUNCTION (this << header << oif);
554  Ipv6Address destination = header.GetDestinationAddress ();
555  Ptr<Ipv6Route> rtentry = 0;
556 
557  if (destination.IsMulticast ())
558  {
559  // Note: Multicast routes for outbound packets are stored in the
560  // normal unicast table. An implication of this is that it is not
561  // possible to source multicast datagrams on multiple interfaces.
562  // This is a well-known property of sockets implementation on
563  // many Unix variants.
564  // So, we just log it and fall through to LookupStatic ()
565  NS_LOG_LOGIC ("RouteOutput ()::Multicast destination");
566  }
567 
568  rtentry = LookupStatic (destination, oif);
569  if (rtentry)
570  {
571  sockerr = Socket::ERROR_NOTERROR;
572  }
573  else
574  {
575  sockerr = Socket::ERROR_NOROUTETOHOST;
576  }
577  return rtentry;
578 }
579 
583 {
584  NS_LOG_FUNCTION (this << p << header << header.GetSourceAddress () << header.GetDestinationAddress () << idev);
585  NS_ASSERT (m_ipv6 != 0);
586  // Check if input device supports IP
587  NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
588  uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
589  Ipv6Address dst = header.GetDestinationAddress ();
590 
591  if (dst.IsMulticast ())
592  {
593  NS_LOG_LOGIC ("Multicast destination");
595  header.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev));
596 
597  if (mrtentry)
598  {
599  NS_LOG_LOGIC ("Multicast route found");
600  mcb (idev, mrtentry, p, header); // multicast forwarding callback
601  return true;
602  }
603  else
604  {
605  NS_LOG_LOGIC ("Multicast route not found");
606  return false; // Let other routing protocols try to handle this
607  }
608  }
609 
611  // Right now, we will be permissive and allow a source to send us
612  // a packet to one of our other interface addresses; that is, the
613  // destination unicast address does not match one of the iif addresses,
614  // but we check our other interfaces. This could be an option
615  // (to remove the outer loop immediately below and just check iif).
616  for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
617  {
618  for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
619  {
620  Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
621  Ipv6Address addr = iaddr.GetAddress ();
622  if (addr.IsEqual (header.GetDestinationAddress ()))
623  {
624  if (j == iif)
625  {
626  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
627  }
628  else
629  {
630  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
631  }
632  lcb (p, header, iif);
633  return true;
634  }
635  NS_LOG_LOGIC ("Address " << addr << " not a match");
636  }
637  }
638  // Check if input device supports IP forwarding
639  if (m_ipv6->IsForwarding (iif) == false)
640  {
641  NS_LOG_LOGIC ("Forwarding disabled for this interface");
642  ecb (p, header, Socket::ERROR_NOROUTETOHOST);
643  return false;
644  }
645  // Next, try to find a route
646  NS_LOG_LOGIC ("Unicast destination");
647  Ptr<Ipv6Route> rtentry = LookupStatic (header.GetDestinationAddress ());
648 
649  if (rtentry != 0)
650  {
651  NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
652  ucb (idev, rtentry, p, header); // unicast forwarding callback
653  return true;
654  }
655  else
656  {
657  NS_LOG_LOGIC ("Did not find unicast destination- returning false");
658  return false; // Let other routing protocols try to handle this
659  }
660 }
661 
663 {
664  for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
665  {
666  if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address ()
667  && m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
668  {
669  if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
670  {
671  /* host route */
672  AddHostRouteTo (m_ipv6->GetAddress (i, j).GetAddress (), i);
673  }
674  else
675  {
676  AddNetworkRouteTo (m_ipv6->GetAddress (i, j).GetAddress ().CombinePrefix (m_ipv6->GetAddress (i, j).GetPrefix ()),
677  m_ipv6->GetAddress (i, j).GetPrefix (), i);
678  }
679  }
680  }
681 }
682 
684 {
685  NS_LOG_FUNCTION (this << i);
686 
687  /* remove all static routes that are going through this interface */
688  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); )
689  {
690  if (it->first->GetInterface () == i)
691  {
692  delete it->first;
693  it = m_networkRoutes.erase (it);
694  }
695  else
696  {
697  it++;
698  }
699  }
700 }
701 
703 {
704  if (!m_ipv6->IsUp (interface))
705  {
706  return;
707  }
708 
709  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
710  Ipv6Prefix networkMask = address.GetPrefix ();
711 
712  if (address.GetAddress () != Ipv6Address () && address.GetPrefix () != Ipv6Prefix ())
713  {
714  AddNetworkRouteTo (networkAddress, networkMask, interface);
715  }
716 }
717 
719 {
720  if (!m_ipv6->IsUp (interface))
721  {
722  return;
723  }
724 
725  Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
726  Ipv6Prefix networkMask = address.GetPrefix ();
727 
728  // Remove all static routes that are going through this interface
729  // which reference this network
730  for (NetworkRoutesI it = m_networkRoutes.begin (); it != m_networkRoutes.end (); )
731  {
732  if (it->first->GetInterface () == interface
733  && it->first->IsNetwork ()
734  && it->first->GetDestNetwork () == networkAddress
735  && it->first->GetDestNetworkPrefix () == networkMask)
736  {
737  delete it->first;
738  it = m_networkRoutes.erase (it);
739  }
740  else
741  {
742  it++;
743  }
744  }
745 }
746 
747 void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
748 {
749  NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
750  if (dst != Ipv6Address::GetZero ())
751  {
752  AddNetworkRouteTo (dst, mask, nextHop, interface);
753  }
754  else /* default route */
755  {
756  /* this case is mainly used by configuring default route following RA processing,
757  * in case of multiple prefix in RA, the first will configured default route
758  */
759 
760  /* for the moment, all default route has the same metric
761  * so according to the longest prefix algorithm,
762  * the default route chosen will be the last added
763  */
764  SetDefaultRoute (nextHop, interface, prefixToUse);
765  }
766 }
767 
768 void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
769 {
770  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
771  if (dst != Ipv6Address::GetZero ())
772  {
773  for (NetworkRoutesI j = m_networkRoutes.begin (); j != m_networkRoutes.end ();)
774  {
775  Ipv6RoutingTableEntry* rtentry = j->first;
776  Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
777  Ipv6Address entry = rtentry->GetDestNetwork ();
778 
779  if (dst == entry && prefix == mask && rtentry->GetInterface () == interface)
780  {
781  delete j->first;
782  j = m_networkRoutes.erase (j);
783  }
784  else
785  {
786  ++j;
787  }
788  }
789  }
790  else
791  {
792  /* default route case */
793  RemoveRoute (dst, mask, interface, prefixToUse);
794  }
795 }
796 
797 } /* namespace ns3 */
798 
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:150
Introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
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 "...
Ipv6Address GetPrefixToUse() const
Get the prefix to use (for multihomed link).
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
NetworkRoutes m_networkRoutes
the forwarding table for network.
Callback template class.
Definition: callback.h:1164
bool RemoveMulticastRoute(Ipv6Address origin, Ipv6Address group, uint32_t inputInterface)
Remove a static multicast route.
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
Ipv6Prefix GetDestNetworkPrefix() const
Get the destination prefix.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
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:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
IPv6 address associated with an interface.
bool IsEqual(const Ipv6Address &other) const
Comparison operation between two Ipv6Addresses.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:339
#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).
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
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
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:252
Introspection did not find any typical Config paths.
uint32_t GetOutputInterface(uint32_t n) const
Get a specified output interface.
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:335
Ipv6RoutingTableEntry GetDefaultRoute()
Get the default route.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
Ipv6Address GetGateway() const
Get the gateway.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
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:90
Describes an IPv6 address.
Definition: ipv6-address.h:47
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.
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:228
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:743
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:389
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:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:826
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.