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