Schedule unicast RA in response to RS.
This commit is contained in:
@@ -51,6 +51,10 @@ using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("Icmpv6RedirectExample");
|
||||
|
||||
/**
|
||||
* \class StackHelper
|
||||
* \brief Helper to set or get some IPv6 information about nodes.
|
||||
*/
|
||||
class StackHelper
|
||||
{
|
||||
public:
|
||||
@@ -69,7 +73,7 @@ class StackHelper
|
||||
routing = routingHelper.GetStaticRouting (ipv6);
|
||||
|
||||
std::cout << "Routing table of " << n << " : " << std::endl;
|
||||
std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << std::endl;
|
||||
std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << "Prefix to use" << std::endl;
|
||||
|
||||
nbRoutes = routing->GetNRoutes ();
|
||||
for(uint32_t i = 0 ; i < nbRoutes ; i++)
|
||||
@@ -77,10 +81,19 @@ class StackHelper
|
||||
route = routing->GetRoute (i);
|
||||
std::cout << route.GetDest () << "\t"
|
||||
<< route.GetGateway () << "\t"
|
||||
<< route.GetInterface () << "\t" << std::endl;
|
||||
<< route.GetInterface () << "\t"
|
||||
<< route.GetPrefixToUse () << "\t"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add an host route.
|
||||
* \param n node
|
||||
* \param dst destination address
|
||||
* \param nextHop next hop for destination
|
||||
* \param interface output interface
|
||||
*/
|
||||
inline void AddHostRouteTo (Ptr<Node>& n, Ipv6Address dst, Ipv6Address nextHop, uint32_t interface)
|
||||
{
|
||||
Ptr<Ipv6StaticRouting> routing = 0;
|
||||
@@ -88,7 +101,6 @@ class StackHelper
|
||||
Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
|
||||
|
||||
routing = routingHelper.GetStaticRouting (ipv6);
|
||||
|
||||
routing->AddHostRouteTo (dst, nextHop, interface);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -46,10 +46,13 @@ using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("RadvdExample");
|
||||
|
||||
/**
|
||||
* \class StackHelper
|
||||
* \brief Helper to set or get some IPv6 information about nodes.
|
||||
*/
|
||||
class StackHelper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Add an address to a IPv6 node.
|
||||
* \param n node
|
||||
|
||||
@@ -39,6 +39,10 @@ using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("SimpleRoutingPing6Example");
|
||||
|
||||
/**
|
||||
* \class StackHelper
|
||||
* \brief Helper to set or get some IPv6 information about nodes.
|
||||
*/
|
||||
class StackHelper
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -94,7 +94,7 @@ void Radvd::StartApplication ()
|
||||
for (RadvdInterfaceListCI it = m_configurations.begin () ; it != m_configurations.end () ; it++)
|
||||
{
|
||||
m_eventIds[(*it)->GetInterface ()] = EventId ();
|
||||
ScheduleTransmit (Seconds (0.), (*it), m_eventIds[(*it)->GetInterface ()]);
|
||||
ScheduleTransmit (Seconds (0.), (*it), m_eventIds[(*it)->GetInterface ()], Ipv6Address::GetAllNodesMulticast (), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,13 +119,13 @@ void Radvd::AddConfiguration (Ptr<RadvdInterface> routerInterface)
|
||||
m_configurations.push_back (routerInterface);
|
||||
}
|
||||
|
||||
void Radvd::ScheduleTransmit (Time dt, Ptr<RadvdInterface> config, EventId& eventId)
|
||||
void Radvd::ScheduleTransmit (Time dt, Ptr<RadvdInterface> config, EventId& eventId, Ipv6Address dst, bool reschedule)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dt);
|
||||
eventId = Simulator::Schedule (dt, &Radvd::Send, this, config, Ipv6Address::GetAllNodesMulticast ());
|
||||
eventId = Simulator::Schedule (dt, &Radvd::Send, this, config, dst, reschedule);
|
||||
}
|
||||
|
||||
void Radvd::Send (Ptr<RadvdInterface> config, Ipv6Address dst)
|
||||
void Radvd::Send (Ptr<RadvdInterface> config, Ipv6Address dst, bool reschedule)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dst);
|
||||
NS_ASSERT (m_eventIds[config->GetInterface ()].IsExpired ());
|
||||
@@ -212,10 +212,14 @@ void Radvd::Send (Ptr<RadvdInterface> config, Ipv6Address dst)
|
||||
NS_LOG_LOGIC ("Send RA");
|
||||
m_socket->Send (p, 0);
|
||||
|
||||
UniformVariable rnd;
|
||||
uint64_t delay = static_cast<uint64_t> (rnd.GetValue (config->GetMinRtrAdvInterval (), config->GetMaxRtrAdvInterval ()) + 0.5);
|
||||
Time t = MilliSeconds (delay);
|
||||
ScheduleTransmit (t, config, m_eventIds[config->GetInterface ()]);
|
||||
if (reschedule)
|
||||
{
|
||||
UniformVariable rnd;
|
||||
uint64_t delay = static_cast<uint64_t> (rnd.GetValue (config->GetMinRtrAdvInterval (), config->GetMaxRtrAdvInterval ()) + 0.5);
|
||||
NS_LOG_INFO ("Reschedule in " << delay);
|
||||
Time t = MilliSeconds (delay);
|
||||
ScheduleTransmit (t, config, m_eventIds[config->GetInterface ()], Ipv6Address::GetAllNodesMulticast (), reschedule);
|
||||
}
|
||||
}
|
||||
|
||||
void Radvd::HandleRead (Ptr<Socket> socket)
|
||||
@@ -236,31 +240,28 @@ void Radvd::HandleRead (Ptr<Socket> socket)
|
||||
Time t;
|
||||
|
||||
packet->RemoveHeader (hdr);
|
||||
|
||||
switch (*packet->PeekData ())
|
||||
{
|
||||
case Icmpv6Header::ICMPV6_ND_ROUTER_SOLICITATION:
|
||||
/* send RA in response of a RS */
|
||||
packet->RemoveHeader (rsHdr);
|
||||
NS_LOG_INFO ("Received ICMPv6 Router Solicitation from " << hdr.GetSourceAddress () << " code = " << (uint32_t)rsHdr.GetCode ());
|
||||
|
||||
delay = static_cast<uint64_t> (rnd.GetValue (0, MAX_RA_DELAY_TIME) + 0.5);
|
||||
t = Simulator::Now () + MilliSeconds (delay);
|
||||
|
||||
#if 0
|
||||
NS_LOG_INFO ("schedule new RA : " << t.GetTimeStep () << " next scheduled RA" << (int64_t)m_sendEvent.GetTs ());
|
||||
|
||||
if (t.GetTimeStep () < static_cast<int64_t> (m_sendEvent.GetTs ()))
|
||||
/* XXX advertise just prefix(es) for the interface not all */
|
||||
for (RadvdInterfaceListCI it = m_configurations.begin () ; it != m_configurations.end () ; it++)
|
||||
{
|
||||
/* send multicast RA */
|
||||
/* maybe replace this by a unicast RA (it is a SHOULD in the RFC) */
|
||||
NS_LOG_INFO ("Respond to RS");
|
||||
/* XXX advertise just the prefix for the interface not all */
|
||||
t = MilliSeconds (delay);
|
||||
/* XXX schedule packet send */
|
||||
/* ScheduleTransmit (t); */
|
||||
/* calculate minimum delay between RA */
|
||||
delay = static_cast<uint64_t> (rnd.GetValue (0, MAX_RA_DELAY_TIME) + 0.5);
|
||||
t = Simulator::Now () + MilliSeconds (delay); /* absolute time of solicited RA */
|
||||
|
||||
/* if our solicited RA is before the next periodic RA, we schedule it */
|
||||
if (t.GetTimeStep () < static_cast<int64_t> (m_eventIds[(*it)->GetInterface ()].GetTs ()))
|
||||
{
|
||||
NS_LOG_INFO ("schedule new RA");
|
||||
EventId ei;
|
||||
|
||||
ScheduleTransmit (MilliSeconds (delay), (*it), ei, address.GetIpv6 (), false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -103,15 +103,18 @@ class Radvd : public Application
|
||||
* \param dt interval between packet
|
||||
* \param config interface configuration
|
||||
* \param eventId event ID associated
|
||||
* \param dst IPv6 destination address
|
||||
* \param reschedule if true another send will be reschedule (periodic)
|
||||
*/
|
||||
void ScheduleTransmit (Time dt, Ptr<RadvdInterface> config, EventId& eventId);
|
||||
void ScheduleTransmit (Time dt, Ptr<RadvdInterface> config, EventId& eventId, Ipv6Address dst = Ipv6Address::GetAllNodesMulticast (), bool reschedule = false);
|
||||
|
||||
/**
|
||||
* \brief Send a packet.
|
||||
* \param config interface configuration
|
||||
* \param dst destination address (default ff02::1)
|
||||
* \param reschedule if true another send will be reschedule (periodic)
|
||||
*/
|
||||
void Send (Ptr<RadvdInterface> config, Ipv6Address dst = Ipv6Address::GetAllNodesMulticast ());
|
||||
void Send (Ptr<RadvdInterface> config, Ipv6Address dst = Ipv6Address::GetAllNodesMulticast (), bool reschedule = false);
|
||||
|
||||
/**
|
||||
* \brief Handle received packet, especially router solicitation
|
||||
|
||||
Reference in New Issue
Block a user