A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv6-static-routing.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007-2009 Strasbourg University
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
18 */
19
20#include "ipv6-static-routing.h"
21
22#include "ipv6-route.h"
24
25#include "ns3/log.h"
26#include "ns3/names.h"
27#include "ns3/net-device.h"
28#include "ns3/node.h"
29#include "ns3/packet.h"
30#include "ns3/simulator.h"
31
32#include <iomanip>
33
34namespace ns3
35{
36
37NS_LOG_COMPONENT_DEFINE("Ipv6StaticRouting");
38
39NS_OBJECT_ENSURE_REGISTERED(Ipv6StaticRouting);
40
41TypeId
43{
44 static TypeId tid = TypeId("ns3::Ipv6StaticRouting")
46 .SetGroupName("Internet")
47 .AddConstructor<Ipv6StaticRouting>();
48 return tid;
49}
50
52 : m_ipv6(nullptr)
53{
54 NS_LOG_FUNCTION(this);
55}
56
58{
59 NS_LOG_FUNCTION(this);
60}
61
62void
64{
65 NS_LOG_FUNCTION(this << ipv6);
66 NS_ASSERT(!m_ipv6 && ipv6);
67 uint32_t i = 0;
68 m_ipv6 = ipv6;
69
70 for (i = 0; i < m_ipv6->GetNInterfaces(); i++)
71 {
72 if (m_ipv6->IsUp(i))
73 {
75 }
76 else
77 {
79 }
80 }
81}
82
83// Formatted like output of "route -n" command
84void
86{
87 NS_LOG_FUNCTION(this << stream);
88 std::ostream* os = stream->GetStream();
89 // Copy the current ostream state
90 std::ios oldState(nullptr);
91 oldState.copyfmt(*os);
92
93 *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
94
95 *os << "Node: " << m_ipv6->GetObject<Node>()->GetId() << ", Time: " << Now().As(unit)
96 << ", Local time: " << m_ipv6->GetObject<Node>()->GetLocalTime().As(unit)
97 << ", Ipv6StaticRouting table" << std::endl;
98
99 if (GetNRoutes() > 0)
100 {
101 *os << "Destination Next Hop Flag Met Ref Use If"
102 << std::endl;
103 for (uint32_t j = 0; j < GetNRoutes(); j++)
104 {
105 std::ostringstream dest;
106 std::ostringstream gw;
107 std::ostringstream mask;
108 std::ostringstream flags;
110 dest << route.GetDest() << "/" << int(route.GetDestNetworkPrefix().GetPrefixLength());
111 *os << std::setw(31) << dest.str();
112 gw << route.GetGateway();
113 *os << std::setw(27) << gw.str();
114 flags << "U";
115 if (route.IsHost())
116 {
117 flags << "H";
118 }
119 else if (route.IsGateway())
120 {
121 flags << "G";
122 }
123 *os << std::setw(5) << flags.str();
124 *os << std::setw(4) << GetMetric(j);
125 // Ref ct not implemented
126 *os << "-"
127 << " ";
128 // Use not implemented
129 *os << "-"
130 << " ";
131 if (!Names::FindName(m_ipv6->GetNetDevice(route.GetInterface())).empty())
132 {
133 *os << Names::FindName(m_ipv6->GetNetDevice(route.GetInterface()));
134 }
135 else
136 {
137 *os << route.GetInterface();
138 }
139 *os << std::endl;
140 }
141 }
142 *os << std::endl;
143 // Restore the previous ostream state
144 (*os).copyfmt(oldState);
145}
146
147void
149 Ipv6Address nextHop,
150 uint32_t interface,
151 Ipv6Address prefixToUse,
152 uint32_t metric)
153{
154 NS_LOG_FUNCTION(this << dst << nextHop << interface << prefixToUse << metric);
155 if (nextHop.IsLinkLocal())
156 {
157 NS_LOG_WARN("Ipv6StaticRouting::AddHostRouteTo - Next hop should be link-local");
158 }
159
160 AddNetworkRouteTo(dst, Ipv6Prefix::GetOnes(), nextHop, interface, prefixToUse, metric);
161}
162
163void
165{
166 NS_LOG_FUNCTION(this << dst << interface << metric);
167 AddNetworkRouteTo(dst, Ipv6Prefix::GetOnes(), interface, metric);
168}
169
170void
172 Ipv6Prefix networkPrefix,
173 Ipv6Address nextHop,
174 uint32_t interface,
175 uint32_t metric)
176{
177 NS_LOG_FUNCTION(this << network << networkPrefix << nextHop << interface << metric);
178
180 Ipv6RoutingTableEntry::CreateNetworkRouteTo(network, networkPrefix, nextHop, interface);
181
182 if (!LookupRoute(route, metric))
183 {
184 Ipv6RoutingTableEntry* routePtr = new Ipv6RoutingTableEntry(route);
185 m_networkRoutes.emplace_back(routePtr, metric);
186 }
187}
188
189void
191 Ipv6Prefix networkPrefix,
192 Ipv6Address nextHop,
193 uint32_t interface,
194 Ipv6Address prefixToUse,
195 uint32_t metric)
196{
197 NS_LOG_FUNCTION(this << network << networkPrefix << nextHop << interface << prefixToUse
198 << metric);
199 if (nextHop.IsLinkLocal())
200 {
201 NS_LOG_WARN("Ipv6StaticRouting::AddNetworkRouteTo - Next hop should be link-local");
202 }
203
205 networkPrefix,
206 nextHop,
207 interface,
208 prefixToUse);
209 if (!LookupRoute(route, metric))
210 {
211 Ipv6RoutingTableEntry* routePtr = new Ipv6RoutingTableEntry(route);
212 m_networkRoutes.emplace_back(routePtr, metric);
213 }
214}
215
216void
218 Ipv6Prefix networkPrefix,
219 uint32_t interface,
220 uint32_t metric)
221{
222 NS_LOG_FUNCTION(this << network << networkPrefix << interface);
223
225 Ipv6RoutingTableEntry::CreateNetworkRouteTo(network, networkPrefix, interface);
226 if (!LookupRoute(route, metric))
227 {
228 Ipv6RoutingTableEntry* routePtr = new Ipv6RoutingTableEntry(route);
229 m_networkRoutes.emplace_back(routePtr, metric);
230 }
231}
232
233void
235 uint32_t interface,
236 Ipv6Address prefixToUse,
237 uint32_t metric)
238{
239 NS_LOG_FUNCTION(this << nextHop << interface << prefixToUse);
242 nextHop,
243 interface,
244 prefixToUse,
245 metric);
246}
247
248void
250 Ipv6Address group,
251 uint32_t inputInterface,
252 std::vector<uint32_t> outputInterfaces)
253{
254 NS_LOG_FUNCTION(this << origin << group << inputInterface);
257 group,
258 inputInterface,
259 outputInterfaces);
260 m_multicastRoutes.push_back(route);
261}
262
263void
265{
266 NS_LOG_FUNCTION(this << outputInterface);
268 Ipv6Address network = Ipv6Address("ff00::"); /* RFC 3513 */
269 Ipv6Prefix networkMask = Ipv6Prefix(8);
270 *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo(network, networkMask, outputInterface);
271 m_networkRoutes.emplace_back(route, 0);
272}
273
276{
277 NS_LOG_FUNCTION(this);
278 return m_multicastRoutes.size();
279}
280
283{
284 NS_LOG_FUNCTION(this << index);
285 NS_ASSERT_MSG(index < m_multicastRoutes.size(),
286 "Ipv6StaticRouting::GetMulticastRoute () : Index out of range");
287
288 if (index < m_multicastRoutes.size())
289 {
290 uint32_t tmp = 0;
291 for (MulticastRoutesCI i = m_multicastRoutes.begin(); i != m_multicastRoutes.end(); i++)
292 {
293 if (tmp == index)
294 {
295 return *i;
296 }
297 tmp++;
298 }
299 }
300 return nullptr;
301}
302
303bool
305 Ipv6Address group,
306 uint32_t inputInterface)
307{
308 NS_LOG_FUNCTION(this << origin << group << inputInterface);
309 for (MulticastRoutesI i = m_multicastRoutes.begin(); i != m_multicastRoutes.end(); i++)
310 {
312 if (origin == route->GetOrigin() && group == route->GetGroup() &&
313 inputInterface == route->GetInputInterface())
314 {
315 delete *i;
316 m_multicastRoutes.erase(i);
317 return true;
318 }
319 }
320 return false;
321}
322
323void
325{
326 NS_LOG_FUNCTION(this << index);
327 uint32_t tmp = 0;
328
329 for (MulticastRoutesI i = m_multicastRoutes.begin(); i != m_multicastRoutes.end(); i++)
330 {
331 if (tmp == index)
332 {
333 delete *i;
334 m_multicastRoutes.erase(i);
335 return;
336 }
337 tmp++;
338 }
339}
340
341bool
343{
344 NS_LOG_FUNCTION(this << network << interfaceIndex);
345
346 /* in the network table */
347 for (NetworkRoutesI j = m_networkRoutes.begin(); j != m_networkRoutes.end(); j++)
348 {
349 Ipv6RoutingTableEntry* rtentry = j->first;
350 Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix();
351 Ipv6Address entry = rtentry->GetDestNetwork();
352
353 if (prefix.IsMatch(network, entry) && rtentry->GetInterface() == interfaceIndex)
354 {
355 return true;
356 }
357 }
358
359 /* beuh!!! not route at all */
360 return false;
361}
362
363bool
365{
366 for (NetworkRoutesI j = m_networkRoutes.begin(); j != m_networkRoutes.end(); j++)
367 {
368 Ipv6RoutingTableEntry* rtentry = j->first;
369
370 if (rtentry->GetDest() == route.GetDest() &&
371 rtentry->GetDestNetworkPrefix() == route.GetDestNetworkPrefix() &&
372 rtentry->GetGateway() == route.GetGateway() &&
373 rtentry->GetInterface() == route.GetInterface() &&
374 rtentry->GetPrefixToUse() == route.GetPrefixToUse() && j->second == metric)
375 {
376 return true;
377 }
378 }
379 return false;
380}
381
384{
385 NS_LOG_FUNCTION(this << dst << interface);
386 Ptr<Ipv6Route> rtentry = nullptr;
387 uint16_t longestMask = 0;
388 uint32_t shortestMetric = 0xffffffff;
389
390 /* when sending on link-local multicast, there have to be interface specified */
391 if (dst.IsLinkLocalMulticast())
392 {
394 interface,
395 "Try to send on link-local multicast address, and no interface index is given!");
396 rtentry = Create<Ipv6Route>();
397 rtentry->SetSource(
398 m_ipv6->SourceAddressSelection(m_ipv6->GetInterfaceForDevice(interface), dst));
399 rtentry->SetDestination(dst);
400 rtentry->SetGateway(Ipv6Address::GetZero());
401 rtentry->SetOutputDevice(interface);
402 return rtentry;
403 }
404
405 for (NetworkRoutesI it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
406 {
407 Ipv6RoutingTableEntry* j = it->first;
408 uint32_t metric = it->second;
410 uint16_t maskLen = mask.GetPrefixLength();
411 Ipv6Address entry = j->GetDestNetwork();
412
413 NS_LOG_LOGIC("Searching for route to " << dst << ", mask length " << maskLen << ", metric "
414 << metric);
415
416 if (mask.IsMatch(dst, entry))
417 {
418 NS_LOG_LOGIC("Found global network route " << *j << ", mask length " << maskLen
419 << ", metric " << metric);
420
421 /* if interface is given, check the route will output on this interface */
422 if (!interface || interface == m_ipv6->GetNetDevice(j->GetInterface()))
423 {
424 if (maskLen < longestMask)
425 {
426 NS_LOG_LOGIC("Previous match longer, skipping");
427 continue;
428 }
429
430 if (maskLen > longestMask)
431 {
432 shortestMetric = 0xffffffff;
433 }
434
435 longestMask = maskLen;
436 if (metric > shortestMetric)
437 {
438 NS_LOG_LOGIC("Equal mask length, but previous metric shorter, skipping");
439 continue;
440 }
441
442 shortestMetric = metric;
443 Ipv6RoutingTableEntry* route = j;
444 uint32_t interfaceIdx = route->GetInterface();
445 rtentry = Create<Ipv6Route>();
446
447 if (route->GetGateway().IsAny())
448 {
449 rtentry->SetSource(
450 m_ipv6->SourceAddressSelection(interfaceIdx, route->GetDest()));
451 }
452 else if (route->GetDest().IsAny()) /* default route */
453 {
454 rtentry->SetSource(m_ipv6->SourceAddressSelection(
455 interfaceIdx,
456 route->GetPrefixToUse().IsAny() ? dst : route->GetPrefixToUse()));
457 }
458 else
459 {
460 rtentry->SetSource(
461 m_ipv6->SourceAddressSelection(interfaceIdx, route->GetDest()));
462 }
463
464 rtentry->SetDestination(route->GetDest());
465 rtentry->SetGateway(route->GetGateway());
466 rtentry->SetOutputDevice(m_ipv6->GetNetDevice(interfaceIdx));
467 if (maskLen == 128)
468 {
469 break;
470 }
471 }
472 }
473 }
474
475 if (rtentry)
476 {
477 NS_LOG_LOGIC("Matching route via " << rtentry->GetDestination() << " (Through "
478 << rtentry->GetGateway() << ") at the end");
479 }
480 return rtentry;
481}
482
483void
485{
486 NS_LOG_FUNCTION(this);
487
488 for (NetworkRoutesI j = m_networkRoutes.begin(); j != m_networkRoutes.end();
489 j = m_networkRoutes.erase(j))
490 {
491 delete j->first;
492 }
493 m_networkRoutes.clear();
494
495 for (MulticastRoutesI i = m_multicastRoutes.begin(); i != m_multicastRoutes.end();
496 i = m_multicastRoutes.erase(i))
497 {
498 delete (*i);
499 }
500 m_multicastRoutes.clear();
501
502 m_ipv6 = nullptr;
504}
505
508{
509 NS_LOG_FUNCTION(this << origin << group << interface);
510 Ptr<Ipv6MulticastRoute> mrtentry = nullptr;
511
512 for (MulticastRoutesI i = m_multicastRoutes.begin(); i != m_multicastRoutes.end(); i++)
513 {
515
516 /*
517 We've been passed an origin address, a multicast group address and an
518 interface index. We have to decide if the current route in the list is
519 a match.
520
521 The first case is the restrictive case where the origin, group and index
522 matches. This picks up exact routes during forwarded and exact routes from
523 the local node (in which case the ifIndex is a wildcard).
524 */
525
526 if (origin == route->GetOrigin() && group == route->GetGroup())
527 {
528 /* skipping SSM case */
529 NS_LOG_LOGIC("Find source specific multicast route" << *i);
530 }
531
532 if (group == route->GetGroup())
533 {
534 if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface())
535 {
536 NS_LOG_LOGIC("Found multicast route" << *i);
537 mrtentry = Create<Ipv6MulticastRoute>();
538 mrtentry->SetGroup(route->GetGroup());
539 mrtentry->SetOrigin(route->GetOrigin());
540 mrtentry->SetParent(route->GetInputInterface());
541 for (uint32_t j = 0; j < route->GetNOutputInterfaces(); j++)
542 {
543 if (route->GetOutputInterface(j))
544 {
545 NS_LOG_LOGIC("Setting output interface index "
546 << route->GetOutputInterface(j));
547 mrtentry->SetOutputTtl(route->GetOutputInterface(j),
549 }
550 }
551 return mrtentry;
552 }
553 }
554 }
555 return mrtentry;
556}
557
560{
561 return m_networkRoutes.size();
562}
563
566{
567 NS_LOG_FUNCTION(this);
568 Ipv6Address dst("::");
569 uint32_t shortestMetric = 0xffffffff;
570 Ipv6RoutingTableEntry* result = nullptr;
571
572 for (NetworkRoutesI it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
573 {
574 Ipv6RoutingTableEntry* j = it->first;
575 uint32_t metric = it->second;
577 uint16_t maskLen = mask.GetPrefixLength();
578 Ipv6Address entry = j->GetDestNetwork();
579
580 if (maskLen)
581 {
582 continue;
583 }
584
585 if (metric > shortestMetric)
586 {
587 continue;
588 }
589 shortestMetric = metric;
590 result = j;
591 }
592
593 if (result)
594 {
595 return result;
596 }
597 else
598 {
599 return Ipv6RoutingTableEntry();
600 }
601}
602
605{
606 NS_LOG_FUNCTION(this << index);
607 uint32_t tmp = 0;
608
609 for (NetworkRoutesCI it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
610 {
611 if (tmp == index)
612 {
613 return it->first;
614 }
615 tmp++;
616 }
617 NS_ASSERT(false);
618 // quiet compiler.
619 return nullptr;
620}
621
624{
625 NS_LOG_FUNCTION(this << index);
626 uint32_t tmp = 0;
627
628 for (NetworkRoutesCI it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
629 {
630 if (tmp == index)
631 {
632 return it->second;
633 }
634 tmp++;
635 }
636 NS_ASSERT(false);
637 // quiet compiler.
638 return 0;
639}
640
641void
643{
644 NS_LOG_FUNCTION(this << index);
645 uint32_t tmp = 0;
646
647 for (NetworkRoutesI it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
648 {
649 if (tmp == index)
650 {
651 delete it->first;
652 m_networkRoutes.erase(it);
653 return;
654 }
655 tmp++;
656 }
657 NS_ASSERT(false);
658}
659
660void
662 Ipv6Prefix prefix,
663 uint32_t ifIndex,
664 Ipv6Address prefixToUse)
665{
666 NS_LOG_FUNCTION(this << network << prefix << ifIndex);
667
668 for (NetworkRoutesI it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
669 {
670 Ipv6RoutingTableEntry* rtentry = it->first;
671 if (network == rtentry->GetDest() && rtentry->GetInterface() == ifIndex &&
672 rtentry->GetPrefixToUse() == prefixToUse)
673 {
674 delete it->first;
675 m_networkRoutes.erase(it);
676 return;
677 }
678 }
679}
680
683 const Ipv6Header& header,
684 Ptr<NetDevice> oif,
685 Socket::SocketErrno& sockerr)
686{
687 NS_LOG_FUNCTION(this << header << oif);
688 Ipv6Address destination = header.GetDestination();
689 Ptr<Ipv6Route> rtentry = nullptr;
690
691 if (destination.IsMulticast())
692 {
693 // Note: Multicast routes for outbound packets are stored in the
694 // normal unicast table. An implication of this is that it is not
695 // possible to source multicast datagrams on multiple interfaces.
696 // This is a well-known property of sockets implementation on
697 // many Unix variants.
698 // So, we just log it and fall through to LookupStatic ()
699 NS_LOG_LOGIC("RouteOutput ()::Multicast destination");
700 }
701
702 rtentry = LookupStatic(destination, oif);
703 if (rtentry)
704 {
705 sockerr = Socket::ERROR_NOTERROR;
706 }
707 else
708 {
710 }
711 return rtentry;
712}
713
714bool
716 const Ipv6Header& header,
718 const UnicastForwardCallback& ucb,
719 const MulticastForwardCallback& mcb,
720 const LocalDeliverCallback& lcb,
721 const ErrorCallback& ecb)
722{
723 NS_LOG_FUNCTION(this << p << header << header.GetSource() << header.GetDestination() << idev);
725 // Check if input device supports IP
726 NS_ASSERT(m_ipv6->GetInterfaceForDevice(idev) >= 0);
727 uint32_t iif = m_ipv6->GetInterfaceForDevice(idev);
728 Ipv6Address dst = header.GetDestination();
729
730 // Multicast recognition; handle local delivery here
731 if (dst.IsMulticast())
732 {
733 NS_LOG_LOGIC("Multicast destination");
735 header.GetDestination(),
736 m_ipv6->GetInterfaceForDevice(idev));
737
738 // \todo check if we want to forward up the packet
739 if (mrtentry)
740 {
741 NS_LOG_LOGIC("Multicast route found");
742 mcb(idev, mrtentry, p, header); // multicast forwarding callback
743 return true;
744 }
745 else
746 {
747 NS_LOG_LOGIC("Multicast route not found");
748 return false; // Let other routing protocols try to handle this
749 }
750 }
751
752 // Check if input device supports IP forwarding
753 if (!m_ipv6->IsForwarding(iif))
754 {
755 NS_LOG_LOGIC("Forwarding disabled for this interface");
756 if (!ecb.IsNull())
757 {
758 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
759 }
760 return true;
761 }
762 // Next, try to find a route
763 NS_LOG_LOGIC("Unicast destination");
764 Ptr<Ipv6Route> rtentry = LookupStatic(header.GetDestination());
765
766 if (rtentry)
767 {
768 NS_LOG_LOGIC("Found unicast destination- calling unicast callback");
769 ucb(idev, rtentry, p, header); // unicast forwarding callback
770 return true;
771 }
772 else
773 {
774 NS_LOG_LOGIC("Did not find unicast destination- returning false");
775 return false; // Let other routing protocols try to handle this
776 }
777}
778
779void
781{
782 for (uint32_t j = 0; j < m_ipv6->GetNAddresses(i); j++)
783 {
784 Ipv6InterfaceAddress addr = m_ipv6->GetAddress(i, j);
785
786 if (addr.GetAddress() != Ipv6Address() && addr.GetPrefix() != Ipv6Prefix())
787 {
788 if (addr.GetPrefix() == Ipv6Prefix(128))
789 {
790 /* host route */
791 AddHostRouteTo(addr.GetAddress(), i);
792 }
793 else
794 {
795 if (addr.GetOnLink())
796 {
798 addr.GetPrefix(),
799 i);
800 }
801 }
802 }
803 }
804}
805
806void
808{
809 NS_LOG_FUNCTION(this << i);
810
811 /* remove all static routes that are going through this interface */
812 for (NetworkRoutesI it = m_networkRoutes.begin(); it != m_networkRoutes.end();)
813 {
814 if (it->first->GetInterface() == i)
815 {
816 delete it->first;
817 it = m_networkRoutes.erase(it);
818 }
819 else
820 {
821 it++;
822 }
823 }
824}
825
826void
828{
829 if (!m_ipv6->IsUp(interface))
830 {
831 return;
832 }
833}
834
835void
837{
838 if (!m_ipv6->IsUp(interface))
839 {
840 return;
841 }
842
843 Ipv6Address networkAddress = address.GetAddress().CombinePrefix(address.GetPrefix());
844 Ipv6Prefix networkMask = address.GetPrefix();
845
846 // Remove all static routes that are going through this interface
847 // which reference this network
848 for (NetworkRoutesI it = m_networkRoutes.begin(); it != m_networkRoutes.end();)
849 {
850 if (it->first->GetInterface() == interface && it->first->IsNetwork() &&
851 it->first->GetDestNetwork() == networkAddress &&
852 it->first->GetDestNetworkPrefix() == networkMask)
853 {
854 delete it->first;
855 it = m_networkRoutes.erase(it);
856 }
857 else
858 {
859 it++;
860 }
861 }
862}
863
864void
866 Ipv6Prefix mask,
867 Ipv6Address nextHop,
868 uint32_t interface,
869 Ipv6Address prefixToUse)
870{
871 NS_LOG_INFO(this << dst << mask << nextHop << interface << prefixToUse);
872 if (nextHop == Ipv6Address::GetZero())
873 {
874 AddNetworkRouteTo(dst, mask, interface);
875 }
876 else if (dst != Ipv6Address::GetZero())
877 {
878 AddNetworkRouteTo(dst, mask, nextHop, interface);
879 }
880 else /* default route */
881 {
882 /* this case is mainly used by configuring default route following RA processing,
883 * in case of multiple prefix in RA, the first will configured default route
884 */
885
886 /* for the moment, all default route has the same metric
887 * so according to the longest prefix algorithm,
888 * the default route chosen will be the last added
889 */
890 SetDefaultRoute(nextHop, interface, prefixToUse);
891 }
892}
893
894void
896 Ipv6Prefix mask,
897 Ipv6Address nextHop,
898 uint32_t interface,
899 Ipv6Address prefixToUse)
900{
901 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
902 if (dst != Ipv6Address::GetZero())
903 {
904 for (NetworkRoutesI j = m_networkRoutes.begin(); j != m_networkRoutes.end();)
905 {
906 Ipv6RoutingTableEntry* rtentry = j->first;
907 Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix();
908 Ipv6Address entry = rtentry->GetDestNetwork();
909
910 if (dst == entry && prefix == mask && rtentry->GetInterface() == interface)
911 {
912 delete j->first;
913 j = m_networkRoutes.erase(j);
914 }
915 else
916 {
917 ++j;
918 }
919 }
920 }
921 else
922 {
923 /* default route case */
924 RemoveRoute(dst, mask, interface, prefixToUse);
925 }
926}
927
928} /* namespace ns3 */
bool IsNull() const
Check for null implementation.
Definition: callback.h:567
Describes an IPv6 address.
Definition: ipv6-address.h:49
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
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.
Ipv6Address CombinePrefix(const Ipv6Prefix &prefix) const
Combine this address with a prefix.
Packet header for IPv6.
Definition: ipv6-header.h:35
Ipv6Address GetDestination() const
Get the "Destination address" field.
Definition: ipv6-header.cc:124
Ipv6Address GetSource() const
Get the "Source address" field.
Definition: ipv6-header.cc:112
static const uint32_t IF_ANY
Any interface magic number.
Definition: ipv6.h:400
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:148
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:455
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.
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
Print the Routing Table entries.
Ipv6RoutingTableEntry GetRoute(uint32_t i) const
Get a specified route.
void NotifyAddAddress(uint32_t interface, Ipv6InterfaceAddress address) override
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.
void NotifyRemoveRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero()) override
Notify route removing.
void RemoveRoute(uint32_t i)
Remove a route from the routing table.
Ptr< Ipv6Route > RouteOutput(Ptr< Packet > p, const Ipv6Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr) override
Query routing cache for an existing route, for an outbound packet.
void NotifyRemoveAddress(uint32_t interface, Ipv6InterfaceAddress address) override
Notify when specified interface add an address.
static TypeId GetTypeId()
The interface Id associated with this class.
Ptr< Ipv6Route > LookupStatic(Ipv6Address dest, Ptr< NetDevice >=nullptr)
Lookup in the forwarding table for destination.
void NotifyAddRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero()) override
Notify a new route.
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.
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.
Ipv6RoutingTableEntry GetDefaultRoute()
Get the default route.
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 NotifyInterfaceDown(uint32_t interface) override
Notify when specified interface goes DOWN.
void DoDispose() override
Dispose this object.
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 NotifyInterfaceUp(uint32_t interface) override
Notify when specified interface goes UP.
void SetDefaultMulticastRoute(uint32_t outputInterface)
Set the default multicast route.
bool RouteInput(Ptr< const Packet > p, const Ipv6Header &header, Ptr< const NetDevice > idev, const UnicastForwardCallback &ucb, const MulticastForwardCallback &mcb, const LocalDeliverCallback &lcb, const ErrorCallback &ecb) override
Route an input packet (to be forwarded or locally delivered)
uint32_t GetMetric(uint32_t index) const
Get a metric for route from the static unicast routing table.
void SetIpv6(Ptr< Ipv6 > ipv6) override
Typically, invoked directly or indirectly from ns3::Ipv6::SetRoutingProtocol.
Ptr< Ipv6 > m_ipv6
Ipv6 reference.
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:830
A network Node.
Definition: node.h:56
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
@ ERROR_NOROUTETOHOST
Definition: socket.h:95
@ ERROR_NOTERROR
Definition: socket.h:85
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:111
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#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:86
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
Every class exported by the ns3 library is enclosed in the ns3 namespace.