From d52260e3781ba74e9929f511fe54a99bcb9d3c43 Mon Sep 17 00:00:00 2001 From: Sebastien Vincent Date: Tue, 8 Sep 2009 18:45:44 +0200 Subject: [PATCH] Schedule unicast RA in response to RS. --- examples/icmpv6-redirect.cc | 18 +++++++++-- examples/radvd-two-prefix.cc | 5 +++- examples/simple-routing-ping6.cc | 4 +++ src/applications/radvd/radvd.cc | 51 ++++++++++++++++---------------- src/applications/radvd/radvd.h | 7 +++-- 5 files changed, 54 insertions(+), 31 deletions(-) diff --git a/examples/icmpv6-redirect.cc b/examples/icmpv6-redirect.cc index c70150445..3ad79a68c 100644 --- a/examples/icmpv6-redirect.cc +++ b/examples/icmpv6-redirect.cc @@ -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& n, Ipv6Address dst, Ipv6Address nextHop, uint32_t interface) { Ptr routing = 0; @@ -88,7 +101,6 @@ class StackHelper Ptr ipv6 = n->GetObject (); routing = routingHelper.GetStaticRouting (ipv6); - routing->AddHostRouteTo (dst, nextHop, interface); } }; diff --git a/examples/radvd-two-prefix.cc b/examples/radvd-two-prefix.cc index 592c05ba1..f382ba52c 100644 --- a/examples/radvd-two-prefix.cc +++ b/examples/radvd-two-prefix.cc @@ -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 diff --git a/examples/simple-routing-ping6.cc b/examples/simple-routing-ping6.cc index 480b72b33..f1c2ad800 100644 --- a/examples/simple-routing-ping6.cc +++ b/examples/simple-routing-ping6.cc @@ -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: diff --git a/src/applications/radvd/radvd.cc b/src/applications/radvd/radvd.cc index c984d0c14..961504b4b 100644 --- a/src/applications/radvd/radvd.cc +++ b/src/applications/radvd/radvd.cc @@ -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 routerInterface) m_configurations.push_back (routerInterface); } -void Radvd::ScheduleTransmit (Time dt, Ptr config, EventId& eventId) +void Radvd::ScheduleTransmit (Time dt, Ptr 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 config, Ipv6Address dst) +void Radvd::Send (Ptr 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 config, Ipv6Address dst) NS_LOG_LOGIC ("Send RA"); m_socket->Send (p, 0); - UniformVariable rnd; - uint64_t delay = static_cast (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 (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) @@ -236,31 +240,28 @@ void Radvd::HandleRead (Ptr 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 (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 (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 (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 (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; diff --git a/src/applications/radvd/radvd.h b/src/applications/radvd/radvd.h index e3e40dc8f..c301c636c 100644 --- a/src/applications/radvd/radvd.h +++ b/src/applications/radvd/radvd.h @@ -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 config, EventId& eventId); + void ScheduleTransmit (Time dt, Ptr 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 config, Ipv6Address dst = Ipv6Address::GetAllNodesMulticast ()); + void Send (Ptr config, Ipv6Address dst = Ipv6Address::GetAllNodesMulticast (), bool reschedule = false); /** * \brief Handle received packet, especially router solicitation