A Discrete-Event Network Simulator
API
ripng.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014 Universita' di Firenze, Italy
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
19 */
20
21#include <iomanip>
22#include "ripng.h"
23#include "ns3/log.h"
24#include "ns3/abort.h"
25#include "ns3/assert.h"
26#include "ns3/random-variable-stream.h"
27#include "ns3/ipv6-route.h"
28#include "ns3/node.h"
29#include "ns3/names.h"
30#include "ns3/ripng-header.h"
31#include "ns3/udp-header.h"
32#include "ns3/enum.h"
33#include "ns3/uinteger.h"
34#include "ns3/ipv6-packet-info-tag.h"
35#include "ns3/simulator.h"
36
37#define RIPNG_ALL_NODE "ff02::9"
38#define RIPNG_PORT 521
39
40namespace ns3 {
41
43
45
47 : m_ipv6 (0), m_splitHorizonStrategy (RipNg::POISON_REVERSE), m_initialized (false)
48{
49 m_rng = CreateObject<UniformRandomVariable> ();
50}
51
53{
54}
55
58{
59 static TypeId tid = TypeId ("ns3::RipNg")
61 .SetGroupName ("Internet")
62 .AddConstructor<RipNg> ()
63 .AddAttribute ("UnsolicitedRoutingUpdate", "The time between two Unsolicited Routing Updates.",
64 TimeValue (Seconds(30)),
67 .AddAttribute ("StartupDelay", "Maximum random delay for protocol startup (send route requests).",
68 TimeValue (Seconds(1)),
71 .AddAttribute ("TimeoutDelay", "The delay to invalidate a route.",
72 TimeValue (Seconds(180)),
75 .AddAttribute ("GarbageCollectionDelay", "The delay to delete an expired route.",
76 TimeValue (Seconds(120)),
79 .AddAttribute ("MinTriggeredCooldown", "Min cooldown delay after a Triggered Update.",
80 TimeValue (Seconds(1)),
83 .AddAttribute ("MaxTriggeredCooldown", "Max cooldown delay after a Triggered Update.",
84 TimeValue (Seconds(5)),
87 .AddAttribute ("SplitHorizon", "Split Horizon strategy.",
91 RipNg::SPLIT_HORIZON, "SplitHorizon",
92 RipNg::POISON_REVERSE, "PoisonReverse"))
93 .AddAttribute ("LinkDownValue", "Value for link down in count to infinity.",
94 UintegerValue (16),
96 MakeUintegerChecker<uint8_t> ())
97 ;
98 return tid;
99}
100
101int64_t RipNg::AssignStreams (int64_t stream)
102{
103 NS_LOG_FUNCTION (this << stream);
104
105 m_rng->SetStream (stream);
106 return 1;
107}
108
110{
111 NS_LOG_FUNCTION (this);
112
113 bool addedGlobal = false;
114
115 m_initialized = true;
116
119
120
121 for (uint32_t i = 0 ; i < m_ipv6->GetNInterfaces (); i++)
122 {
123 bool activeInterface = false;
124 if (m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
125 {
126 activeInterface = true;
127 m_ipv6->SetForwarding (i, true);
128 }
129
130 for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
131 {
132 Ipv6InterfaceAddress address = m_ipv6->GetAddress (i, j);
133 if (address.GetScope() == Ipv6InterfaceAddress::LINKLOCAL && activeInterface == true)
134 {
135 NS_LOG_LOGIC ("RIPng: adding socket to " << address.GetAddress ());
136 TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
137 Ptr<Node> theNode = GetObject<Node> ();
138 Ptr<Socket> socket = Socket::CreateSocket (theNode, tid);
140 socket->BindToNetDevice (m_ipv6->GetNetDevice (i));
141 int ret = socket->Bind (local);
142 NS_ASSERT_MSG (ret == 0, "Bind unsuccessful");
144 socket->SetIpv6RecvHopLimit (true);
145 socket->SetRecvPktInfo (true);
146 m_unicastSocketList[socket] = i;
147 }
148 else if (m_ipv6->GetAddress (i, j).GetScope() == Ipv6InterfaceAddress::GLOBAL)
149 {
150 addedGlobal = true;
151 }
152 }
153 }
154
156 {
157 NS_LOG_LOGIC ("RIPng: adding receiving socket");
158 TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
159 Ptr<Node> theNode = GetObject<Node> ();
166 }
167
168
169 if (addedGlobal)
170 {
173 }
174
175 delay = Seconds (m_rng->GetValue (0.01, m_startupDelay.GetSeconds ()));
177
179}
180
182{
183 NS_LOG_FUNCTION (this << header << oif);
184
185 Ipv6Address destination = header.GetDestination ();
186 Ptr<Ipv6Route> rtentry = 0;
187
188 if (destination.IsMulticast ())
189 {
190 // Note: Multicast routes for outbound packets are stored in the
191 // normal unicast table. An implication of this is that it is not
192 // possible to source multicast datagrams on multiple interfaces.
193 // This is a well-known property of sockets implementation on
194 // many Unix variants.
195 // So, we just log it and fall through to LookupStatic ()
196 NS_LOG_LOGIC ("RouteOutput (): Multicast destination");
197 }
198
199 rtentry = Lookup (destination, true, oif);
200 if (rtentry)
201 {
202 sockerr = Socket::ERROR_NOTERROR;
203 }
204 else
205 {
207 }
208 return rtentry;
209}
210
214{
215 NS_LOG_FUNCTION (this << p << header << header.GetSource () << header.GetDestination () << idev);
216
217 NS_ASSERT (m_ipv6 != 0);
218 // Check if input device supports IP
219 NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
220 uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
221 Ipv6Address dst = header.GetDestination ();
222
223 if (dst.IsMulticast ())
224 {
225 NS_LOG_LOGIC ("Multicast route not supported by RIPng");
226 return false; // Let other routing protocols try to handle this
227 }
228
229 if (header.GetDestination ().IsLinkLocal () ||
230 header.GetSource ().IsLinkLocal ())
231 {
232 NS_LOG_LOGIC ("Dropping packet not for me and with src or dst LinkLocal");
233 if (!ecb.IsNull ())
234 {
235 ecb (p, header, Socket::ERROR_NOROUTETOHOST);
236 }
237 return false;
238 }
239
240 // Check if input device supports IP forwarding
241 if (m_ipv6->IsForwarding (iif) == false)
242 {
243 NS_LOG_LOGIC ("Forwarding disabled for this interface");
244 if (!ecb.IsNull ())
245 {
246 ecb (p, header, Socket::ERROR_NOROUTETOHOST);
247 }
248 return true;
249 }
250 // Next, try to find a route
251 NS_LOG_LOGIC ("Unicast destination");
252 Ptr<Ipv6Route> rtentry = Lookup (header.GetDestination (), false);
253
254 if (rtentry != 0)
255 {
256 NS_LOG_LOGIC ("Found unicast destination - calling unicast callback");
257 ucb (idev, rtentry, p, header); // unicast forwarding callback
258 return true;
259 }
260 else
261 {
262 NS_LOG_LOGIC ("Did not find unicast destination - returning false");
263 return false; // Let other routing protocols try to handle this
264 }
265}
266
268{
269 NS_LOG_FUNCTION (this << i);
270
271 for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
272 {
273 Ipv6InterfaceAddress address = m_ipv6->GetAddress (i, j);
274 Ipv6Prefix networkMask = address.GetPrefix ();
275 Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (networkMask);
276
277 if (address.GetScope () == Ipv6InterfaceAddress::GLOBAL)
278 {
279 AddNetworkRouteTo (networkAddress, networkMask, i);
280 }
281 }
282
283 if (!m_initialized)
284 {
285 return;
286 }
287
288
289 bool sendSocketFound = false;
290 for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
291 {
292 if (iter->second == i)
293 {
294 sendSocketFound = true;
295 break;
296 }
297 }
298
299 bool activeInterface = false;
300 if (m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
301 {
302 activeInterface = true;
303 m_ipv6->SetForwarding (i, true);
304 }
305
306 for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
307 {
308 Ipv6InterfaceAddress address = m_ipv6->GetAddress (i, j);
309
310 if (address.GetScope() == Ipv6InterfaceAddress::LINKLOCAL && sendSocketFound == false && activeInterface == true)
311 {
312 NS_LOG_LOGIC ("RIPng: adding sending socket to " << address.GetAddress ());
313 TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
314 Ptr<Node> theNode = GetObject<Node> ();
315 Ptr<Socket> socket = Socket::CreateSocket (theNode, tid);
317 socket->BindToNetDevice (m_ipv6->GetNetDevice (i));
318 socket->Bind (local);
320 socket->SetIpv6RecvHopLimit (true);
321 socket->SetRecvPktInfo (true);
322 m_unicastSocketList[socket] = i;
323 }
324 else if (address.GetScope() == Ipv6InterfaceAddress::GLOBAL)
325 {
327 }
328 }
329
331 {
332 NS_LOG_LOGIC ("RIPng: adding receiving socket");
333 TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
334 Ptr<Node> theNode = GetObject<Node> ();
341 }
342}
343
345{
346 NS_LOG_FUNCTION (this << interface);
347
348 /* remove all routes that are going through this interface */
349 for (RoutesI it = m_routes.begin (); it != m_routes.end (); it++)
350 {
351 if (it->first->GetInterface () == interface)
352 {
353 InvalidateRoute (it->first);
354 }
355 }
356
357 for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
358 {
359 NS_LOG_INFO ("Checking socket for interface " << interface);
360 if (iter->second == interface)
361 {
362 NS_LOG_INFO ("Removed socket for interface " << interface);
363 iter->first->Close ();
364 m_unicastSocketList.erase (iter);
365 break;
366 }
367 }
368
369 if (m_interfaceExclusions.find (interface) == m_interfaceExclusions.end ())
370 {
372 }
373}
374
376{
377 NS_LOG_FUNCTION (this << interface << address);
378
379 if (!m_ipv6->IsUp (interface))
380 {
381 return;
382 }
383
384 if (m_interfaceExclusions.find (interface) != m_interfaceExclusions.end ())
385 {
386 return;
387 }
388
389 Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
390 Ipv6Prefix networkMask = address.GetPrefix ();
391
392 if (address.GetScope () == Ipv6InterfaceAddress::GLOBAL)
393 {
394 AddNetworkRouteTo (networkAddress, networkMask, interface);
395 }
396
398}
399
401{
402 NS_LOG_FUNCTION (this << interface << address);
403
404 if (!m_ipv6->IsUp (interface))
405 {
406 return;
407 }
408
409 if (address.GetScope() != Ipv6InterfaceAddress::GLOBAL)
410 {
411 return;
412 }
413
414 Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
415 Ipv6Prefix networkMask = address.GetPrefix ();
416
417 // Remove all routes that are going through this interface
418 // which reference this network
419 for (RoutesI it = m_routes.begin (); it != m_routes.end (); it++)
420 {
421 if (it->first->GetInterface () == interface
422 && it->first->IsNetwork ()
423 && it->first->GetDestNetwork () == networkAddress
424 && it->first->GetDestNetworkPrefix () == networkMask)
425 {
426 InvalidateRoute (it->first);
427 }
428 }
429
430 if (m_interfaceExclusions.find (interface) == m_interfaceExclusions.end ())
431 {
433 }
434
435}
436
437void RipNg::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
438{
439 NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
440 // \todo this can be used to add delegate routes
441}
442
443void RipNg::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
444{
445 NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
446 // \todo this can be used to delete delegate routes
447}
448
450{
451 NS_LOG_FUNCTION (this << ipv6);
452
453 NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
454 uint32_t i = 0;
455 m_ipv6 = ipv6;
456
457 for (i = 0; i < m_ipv6->GetNInterfaces (); i++)
458 {
459 if (m_ipv6->IsUp (i))
460 {
462 }
463 else
464 {
466 }
467 }
468}
469
471{
472 NS_LOG_FUNCTION (this << stream);
473
474 std::ostream* os = stream->GetStream ();
475 *os << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left);
476
477 *os << "Node: " << m_ipv6->GetObject<Node> ()->GetId ()
478 << ", Time: " << Now().As (unit)
479 << ", Local time: " << m_ipv6->GetObject<Node> ()->GetLocalTime ().As (unit)
480 << ", IPv6 RIPng table" << std::endl;
481
482 if (!m_routes.empty ())
483 {
484 *os << "Destination Next Hop Flag Met Ref Use If" << std::endl;
485 for (RoutesCI it = m_routes.begin (); it != m_routes.end (); it++)
486 {
487 RipNgRoutingTableEntry* route = it->first;
489
491 {
492 std::ostringstream dest, gw, mask, flags;
493
494 dest << route->GetDest () << "/" << int(route->GetDestNetworkPrefix ().GetPrefixLength ());
495 *os << std::setw (31) << dest.str ();
496 gw << route->GetGateway ();
497 *os << std::setw (27) << gw.str ();
498 flags << "U";
499 if (route->IsHost ())
500 {
501 flags << "H";
502 }
503 else if (route->IsGateway ())
504 {
505 flags << "G";
506 }
507 *os << std::setw (5) << flags.str ();
508 *os << std::setw (4) << int(route->GetRouteMetric ());
509 // Ref ct not implemented
510 *os << "-" << " ";
511 // Use not implemented
512 *os << "-" << " ";
513 if (Names::FindName (m_ipv6->GetNetDevice (route->GetInterface ())) != "")
514 {
515 *os << Names::FindName (m_ipv6->GetNetDevice (route->GetInterface ()));
516 }
517 else
518 {
519 *os << route->GetInterface ();
520 }
521 *os << std::endl;
522 }
523 }
524 }
525 *os << std::endl;
526}
527
529{
530 NS_LOG_FUNCTION (this);
531
532 for (RoutesI j = m_routes.begin (); j != m_routes.end (); j = m_routes.erase (j))
533 {
534 delete j->first;
535 }
536 m_routes.clear ();
537
542
543 for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
544 {
545 iter->first->Close ();
546 }
547 m_unicastSocketList.clear ();
548
551
552 m_ipv6 = 0;
553
555}
556
558{
559 NS_LOG_FUNCTION (this << dst << interface);
560
561 Ptr<Ipv6Route> rtentry = 0;
562 uint16_t longestMask = 0;
563
564 /* when sending on link-local multicast, there have to be interface specified */
565 if (dst.IsLinkLocalMulticast ())
566 {
567 NS_ASSERT_MSG (interface, "Try to send on link-local multicast address, and no interface index is given!");
568 rtentry = Create<Ipv6Route> ();
569 rtentry->SetSource (m_ipv6->SourceAddressSelection (m_ipv6->GetInterfaceForDevice (interface), dst));
570 rtentry->SetDestination (dst);
571 rtentry->SetGateway (Ipv6Address::GetZero ());
572 rtentry->SetOutputDevice (interface);
573 return rtentry;
574 }
575
576 for (RoutesI it = m_routes.begin (); it != m_routes.end (); it++)
577 {
578 RipNgRoutingTableEntry* j = it->first;
579
581 {
582 Ipv6Prefix mask = j->GetDestNetworkPrefix ();
583 uint16_t maskLen = mask.GetPrefixLength ();
584 Ipv6Address entry = j->GetDestNetwork ();
585
586 NS_LOG_LOGIC ("Searching for route to " << dst << ", mask length " << maskLen);
587
588 if (mask.IsMatch (dst, entry))
589 {
590 NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << maskLen);
591
592 /* if interface is given, check the route will output on this interface */
593 if (!interface || interface == m_ipv6->GetNetDevice (j->GetInterface ()))
594 {
595 if (maskLen < longestMask)
596 {
597 NS_LOG_LOGIC ("Previous match longer, skipping");
598 continue;
599 }
600
601 longestMask = maskLen;
602
603 Ipv6RoutingTableEntry* route = j;
604 uint32_t interfaceIdx = route->GetInterface ();
605 rtentry = Create<Ipv6Route> ();
606
607 if (setSource)
608 {
609 if (route->GetGateway ().IsAny ())
610 {
611 rtentry->SetSource (m_ipv6->SourceAddressSelection (interfaceIdx, route->GetDest ()));
612 }
613 else if (route->GetDest ().IsAny ()) /* default route */
614 {
615 rtentry->SetSource (m_ipv6->SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? dst : route->GetPrefixToUse ()));
616 }
617 else
618 {
619 rtentry->SetSource (m_ipv6->SourceAddressSelection (interfaceIdx, route->GetDest ()));
620 }
621 }
622
623 rtentry->SetDestination (route->GetDest ());
624 rtentry->SetGateway (route->GetGateway ());
625 rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
626 }
627 }
628 }
629 }
630
631 if (rtentry)
632 {
633 NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (through " << rtentry->GetGateway () << ") at the end");
634 }
635 return rtentry;
636}
637
638void RipNg::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
639{
640 NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse);
641
642 if (nextHop.IsLinkLocal())
643 {
644 NS_LOG_WARN ("Ripng::AddNetworkRouteTo - Next hop should be link-local");
645 }
646
647 RipNgRoutingTableEntry* route = new RipNgRoutingTableEntry (network, networkPrefix, nextHop, interface, prefixToUse);
648 route->SetRouteMetric (1);
650 route->SetRouteChanged (true);
651
652 m_routes.push_back (std::make_pair (route, EventId ()));
653}
654
655void RipNg::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
656{
657 NS_LOG_FUNCTION (this << network << networkPrefix << interface);
658
659 RipNgRoutingTableEntry* route = new RipNgRoutingTableEntry (network, networkPrefix, interface);
660 route->SetRouteMetric (1);
662 route->SetRouteChanged (true);
663
664 m_routes.push_back (std::make_pair (route, EventId ()));
665}
666
668{
669 NS_LOG_FUNCTION (this << *route);
670
671 for (RoutesI it = m_routes.begin (); it != m_routes.end (); it++)
672 {
673 if (it->first == route)
674 {
676 route->SetRouteMetric (m_linkDown);
677 route->SetRouteChanged (true);
678 if (it->second.IsRunning ())
679 {
680 it->second.Cancel ();
681 }
683 return;
684 }
685 }
686 NS_ABORT_MSG ("Ripng::InvalidateRoute - cannot find the route to update");
687}
688
690{
691 NS_LOG_FUNCTION (this << *route);
692
693 for (RoutesI it = m_routes.begin (); it != m_routes.end (); it++)
694 {
695 if (it->first == route)
696 {
697 delete route;
698 m_routes.erase (it);
699 return;
700 }
701 }
702 NS_ABORT_MSG ("Ripng::DeleteRoute - cannot find the route to delete");
703}
704
705
707{
708 NS_LOG_FUNCTION (this << socket);
709
710 Address sender;
711 Ptr<Packet> packet = socket->RecvFrom (sender);
713 NS_LOG_INFO ("Received " << *packet << " from " << senderAddr);
714
715 Ipv6Address senderAddress = senderAddr.GetIpv6 ();
716 uint16_t senderPort = senderAddr.GetPort ();
717
718 Ipv6PacketInfoTag interfaceInfo;
719 if (!packet->RemovePacketTag (interfaceInfo))
720 {
721 NS_ABORT_MSG ("No incoming interface on RIPng message, aborting.");
722 }
723 uint32_t incomingIf = interfaceInfo.GetRecvIf ();
724 Ptr<Node> node = this->GetObject<Node> ();
725 Ptr<NetDevice> dev = node->GetDevice (incomingIf);
726 uint32_t ipInterfaceIndex = m_ipv6->GetInterfaceForDevice (dev);
727
728 SocketIpv6HopLimitTag hoplimitTag;
729 if (!packet->RemovePacketTag (hoplimitTag))
730 {
731 NS_ABORT_MSG ("No incoming Hop Count on RIPng message, aborting.");
732 }
733 uint8_t hopLimit = hoplimitTag.GetHopLimit ();
734
735 int32_t interfaceForAddress = m_ipv6->GetInterfaceForAddress (senderAddress);
736 if (interfaceForAddress != -1)
737 {
738 NS_LOG_LOGIC ("Ignoring a packet sent by myself.");
739 return;
740 }
741
742 RipNgHeader hdr;
743 packet->RemoveHeader (hdr);
744
745 if (hdr.GetCommand () == RipNgHeader::RESPONSE)
746 {
747 HandleResponses (hdr, senderAddress, ipInterfaceIndex, hopLimit);
748 }
749 else if (hdr.GetCommand () == RipNgHeader::REQUEST)
750 {
751 HandleRequests (hdr, senderAddress, senderPort, ipInterfaceIndex, hopLimit);
752 }
753 else
754 {
755 NS_LOG_LOGIC ("Ignoring message with unknown command: " << int (hdr.GetCommand ()));
756 }
757 return;
758}
759
760void RipNg::HandleRequests (RipNgHeader requestHdr, Ipv6Address senderAddress, uint16_t senderPort, uint32_t incomingInterface, uint8_t hopLimit)
761{
762 NS_LOG_FUNCTION (this << senderAddress << int (senderPort) << incomingInterface << int (hopLimit) << requestHdr);
763
764 std::list<RipNgRte> rtes = requestHdr.GetRteList ();
765
766 if (rtes.empty ())
767 {
768 return;
769 }
770
771 // check if it's a request for the full table from a neighbor
772 if (rtes.size () == 1 && senderAddress.IsLinkLocal ())
773 {
774 if (rtes.begin ()->GetPrefix () == Ipv6Address::GetAny () &&
775 rtes.begin ()->GetPrefixLen () == 0 &&
776 rtes.begin ()->GetRouteMetric () == m_linkDown)
777 {
778 // Output whole thing. Use Split Horizon
779 if (m_interfaceExclusions.find (incomingInterface) == m_interfaceExclusions.end ())
780 {
781 // we use one of the sending sockets, as they're bound to the right interface
782 // and the local address might be used on different interfaces.
783 Ptr<Socket> sendingSocket;
784 for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
785 {
786 if (iter->second == incomingInterface)
787 {
788 sendingSocket = iter->first;
789 }
790 }
791 NS_ASSERT_MSG (sendingSocket, "HandleRequest - Impossible to find a socket to send the reply");
792
793 uint16_t mtu = m_ipv6->GetMtu (incomingInterface);
795
796 Ptr<Packet> p = Create<Packet> ();
798 p->RemovePacketTag (tag);
799 tag.SetHopLimit (255);
800 p->AddPacketTag (tag);
801
802 RipNgHeader hdr;
804
805 for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
806 {
807 bool splitHorizoning = (rtIter->first->GetInterface () == incomingInterface);
808
809 Ipv6InterfaceAddress rtDestAddr = Ipv6InterfaceAddress (rtIter->first->GetDestNetwork (), rtIter->first->GetDestNetworkPrefix ());
810
811 bool isGlobal = (rtDestAddr.GetScope () == Ipv6InterfaceAddress::GLOBAL);
812 bool isDefaultRoute = ((rtIter->first->GetDestNetwork () == Ipv6Address::GetAny ()) &&
813 (rtIter->first->GetDestNetworkPrefix () == Ipv6Prefix::GetZero ()) &&
814 (rtIter->first->GetInterface () != incomingInterface));
815
816 if ((isGlobal || isDefaultRoute) &&
817 (rtIter->first->GetRouteStatus () == RipNgRoutingTableEntry::RIPNG_VALID) )
818 {
819 RipNgRte rte;
820 rte.SetPrefix (rtIter->first->GetDestNetwork ());
821 rte.SetPrefixLen (rtIter->first->GetDestNetworkPrefix ().GetPrefixLength ());
822 if (m_splitHorizonStrategy == POISON_REVERSE && splitHorizoning)
823 {
825 }
826 else
827 {
828 rte.SetRouteMetric (rtIter->first->GetRouteMetric ());
829 }
830 rte.SetRouteTag (rtIter->first->GetRouteTag ());
832 (m_splitHorizonStrategy == SPLIT_HORIZON && !splitHorizoning))
833 {
834 hdr.AddRte (rte);
835 }
836 }
837 if (hdr.GetRteNumber () == maxRte)
838 {
839 p->AddHeader (hdr);
840 NS_LOG_DEBUG ("SendTo: " << *p);
841 sendingSocket->SendTo (p, 0, Inet6SocketAddress (senderAddress, RIPNG_PORT));
842 p->RemoveHeader (hdr);
843 hdr.ClearRtes ();
844 }
845 }
846 if (hdr.GetRteNumber () > 0)
847 {
848 p->AddHeader (hdr);
849 NS_LOG_DEBUG ("SendTo: " << *p);
850 sendingSocket->SendTo (p, 0, Inet6SocketAddress (senderAddress, RIPNG_PORT));
851 }
852 }
853 }
854 }
855 else
856 {
857 // note: we got the request as a single packet, so no check is necessary for MTU limit
858
859 // we use one of the sending sockets, as they're bound to the right interface
860 // and the local address might be used on different interfaces.
861 Ptr<Socket> sendingSocket;
862 if (senderAddress.IsLinkLocal ())
863 {
864 for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
865 {
866 if (iter->second == incomingInterface)
867 {
868 sendingSocket = iter->first;
869 }
870 }
871 }
872 else
873 {
874 sendingSocket = m_multicastRecvSocket;
875 }
876
877 Ptr<Packet> p = Create<Packet> ();
879 p->RemovePacketTag (tag);
880 tag.SetHopLimit (255);
881 p->AddPacketTag (tag);
882
883 RipNgHeader hdr;
885
886 for (std::list<RipNgRte>::iterator iter = rtes.begin ();
887 iter != rtes.end (); iter++)
888 {
889 bool found = false;
890 for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
891 {
892 Ipv6InterfaceAddress rtDestAddr = Ipv6InterfaceAddress(rtIter->first->GetDestNetwork (), rtIter->first->GetDestNetworkPrefix ());
893 if ((rtDestAddr.GetScope () == Ipv6InterfaceAddress::GLOBAL) &&
894 (rtIter->first->GetRouteStatus () == RipNgRoutingTableEntry::RIPNG_VALID))
895 {
896 Ipv6Address requestedAddress = iter->GetPrefix ();
897 requestedAddress.CombinePrefix (Ipv6Prefix (iter->GetPrefixLen ()));
898 Ipv6Address rtAddress = rtIter->first->GetDestNetwork ();
899 rtAddress.CombinePrefix (rtIter->first->GetDestNetworkPrefix ());
900
901 if (requestedAddress == rtAddress)
902 {
903 iter->SetRouteMetric (rtIter->first->GetRouteMetric ());
904 iter->SetRouteTag (rtIter->first->GetRouteTag ());
905 hdr.AddRte (*iter);
906 found = true;
907 break;
908 }
909 }
910 }
911 if (!found)
912 {
913 iter->SetRouteMetric (m_linkDown);
914 iter->SetRouteTag (0);
915 hdr.AddRte (*iter);
916 }
917 }
918 p->AddHeader (hdr);
919 NS_LOG_DEBUG ("SendTo: " << *p);
920 sendingSocket->SendTo (p, 0, Inet6SocketAddress (senderAddress, senderPort));
921 }
922
923}
924
925void RipNg::HandleResponses (RipNgHeader hdr, Ipv6Address senderAddress, uint32_t incomingInterface, uint8_t hopLimit)
926{
927 NS_LOG_FUNCTION (this << senderAddress << incomingInterface << int (hopLimit) << hdr);
928
929 if (m_interfaceExclusions.find (incomingInterface) != m_interfaceExclusions.end ())
930 {
931 NS_LOG_LOGIC ("Ignoring an update message from an excluded interface: " << incomingInterface);
932 return;
933 }
934
935 if (!senderAddress.IsLinkLocal ())
936 {
937 NS_LOG_LOGIC ("Ignoring an update message from a non-link-local source: " << senderAddress);
938 return;
939 }
940
941 if (hopLimit != 255)
942 {
943 NS_LOG_LOGIC ("Ignoring an update message with suspicious hop count: " << int (hopLimit));
944 return;
945 }
946
947 std::list<RipNgRte> rtes = hdr.GetRteList ();
948
949 // validate the RTEs before processing
950 for (std::list<RipNgRte>::iterator iter = rtes.begin ();
951 iter != rtes.end (); iter++)
952 {
953 if (iter->GetRouteMetric () == 0 || iter->GetRouteMetric () > m_linkDown)
954 {
955 NS_LOG_LOGIC ("Ignoring an update message with malformed metric: " << int (iter->GetRouteMetric ()));
956 return;
957 }
958 if (iter->GetPrefixLen () > 128)
959 {
960 NS_LOG_LOGIC ("Ignoring an update message with malformed prefix length: " << int (iter->GetPrefixLen ()));
961 return;
962 }
963 if (iter->GetPrefix ().IsLocalhost () ||
964 iter->GetPrefix ().IsLinkLocal () ||
965 iter->GetPrefix ().IsMulticast ())
966 {
967 NS_LOG_LOGIC ("Ignoring an update message with wrong prefixes: " << iter->GetPrefix ());
968 return;
969 }
970 }
971
972 bool changed = false;
973
974 for (std::list<RipNgRte>::iterator iter = rtes.begin ();
975 iter != rtes.end (); iter++)
976 {
977 Ipv6Prefix rtePrefix = Ipv6Prefix (iter->GetPrefixLen ());
978 Ipv6Address rteAddr = iter->GetPrefix ().CombinePrefix (rtePrefix);
979
980 NS_LOG_LOGIC ("Processing RTE " << *iter);
981
982 uint8_t interfaceMetric = 1;
983 if (m_interfaceMetrics.find (incomingInterface) != m_interfaceMetrics.end ())
984 {
985 interfaceMetric = m_interfaceMetrics[incomingInterface];
986 }
987 uint16_t rteMetric = iter->GetRouteMetric () + interfaceMetric;
988 if (rteMetric > m_linkDown)
989 {
990 rteMetric = m_linkDown;
991 }
992 RoutesI it;
993 bool found = false;
994 for (it = m_routes.begin (); it != m_routes.end (); it++)
995 {
996 if (it->first->GetDestNetwork () == rteAddr &&
997 it->first->GetDestNetworkPrefix () == rtePrefix)
998 {
999 found = true;
1000 if (rteMetric < it->first->GetRouteMetric ())
1001 {
1002 if (senderAddress != it->first->GetGateway ())
1003 {
1004 RipNgRoutingTableEntry* route = new RipNgRoutingTableEntry (rteAddr, rtePrefix, senderAddress, incomingInterface, Ipv6Address::GetAny ());
1005 delete it->first;
1006 it->first = route;
1007 }
1008 it->first->SetRouteMetric (rteMetric);
1009 it->first->SetRouteStatus (RipNgRoutingTableEntry::RIPNG_VALID);
1010 it->first->SetRouteTag (iter->GetRouteTag ());
1011 it->first->SetRouteChanged (true);
1012 it->second.Cancel ();
1013 it->second = Simulator::Schedule (m_timeoutDelay, &RipNg::InvalidateRoute, this, it->first);
1014 changed = true;
1015 }
1016 else if (rteMetric == it->first->GetRouteMetric ())
1017 {
1018 if (senderAddress == it->first->GetGateway ())
1019 {
1020 it->second.Cancel ();
1021 it->second = Simulator::Schedule (m_timeoutDelay, &RipNg::InvalidateRoute, this, it->first);
1022 }
1023 else
1024 {
1025 if (Simulator::GetDelayLeft (it->second) < m_timeoutDelay/2)
1026 {
1027 RipNgRoutingTableEntry* route = new RipNgRoutingTableEntry (rteAddr, rtePrefix, senderAddress, incomingInterface, Ipv6Address::GetAny ());
1028 route->SetRouteMetric (rteMetric);
1030 route->SetRouteTag (iter->GetRouteTag ());
1031 route->SetRouteChanged (true);
1032 delete it->first;
1033 it->first = route;
1034 it->second.Cancel ();
1035 it->second = Simulator::Schedule (m_timeoutDelay, &RipNg::InvalidateRoute, this, route);
1036 changed = true;
1037 }
1038 }
1039 }
1040 else if (rteMetric > it->first->GetRouteMetric () && senderAddress == it->first->GetGateway ())
1041 {
1042 it->second.Cancel ();
1043 if (rteMetric < m_linkDown)
1044 {
1045 it->first->SetRouteMetric (rteMetric);
1046 it->first->SetRouteStatus (RipNgRoutingTableEntry::RIPNG_VALID);
1047 it->first->SetRouteTag (iter->GetRouteTag ());
1048 it->first->SetRouteChanged (true);
1049 it->second.Cancel ();
1050 it->second = Simulator::Schedule (m_timeoutDelay, &RipNg::InvalidateRoute, this, it->first);
1051 }
1052 else
1053 {
1054 InvalidateRoute (it->first);
1055 }
1056 changed = true;
1057 }
1058 }
1059 }
1060 if (!found && rteMetric != m_linkDown)
1061 {
1062 NS_LOG_LOGIC ("Received a RTE with new route, adding.");
1063
1064 RipNgRoutingTableEntry* route = new RipNgRoutingTableEntry (rteAddr, rtePrefix, senderAddress, incomingInterface, Ipv6Address::GetAny ());
1065 route->SetRouteMetric (rteMetric);
1067 route->SetRouteChanged (true);
1068 m_routes.push_front (std::make_pair (route, EventId ()));
1069 EventId invalidateEvent = Simulator::Schedule (m_timeoutDelay, &RipNg::InvalidateRoute, this, route);
1070 (m_routes.begin ())->second = invalidateEvent;
1071 changed = true;
1072 }
1073 }
1074
1075 if (changed)
1076 {
1078 }
1079}
1080
1081void RipNg::DoSendRouteUpdate (bool periodic)
1082{
1083 NS_LOG_FUNCTION (this << (periodic ? " periodic" : " triggered"));
1084
1085 for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
1086 {
1087 uint32_t interface = iter->second;
1088
1089 if (m_interfaceExclusions.find (interface) == m_interfaceExclusions.end ())
1090 {
1091 uint16_t mtu = m_ipv6->GetMtu (interface);
1093
1094 Ptr<Packet> p = Create<Packet> ();
1096 tag.SetHopLimit (255);
1097 p->AddPacketTag (tag);
1098
1099 RipNgHeader hdr;
1101
1102 for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
1103 {
1104 bool splitHorizoning = (rtIter->first->GetInterface () == interface);
1105 Ipv6InterfaceAddress rtDestAddr = Ipv6InterfaceAddress(rtIter->first->GetDestNetwork (), rtIter->first->GetDestNetworkPrefix ());
1106
1107 NS_LOG_DEBUG ("Processing RT " << rtDestAddr << " " << int(rtIter->first->IsRouteChanged ()));
1108
1109 bool isGlobal = (rtDestAddr.GetScope () == Ipv6InterfaceAddress::GLOBAL);
1110 bool isDefaultRoute = ((rtIter->first->GetDestNetwork () == Ipv6Address::GetAny ()) &&
1111 (rtIter->first->GetDestNetworkPrefix () == Ipv6Prefix::GetZero ()) &&
1112 (rtIter->first->GetInterface () != interface));
1113
1114 if ((isGlobal || isDefaultRoute) &&
1115 (periodic || rtIter->first->IsRouteChanged ()))
1116 {
1117 RipNgRte rte;
1118 rte.SetPrefix (rtIter->first->GetDestNetwork ());
1119 rte.SetPrefixLen (rtIter->first->GetDestNetworkPrefix ().GetPrefixLength ());
1120 if (m_splitHorizonStrategy == POISON_REVERSE && splitHorizoning)
1121 {
1123 }
1124 else
1125 {
1126 rte.SetRouteMetric (rtIter->first->GetRouteMetric ());
1127 }
1128 rte.SetRouteTag (rtIter->first->GetRouteTag ());
1129 if (m_splitHorizonStrategy == SPLIT_HORIZON && !splitHorizoning)
1130 {
1131 hdr.AddRte (rte);
1132 }
1134 {
1135 hdr.AddRte (rte);
1136 }
1137 }
1138 if (hdr.GetRteNumber () == maxRte)
1139 {
1140 p->AddHeader (hdr);
1141 NS_LOG_DEBUG ("SendTo: " << *p);
1142 iter->first->SendTo (p, 0, Inet6SocketAddress (RIPNG_ALL_NODE, RIPNG_PORT));
1143 p->RemoveHeader (hdr);
1144 hdr.ClearRtes ();
1145 }
1146 }
1147 if (hdr.GetRteNumber () > 0)
1148 {
1149 p->AddHeader (hdr);
1150 NS_LOG_DEBUG ("SendTo: " << *p);
1151 iter->first->SendTo (p, 0, Inet6SocketAddress (RIPNG_ALL_NODE, RIPNG_PORT));
1152 }
1153 }
1154 }
1155 for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
1156 {
1157 rtIter->first->SetRouteChanged (false);
1158 }
1159}
1160
1162{
1163 NS_LOG_FUNCTION (this);
1164
1166 {
1167 NS_LOG_LOGIC ("Skipping Triggered Update due to cooldown");
1168 return;
1169 }
1170
1171 // DoSendRouteUpdate (false);
1172
1173 // note: The RFC states:
1174 // After a triggered
1175 // update is sent, a timer should be set for a random interval between 1
1176 // and 5 seconds. If other changes that would trigger updates occur
1177 // before the timer expires, a single update is triggered when the timer
1178 // expires. The timer is then reset to another random value between 1
1179 // and 5 seconds. Triggered updates may be suppressed if a regular
1180 // update is due by the time the triggered update would be sent.
1181 // Here we rely on this:
1182 // When an update occurs (either Triggered or Periodic) the "IsChanged ()"
1183 // route field will be cleared.
1184 // Hence, the following Triggered Update will be fired, but will not send
1185 // any route update.
1186
1189}
1190
1192{
1193 NS_LOG_FUNCTION (this);
1194
1196 {
1198 }
1199
1200 DoSendRouteUpdate (true);
1201
1204}
1205
1206std::set<uint32_t> RipNg::GetInterfaceExclusions () const
1207{
1208 return m_interfaceExclusions;
1209}
1210
1211void RipNg::SetInterfaceExclusions (std::set<uint32_t> exceptions)
1212{
1213 NS_LOG_FUNCTION (this);
1214
1215 m_interfaceExclusions = exceptions;
1216}
1217
1218uint8_t RipNg::GetInterfaceMetric (uint32_t interface) const
1219{
1220 NS_LOG_FUNCTION (this << interface);
1221
1222 std::map<uint32_t, uint8_t>::const_iterator iter = m_interfaceMetrics.find (interface);
1223 if (iter != m_interfaceMetrics.end ())
1224 {
1225 return iter->second;
1226 }
1227 return 1;
1228}
1229
1230void RipNg::SetInterfaceMetric (uint32_t interface, uint8_t metric)
1231{
1232 NS_LOG_FUNCTION (this << interface << int (metric));
1233
1234 if (metric < m_linkDown)
1235 {
1236 m_interfaceMetrics[interface] = metric;
1237 }
1238}
1239
1241{
1242 NS_LOG_FUNCTION (this);
1243
1244 Ptr<Packet> p = Create<Packet> ();
1246 p->RemovePacketTag (tag);
1247 tag.SetHopLimit (255);
1248 p->AddPacketTag (tag);
1249
1250 RipNgHeader hdr;
1252
1253 RipNgRte rte;
1255 rte.SetPrefixLen (0);
1257
1258 hdr.AddRte (rte);
1259 p->AddHeader (hdr);
1260
1261 for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
1262 {
1263 uint32_t interface = iter->second;
1264
1265 if (m_interfaceExclusions.find (interface) == m_interfaceExclusions.end ())
1266 {
1267 NS_LOG_DEBUG ("SendTo: " << *p);
1268 iter->first->SendTo (p, 0, Inet6SocketAddress (RIPNG_ALL_NODE, RIPNG_PORT));
1269 }
1270 }
1271}
1272
1274{
1275 NS_LOG_FUNCTION (this << interface);
1276
1277 AddNetworkRouteTo (Ipv6Address ("::"), Ipv6Prefix::GetZero (), nextHop, interface, Ipv6Address ("::"));
1278}
1279
1280
1281/*
1282 * RipNgRoutingTableEntry
1283 */
1284
1286 : m_tag (0), m_metric (0), m_status (RIPNG_INVALID), m_changed (false)
1287{
1288}
1289
1291 : Ipv6RoutingTableEntry ( RipNgRoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse) ),
1292 m_tag (0), m_metric (0), m_status (RIPNG_INVALID), m_changed (false)
1293{
1294}
1295
1297 : Ipv6RoutingTableEntry ( Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface) ),
1298 m_tag (0), m_metric (0), m_status (RIPNG_INVALID), m_changed (false)
1299{
1300}
1301
1303{
1304}
1305
1306
1308{
1309 if (m_tag != routeTag)
1310 {
1311 m_tag = routeTag;
1312 m_changed = true;
1313 }
1314}
1315
1317{
1318 return m_tag;
1319}
1320
1322{
1323 if (m_metric != routeMetric)
1324 {
1325 m_metric = routeMetric;
1326 m_changed = true;
1327 }
1328}
1329
1331{
1332 return m_metric;
1333}
1334
1336{
1337 if (m_status != status)
1338 {
1339 m_status = status;
1340 m_changed = true;
1341 }
1342}
1343
1345{
1346 return m_status;
1347}
1348
1350{
1351 m_changed = changed;
1352}
1353
1355{
1356 return m_changed;
1357}
1358
1359
1360std::ostream & operator << (std::ostream& os, const RipNgRoutingTableEntry& rte)
1361{
1362 os << static_cast<const Ipv6RoutingTableEntry &>(rte);
1363 os << ", metric: " << int (rte.GetRouteMetric ()) << ", tag: " << int (rte.GetRouteTag ());
1364
1365 return os;
1366}
1367
1368
1369}
1370
a polymophic address class
Definition: address.h:91
Callback template class.
Definition: callback.h:1279
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
Hold variables of type enum.
Definition: enum.h:55
An identifier for simulation events.
Definition: event-id.h:54
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
An Inet6 address class.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
Ipv6Address GetIpv6(void) const
Get the IPv6 address.
uint16_t GetPort(void) const
Get the port.
Describes an IPv6 address.
Definition: ipv6-address.h:50
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
Ipv6Address CombinePrefix(Ipv6Prefix const &prefix) const
Combine this address with a prefix.
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
bool IsAny() const
If the IPv6 address is the "Any" address.
Packet header for IPv6.
Definition: ipv6-header.h:36
Ipv6Address GetSource(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:105
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
Definition: ipv6-header.cc:163
Ipv6Address GetDestination(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:125
IPv6 address associated with an interface.
Ipv6InterfaceAddress::Scope_e GetScope() const
Get address scope.
@ 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.
uint32_t GetRecvIf(void) const
Get the tag's receiving interface.
Describes an IPv6 prefix.
Definition: ipv6-address.h:456
uint8_t GetPrefixLength() const
Get prefix length.
static Ipv6Prefix GetZero()
Get the zero prefix ( /0).
bool IsMatch(Ipv6Address a, Ipv6Address b) const
If the Address match the type.
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.
Ipv6Address GetGateway() const
Get the gateway.
bool IsGateway() const
Is it the gateway ?
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and,...
Definition: names.cc:817
A network Node.
Definition: node.h:57
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:144
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
virtual void DoInitialize(void)
Initialize() implementation.
Definition: object.cc:353
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
RipNgHeader - see RFC 2080
Definition: ripng-header.h:147
uint16_t GetRteNumber(void) const
Get the number of RTE included in the message.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
void SetCommand(Command_e command)
Set the command.
void ClearRtes()
Clear all the RTEs from the header.
Command_e GetCommand(void) const
Get the command.
std::list< RipNgRte > GetRteList(void) const
Get the list of the RTEs included in the message.
void AddRte(RipNgRte rte)
Add a RTE to the message.
RIPng Routing Protocol, defined in RFC 2080.
Definition: ripng.h:175
virtual void DoDispose()
Dispose this object.
Definition: ripng.cc:528
virtual void NotifyRemoveAddress(uint32_t interface, Ipv6InterfaceAddress address)
Notify when specified interface add an address.
Definition: ripng.cc:400
Ptr< Socket > m_multicastRecvSocket
multicast receive socket
Definition: ripng.h:400
void DoSendRouteUpdate(bool periodic)
Send Routing Updates on all interfaces.
Definition: ripng.cc:1081
Time m_startupDelay
Random delay before protocol startup.
Definition: ripng.h:383
std::list< std::pair< RipNgRoutingTableEntry *, EventId > >::const_iterator RoutesCI
Const Iterator for container for the network routes.
Definition: ripng.h:276
virtual void NotifyInterfaceDown(uint32_t interface)
Notify when specified interface goes DOWN.
Definition: ripng.cc:344
SplitHorizonType_e m_splitHorizonStrategy
Split Horizon strategy.
Definition: ripng.h:410
@ SPLIT_HORIZON
Split Horizon.
Definition: ripng.h:209
@ POISON_REVERSE
Poison Reverse Split Horizon.
Definition: ripng.h:210
@ NO_SPLIT_HORIZON
No Split Horizon.
Definition: ripng.h:208
EventId m_nextTriggeredUpdate
Next Triggered Update event.
Definition: ripng.h:403
std::list< std::pair< RipNgRoutingTableEntry *, EventId > >::iterator RoutesI
Iterator for container for the network routes.
Definition: ripng.h:279
static TypeId GetTypeId(void)
Get the type ID.
Definition: ripng.cc:57
Time m_minTriggeredUpdateDelay
Min cooldown delay after a Triggered Update.
Definition: ripng.h:384
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
Set the set of interface excluded from the protocol.
Definition: ripng.cc:1211
virtual void NotifyAddRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero())
Notify a new route.
Definition: ripng.cc:437
virtual void NotifyInterfaceUp(uint32_t interface)
Notify when specified interface goes UP.
Definition: ripng.cc:267
EventId m_nextUnsolicitedUpdate
Next Unsolicited Update event.
Definition: ripng.h:402
uint8_t m_linkDown
Link down value.
Definition: ripng.h:413
Time m_maxTriggeredUpdateDelay
Max cooldown delay after a Triggered Update.
Definition: ripng.h:385
virtual void NotifyRemoveRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero())
Notify route removing.
Definition: ripng.cc:443
bool m_initialized
flag to allow socket's late-creation.
Definition: ripng.h:412
SocketList m_unicastSocketList
list of sockets for unicast messages (socket, interface index)
Definition: ripng.h:399
std::map< Ptr< Socket >, uint32_t >::iterator SocketListI
Socket list type iterator.
Definition: ripng.h:395
uint8_t GetInterfaceMetric(uint32_t interface) const
Get the metric for an interface.
Definition: ripng.cc:1218
void DoInitialize()
Start protocol operation.
Definition: ripng.cc:109
Ptr< Ipv6Route > Lookup(Ipv6Address dest, bool setSource, Ptr< NetDevice >=0)
Lookup in the forwarding table for destination.
Definition: ripng.cc:557
Time m_unsolicitedUpdate
time between two Unsolicited Routing Updates
Definition: ripng.h:386
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
Definition: ripng.cc:470
std::set< uint32_t > m_interfaceExclusions
Set of excluded interfaces.
Definition: ripng.h:407
void SetInterfaceMetric(uint32_t interface, uint8_t metric)
Set the metric for an interface.
Definition: ripng.cc:1230
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: ripng.cc:101
void DeleteRoute(RipNgRoutingTableEntry *route)
Delete a route.
Definition: ripng.cc:689
virtual void NotifyAddAddress(uint32_t interface, Ipv6InterfaceAddress address)
Notify when specified interface add an address.
Definition: ripng.cc:375
void AddNetworkRouteTo(Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
Add route to network.
Definition: ripng.cc:638
Time m_garbageCollectionDelay
Delay before deleting an INVALID route.
Definition: ripng.h:388
std::map< uint32_t, uint8_t > m_interfaceMetrics
Map of interface metrics.
Definition: ripng.h:408
RipNg()
Definition: ripng.cc:46
void SendRouteRequest()
Send Routing Request on all interfaces.
Definition: ripng.cc:1240
Ptr< Ipv6 > m_ipv6
IPv6 reference.
Definition: ripng.h:382
Ptr< Ipv6Route > RouteOutput(Ptr< Packet > p, const Ipv6Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
Definition: ripng.cc:181
virtual void SetIpv6(Ptr< Ipv6 > ipv6)
Typically, invoked directly or indirectly from ns3::Ipv6::SetRoutingProtocol.
Definition: ripng.cc:449
Routes m_routes
the forwarding table for network.
Definition: ripng.h:381
std::set< uint32_t > GetInterfaceExclusions() const
Get the set of interface excluded from the protocol.
Definition: ripng.cc:1206
void SendTriggeredRouteUpdate()
Send Triggered Routing Updates on all interfaces.
Definition: ripng.cc:1161
bool RouteInput(Ptr< const Packet > p, const Ipv6Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
Definition: ripng.cc:211
void HandleRequests(RipNgHeader hdr, Ipv6Address senderAddress, uint16_t senderPort, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIPng requests.
Definition: ripng.cc:760
Ptr< UniformRandomVariable > m_rng
Rng stream.
Definition: ripng.h:405
void HandleResponses(RipNgHeader hdr, Ipv6Address senderAddress, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIPng responses.
Definition: ripng.cc:925
void InvalidateRoute(RipNgRoutingTableEntry *route)
Invalidate a route.
Definition: ripng.cc:667
void Receive(Ptr< Socket > socket)
Receive RIPng packets.
Definition: ripng.cc:706
void AddDefaultRouteTo(Ipv6Address nextHop, uint32_t interface)
Add a default route to the router through the nextHop located on interface.
Definition: ripng.cc:1273
Time m_timeoutDelay
Delay before invalidating a route.
Definition: ripng.h:387
void SendUnsolicitedRouteUpdate(void)
Send Unsolicited Routing Updates on all interfaces.
Definition: ripng.cc:1191
virtual ~RipNg()
Definition: ripng.cc:52
RipNg Routing Table Entry.
Definition: ripng.h:64
Status_e GetRouteStatus(void) const
Get the route status.
Definition: ripng.cc:1344
bool m_changed
route has been updated
Definition: ripng.h:155
uint16_t m_tag
route tag
Definition: ripng.h:152
uint8_t GetRouteMetric(void) const
Get the route metric.
Definition: ripng.cc:1330
void SetRouteTag(uint16_t routeTag)
Set the route tag.
Definition: ripng.cc:1307
uint16_t GetRouteTag(void) const
Get the route tag.
Definition: ripng.cc:1316
RipNgRoutingTableEntry(void)
Definition: ripng.cc:1285
void SetRouteMetric(uint8_t routeMetric)
Set the route metric.
Definition: ripng.cc:1321
uint8_t m_metric
route metric
Definition: ripng.h:153
bool IsRouteChanged(void) const
Get the route changed status.
Definition: ripng.cc:1354
Status_e m_status
route status
Definition: ripng.h:154
void SetRouteChanged(bool changed)
Set the route as changed.
Definition: ripng.cc:1349
Status_e
Route status.
Definition: ripng.h:70
@ RIPNG_INVALID
Definition: ripng.h:72
@ RIPNG_VALID
Definition: ripng.h:71
virtual ~RipNgRoutingTableEntry()
Definition: ripng.cc:1302
void SetRouteStatus(Status_e status)
Set the route status.
Definition: ripng.cc:1335
RipNg Routing Table Entry (RTE) - see RFC 2080
Definition: ripng-header.h:39
void SetPrefix(Ipv6Address prefix)
Set the prefix.
Definition: ripng-header.cc:85
void SetPrefixLen(uint8_t prefixLen)
Set the prefix length.
Definition: ripng-header.cc:95
void SetRouteMetric(uint8_t routeMetric)
Set the route metric.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
Definition: ripng-header.cc:55
void SetRouteTag(uint16_t routeTag)
Set the route tag.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:204
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
Definition: socket.cc:358
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
virtual int Close(void)=0
Close a socket.
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
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:71
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
@ ERROR_NOROUTETOHOST
Definition: socket.h:93
@ ERROR_NOTERROR
Definition: socket.h:83
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:551
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer.
Definition: socket.h:1165
void SetHopLimit(uint8_t hopLimit)
Set the tag's Hop Limit.
Definition: socket.cc:665
uint8_t GetHopLimit(void) const
Get the tag's Hop Limit.
Definition: socket.cc:671
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:109
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:432
AttributeValue implementation for Time.
Definition: nstime.h:1308
a unique identifier for an interface.
Definition: type-id.h:59
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:829
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Packet header for UDP packets.
Definition: udp-header.h:40
virtual uint32_t GetSerializedSize(void) const
Definition: udp-header.cc:178
Hold an unsigned integer type.
Definition: uinteger.h:44
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition: enum.h:205
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1309
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:45
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Definition: first.py:1
address
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:536
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:162
Definition: second.py:1
#define RIPNG_ALL_NODE
Definition: ripng.cc:37
#define RIPNG_PORT
Definition: ripng.cc:38