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 auto 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 auto 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 auto 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);
255 auto route = new Ipv6MulticastRoutingTableEntry();
257 group,
258 inputInterface,
259 outputInterfaces);
260 m_multicastRoutes.push_back(route);
261}
262
263void
265{
266 NS_LOG_FUNCTION(this << outputInterface);
267 auto route = new Ipv6RoutingTableEntry();
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 (auto 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 (auto 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 (auto 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 (auto 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 (auto 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 (auto 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() || !route->GetDest().IsAny())
448 {
449 rtentry->SetSource(
450 m_ipv6->SourceAddressSelection(interfaceIdx, route->GetDest()));
451 }
452 else
453 {
454 // Default route
455 rtentry->SetSource(m_ipv6->SourceAddressSelection(
456 interfaceIdx,
457 route->GetPrefixToUse().IsAny() ? dst : route->GetPrefixToUse()));
458 }
459
460 rtentry->SetDestination(route->GetDest());
461 rtentry->SetGateway(route->GetGateway());
462 rtentry->SetOutputDevice(m_ipv6->GetNetDevice(interfaceIdx));
463 if (maskLen == 128)
464 {
465 break;
466 }
467 }
468 }
469 }
470
471 if (rtentry)
472 {
473 NS_LOG_LOGIC("Matching route via " << rtentry->GetDestination() << " (Through "
474 << rtentry->GetGateway() << ") at the end");
475 }
476 return rtentry;
477}
478
479void
481{
482 NS_LOG_FUNCTION(this);
483
484 for (auto j = m_networkRoutes.begin(); j != m_networkRoutes.end(); j = m_networkRoutes.erase(j))
485 {
486 delete j->first;
487 }
488 m_networkRoutes.clear();
489
490 for (auto i = m_multicastRoutes.begin(); i != m_multicastRoutes.end();
491 i = m_multicastRoutes.erase(i))
492 {
493 delete (*i);
494 }
495 m_multicastRoutes.clear();
496
497 m_ipv6 = nullptr;
499}
500
503{
504 NS_LOG_FUNCTION(this << origin << group << interface);
505 Ptr<Ipv6MulticastRoute> mrtentry = nullptr;
506
507 for (auto i = m_multicastRoutes.begin(); i != m_multicastRoutes.end(); i++)
508 {
510
511 /*
512 We've been passed an origin address, a multicast group address and an
513 interface index. We have to decide if the current route in the list is
514 a match.
515
516 The first case is the restrictive case where the origin, group and index
517 matches. This picks up exact routes during forwarded and exact routes from
518 the local node (in which case the ifIndex is a wildcard).
519 */
520
521 if (origin == route->GetOrigin() && group == route->GetGroup())
522 {
523 /* skipping SSM case */
524 NS_LOG_LOGIC("Find source specific multicast route" << *i);
525 }
526
527 if (group == route->GetGroup())
528 {
529 if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface())
530 {
531 NS_LOG_LOGIC("Found multicast route" << *i);
532 mrtentry = Create<Ipv6MulticastRoute>();
533 mrtentry->SetGroup(route->GetGroup());
534 mrtentry->SetOrigin(route->GetOrigin());
535 mrtentry->SetParent(route->GetInputInterface());
536 for (uint32_t j = 0; j < route->GetNOutputInterfaces(); j++)
537 {
538 if (route->GetOutputInterface(j))
539 {
540 NS_LOG_LOGIC("Setting output interface index "
541 << route->GetOutputInterface(j));
542 mrtentry->SetOutputTtl(route->GetOutputInterface(j),
544 }
545 }
546 return mrtentry;
547 }
548 }
549 }
550 return mrtentry;
551}
552
555{
556 return m_networkRoutes.size();
557}
558
561{
562 NS_LOG_FUNCTION(this);
563 Ipv6Address dst("::");
564 uint32_t shortestMetric = 0xffffffff;
565 Ipv6RoutingTableEntry* result = nullptr;
566
567 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
568 {
569 Ipv6RoutingTableEntry* j = it->first;
570 uint32_t metric = it->second;
572 uint16_t maskLen = mask.GetPrefixLength();
573 Ipv6Address entry = j->GetDestNetwork();
574
575 if (maskLen)
576 {
577 continue;
578 }
579
580 if (metric > shortestMetric)
581 {
582 continue;
583 }
584 shortestMetric = metric;
585 result = j;
586 }
587
588 if (result)
589 {
590 return result;
591 }
592 else
593 {
594 return Ipv6RoutingTableEntry();
595 }
596}
597
600{
601 NS_LOG_FUNCTION(this << index);
602 uint32_t tmp = 0;
603
604 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
605 {
606 if (tmp == index)
607 {
608 return it->first;
609 }
610 tmp++;
611 }
612 NS_ASSERT(false);
613 // quiet compiler.
614 return nullptr;
615}
616
619{
620 NS_LOG_FUNCTION(this << index);
621 uint32_t tmp = 0;
622
623 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
624 {
625 if (tmp == index)
626 {
627 return it->second;
628 }
629 tmp++;
630 }
631 NS_ASSERT(false);
632 // quiet compiler.
633 return 0;
634}
635
636void
638{
639 NS_LOG_FUNCTION(this << index);
640 uint32_t tmp = 0;
641
642 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
643 {
644 if (tmp == index)
645 {
646 delete it->first;
647 m_networkRoutes.erase(it);
648 return;
649 }
650 tmp++;
651 }
652 NS_ASSERT(false);
653}
654
655void
657 Ipv6Prefix prefix,
658 uint32_t ifIndex,
659 Ipv6Address prefixToUse)
660{
661 NS_LOG_FUNCTION(this << network << prefix << ifIndex);
662
663 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
664 {
665 Ipv6RoutingTableEntry* rtentry = it->first;
666 if (network == rtentry->GetDest() && rtentry->GetInterface() == ifIndex &&
667 rtentry->GetPrefixToUse() == prefixToUse)
668 {
669 delete it->first;
670 m_networkRoutes.erase(it);
671 return;
672 }
673 }
674}
675
678 const Ipv6Header& header,
679 Ptr<NetDevice> oif,
680 Socket::SocketErrno& sockerr)
681{
682 NS_LOG_FUNCTION(this << header << oif);
683 Ipv6Address destination = header.GetDestination();
684 Ptr<Ipv6Route> rtentry = nullptr;
685
686 if (destination.IsMulticast())
687 {
688 // Note: Multicast routes for outbound packets are stored in the
689 // normal unicast table. An implication of this is that it is not
690 // possible to source multicast datagrams on multiple interfaces.
691 // This is a well-known property of sockets implementation on
692 // many Unix variants.
693 // So, we just log it and fall through to LookupStatic ()
694 NS_LOG_LOGIC("RouteOutput ()::Multicast destination");
695 }
696
697 rtentry = LookupStatic(destination, oif);
698 if (rtentry)
699 {
700 sockerr = Socket::ERROR_NOTERROR;
701 }
702 else
703 {
705 }
706 return rtentry;
707}
708
709bool
711 const Ipv6Header& header,
713 const UnicastForwardCallback& ucb,
714 const MulticastForwardCallback& mcb,
715 const LocalDeliverCallback& lcb,
716 const ErrorCallback& ecb)
717{
718 NS_LOG_FUNCTION(this << p << header << header.GetSource() << header.GetDestination() << idev);
720 // Check if input device supports IP
721 NS_ASSERT(m_ipv6->GetInterfaceForDevice(idev) >= 0);
722 uint32_t iif = m_ipv6->GetInterfaceForDevice(idev);
723 Ipv6Address dst = header.GetDestination();
724
725 // Multicast recognition; handle local delivery here
726 if (dst.IsMulticast())
727 {
728 NS_LOG_LOGIC("Multicast destination");
730 header.GetDestination(),
731 m_ipv6->GetInterfaceForDevice(idev));
732
733 // \todo check if we want to forward up the packet
734 if (mrtentry)
735 {
736 NS_LOG_LOGIC("Multicast route found");
737 mcb(idev, mrtentry, p, header); // multicast forwarding callback
738 return true;
739 }
740 else
741 {
742 NS_LOG_LOGIC("Multicast route not found");
743 return false; // Let other routing protocols try to handle this
744 }
745 }
746
747 // Check if input device supports IP forwarding
748 if (!m_ipv6->IsForwarding(iif))
749 {
750 NS_LOG_LOGIC("Forwarding disabled for this interface");
751 if (!ecb.IsNull())
752 {
753 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
754 }
755 return true;
756 }
757 // Next, try to find a route
758 NS_LOG_LOGIC("Unicast destination");
759 Ptr<Ipv6Route> rtentry = LookupStatic(header.GetDestination());
760
761 if (rtentry)
762 {
763 NS_LOG_LOGIC("Found unicast destination- calling unicast callback");
764 ucb(idev, rtentry, p, header); // unicast forwarding callback
765 return true;
766 }
767 else
768 {
769 NS_LOG_LOGIC("Did not find unicast destination- returning false");
770 return false; // Let other routing protocols try to handle this
771 }
772}
773
774void
776{
777 for (uint32_t j = 0; j < m_ipv6->GetNAddresses(i); j++)
778 {
779 Ipv6InterfaceAddress addr = m_ipv6->GetAddress(i, j);
780
781 if (addr.GetAddress() != Ipv6Address() && addr.GetPrefix() != Ipv6Prefix())
782 {
783 if (addr.GetPrefix() == Ipv6Prefix(128))
784 {
785 /* host route */
786 AddHostRouteTo(addr.GetAddress(), i);
787 }
788 else
789 {
790 if (addr.GetOnLink())
791 {
793 addr.GetPrefix(),
794 i);
795 }
796 }
797 }
798 }
799}
800
801void
803{
804 NS_LOG_FUNCTION(this << i);
805
806 /* remove all static routes that are going through this interface */
807 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end();)
808 {
809 if (it->first->GetInterface() == i)
810 {
811 delete it->first;
812 it = m_networkRoutes.erase(it);
813 }
814 else
815 {
816 it++;
817 }
818 }
819}
820
821void
823{
824 if (!m_ipv6->IsUp(interface))
825 {
826 return;
827 }
828}
829
830void
832{
833 if (!m_ipv6->IsUp(interface))
834 {
835 return;
836 }
837
838 Ipv6Address networkAddress = address.GetAddress().CombinePrefix(address.GetPrefix());
839 Ipv6Prefix networkMask = address.GetPrefix();
840
841 // Remove all static routes that are going through this interface
842 // which reference this network
843 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end();)
844 {
845 if (it->first->GetInterface() == interface && it->first->IsNetwork() &&
846 it->first->GetDestNetwork() == networkAddress &&
847 it->first->GetDestNetworkPrefix() == networkMask)
848 {
849 delete it->first;
850 it = m_networkRoutes.erase(it);
851 }
852 else
853 {
854 it++;
855 }
856 }
857}
858
859void
861 Ipv6Prefix mask,
862 Ipv6Address nextHop,
863 uint32_t interface,
864 Ipv6Address prefixToUse)
865{
866 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface << prefixToUse);
867 if (nextHop == Ipv6Address::GetZero())
868 {
869 AddNetworkRouteTo(dst, mask, interface);
870 }
871 else if (dst != Ipv6Address::GetZero())
872 {
873 AddNetworkRouteTo(dst, mask, nextHop, interface);
874 }
875 else /* default route */
876 {
877 /* this case is mainly used by configuring default route following RA processing,
878 * in case of multiple prefix in RA, the first will configured default route
879 */
880
881 /* for the moment, all default route has the same metric
882 * so according to the longest prefix algorithm,
883 * the default route chosen will be the last added
884 */
885 SetDefaultRoute(nextHop, interface, prefixToUse);
886 }
887}
888
889void
891 Ipv6Prefix mask,
892 Ipv6Address nextHop,
893 uint32_t interface,
894 Ipv6Address prefixToUse)
895{
896 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
897 if (dst != Ipv6Address::GetZero())
898 {
899 for (auto j = m_networkRoutes.begin(); j != m_networkRoutes.end();)
900 {
901 Ipv6RoutingTableEntry* rtentry = j->first;
902 Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix();
903 Ipv6Address entry = rtentry->GetDestNetwork();
904
905 if (dst == entry && prefix == mask && rtentry->GetInterface() == interface)
906 {
907 delete j->first;
908 j = m_networkRoutes.erase(j);
909 }
910 else
911 {
912 ++j;
913 }
914 }
915 }
916 else
917 {
918 /* default route case */
919 RemoveRoute(dst, mask, interface, prefixToUse);
920 }
921}
922
923} /* namespace ns3 */
bool IsNull() const
Check for null implementation.
Definition: callback.h:571
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.
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.
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.
bool LookupRoute(const Ipv6RoutingTableEntry &route, uint32_t metric)
Checks if a route is already present in the forwarding table.
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:829
A network Node.
Definition: node.h:57
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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:415
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:932
#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_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:305
Every class exported by the ns3 library is enclosed in the ns3 namespace.