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())
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 (auto j = m_networkRoutes.begin(); j != m_networkRoutes.end(); j = m_networkRoutes.erase(j))
489 {
490 delete j->first;
491 }
492 m_networkRoutes.clear();
493
494 for (auto i = m_multicastRoutes.begin(); i != m_multicastRoutes.end();
495 i = m_multicastRoutes.erase(i))
496 {
497 delete (*i);
498 }
499 m_multicastRoutes.clear();
500
501 m_ipv6 = nullptr;
503}
504
507{
508 NS_LOG_FUNCTION(this << origin << group << interface);
509 Ptr<Ipv6MulticastRoute> mrtentry = nullptr;
510
511 for (auto i = m_multicastRoutes.begin(); i != m_multicastRoutes.end(); i++)
512 {
514
515 /*
516 We've been passed an origin address, a multicast group address and an
517 interface index. We have to decide if the current route in the list is
518 a match.
519
520 The first case is the restrictive case where the origin, group and index
521 matches. This picks up exact routes during forwarded and exact routes from
522 the local node (in which case the ifIndex is a wildcard).
523 */
524
525 if (origin == route->GetOrigin() && group == route->GetGroup())
526 {
527 /* skipping SSM case */
528 NS_LOG_LOGIC("Find source specific multicast route" << *i);
529 }
530
531 if (group == route->GetGroup())
532 {
533 if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface())
534 {
535 NS_LOG_LOGIC("Found multicast route" << *i);
536 mrtentry = Create<Ipv6MulticastRoute>();
537 mrtentry->SetGroup(route->GetGroup());
538 mrtentry->SetOrigin(route->GetOrigin());
539 mrtentry->SetParent(route->GetInputInterface());
540 for (uint32_t j = 0; j < route->GetNOutputInterfaces(); j++)
541 {
542 if (route->GetOutputInterface(j))
543 {
544 NS_LOG_LOGIC("Setting output interface index "
545 << route->GetOutputInterface(j));
546 mrtentry->SetOutputTtl(route->GetOutputInterface(j),
548 }
549 }
550 return mrtentry;
551 }
552 }
553 }
554 return mrtentry;
555}
556
559{
560 return m_networkRoutes.size();
561}
562
565{
566 NS_LOG_FUNCTION(this);
567 Ipv6Address dst("::");
568 uint32_t shortestMetric = 0xffffffff;
569 Ipv6RoutingTableEntry* result = nullptr;
570
571 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
572 {
573 Ipv6RoutingTableEntry* j = it->first;
574 uint32_t metric = it->second;
576 uint16_t maskLen = mask.GetPrefixLength();
577 Ipv6Address entry = j->GetDestNetwork();
578
579 if (maskLen)
580 {
581 continue;
582 }
583
584 if (metric > shortestMetric)
585 {
586 continue;
587 }
588 shortestMetric = metric;
589 result = j;
590 }
591
592 if (result)
593 {
594 return result;
595 }
596 else
597 {
598 return Ipv6RoutingTableEntry();
599 }
600}
601
604{
605 NS_LOG_FUNCTION(this << index);
606 uint32_t tmp = 0;
607
608 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
609 {
610 if (tmp == index)
611 {
612 return it->first;
613 }
614 tmp++;
615 }
616 NS_ASSERT(false);
617 // quiet compiler.
618 return nullptr;
619}
620
623{
624 NS_LOG_FUNCTION(this << index);
625 uint32_t tmp = 0;
626
627 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
628 {
629 if (tmp == index)
630 {
631 return it->second;
632 }
633 tmp++;
634 }
635 NS_ASSERT(false);
636 // quiet compiler.
637 return 0;
638}
639
640void
642{
643 NS_LOG_FUNCTION(this << index);
644 uint32_t tmp = 0;
645
646 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
647 {
648 if (tmp == index)
649 {
650 delete it->first;
651 m_networkRoutes.erase(it);
652 return;
653 }
654 tmp++;
655 }
656 NS_ASSERT(false);
657}
658
659void
661 Ipv6Prefix prefix,
662 uint32_t ifIndex,
663 Ipv6Address prefixToUse)
664{
665 NS_LOG_FUNCTION(this << network << prefix << ifIndex);
666
667 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end(); it++)
668 {
669 Ipv6RoutingTableEntry* rtentry = it->first;
670 if (network == rtentry->GetDest() && rtentry->GetInterface() == ifIndex &&
671 rtentry->GetPrefixToUse() == prefixToUse)
672 {
673 delete it->first;
674 m_networkRoutes.erase(it);
675 return;
676 }
677 }
678}
679
682 const Ipv6Header& header,
683 Ptr<NetDevice> oif,
684 Socket::SocketErrno& sockerr)
685{
686 NS_LOG_FUNCTION(this << header << oif);
687 Ipv6Address destination = header.GetDestination();
688 Ptr<Ipv6Route> rtentry = nullptr;
689
690 if (destination.IsMulticast())
691 {
692 // Note: Multicast routes for outbound packets are stored in the
693 // normal unicast table. An implication of this is that it is not
694 // possible to source multicast datagrams on multiple interfaces.
695 // This is a well-known property of sockets implementation on
696 // many Unix variants.
697 // So, we just log it and fall through to LookupStatic ()
698 NS_LOG_LOGIC("RouteOutput ()::Multicast destination");
699 }
700
701 rtentry = LookupStatic(destination, oif);
702 if (rtentry)
703 {
704 sockerr = Socket::ERROR_NOTERROR;
705 }
706 else
707 {
709 }
710 return rtentry;
711}
712
713bool
715 const Ipv6Header& header,
717 const UnicastForwardCallback& ucb,
718 const MulticastForwardCallback& mcb,
719 const LocalDeliverCallback& lcb,
720 const ErrorCallback& ecb)
721{
722 NS_LOG_FUNCTION(this << p << header << header.GetSource() << header.GetDestination() << idev);
724 // Check if input device supports IP
725 NS_ASSERT(m_ipv6->GetInterfaceForDevice(idev) >= 0);
726 uint32_t iif = m_ipv6->GetInterfaceForDevice(idev);
727 Ipv6Address dst = header.GetDestination();
728
729 // Multicast recognition; handle local delivery here
730 if (dst.IsMulticast())
731 {
732 NS_LOG_LOGIC("Multicast destination");
734 header.GetDestination(),
735 m_ipv6->GetInterfaceForDevice(idev));
736
737 // \todo check if we want to forward up the packet
738 if (mrtentry)
739 {
740 NS_LOG_LOGIC("Multicast route found");
741 mcb(idev, mrtentry, p, header); // multicast forwarding callback
742 return true;
743 }
744 else
745 {
746 NS_LOG_LOGIC("Multicast route not found");
747 return false; // Let other routing protocols try to handle this
748 }
749 }
750
751 // Check if input device supports IP forwarding
752 if (!m_ipv6->IsForwarding(iif))
753 {
754 NS_LOG_LOGIC("Forwarding disabled for this interface");
755 if (!ecb.IsNull())
756 {
757 ecb(p, header, Socket::ERROR_NOROUTETOHOST);
758 }
759 return true;
760 }
761 // Next, try to find a route
762 NS_LOG_LOGIC("Unicast destination");
763 Ptr<Ipv6Route> rtentry = LookupStatic(header.GetDestination());
764
765 if (rtentry)
766 {
767 NS_LOG_LOGIC("Found unicast destination- calling unicast callback");
768 ucb(idev, rtentry, p, header); // unicast forwarding callback
769 return true;
770 }
771 else
772 {
773 NS_LOG_LOGIC("Did not find unicast destination- returning false");
774 return false; // Let other routing protocols try to handle this
775 }
776}
777
778void
780{
781 for (uint32_t j = 0; j < m_ipv6->GetNAddresses(i); j++)
782 {
783 Ipv6InterfaceAddress addr = m_ipv6->GetAddress(i, j);
784
785 if (addr.GetAddress() != Ipv6Address() && addr.GetPrefix() != Ipv6Prefix())
786 {
787 if (addr.GetPrefix() == Ipv6Prefix(128))
788 {
789 /* host route */
790 AddHostRouteTo(addr.GetAddress(), i);
791 }
792 else
793 {
794 if (addr.GetOnLink())
795 {
797 addr.GetPrefix(),
798 i);
799 }
800 }
801 }
802 }
803}
804
805void
807{
808 NS_LOG_FUNCTION(this << i);
809
810 /* remove all static routes that are going through this interface */
811 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end();)
812 {
813 if (it->first->GetInterface() == i)
814 {
815 delete it->first;
816 it = m_networkRoutes.erase(it);
817 }
818 else
819 {
820 it++;
821 }
822 }
823}
824
825void
827{
828 if (!m_ipv6->IsUp(interface))
829 {
830 return;
831 }
832}
833
834void
836{
837 if (!m_ipv6->IsUp(interface))
838 {
839 return;
840 }
841
842 Ipv6Address networkAddress = address.GetAddress().CombinePrefix(address.GetPrefix());
843 Ipv6Prefix networkMask = address.GetPrefix();
844
845 // Remove all static routes that are going through this interface
846 // which reference this network
847 for (auto it = m_networkRoutes.begin(); it != m_networkRoutes.end();)
848 {
849 if (it->first->GetInterface() == interface && it->first->IsNetwork() &&
850 it->first->GetDestNetwork() == networkAddress &&
851 it->first->GetDestNetworkPrefix() == networkMask)
852 {
853 delete it->first;
854 it = m_networkRoutes.erase(it);
855 }
856 else
857 {
858 it++;
859 }
860 }
861}
862
863void
865 Ipv6Prefix mask,
866 Ipv6Address nextHop,
867 uint32_t interface,
868 Ipv6Address prefixToUse)
869{
870 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface << prefixToUse);
871 if (nextHop == Ipv6Address::GetZero())
872 {
873 AddNetworkRouteTo(dst, mask, interface);
874 }
875 else if (dst != Ipv6Address::GetZero())
876 {
877 AddNetworkRouteTo(dst, mask, nextHop, interface);
878 }
879 else /* default route */
880 {
881 /* this case is mainly used by configuring default route following RA processing,
882 * in case of multiple prefix in RA, the first will configured default route
883 */
884
885 /* for the moment, all default route has the same metric
886 * so according to the longest prefix algorithm,
887 * the default route chosen will be the last added
888 */
889 SetDefaultRoute(nextHop, interface, prefixToUse);
890 }
891}
892
893void
895 Ipv6Prefix mask,
896 Ipv6Address nextHop,
897 uint32_t interface,
898 Ipv6Address prefixToUse)
899{
900 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
901 if (dst != Ipv6Address::GetZero())
902 {
903 for (auto j = m_networkRoutes.begin(); j != m_networkRoutes.end();)
904 {
905 Ipv6RoutingTableEntry* rtentry = j->first;
906 Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix();
907 Ipv6Address entry = rtentry->GetDestNetwork();
908
909 if (dst == entry && prefix == mask && rtentry->GetInterface() == interface)
910 {
911 delete j->first;
912 j = m_networkRoutes.erase(j);
913 }
914 else
915 {
916 ++j;
917 }
918 }
919 }
920 else
921 {
922 /* default route case */
923 RemoveRoute(dst, mask, interface, prefixToUse);
924 }
925}
926
927} /* 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.