Schedule unicast RA in response to RS.
1.1 --- a/examples/icmpv6-redirect.cc Tue Sep 08 18:40:47 2009 +0200
1.2 +++ b/examples/icmpv6-redirect.cc Tue Sep 08 18:45:44 2009 +0200
1.3 @@ -51,6 +51,10 @@
1.4
1.5 NS_LOG_COMPONENT_DEFINE ("Icmpv6RedirectExample");
1.6
1.7 +/**
1.8 + * \class StackHelper
1.9 + * \brief Helper to set or get some IPv6 information about nodes.
1.10 + */
1.11 class StackHelper
1.12 {
1.13 public:
1.14 @@ -69,7 +73,7 @@
1.15 routing = routingHelper.GetStaticRouting (ipv6);
1.16
1.17 std::cout << "Routing table of " << n << " : " << std::endl;
1.18 - std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << std::endl;
1.19 + std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << "Prefix to use" << std::endl;
1.20
1.21 nbRoutes = routing->GetNRoutes ();
1.22 for(uint32_t i = 0 ; i < nbRoutes ; i++)
1.23 @@ -77,10 +81,19 @@
1.24 route = routing->GetRoute (i);
1.25 std::cout << route.GetDest () << "\t"
1.26 << route.GetGateway () << "\t"
1.27 - << route.GetInterface () << "\t" << std::endl;
1.28 + << route.GetInterface () << "\t"
1.29 + << route.GetPrefixToUse () << "\t"
1.30 + << std::endl;
1.31 }
1.32 }
1.33
1.34 + /**
1.35 + * \brief Add an host route.
1.36 + * \param n node
1.37 + * \param dst destination address
1.38 + * \param nextHop next hop for destination
1.39 + * \param interface output interface
1.40 + */
1.41 inline void AddHostRouteTo (Ptr<Node>& n, Ipv6Address dst, Ipv6Address nextHop, uint32_t interface)
1.42 {
1.43 Ptr<Ipv6StaticRouting> routing = 0;
1.44 @@ -88,7 +101,6 @@
1.45 Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
1.46
1.47 routing = routingHelper.GetStaticRouting (ipv6);
1.48 -
1.49 routing->AddHostRouteTo (dst, nextHop, interface);
1.50 }
1.51 };
2.1 --- a/examples/radvd-two-prefix.cc Tue Sep 08 18:40:47 2009 +0200
2.2 +++ b/examples/radvd-two-prefix.cc Tue Sep 08 18:45:44 2009 +0200
2.3 @@ -46,10 +46,13 @@
2.4
2.5 NS_LOG_COMPONENT_DEFINE ("RadvdExample");
2.6
2.7 +/**
2.8 + * \class StackHelper
2.9 + * \brief Helper to set or get some IPv6 information about nodes.
2.10 + */
2.11 class StackHelper
2.12 {
2.13 public:
2.14 -
2.15 /**
2.16 * \brief Add an address to a IPv6 node.
2.17 * \param n node
3.1 --- a/examples/simple-routing-ping6.cc Tue Sep 08 18:40:47 2009 +0200
3.2 +++ b/examples/simple-routing-ping6.cc Tue Sep 08 18:45:44 2009 +0200
3.3 @@ -39,6 +39,10 @@
3.4
3.5 NS_LOG_COMPONENT_DEFINE ("SimpleRoutingPing6Example");
3.6
3.7 +/**
3.8 + * \class StackHelper
3.9 + * \brief Helper to set or get some IPv6 information about nodes.
3.10 + */
3.11 class StackHelper
3.12 {
3.13 public:
4.1 --- a/src/applications/radvd/radvd.cc Tue Sep 08 18:40:47 2009 +0200
4.2 +++ b/src/applications/radvd/radvd.cc Tue Sep 08 18:45:44 2009 +0200
4.3 @@ -94,7 +94,7 @@
4.4 for (RadvdInterfaceListCI it = m_configurations.begin () ; it != m_configurations.end () ; it++)
4.5 {
4.6 m_eventIds[(*it)->GetInterface ()] = EventId ();
4.7 - ScheduleTransmit (Seconds (0.), (*it), m_eventIds[(*it)->GetInterface ()]);
4.8 + ScheduleTransmit (Seconds (0.), (*it), m_eventIds[(*it)->GetInterface ()], Ipv6Address::GetAllNodesMulticast (), true);
4.9 }
4.10 }
4.11
4.12 @@ -119,13 +119,13 @@
4.13 m_configurations.push_back (routerInterface);
4.14 }
4.15
4.16 -void Radvd::ScheduleTransmit (Time dt, Ptr<RadvdInterface> config, EventId& eventId)
4.17 +void Radvd::ScheduleTransmit (Time dt, Ptr<RadvdInterface> config, EventId& eventId, Ipv6Address dst, bool reschedule)
4.18 {
4.19 NS_LOG_FUNCTION (this << dt);
4.20 - eventId = Simulator::Schedule (dt, &Radvd::Send, this, config, Ipv6Address::GetAllNodesMulticast ());
4.21 + eventId = Simulator::Schedule (dt, &Radvd::Send, this, config, dst, reschedule);
4.22 }
4.23
4.24 -void Radvd::Send (Ptr<RadvdInterface> config, Ipv6Address dst)
4.25 +void Radvd::Send (Ptr<RadvdInterface> config, Ipv6Address dst, bool reschedule)
4.26 {
4.27 NS_LOG_FUNCTION (this << dst);
4.28 NS_ASSERT (m_eventIds[config->GetInterface ()].IsExpired ());
4.29 @@ -212,10 +212,14 @@
4.30 NS_LOG_LOGIC ("Send RA");
4.31 m_socket->Send (p, 0);
4.32
4.33 - UniformVariable rnd;
4.34 - uint64_t delay = static_cast<uint64_t> (rnd.GetValue (config->GetMinRtrAdvInterval (), config->GetMaxRtrAdvInterval ()) + 0.5);
4.35 - Time t = MilliSeconds (delay);
4.36 - ScheduleTransmit (t, config, m_eventIds[config->GetInterface ()]);
4.37 + if (reschedule)
4.38 + {
4.39 + UniformVariable rnd;
4.40 + uint64_t delay = static_cast<uint64_t> (rnd.GetValue (config->GetMinRtrAdvInterval (), config->GetMaxRtrAdvInterval ()) + 0.5);
4.41 + NS_LOG_INFO ("Reschedule in " << delay);
4.42 + Time t = MilliSeconds (delay);
4.43 + ScheduleTransmit (t, config, m_eventIds[config->GetInterface ()], Ipv6Address::GetAllNodesMulticast (), reschedule);
4.44 + }
4.45 }
4.46
4.47 void Radvd::HandleRead (Ptr<Socket> socket)
4.48 @@ -236,31 +240,28 @@
4.49 Time t;
4.50
4.51 packet->RemoveHeader (hdr);
4.52 -
4.53 switch (*packet->PeekData ())
4.54 {
4.55 case Icmpv6Header::ICMPV6_ND_ROUTER_SOLICITATION:
4.56 - /* send RA in response of a RS */
4.57 packet->RemoveHeader (rsHdr);
4.58 NS_LOG_INFO ("Received ICMPv6 Router Solicitation from " << hdr.GetSourceAddress () << " code = " << (uint32_t)rsHdr.GetCode ());
4.59
4.60 - delay = static_cast<uint64_t> (rnd.GetValue (0, MAX_RA_DELAY_TIME) + 0.5);
4.61 - t = Simulator::Now () + MilliSeconds (delay);
4.62 -
4.63 -#if 0
4.64 - NS_LOG_INFO ("schedule new RA : " << t.GetTimeStep () << " next scheduled RA" << (int64_t)m_sendEvent.GetTs ());
4.65 -
4.66 - if (t.GetTimeStep () < static_cast<int64_t> (m_sendEvent.GetTs ()))
4.67 + /* XXX advertise just prefix(es) for the interface not all */
4.68 + for (RadvdInterfaceListCI it = m_configurations.begin () ; it != m_configurations.end () ; it++)
4.69 {
4.70 - /* send multicast RA */
4.71 - /* maybe replace this by a unicast RA (it is a SHOULD in the RFC) */
4.72 - NS_LOG_INFO ("Respond to RS");
4.73 - /* XXX advertise just the prefix for the interface not all */
4.74 - t = MilliSeconds (delay);
4.75 - /* XXX schedule packet send */
4.76 - /* ScheduleTransmit (t); */
4.77 + /* calculate minimum delay between RA */
4.78 + delay = static_cast<uint64_t> (rnd.GetValue (0, MAX_RA_DELAY_TIME) + 0.5);
4.79 + t = Simulator::Now () + MilliSeconds (delay); /* absolute time of solicited RA */
4.80 +
4.81 + /* if our solicited RA is before the next periodic RA, we schedule it */
4.82 + if (t.GetTimeStep () < static_cast<int64_t> (m_eventIds[(*it)->GetInterface ()].GetTs ()))
4.83 + {
4.84 + NS_LOG_INFO ("schedule new RA");
4.85 + EventId ei;
4.86 +
4.87 + ScheduleTransmit (MilliSeconds (delay), (*it), ei, address.GetIpv6 (), false);
4.88 + }
4.89 }
4.90 -#endif
4.91 break;
4.92 default:
4.93 break;
5.1 --- a/src/applications/radvd/radvd.h Tue Sep 08 18:40:47 2009 +0200
5.2 +++ b/src/applications/radvd/radvd.h Tue Sep 08 18:45:44 2009 +0200
5.3 @@ -103,15 +103,18 @@
5.4 * \param dt interval between packet
5.5 * \param config interface configuration
5.6 * \param eventId event ID associated
5.7 + * \param dst IPv6 destination address
5.8 + * \param reschedule if true another send will be reschedule (periodic)
5.9 */
5.10 - void ScheduleTransmit (Time dt, Ptr<RadvdInterface> config, EventId& eventId);
5.11 + void ScheduleTransmit (Time dt, Ptr<RadvdInterface> config, EventId& eventId, Ipv6Address dst = Ipv6Address::GetAllNodesMulticast (), bool reschedule = false);
5.12
5.13 /**
5.14 * \brief Send a packet.
5.15 * \param config interface configuration
5.16 * \param dst destination address (default ff02::1)
5.17 + * \param reschedule if true another send will be reschedule (periodic)
5.18 */
5.19 - void Send (Ptr<RadvdInterface> config, Ipv6Address dst = Ipv6Address::GetAllNodesMulticast ());
5.20 + void Send (Ptr<RadvdInterface> config, Ipv6Address dst = Ipv6Address::GetAllNodesMulticast (), bool reschedule = false);
5.21
5.22 /**
5.23 * \brief Handle received packet, especially router solicitation