A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ripng.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 Universita' di Firenze, Italy
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
7 */
8
9#include "ripng.h"
10
12#include "ipv6-route.h"
13#include "ripng-header.h"
14#include "udp-header.h"
15
16#include "ns3/abort.h"
17#include "ns3/assert.h"
18#include "ns3/enum.h"
19#include "ns3/log.h"
20#include "ns3/names.h"
21#include "ns3/node.h"
22#include "ns3/random-variable-stream.h"
23#include "ns3/simulator.h"
24#include "ns3/uinteger.h"
25
26#include <iomanip>
27
28#define RIPNG_ALL_NODE "ff02::9"
29#define RIPNG_PORT 521
30
31namespace ns3
32{
33
35
37
39 : m_ipv6(nullptr),
40 m_splitHorizonStrategy(RipNg::POISON_REVERSE),
41 m_initialized(false)
42{
44}
45
47{
48}
49
52{
53 static TypeId tid =
54 TypeId("ns3::RipNg")
56 .SetGroupName("Internet")
57 .AddConstructor<RipNg>()
58 .AddAttribute("UnsolicitedRoutingUpdate",
59 "The time between two Unsolicited Routing Updates.",
60 TimeValue(Seconds(30)),
63 .AddAttribute("StartupDelay",
64 "Maximum random delay for protocol startup (send route requests).",
68 .AddAttribute("TimeoutDelay",
69 "The delay to invalidate a route.",
70 TimeValue(Seconds(180)),
73 .AddAttribute("GarbageCollectionDelay",
74 "The delay to delete an expired route.",
75 TimeValue(Seconds(120)),
78 .AddAttribute("MinTriggeredCooldown",
79 "Min cooldown delay after a Triggered Update.",
83 .AddAttribute("MaxTriggeredCooldown",
84 "Max cooldown delay after a Triggered Update.",
88 .AddAttribute("SplitHorizon",
89 "Split Horizon strategy.",
93 "NoSplitHorizon",
95 "SplitHorizon",
97 "PoisonReverse"))
98 .AddAttribute("LinkDownValue",
99 "Value for link down in count to infinity.",
100 UintegerValue(16),
103 return tid;
104}
105
106int64_t
107RipNg::AssignStreams(int64_t stream)
108{
109 NS_LOG_FUNCTION(this << stream);
110
111 m_rng->SetStream(stream);
112 return 1;
113}
114
115void
117{
118 NS_LOG_FUNCTION(this);
119
120 bool addedGlobal = false;
121
122 m_initialized = true;
123
124 Time delay =
127
128 for (uint32_t i = 0; i < m_ipv6->GetNInterfaces(); i++)
129 {
130 bool activeInterface = false;
132 {
133 activeInterface = true;
134 m_ipv6->SetForwarding(i, true);
135 }
136
137 for (uint32_t j = 0; j < m_ipv6->GetNAddresses(i); j++)
138 {
139 Ipv6InterfaceAddress address = m_ipv6->GetAddress(i, j);
140 if (address.GetScope() == Ipv6InterfaceAddress::LINKLOCAL && activeInterface)
141 {
142 NS_LOG_LOGIC("RIPng: adding socket to " << address.GetAddress());
143 TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
146 Inet6SocketAddress local = Inet6SocketAddress(address.GetAddress(), RIPNG_PORT);
147 socket->BindToNetDevice(m_ipv6->GetNetDevice(i));
148 int ret = socket->Bind(local);
149 NS_ASSERT_MSG(ret == 0, "Bind unsuccessful");
150 socket->SetRecvCallback(MakeCallback(&RipNg::Receive, this));
151 socket->SetIpv6RecvHopLimit(true);
152 socket->SetRecvPktInfo(true);
153 m_unicastSocketList[socket] = i;
154 }
155 else if (m_ipv6->GetAddress(i, j).GetScope() == Ipv6InterfaceAddress::GLOBAL)
156 {
157 addedGlobal = true;
158 }
159 }
160 }
161
163 {
164 NS_LOG_LOGIC("RIPng: adding receiving socket");
165 TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
173 }
174
175 if (addedGlobal)
176 {
180 }
181
182 delay = Seconds(m_rng->GetValue(0.01, m_startupDelay.GetSeconds()));
184
186}
187
190 const Ipv6Header& header,
191 Ptr<NetDevice> oif,
193{
194 NS_LOG_FUNCTION(this << header << oif);
195
196 Ipv6Address destination = header.GetDestination();
197 Ptr<Ipv6Route> rtentry = nullptr;
198
199 if (destination.IsMulticast())
200 {
201 // Note: Multicast routes for outbound packets are stored in the
202 // normal unicast table. An implication of this is that it is not
203 // possible to source multicast datagrams on multiple interfaces.
204 // This is a well-known property of sockets implementation on
205 // many Unix variants.
206 // So, we just log it and fall through to LookupStatic ()
207 NS_LOG_LOGIC("RouteOutput (): Multicast destination");
208 }
209
210 rtentry = Lookup(destination, true, oif);
211 if (rtentry)
212 {
214 }
215 else
216 {
218 }
219 return rtentry;
220}
221
222bool
224 const Ipv6Header& header,
229 const ErrorCallback& ecb)
230{
231 NS_LOG_FUNCTION(this << p << header << header.GetSource() << header.GetDestination() << idev);
232
234 // Check if input device supports IP
235 NS_ASSERT(m_ipv6->GetInterfaceForDevice(idev) >= 0);
236 uint32_t iif = m_ipv6->GetInterfaceForDevice(idev);
237 Ipv6Address dst = header.GetDestination();
238
239 if (dst.IsMulticast())
240 {
241 NS_LOG_LOGIC("Multicast route not supported by RIPng");
242 return false; // Let other routing protocols try to handle this
243 }
244
245 if (header.GetDestination().IsLinkLocal() || header.GetSource().IsLinkLocal())
246 {
247 NS_LOG_LOGIC("Dropping packet not for me and with src or dst LinkLocal");
248 if (!ecb.IsNull())
249 {
251 }
252 return false;
253 }
254
255 // Check if input device supports IP forwarding
256 if (!m_ipv6->IsForwarding(iif))
257 {
258 NS_LOG_LOGIC("Forwarding disabled for this interface");
259 if (!ecb.IsNull())
260 {
262 }
263 return true;
264 }
265 // Next, try to find a route
266 NS_LOG_LOGIC("Unicast destination");
267 Ptr<Ipv6Route> rtentry = Lookup(header.GetDestination(), false);
268
269 if (rtentry)
270 {
271 NS_LOG_LOGIC("Found unicast destination - calling unicast callback");
272 ucb(idev, rtentry, p, header); // unicast forwarding callback
273 return true;
274 }
275 else
276 {
277 NS_LOG_LOGIC("Did not find unicast destination - returning false");
278 return false; // Let other routing protocols try to handle this
279 }
280}
281
282void
284{
285 NS_LOG_FUNCTION(this << i);
286
287 for (uint32_t j = 0; j < m_ipv6->GetNAddresses(i); j++)
288 {
289 Ipv6InterfaceAddress address = m_ipv6->GetAddress(i, j);
290 Ipv6Prefix networkMask = address.GetPrefix();
291 Ipv6Address networkAddress = address.GetAddress().CombinePrefix(networkMask);
292
293 if (address.GetScope() == Ipv6InterfaceAddress::GLOBAL)
294 {
296 }
297 }
298
299 if (!m_initialized)
300 {
301 return;
302 }
303
304 bool sendSocketFound = false;
305 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
306 {
307 if (iter->second == i)
308 {
309 sendSocketFound = true;
310 break;
311 }
312 }
313
314 bool activeInterface = false;
316 {
317 activeInterface = true;
318 m_ipv6->SetForwarding(i, true);
319 }
320
321 for (uint32_t j = 0; j < m_ipv6->GetNAddresses(i); j++)
322 {
323 Ipv6InterfaceAddress address = m_ipv6->GetAddress(i, j);
324
325 if (address.GetScope() == Ipv6InterfaceAddress::LINKLOCAL && !sendSocketFound &&
327 {
328 NS_LOG_LOGIC("RIPng: adding sending socket to " << address.GetAddress());
329 TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
332 Inet6SocketAddress local = Inet6SocketAddress(address.GetAddress(), RIPNG_PORT);
333 socket->BindToNetDevice(m_ipv6->GetNetDevice(i));
334 socket->Bind(local);
335 socket->SetRecvCallback(MakeCallback(&RipNg::Receive, this));
336 socket->SetIpv6RecvHopLimit(true);
337 socket->SetRecvPktInfo(true);
338 m_unicastSocketList[socket] = i;
339 }
340 else if (address.GetScope() == Ipv6InterfaceAddress::GLOBAL)
341 {
343 }
344 }
345
347 {
348 NS_LOG_LOGIC("RIPng: adding receiving socket");
349 TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
357 }
358}
359
360void
362{
363 NS_LOG_FUNCTION(this << interface);
364
365 /* remove all routes that are going through this interface */
366 for (auto it = m_routes.begin(); it != m_routes.end(); it++)
367 {
368 if (it->first->GetInterface() == interface)
369 {
370 InvalidateRoute(it->first);
371 }
372 }
373
374 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
375 {
376 NS_LOG_INFO("Checking socket for interface " << interface);
377 if (iter->second == interface)
378 {
379 NS_LOG_INFO("Removed socket for interface " << interface);
380 iter->first->Close();
382 break;
383 }
384 }
385
386 if (m_interfaceExclusions.find(interface) == m_interfaceExclusions.end())
387 {
389 }
390}
391
392void
394{
395 NS_LOG_FUNCTION(this << interface << address);
396
397 if (!m_ipv6->IsUp(interface))
398 {
399 return;
400 }
401
402 if (m_interfaceExclusions.find(interface) != m_interfaceExclusions.end())
403 {
404 return;
405 }
406
407 Ipv6Address networkAddress = address.GetAddress().CombinePrefix(address.GetPrefix());
408 Ipv6Prefix networkMask = address.GetPrefix();
409
410 if (address.GetScope() == Ipv6InterfaceAddress::GLOBAL)
411 {
413 }
414
416}
417
418void
420{
421 NS_LOG_FUNCTION(this << interface << address);
422
423 if (!m_ipv6->IsUp(interface))
424 {
425 return;
426 }
427
428 if (address.GetScope() != Ipv6InterfaceAddress::GLOBAL)
429 {
430 return;
431 }
432
433 Ipv6Address networkAddress = address.GetAddress().CombinePrefix(address.GetPrefix());
434 Ipv6Prefix networkMask = address.GetPrefix();
435
436 // Remove all routes that are going through this interface
437 // which reference this network
438 for (auto it = m_routes.begin(); it != m_routes.end(); it++)
439 {
440 if (it->first->GetInterface() == interface && it->first->IsNetwork() &&
441 it->first->GetDestNetwork() == networkAddress &&
442 it->first->GetDestNetworkPrefix() == networkMask)
443 {
444 InvalidateRoute(it->first);
445 }
446 }
447
448 if (m_interfaceExclusions.find(interface) == m_interfaceExclusions.end())
449 {
451 }
452}
453
454void
456 Ipv6Prefix mask,
457 Ipv6Address nextHop,
458 uint32_t interface,
460{
461 NS_LOG_INFO(this << dst << mask << nextHop << interface << prefixToUse);
462 // \todo this can be used to add delegate routes
463}
464
465void
467 Ipv6Prefix mask,
468 Ipv6Address nextHop,
469 uint32_t interface,
471{
472 NS_LOG_FUNCTION(this << dst << mask << nextHop << interface);
473 // \todo this can be used to delete delegate routes
474}
475
476void
478{
479 NS_LOG_FUNCTION(this << ipv6);
480
481 NS_ASSERT(!m_ipv6 && ipv6);
482 uint32_t i = 0;
483 m_ipv6 = ipv6;
484
485 for (i = 0; i < m_ipv6->GetNInterfaces(); i++)
486 {
487 if (m_ipv6->IsUp(i))
488 {
490 }
491 else
492 {
494 }
495 }
496}
497
498void
500{
501 NS_LOG_FUNCTION(this << stream);
502
503 std::ostream* os = stream->GetStream();
504 *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
505
506 *os << "Node: " << m_ipv6->GetObject<Node>()->GetId() << ", Time: " << Now().As(unit)
507 << ", Local time: " << m_ipv6->GetObject<Node>()->GetLocalTime().As(unit)
508 << ", IPv6 RIPng table" << std::endl;
509
510 if (!m_routes.empty())
511 {
512 *os << "Destination Next Hop Flag Met Ref Use If"
513 << std::endl;
514 for (auto it = m_routes.begin(); it != m_routes.end(); it++)
515 {
518
520 {
521 std::ostringstream dest;
522 std::ostringstream gw;
523 std::ostringstream mask;
524 std::ostringstream flags;
525
526 dest << route->GetDest() << "/"
527 << int(route->GetDestNetworkPrefix().GetPrefixLength());
528 *os << std::setw(31) << dest.str();
529 gw << route->GetGateway();
530 *os << std::setw(27) << gw.str();
531 flags << "U";
532 if (route->IsHost())
533 {
534 flags << "H";
535 }
536 else if (route->IsGateway())
537 {
538 flags << "G";
539 }
540 *os << std::setw(5) << flags.str();
541 *os << std::setw(4) << int(route->GetRouteMetric());
542 // Ref ct not implemented
543 *os << "-"
544 << " ";
545 // Use not implemented
546 *os << "-"
547 << " ";
548 if (!Names::FindName(m_ipv6->GetNetDevice(route->GetInterface())).empty())
549 {
550 *os << Names::FindName(m_ipv6->GetNetDevice(route->GetInterface()));
551 }
552 else
553 {
554 *os << route->GetInterface();
555 }
556 *os << std::endl;
557 }
558 }
559 }
560 *os << std::endl;
561}
562
563void
565{
566 NS_LOG_FUNCTION(this);
567
568 for (auto j = m_routes.begin(); j != m_routes.end(); j = m_routes.erase(j))
569 {
570 delete j->first;
571 }
572 m_routes.clear();
573
578
579 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
580 {
581 iter->first->Close();
582 }
583 m_unicastSocketList.clear();
584
586 m_multicastRecvSocket = nullptr;
587
588 m_ipv6 = nullptr;
589
591}
592
595{
596 NS_LOG_FUNCTION(this << dst << interface);
597
598 Ptr<Ipv6Route> rtentry = nullptr;
599 uint16_t longestMask = 0;
600
601 /* when sending on link-local multicast, there have to be interface specified */
602 if (dst.IsLinkLocalMulticast())
603 {
605 interface,
606 "Try to send on link-local multicast address, and no interface index is given!");
608 rtentry->SetSource(
609 m_ipv6->SourceAddressSelection(m_ipv6->GetInterfaceForDevice(interface), dst));
610 rtentry->SetDestination(dst);
611 rtentry->SetGateway(Ipv6Address::GetZero());
612 rtentry->SetOutputDevice(interface);
613 return rtentry;
614 }
615
616 for (auto it = m_routes.begin(); it != m_routes.end(); it++)
617 {
618 RipNgRoutingTableEntry* j = it->first;
619
620 if (j->GetRouteStatus() == RipNgRoutingTableEntry::RIPNG_VALID)
621 {
622 Ipv6Prefix mask = j->GetDestNetworkPrefix();
623 uint16_t maskLen = mask.GetPrefixLength();
624 Ipv6Address entry = j->GetDestNetwork();
625
626 NS_LOG_LOGIC("Searching for route to " << dst << ", mask length " << maskLen);
627
628 if (mask.IsMatch(dst, entry))
629 {
630 NS_LOG_LOGIC("Found global network route " << j << ", mask length " << maskLen);
631
632 /* if interface is given, check the route will output on this interface */
633 if (!interface || interface == m_ipv6->GetNetDevice(j->GetInterface()))
634 {
635 if (maskLen < longestMask)
636 {
637 NS_LOG_LOGIC("Previous match longer, skipping");
638 continue;
639 }
640
642
644 uint32_t interfaceIdx = route->GetInterface();
646
647 if (setSource)
648 {
649 // GetGateway().IsAny() means that the destination is reachable without a
650 // gateway (is on-link). GetDest().IsAny() means that the route is the
651 // default route. Having both true is very strange, but possible.
652 // If the RT entry is specific for a destination, use that as a hint for the
653 // source address to be used. Else, use the destination or the prefix to be
654 // used stated in the RT entry.
655 if (!route->GetDest().IsAny())
656 {
657 rtentry->SetSource(
658 m_ipv6->SourceAddressSelection(interfaceIdx, route->GetDest()));
659 }
660 else
661 {
662 rtentry->SetSource(m_ipv6->SourceAddressSelection(
664 route->GetPrefixToUse().IsAny() ? dst : route->GetPrefixToUse()));
665 }
666 }
667
668 rtentry->SetDestination(route->GetDest());
669 rtentry->SetGateway(route->GetGateway());
670 rtentry->SetOutputDevice(m_ipv6->GetNetDevice(interfaceIdx));
671 }
672 }
673 }
674 }
675
676 if (rtentry)
677 {
678 NS_LOG_LOGIC("Matching route via " << rtentry->GetDestination() << " (through "
679 << rtentry->GetGateway() << ") at the end");
680 }
681 return rtentry;
682}
683
684void
687 Ipv6Address nextHop,
688 uint32_t interface,
690{
691 NS_LOG_FUNCTION(this << network << networkPrefix << nextHop << interface << prefixToUse);
692
693 if (nextHop.IsLinkLocal())
694 {
695 NS_LOG_WARN("Ripng::AddNetworkRouteTo - Next hop should be link-local");
696 }
697
698 auto route =
699 new RipNgRoutingTableEntry(network, networkPrefix, nextHop, interface, prefixToUse);
700 route->SetRouteMetric(1);
702 route->SetRouteChanged(true);
703
704 m_routes.emplace_back(route, EventId());
705}
706
707void
709{
710 NS_LOG_FUNCTION(this << network << networkPrefix << interface);
711
712 auto route = new RipNgRoutingTableEntry(network, networkPrefix, interface);
713 route->SetRouteMetric(1);
715 route->SetRouteChanged(true);
716
717 m_routes.emplace_back(route, EventId());
718}
719
720void
722{
723 NS_LOG_FUNCTION(this << *route);
724
725 for (auto it = m_routes.begin(); it != m_routes.end(); it++)
726 {
727 if (it->first == route)
728 {
730 route->SetRouteMetric(m_linkDown);
731 route->SetRouteChanged(true);
732 if (it->second.IsPending())
733 {
734 it->second.Cancel();
735 }
736 it->second =
738 return;
739 }
740 }
741 NS_ABORT_MSG("Ripng::InvalidateRoute - cannot find the route to update");
742}
743
744void
746{
747 NS_LOG_FUNCTION(this << *route);
748
749 for (auto it = m_routes.begin(); it != m_routes.end(); it++)
750 {
751 if (it->first == route)
752 {
753 delete route;
754 m_routes.erase(it);
755 return;
756 }
757 }
758 NS_ABORT_MSG("Ripng::DeleteRoute - cannot find the route to delete");
759}
760
761void
763{
764 NS_LOG_FUNCTION(this << socket);
765
767 Ptr<Packet> packet = socket->RecvFrom(sender);
769 NS_LOG_INFO("Received " << *packet << " from " << senderAddr);
770
772 uint16_t senderPort = senderAddr.GetPort();
773
775 if (!packet->RemovePacketTag(interfaceInfo))
776 {
777 NS_ABORT_MSG("No incoming interface on RIPng message, aborting.");
778 }
779 uint32_t incomingIf = interfaceInfo.GetRecvIf();
780 Ptr<Node> node = this->GetObject<Node>();
781 Ptr<NetDevice> dev = node->GetDevice(incomingIf);
782 uint32_t ipInterfaceIndex = m_ipv6->GetInterfaceForDevice(dev);
783
785 if (!packet->RemovePacketTag(hoplimitTag))
786 {
787 NS_ABORT_MSG("No incoming Hop Count on RIPng message, aborting.");
788 }
789 uint8_t hopLimit = hoplimitTag.GetHopLimit();
790
791 int32_t interfaceForAddress = m_ipv6->GetInterfaceForAddress(senderAddress);
792 if (interfaceForAddress != -1)
793 {
794 NS_LOG_LOGIC("Ignoring a packet sent by myself.");
795 return;
796 }
797
799 packet->RemoveHeader(hdr);
800
801 if (hdr.GetCommand() == RipNgHeader::RESPONSE)
802 {
804 }
805 else if (hdr.GetCommand() == RipNgHeader::REQUEST)
806 {
808 }
809 else
810 {
811 NS_LOG_LOGIC("Ignoring message with unknown command: " << int(hdr.GetCommand()));
812 }
813}
814
815void
818 uint16_t senderPort,
820 uint8_t hopLimit)
821{
823 << requestHdr);
824
825 std::list<RipNgRte> rtes = requestHdr.GetRteList();
826
827 if (rtes.empty())
828 {
829 return;
830 }
831
832 // check if it's a request for the full table from a neighbor
833 if (rtes.size() == 1 && senderAddress.IsLinkLocal())
834 {
835 if (rtes.begin()->GetPrefix() == Ipv6Address::GetAny() &&
836 rtes.begin()->GetPrefixLen() == 0 && rtes.begin()->GetRouteMetric() == m_linkDown)
837 {
838 // Output whole thing. Use Split Horizon
840 {
841 // we use one of the sending sockets, as they're bound to the right interface
842 // and the local address might be used on different interfaces.
844 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end();
845 iter++)
846 {
847 if (iter->second == incomingInterface)
848 {
849 sendingSocket = iter->first;
850 }
851 }
853 "HandleRequest - Impossible to find a socket to send the reply");
854
855 uint16_t mtu = m_ipv6->GetMtu(incomingInterface);
856 uint16_t maxRte =
860
863 p->RemovePacketTag(tag);
864 tag.SetHopLimit(255);
865 p->AddPacketTag(tag);
866
869
870 for (auto rtIter = m_routes.begin(); rtIter != m_routes.end(); rtIter++)
871 {
872 bool splitHorizoning = (rtIter->first->GetInterface() == incomingInterface);
873
875 Ipv6InterfaceAddress(rtIter->first->GetDestNetwork(),
876 rtIter->first->GetDestNetworkPrefix());
877
878 bool isGlobal = (rtDestAddr.GetScope() == Ipv6InterfaceAddress::GLOBAL);
879 bool isDefaultRoute =
880 ((rtIter->first->GetDestNetwork() == Ipv6Address::GetAny()) &&
881 (rtIter->first->GetDestNetworkPrefix() == Ipv6Prefix::GetZero()) &&
882 (rtIter->first->GetInterface() != incomingInterface));
883
884 if ((isGlobal || isDefaultRoute) &&
885 (rtIter->first->GetRouteStatus() == RipNgRoutingTableEntry::RIPNG_VALID))
886 {
888 rte.SetPrefix(rtIter->first->GetDestNetwork());
889 rte.SetPrefixLen(rtIter->first->GetDestNetworkPrefix().GetPrefixLength());
891 {
892 rte.SetRouteMetric(m_linkDown);
893 }
894 else
895 {
896 rte.SetRouteMetric(rtIter->first->GetRouteMetric());
897 }
898 rte.SetRouteTag(rtIter->first->GetRouteTag());
901 {
902 hdr.AddRte(rte);
903 }
904 }
905 if (hdr.GetRteNumber() == maxRte)
906 {
907 p->AddHeader(hdr);
908 NS_LOG_DEBUG("SendTo: " << *p);
910 p->RemoveHeader(hdr);
911 hdr.ClearRtes();
912 }
913 }
914 if (hdr.GetRteNumber() > 0)
915 {
916 p->AddHeader(hdr);
917 NS_LOG_DEBUG("SendTo: " << *p);
919 }
920 }
921 }
922 }
923 else
924 {
925 // note: we got the request as a single packet, so no check is necessary for MTU limit
926
927 // we use one of the sending sockets, as they're bound to the right interface
928 // and the local address might be used on different interfaces.
930 if (senderAddress.IsLinkLocal())
931 {
932 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
933 {
934 if (iter->second == incomingInterface)
935 {
936 sendingSocket = iter->first;
937 }
938 }
939 }
940 else
941 {
943 }
944
947 p->RemovePacketTag(tag);
948 tag.SetHopLimit(255);
949 p->AddPacketTag(tag);
950
953
954 for (auto iter = rtes.begin(); iter != rtes.end(); iter++)
955 {
956 bool found = false;
957 for (auto rtIter = m_routes.begin(); rtIter != m_routes.end(); rtIter++)
958 {
960 Ipv6InterfaceAddress(rtIter->first->GetDestNetwork(),
961 rtIter->first->GetDestNetworkPrefix());
962 if ((rtDestAddr.GetScope() == Ipv6InterfaceAddress::GLOBAL) &&
963 (rtIter->first->GetRouteStatus() == RipNgRoutingTableEntry::RIPNG_VALID))
964 {
965 Ipv6Address requestedAddress = iter->GetPrefix();
967 Ipv6Address rtAddress = rtIter->first->GetDestNetwork();
968 rtAddress.CombinePrefix(rtIter->first->GetDestNetworkPrefix());
969
971 {
972 iter->SetRouteMetric(rtIter->first->GetRouteMetric());
973 iter->SetRouteTag(rtIter->first->GetRouteTag());
974 hdr.AddRte(*iter);
975 found = true;
976 break;
977 }
978 }
979 }
980 if (!found)
981 {
982 iter->SetRouteMetric(m_linkDown);
983 iter->SetRouteTag(0);
984 hdr.AddRte(*iter);
985 }
986 }
987 p->AddHeader(hdr);
988 NS_LOG_DEBUG("SendTo: " << *p);
990 }
991}
992
993void
997 uint8_t hopLimit)
998{
1000
1002 {
1004 "Ignoring an update message from an excluded interface: " << incomingInterface);
1005 return;
1006 }
1007
1008 if (!senderAddress.IsLinkLocal())
1009 {
1010 NS_LOG_LOGIC("Ignoring an update message from a non-link-local source: " << senderAddress);
1011 return;
1012 }
1013
1014 if (hopLimit != 255)
1015 {
1016 NS_LOG_LOGIC("Ignoring an update message with suspicious hop count: " << int(hopLimit));
1017 return;
1018 }
1019
1020 std::list<RipNgRte> rtes = hdr.GetRteList();
1021
1022 // validate the RTEs before processing
1023 for (auto iter = rtes.begin(); iter != rtes.end(); iter++)
1024 {
1025 if (iter->GetRouteMetric() == 0 || iter->GetRouteMetric() > m_linkDown)
1026 {
1027 NS_LOG_LOGIC("Ignoring an update message with malformed metric: "
1028 << int(iter->GetRouteMetric()));
1029 return;
1030 }
1031 if (iter->GetPrefixLen() > 128)
1032 {
1033 NS_LOG_LOGIC("Ignoring an update message with malformed prefix length: "
1034 << int(iter->GetPrefixLen()));
1035 return;
1036 }
1037 if (iter->GetPrefix().IsLocalhost() || iter->GetPrefix().IsLinkLocal() ||
1038 iter->GetPrefix().IsMulticast())
1039 {
1040 NS_LOG_LOGIC("Ignoring an update message with wrong prefixes: " << iter->GetPrefix());
1041 return;
1042 }
1043 }
1044
1045 bool changed = false;
1046
1047 for (auto iter = rtes.begin(); iter != rtes.end(); iter++)
1048 {
1049 Ipv6Prefix rtePrefix = Ipv6Prefix(iter->GetPrefixLen());
1051
1052 NS_LOG_LOGIC("Processing RTE " << *iter);
1053
1054 uint8_t interfaceMetric = 1;
1056 {
1058 }
1059 uint16_t rteMetric = iter->GetRouteMetric() + interfaceMetric;
1060 if (rteMetric > m_linkDown)
1061 {
1063 }
1064 RoutesI it;
1065 bool found = false;
1066 for (it = m_routes.begin(); it != m_routes.end(); it++)
1067 {
1068 if (it->first->GetDestNetwork() == rteAddr &&
1069 it->first->GetDestNetworkPrefix() == rtePrefix)
1070 {
1071 found = true;
1072 if (rteMetric < it->first->GetRouteMetric())
1073 {
1074 if (senderAddress != it->first->GetGateway())
1075 {
1077 rtePrefix,
1081 delete it->first;
1082 it->first = route;
1083 }
1084 it->first->SetRouteMetric(rteMetric);
1085 it->first->SetRouteStatus(RipNgRoutingTableEntry::RIPNG_VALID);
1086 it->first->SetRouteTag(iter->GetRouteTag());
1087 it->first->SetRouteChanged(true);
1088 it->second.Cancel();
1091 this,
1092 it->first);
1093 changed = true;
1094 }
1095 else if (rteMetric == it->first->GetRouteMetric())
1096 {
1097 if (senderAddress == it->first->GetGateway())
1098 {
1099 it->second.Cancel();
1102 this,
1103 it->first);
1104 }
1105 else
1106 {
1107 if (Simulator::GetDelayLeft(it->second) < m_timeoutDelay / 2)
1108 {
1110 rtePrefix,
1114 route->SetRouteMetric(rteMetric);
1116 route->SetRouteTag(iter->GetRouteTag());
1117 route->SetRouteChanged(true);
1118 delete it->first;
1119 it->first = route;
1120 it->second.Cancel();
1123 this,
1124 route);
1125 changed = true;
1126 }
1127 }
1128 }
1129 else if (rteMetric > it->first->GetRouteMetric() &&
1130 senderAddress == it->first->GetGateway())
1131 {
1132 it->second.Cancel();
1133 if (rteMetric < m_linkDown)
1134 {
1135 it->first->SetRouteMetric(rteMetric);
1136 it->first->SetRouteStatus(RipNgRoutingTableEntry::RIPNG_VALID);
1137 it->first->SetRouteTag(iter->GetRouteTag());
1138 it->first->SetRouteChanged(true);
1139 it->second.Cancel();
1142 this,
1143 it->first);
1144 }
1145 else
1146 {
1147 InvalidateRoute(it->first);
1148 }
1149 changed = true;
1150 }
1151 }
1152 }
1153 if (!found && rteMetric != m_linkDown)
1154 {
1155 NS_LOG_LOGIC("Received a RTE with new route, adding.");
1156
1158 rtePrefix,
1162 route->SetRouteMetric(rteMetric);
1164 route->SetRouteChanged(true);
1165 m_routes.emplace_front(route, EventId());
1168 (m_routes.begin())->second = invalidateEvent;
1169 changed = true;
1170 }
1171 }
1172
1173 if (changed)
1174 {
1176 }
1177}
1178
1179void
1181{
1182 NS_LOG_FUNCTION(this << (periodic ? " periodic" : " triggered"));
1183
1184 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
1185 {
1186 uint32_t interface = iter->second;
1187
1188 if (m_interfaceExclusions.find(interface) == m_interfaceExclusions.end())
1189 {
1190 uint16_t mtu = m_ipv6->GetMtu(interface);
1191 uint16_t maxRte =
1195
1198 tag.SetHopLimit(255);
1199 p->AddPacketTag(tag);
1200
1203
1204 for (auto rtIter = m_routes.begin(); rtIter != m_routes.end(); rtIter++)
1205 {
1206 bool splitHorizoning = (rtIter->first->GetInterface() == interface);
1208 Ipv6InterfaceAddress(rtIter->first->GetDestNetwork(),
1209 rtIter->first->GetDestNetworkPrefix());
1210
1211 NS_LOG_DEBUG("Processing RT " << rtDestAddr << " "
1212 << int(rtIter->first->IsRouteChanged()));
1213
1214 bool isGlobal = (rtDestAddr.GetScope() == Ipv6InterfaceAddress::GLOBAL);
1215 bool isDefaultRoute =
1216 ((rtIter->first->GetDestNetwork() == Ipv6Address::GetAny()) &&
1217 (rtIter->first->GetDestNetworkPrefix() == Ipv6Prefix::GetZero()) &&
1218 (rtIter->first->GetInterface() != interface));
1219
1220 if ((isGlobal || isDefaultRoute) && (periodic || rtIter->first->IsRouteChanged()))
1221 {
1222 RipNgRte rte;
1223 rte.SetPrefix(rtIter->first->GetDestNetwork());
1224 rte.SetPrefixLen(rtIter->first->GetDestNetworkPrefix().GetPrefixLength());
1226 {
1227 rte.SetRouteMetric(m_linkDown);
1228 }
1229 else
1230 {
1231 rte.SetRouteMetric(rtIter->first->GetRouteMetric());
1232 }
1233 rte.SetRouteTag(rtIter->first->GetRouteTag());
1236 {
1237 hdr.AddRte(rte);
1238 }
1239 }
1240 if (hdr.GetRteNumber() == maxRte)
1241 {
1242 p->AddHeader(hdr);
1243 NS_LOG_DEBUG("SendTo: " << *p);
1244 iter->first->SendTo(p, 0, Inet6SocketAddress(RIPNG_ALL_NODE, RIPNG_PORT));
1245 p->RemoveHeader(hdr);
1246 hdr.ClearRtes();
1247 }
1248 }
1249 if (hdr.GetRteNumber() > 0)
1250 {
1251 p->AddHeader(hdr);
1252 NS_LOG_DEBUG("SendTo: " << *p);
1253 iter->first->SendTo(p, 0, Inet6SocketAddress(RIPNG_ALL_NODE, RIPNG_PORT));
1254 }
1255 }
1256 }
1257 for (auto rtIter = m_routes.begin(); rtIter != m_routes.end(); rtIter++)
1258 {
1259 rtIter->first->SetRouteChanged(false);
1260 }
1261}
1262
1263void
1265{
1266 NS_LOG_FUNCTION(this);
1267
1269 {
1270 NS_LOG_LOGIC("Skipping Triggered Update due to cooldown");
1271 return;
1272 }
1273
1274 // DoSendRouteUpdate (false);
1275
1276 // note: The RFC states:
1277 // After a triggered
1278 // update is sent, a timer should be set for a random interval between 1
1279 // and 5 seconds. If other changes that would trigger updates occur
1280 // before the timer expires, a single update is triggered when the timer
1281 // expires. The timer is then reset to another random value between 1
1282 // and 5 seconds. Triggered updates may be suppressed if a regular
1283 // update is due by the time the triggered update would be sent.
1284 // Here we rely on this:
1285 // When an update occurs (either Triggered or Periodic) the "IsChanged ()"
1286 // route field will be cleared.
1287 // Hence, the following Triggered Update will be fired, but will not send
1288 // any route update.
1289
1293}
1294
1295void
1311
1312std::set<uint32_t>
1317
1318void
1320{
1321 NS_LOG_FUNCTION(this);
1322
1324}
1325
1326uint8_t
1328{
1329 NS_LOG_FUNCTION(this << interface);
1330
1331 auto iter = m_interfaceMetrics.find(interface);
1332 if (iter != m_interfaceMetrics.end())
1333 {
1334 return iter->second;
1335 }
1336 return 1;
1337}
1338
1339void
1340RipNg::SetInterfaceMetric(uint32_t interface, uint8_t metric)
1341{
1342 NS_LOG_FUNCTION(this << interface << int(metric));
1343
1344 if (metric < m_linkDown)
1345 {
1346 m_interfaceMetrics[interface] = metric;
1347 }
1348}
1349
1350void
1352{
1353 NS_LOG_FUNCTION(this);
1354
1357 p->RemovePacketTag(tag);
1358 tag.SetHopLimit(255);
1359 p->AddPacketTag(tag);
1360
1363
1364 RipNgRte rte;
1366 rte.SetPrefixLen(0);
1367 rte.SetRouteMetric(m_linkDown);
1368
1369 hdr.AddRte(rte);
1370 p->AddHeader(hdr);
1371
1372 for (auto iter = m_unicastSocketList.begin(); iter != m_unicastSocketList.end(); iter++)
1373 {
1374 uint32_t interface = iter->second;
1375
1376 if (m_interfaceExclusions.find(interface) == m_interfaceExclusions.end())
1377 {
1378 NS_LOG_DEBUG("SendTo: " << *p);
1379 iter->first->SendTo(p, 0, Inet6SocketAddress(RIPNG_ALL_NODE, RIPNG_PORT));
1380 }
1381 }
1382}
1383
1384void
1386{
1387 NS_LOG_FUNCTION(this << interface);
1388
1391 nextHop,
1392 interface,
1393 Ipv6Address("::"));
1394}
1395
1396/*
1397 * RipNgRoutingTableEntry
1398 */
1399
1401 : m_tag(0),
1402 m_metric(0),
1403 m_status(RIPNG_INVALID),
1404 m_changed(false)
1405{
1406}
1407
1410 Ipv6Address nextHop,
1411 uint32_t interface,
1413 : Ipv6RoutingTableEntry(RipNgRoutingTableEntry::CreateNetworkRouteTo(network,
1415 nextHop,
1416 interface,
1417 prefixToUse)),
1418 m_tag(0),
1419 m_metric(0),
1420 m_status(RIPNG_INVALID),
1421 m_changed(false)
1422{
1423}
1424
1427 uint32_t interface)
1429 Ipv6RoutingTableEntry::CreateNetworkRouteTo(network, networkPrefix, interface)),
1430 m_tag(0),
1431 m_metric(0),
1432 m_status(RIPNG_INVALID),
1433 m_changed(false)
1434{
1435}
1436
1440
1441void
1443{
1444 if (m_tag != routeTag)
1445 {
1446 m_tag = routeTag;
1447 m_changed = true;
1448 }
1449}
1450
1451uint16_t
1453{
1454 return m_tag;
1455}
1456
1457void
1459{
1460 if (m_metric != routeMetric)
1461 {
1463 m_changed = true;
1464 }
1465}
1466
1467uint8_t
1469{
1470 return m_metric;
1471}
1472
1473void
1475{
1476 if (m_status != status)
1477 {
1478 m_status = status;
1479 m_changed = true;
1480 }
1481}
1482
1485{
1486 return m_status;
1487}
1488
1489void
1494
1495bool
1497{
1498 return m_changed;
1499}
1500
1501std::ostream&
1502operator<<(std::ostream& os, const RipNgRoutingTableEntry& rte)
1503{
1505 os << ", metric: " << int(rte.GetRouteMetric()) << ", tag: " << int(rte.GetRouteTag());
1506
1507 return os;
1508}
1509
1510} // namespace ns3
a polymophic address class
Definition address.h:90
Hold variables of type enum.
Definition enum.h:52
An identifier for simulation events.
Definition event-id.h:45
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition event-id.cc:44
bool IsPending() const
This method is syntactic sugar for !IsExpired().
Definition event-id.cc:65
An Inet6 address class.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
Describes an IPv6 address.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
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).
Ipv6Address CombinePrefix(const Ipv6Prefix &prefix) const
Combine this address with a prefix.
Packet header for IPv6.
Definition ipv6-header.h:24
Ipv6Address GetDestination() const
Get the "Destination address" field.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Ipv6Address GetSource() const
Get the "Source address" field.
IPv6 address associated with an interface.
@ LINKLOCAL
Link-local address (fe80::/64)
@ GLOBAL
Global address (2000::/3)
This class implements a tag that carries socket ancillary data to the socket interface.
Describes an IPv6 prefix.
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.
Abstract base class for IPv6 routing protocols.
A record of an IPv6 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:818
A network Node.
Definition node.h:46
virtual void DoInitialize()
Initialize() implementation.
Definition object.cc:440
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
RipNgHeader - see RFC 2080
void SetCommand(Command_e command)
Set the command.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
RIPng Routing Protocol, defined in RFC 2080.
Definition ripng.h:167
Ptr< Socket > m_multicastRecvSocket
multicast receive socket
Definition ripng.h:417
void NotifyInterfaceUp(uint32_t interface) override
Notify when specified interface goes UP.
Definition ripng.cc:283
void NotifyAddAddress(uint32_t interface, Ipv6InterfaceAddress address) override
Notify when specified interface add an address.
Definition ripng.cc:393
void NotifyAddRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero()) override
Notify a new route.
Definition ripng.cc:455
void DoSendRouteUpdate(bool periodic)
Send Routing Updates on all interfaces.
Definition ripng.cc:1180
Time m_startupDelay
Random delay before protocol startup.
Definition ripng.h:399
void DoDispose() override
Dispose this object.
Definition ripng.cc:564
SplitHorizonType_e m_splitHorizonStrategy
Split Horizon strategy.
Definition ripng.h:427
@ SPLIT_HORIZON
Split Horizon.
Definition ripng.h:215
@ POISON_REVERSE
Poison Reverse Split Horizon.
Definition ripng.h:216
@ NO_SPLIT_HORIZON
No Split Horizon.
Definition ripng.h:214
EventId m_nextTriggeredUpdate
Next Triggered Update event.
Definition ripng.h:420
std::list< std::pair< RipNgRoutingTableEntry *, EventId > >::iterator RoutesI
Iterator for container for the network routes.
Definition ripng.h:285
~RipNg() override
Definition ripng.cc:46
void NotifyRemoveAddress(uint32_t interface, Ipv6InterfaceAddress address) override
Notify when specified interface add an address.
Definition ripng.cc:419
Time m_minTriggeredUpdateDelay
Min cooldown delay after a Triggered Update.
Definition ripng.h:400
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
Set the set of interface excluded from the protocol.
Definition ripng.cc:1319
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.
Definition ripng.cc:189
EventId m_nextUnsolicitedUpdate
Next Unsolicited Update event.
Definition ripng.h:419
uint8_t m_linkDown
Link down value.
Definition ripng.h:430
Time m_maxTriggeredUpdateDelay
Max cooldown delay after a Triggered Update.
Definition ripng.h:401
void DoInitialize() override
Start protocol operation.
Definition ripng.cc:116
bool m_initialized
flag to allow socket's late-creation.
Definition ripng.h:429
SocketList m_unicastSocketList
list of sockets for unicast messages (socket, interface index)
Definition ripng.h:416
uint8_t GetInterfaceMetric(uint32_t interface) const
Get the metric for an interface.
Definition ripng.cc:1327
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)
Definition ripng.cc:223
Time m_unsolicitedUpdate
time between two Unsolicited Routing Updates
Definition ripng.h:402
std::set< uint32_t > m_interfaceExclusions
Set of excluded interfaces.
Definition ripng.h:424
void SetInterfaceMetric(uint32_t interface, uint8_t metric)
Set the metric for an interface.
Definition ripng.cc:1340
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition ripng.cc:107
void DeleteRoute(RipNgRoutingTableEntry *route)
Delete a route.
Definition ripng.cc:745
void AddNetworkRouteTo(Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
Add route to network.
Definition ripng.cc:685
Time m_garbageCollectionDelay
Delay before deleting an INVALID route.
Definition ripng.h:404
std::map< uint32_t, uint8_t > m_interfaceMetrics
Map of interface metrics.
Definition ripng.h:425
void SendRouteRequest()
Send Routing Request on all interfaces.
Definition ripng.cc:1351
void NotifyInterfaceDown(uint32_t interface) override
Notify when specified interface goes DOWN.
Definition ripng.cc:361
Ptr< Ipv6 > m_ipv6
IPv6 reference.
Definition ripng.h:398
Routes m_routes
the forwarding table for network.
Definition ripng.h:397
std::set< uint32_t > GetInterfaceExclusions() const
Get the set of interface excluded from the protocol.
Definition ripng.cc:1313
void SendTriggeredRouteUpdate()
Send Triggered Routing Updates on all interfaces.
Definition ripng.cc:1264
void HandleRequests(RipNgHeader hdr, Ipv6Address senderAddress, uint16_t senderPort, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIPng requests.
Definition ripng.cc:816
Ptr< UniformRandomVariable > m_rng
Rng stream.
Definition ripng.h:422
void HandleResponses(RipNgHeader hdr, Ipv6Address senderAddress, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIPng responses.
Definition ripng.cc:994
void NotifyRemoveRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero()) override
Notify route removing.
Definition ripng.cc:466
static TypeId GetTypeId()
Get the type ID.
Definition ripng.cc:51
void InvalidateRoute(RipNgRoutingTableEntry *route)
Invalidate a route.
Definition ripng.cc:721
void SetIpv6(Ptr< Ipv6 > ipv6) override
Typically, invoked directly or indirectly from ns3::Ipv6::SetRoutingProtocol.
Definition ripng.cc:477
void Receive(Ptr< Socket > socket)
Receive RIPng packets.
Definition ripng.cc:762
void AddDefaultRouteTo(Ipv6Address nextHop, uint32_t interface)
Add a default route to the router through the nextHop located on interface.
Definition ripng.cc:1385
Time m_timeoutDelay
Delay before invalidating a route.
Definition ripng.h:403
void SendUnsolicitedRouteUpdate()
Send Unsolicited Routing Updates on all interfaces.
Definition ripng.cc:1296
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
Print the Routing Table entries.
Definition ripng.cc:499
Ptr< Ipv6Route > Lookup(Ipv6Address dest, bool setSource, Ptr< NetDevice >=nullptr)
Lookup in the forwarding table for destination.
Definition ripng.cc:594
RipNg Routing Table Entry.
Definition ripng.h:54
bool IsRouteChanged() const
Get the route changed status.
Definition ripng.cc:1496
RipNgRoutingTableEntry()
Definition ripng.cc:1400
uint16_t GetRouteTag() const
Get the route tag.
Definition ripng.cc:1452
bool m_changed
route has been updated
Definition ripng.h:149
uint16_t m_tag
route tag
Definition ripng.h:146
void SetRouteTag(uint16_t routeTag)
Set the route tag.
Definition ripng.cc:1442
uint8_t GetRouteMetric() const
Get the route metric.
Definition ripng.cc:1468
void SetRouteMetric(uint8_t routeMetric)
Set the route metric.
Definition ripng.cc:1458
uint8_t m_metric
route metric
Definition ripng.h:147
Status_e m_status
route status
Definition ripng.h:148
Status_e GetRouteStatus() const
Get the route status.
Definition ripng.cc:1484
void SetRouteChanged(bool changed)
Set the route as changed.
Definition ripng.cc:1490
~RipNgRoutingTableEntry() override
Definition ripng.cc:1437
Status_e
Route status.
Definition ripng.h:60
@ RIPNG_INVALID
Definition ripng.h:62
@ RIPNG_VALID
Definition ripng.h:61
void SetRouteStatus(Status_e status)
Set the route status.
Definition ripng.cc:1474
RipNg Routing Table Entry (RTE) - see RFC 2080
void SetPrefix(Ipv6Address prefix)
Set the prefix.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition simulator.cc:206
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
Definition socket.cc:343
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition socket.cc:117
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition socket.cc:61
virtual int Close()=0
Close a socket.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition socket.h:73
@ ERROR_NOROUTETOHOST
Definition socket.h:84
@ ERROR_NOTERROR
Definition socket.h:74
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
void SetIpv6RecvHopLimit(bool ipv6RecvHopLimit)
Tells a socket to pass information about IPv6 Hop Limit up the stack.
Definition socket.cc:537
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer.
Definition socket.h:1161
void SetHopLimit(uint8_t hopLimit)
Set the tag's Hop Limit.
Definition socket.cc:657
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:404
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
Unit
The unit to use to interpret a number representing time.
Definition nstime.h:100
AttributeValue implementation for Time.
Definition nstime.h:1431
a unique identifier for an interface.
Definition type-id.h:49
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition type-id.cc:872
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Packet header for UDP packets.
Definition udp-header.h:30
uint32_t GetSerializedSize() const override
Hold an unsigned integer type.
Definition uinteger.h:34
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1452
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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:250
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition simulator.cc:294
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Definition first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition nstime.h:1432
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition enum.h:179
#define RIPNG_ALL_NODE
Definition ripng.cc:28
#define RIPNG_PORT
Definition ripng.cc:29