17#include "ns3/assert.h"
22#include "ns3/random-variable-stream.h"
23#include "ns3/simulator.h"
24#include "ns3/uinteger.h"
28#define RIPNG_ALL_NODE "ff02::9"
40 m_splitHorizonStrategy(
RipNg::POISON_REVERSE),
56 .SetGroupName(
"Internet")
57 .AddConstructor<
RipNg>()
58 .AddAttribute(
"UnsolicitedRoutingUpdate",
59 "The time between two Unsolicited Routing Updates.",
63 .AddAttribute(
"StartupDelay",
64 "Maximum random delay for protocol startup (send route requests).",
68 .AddAttribute(
"TimeoutDelay",
69 "The delay to invalidate a route.",
73 .AddAttribute(
"GarbageCollectionDelay",
74 "The delay to delete an expired route.",
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.",
98 .AddAttribute(
"LinkDownValue",
99 "Value for link down in count to infinity.",
111 m_rng->SetStream(stream);
134 m_ipv6->SetForwarding(
i,
true);
142 NS_LOG_LOGIC(
"RIPng: adding socket to " << address.GetAddress());
147 socket->BindToNetDevice(
m_ipv6->GetNetDevice(
i));
151 socket->SetIpv6RecvHopLimit(
true);
152 socket->SetRecvPktInfo(
true);
247 NS_LOG_LOGIC(
"Dropping packet not for me and with src or dst LinkLocal");
271 NS_LOG_LOGIC(
"Found unicast destination - calling unicast callback");
277 NS_LOG_LOGIC(
"Did not find unicast destination - returning false");
307 if (
iter->second ==
i)
318 m_ipv6->SetForwarding(
i,
true);
328 NS_LOG_LOGIC(
"RIPng: adding sending socket to " << address.GetAddress());
333 socket->BindToNetDevice(
m_ipv6->GetNetDevice(
i));
336 socket->SetIpv6RecvHopLimit(
true);
337 socket->SetRecvPktInfo(
true);
368 if (
it->first->GetInterface() == interface)
376 NS_LOG_INFO(
"Checking socket for interface " << interface);
377 if (
iter->second == interface)
379 NS_LOG_INFO(
"Removed socket for interface " << interface);
380 iter->first->Close();
397 if (!
m_ipv6->IsUp(interface))
423 if (!
m_ipv6->IsUp(interface))
440 if (
it->first->GetInterface() ==
interface &&
it->first->IsNetwork() &&
485 for (
i = 0;
i <
m_ipv6->GetNInterfaces();
i++)
503 std::ostream* os = stream->GetStream();
504 *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
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;
512 *os <<
"Destination Next Hop Flag Met Ref Use If"
521 std::ostringstream
dest;
522 std::ostringstream
gw;
523 std::ostringstream mask;
524 std::ostringstream flags;
527 << int(
route->GetDestNetworkPrefix().GetPrefixLength());
528 *os << std::setw(31) <<
dest.str();
530 *os << std::setw(27) <<
gw.str();
536 else if (
route->IsGateway())
540 *os << std::setw(5) << flags.str();
541 *os << std::setw(4) << int(
route->GetRouteMetric());
554 *os <<
route->GetInterface();
581 iter->first->Close();
606 "Try to send on link-local multicast address, and no interface index is given!");
609 m_ipv6->SourceAddressSelection(
m_ipv6->GetInterfaceForDevice(interface), dst));
612 rtentry->SetOutputDevice(interface);
633 if (!interface || interface ==
m_ipv6->GetNetDevice(
j->GetInterface()))
655 if (!
route->GetDest().IsAny())
664 route->GetPrefixToUse().IsAny() ? dst :
route->GetPrefixToUse()));
679 <<
rtentry->GetGateway() <<
") at the end");
695 NS_LOG_WARN(
"Ripng::AddNetworkRouteTo - Next hop should be link-local");
700 route->SetRouteMetric(1);
702 route->SetRouteChanged(
true);
713 route->SetRouteMetric(1);
715 route->SetRouteChanged(
true);
731 route->SetRouteChanged(
true);
732 if (
it->second.IsPending())
741 NS_ABORT_MSG(
"Ripng::InvalidateRoute - cannot find the route to update");
758 NS_ABORT_MSG(
"Ripng::DeleteRoute - cannot find the route to delete");
777 NS_ABORT_MSG(
"No incoming interface on RIPng message, aborting.");
787 NS_ABORT_MSG(
"No incoming Hop Count on RIPng message, aborting.");
799 packet->RemoveHeader(
hdr);
811 NS_LOG_LOGIC(
"Ignoring message with unknown command: " <<
int(
hdr.GetCommand()));
853 "HandleRequest - Impossible to find a socket to send the reply");
863 p->RemovePacketTag(
tag);
864 tag.SetHopLimit(255);
865 p->AddPacketTag(
tag);
876 rtIter->first->GetDestNetworkPrefix());
889 rte.SetPrefixLen(
rtIter->first->GetDestNetworkPrefix().GetPrefixLength());
896 rte.SetRouteMetric(
rtIter->first->GetRouteMetric());
898 rte.SetRouteTag(
rtIter->first->GetRouteTag());
910 p->RemoveHeader(
hdr);
914 if (
hdr.GetRteNumber() > 0)
947 p->RemovePacketTag(
tag);
948 tag.SetHopLimit(255);
949 p->AddPacketTag(
tag);
961 rtIter->first->GetDestNetworkPrefix());
972 iter->SetRouteMetric(
rtIter->first->GetRouteMetric());
973 iter->SetRouteTag(
rtIter->first->GetRouteTag());
983 iter->SetRouteTag(0);
1004 "Ignoring an update message from an excluded interface: " <<
incomingInterface);
1020 std::list<RipNgRte>
rtes =
hdr.GetRteList();
1027 NS_LOG_LOGIC(
"Ignoring an update message with malformed metric: "
1028 <<
int(
iter->GetRouteMetric()));
1031 if (
iter->GetPrefixLen() > 128)
1033 NS_LOG_LOGIC(
"Ignoring an update message with malformed prefix length: "
1034 <<
int(
iter->GetPrefixLen()));
1037 if (
iter->GetPrefix().IsLocalhost() ||
iter->GetPrefix().IsLinkLocal() ||
1038 iter->GetPrefix().IsMulticast())
1040 NS_LOG_LOGIC(
"Ignoring an update message with wrong prefixes: " <<
iter->GetPrefix());
1068 if (
it->first->GetDestNetwork() ==
rteAddr &&
1086 it->first->SetRouteTag(
iter->GetRouteTag());
1087 it->first->SetRouteChanged(
true);
1088 it->second.Cancel();
1095 else if (
rteMetric ==
it->first->GetRouteMetric())
1099 it->second.Cancel();
1116 route->SetRouteTag(
iter->GetRouteTag());
1117 route->SetRouteChanged(
true);
1120 it->second.Cancel();
1129 else if (
rteMetric >
it->first->GetRouteMetric() &&
1132 it->second.Cancel();
1137 it->first->SetRouteTag(
iter->GetRouteTag());
1138 it->first->SetRouteChanged(
true);
1139 it->second.Cancel();
1155 NS_LOG_LOGIC(
"Received a RTE with new route, adding.");
1164 route->SetRouteChanged(
true);
1190 uint16_t
mtu =
m_ipv6->GetMtu(interface);
1199 p->AddPacketTag(
tag);
1209 rtIter->first->GetDestNetworkPrefix());
1212 <<
int(
rtIter->first->IsRouteChanged()));
1218 (
rtIter->first->GetInterface() != interface));
1224 rte.SetPrefixLen(
rtIter->first->GetDestNetworkPrefix().GetPrefixLength());
1231 rte.SetRouteMetric(
rtIter->first->GetRouteMetric());
1233 rte.SetRouteTag(
rtIter->first->GetRouteTag());
1245 p->RemoveHeader(
hdr);
1249 if (
hdr.GetRteNumber() > 0)
1259 rtIter->first->SetRouteChanged(
false);
1270 NS_LOG_LOGIC(
"Skipping Triggered Update due to cooldown");
1334 return iter->second;
1357 p->RemovePacketTag(
tag);
1358 tag.SetHopLimit(255);
1359 p->AddPacketTag(
tag);
1366 rte.SetPrefixLen(0);
1403 m_status(RIPNG_INVALID),
1420 m_status(RIPNG_INVALID),
1432 m_status(RIPNG_INVALID),
1505 os <<
", metric: " << int(
rte.GetRouteMetric()) <<
", tag: " << int(
rte.GetRouteTag());
a polymophic address class
Hold variables of type enum.
An identifier for simulation events.
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
bool IsPending() const
This method is syntactic sugar for !IsExpired().
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.
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,...
virtual void DoInitialize()
Initialize() implementation.
virtual void DoDispose()
Destructor implementation.
Smart pointer class similar to boost::intrusive_ptr.
RIPng Routing Protocol, defined in RFC 2080.
Ptr< Socket > m_multicastRecvSocket
multicast receive socket
void NotifyInterfaceUp(uint32_t interface) override
Notify when specified interface goes UP.
void NotifyAddAddress(uint32_t interface, Ipv6InterfaceAddress address) override
Notify when specified interface add an address.
void NotifyAddRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero()) override
Notify a new route.
void DoSendRouteUpdate(bool periodic)
Send Routing Updates on all interfaces.
Time m_startupDelay
Random delay before protocol startup.
void DoDispose() override
Dispose this object.
SplitHorizonType_e m_splitHorizonStrategy
Split Horizon strategy.
@ SPLIT_HORIZON
Split Horizon.
@ POISON_REVERSE
Poison Reverse Split Horizon.
@ NO_SPLIT_HORIZON
No Split Horizon.
EventId m_nextTriggeredUpdate
Next Triggered Update event.
std::list< std::pair< RipNgRoutingTableEntry *, EventId > >::iterator RoutesI
Iterator for container for the network routes.
void NotifyRemoveAddress(uint32_t interface, Ipv6InterfaceAddress address) override
Notify when specified interface add an address.
Time m_minTriggeredUpdateDelay
Min cooldown delay after a Triggered Update.
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
Set the set of interface excluded from the protocol.
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.
EventId m_nextUnsolicitedUpdate
Next Unsolicited Update event.
uint8_t m_linkDown
Link down value.
Time m_maxTriggeredUpdateDelay
Max cooldown delay after a Triggered Update.
void DoInitialize() override
Start protocol operation.
bool m_initialized
flag to allow socket's late-creation.
SocketList m_unicastSocketList
list of sockets for unicast messages (socket, interface index)
uint8_t GetInterfaceMetric(uint32_t interface) const
Get the metric for an interface.
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)
Time m_unsolicitedUpdate
time between two Unsolicited Routing Updates
std::set< uint32_t > m_interfaceExclusions
Set of excluded interfaces.
void SetInterfaceMetric(uint32_t interface, uint8_t metric)
Set the metric for an interface.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void DeleteRoute(RipNgRoutingTableEntry *route)
Delete a route.
void AddNetworkRouteTo(Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
Add route to network.
Time m_garbageCollectionDelay
Delay before deleting an INVALID route.
std::map< uint32_t, uint8_t > m_interfaceMetrics
Map of interface metrics.
void SendRouteRequest()
Send Routing Request on all interfaces.
void NotifyInterfaceDown(uint32_t interface) override
Notify when specified interface goes DOWN.
Ptr< Ipv6 > m_ipv6
IPv6 reference.
Routes m_routes
the forwarding table for network.
std::set< uint32_t > GetInterfaceExclusions() const
Get the set of interface excluded from the protocol.
void SendTriggeredRouteUpdate()
Send Triggered Routing Updates on all interfaces.
void HandleRequests(RipNgHeader hdr, Ipv6Address senderAddress, uint16_t senderPort, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIPng requests.
Ptr< UniformRandomVariable > m_rng
Rng stream.
void HandleResponses(RipNgHeader hdr, Ipv6Address senderAddress, uint32_t incomingInterface, uint8_t hopLimit)
Handle RIPng responses.
void NotifyRemoveRoute(Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address::GetZero()) override
Notify route removing.
static TypeId GetTypeId()
Get the type ID.
void InvalidateRoute(RipNgRoutingTableEntry *route)
Invalidate a route.
void SetIpv6(Ptr< Ipv6 > ipv6) override
Typically, invoked directly or indirectly from ns3::Ipv6::SetRoutingProtocol.
void Receive(Ptr< Socket > socket)
Receive RIPng packets.
void AddDefaultRouteTo(Ipv6Address nextHop, uint32_t interface)
Add a default route to the router through the nextHop located on interface.
Time m_timeoutDelay
Delay before invalidating a route.
void SendUnsolicitedRouteUpdate()
Send Unsolicited Routing Updates on all interfaces.
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
Print the Routing Table entries.
Ptr< Ipv6Route > Lookup(Ipv6Address dest, bool setSource, Ptr< NetDevice >=nullptr)
Lookup in the forwarding table for destination.
RipNg Routing Table Entry.
bool IsRouteChanged() const
Get the route changed status.
uint16_t GetRouteTag() const
Get the route tag.
bool m_changed
route has been updated
void SetRouteTag(uint16_t routeTag)
Set the route tag.
uint8_t GetRouteMetric() const
Get the route metric.
void SetRouteMetric(uint8_t routeMetric)
Set the route metric.
uint8_t m_metric
route metric
Status_e m_status
route status
Status_e GetRouteStatus() const
Get the route status.
void SetRouteChanged(bool changed)
Set the route as changed.
~RipNgRoutingTableEntry() override
void SetRouteStatus(Status_e status)
Set the route status.
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.
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
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...
virtual int Close()=0
Close a socket.
SocketErrno
Enumeration of the possible errors returned by a socket.
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.
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer.
void SetHopLimit(uint8_t hopLimit)
Set the tag's Hop Limit.
Simulation virtual time values and global simulation resolution.
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Unit
The unit to use to interpret a number representing time.
AttributeValue implementation for Time.
a unique identifier for an interface.
static TypeId LookupByName(std::string name)
Get a TypeId by name.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#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.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Time Now()
create an ns3::Time instance which contains the current simulation time.
Time Seconds(double value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
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...
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
std::ostream & operator<<(std::ostream &os, const Angles &a)
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.