View | Details | Raw Unified | Return to bug 2016
Collapse All | Expand All

(-)a/examples/ipv6/radvd.cc (-1 / +6 lines)
 Lines 115-124    Link Here 
115
115
116
  /* radvd configuration */
116
  /* radvd configuration */
117
  RadvdHelper radvdHelper;
117
  RadvdHelper radvdHelper;
118
118
  /* R interface (n0 - R) */
119
  /* R interface (n0 - R) */
119
  radvdHelper.AddAnnouncedPrefix(iic1.GetInterfaceIndex (1), Ipv6Address("2001:1::0"), 64);
120
  /* n0 will receive unsolicited (periodic) RA */
121
  radvdHelper.AddAnnouncedPrefix (iic1.GetInterfaceIndex (1), Ipv6Address("2001:1::0"), 64);
122
120
  /* R interface (R - n1) */
123
  /* R interface (R - n1) */
124
  /* n1 will have to use RS, as RA are not sent automatically */
121
  radvdHelper.AddAnnouncedPrefix(iic2.GetInterfaceIndex (1), Ipv6Address("2001:2::0"), 64);
125
  radvdHelper.AddAnnouncedPrefix(iic2.GetInterfaceIndex (1), Ipv6Address("2001:2::0"), 64);
126
  radvdHelper.GetRadvdInterface (iic2.GetInterfaceIndex (1))->SetSendAdvert (false);
122
127
123
  ApplicationContainer radvdApps = radvdHelper.Install (r);
128
  ApplicationContainer radvdApps = radvdHelper.Install (r);
124
  radvdApps.Start (Seconds (1.0));
129
  radvdApps.Start (Seconds (1.0));
(-)a/src/applications/model/radvd.cc (-35 / +75 lines)
 Lines 21-26    Link Here 
21
 */
21
 */
22
22
23
#include "ns3/log.h"
23
#include "ns3/log.h"
24
#include "ns3/abort.h"
24
#include "ns3/ipv6-address.h"
25
#include "ns3/ipv6-address.h"
25
#include "ns3/nstime.h"
26
#include "ns3/nstime.h"
26
#include "ns3/simulator.h"
27
#include "ns3/simulator.h"
 Lines 29-35    Link Here 
29
#include "ns3/uinteger.h"
30
#include "ns3/uinteger.h"
30
#include "ns3/inet6-socket-address.h"
31
#include "ns3/inet6-socket-address.h"
31
#include "ns3/ipv6.h"
32
#include "ns3/ipv6.h"
33
#include "ns3/ipv6-l3-protocol.h"
34
#include "ns3/ipv6-interface.h"
32
#include "ns3/ipv6-raw-socket-factory.h"
35
#include "ns3/ipv6-raw-socket-factory.h"
36
#include "ns3/ipv6-packet-info-tag.h"
33
#include "ns3/ipv6-header.h"
37
#include "ns3/ipv6-header.h"
34
#include "ns3/icmpv6-header.h"
38
#include "ns3/icmpv6-header.h"
35
#include "ns3/string.h"
39
#include "ns3/string.h"
 Lines 71-82    Link Here 
71
      *it = 0;
75
      *it = 0;
72
    }
76
    }
73
  m_configurations.clear ();
77
  m_configurations.clear ();
74
  m_socket = 0;
78
  m_recvSocket = 0;
75
}
79
}
76
80
77
void Radvd::DoDispose ()
81
void Radvd::DoDispose ()
78
{
82
{
79
  NS_LOG_FUNCTION (this);
83
  NS_LOG_FUNCTION (this);
84
85
  m_recvSocket->Close ();
86
  m_recvSocket = 0;
87
88
  for (SocketMapI it = m_sendSockets.begin (); it != m_sendSockets.end (); ++it)
89
    {
90
      it->second->Close ();
91
      it->second = 0;
92
    }
93
80
  Application::DoDispose ();
94
  Application::DoDispose ();
81
}
95
}
82
96
 Lines 84-106    Link Here 
84
{
98
{
85
  NS_LOG_FUNCTION (this);
99
  NS_LOG_FUNCTION (this);
86
100
87
  if (!m_socket)
101
  TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory");
102
103
  if (!m_recvSocket)
88
    {
104
    {
89
      TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory");
105
      m_recvSocket = Socket::CreateSocket (GetNode (), tid);
90
      m_socket = Socket::CreateSocket (GetNode (), tid);
91
106
92
      NS_ASSERT (m_socket);
107
      NS_ASSERT (m_recvSocket);
93
108
94
      /*    m_socket->Bind (Inet6SocketAddress (m_localAddress, 0)); */
109
      m_recvSocket->Bind (Inet6SocketAddress (Ipv6Address::GetAllRoutersMulticast (), 0));
95
      /*    m_socket->Connect (Inet6SocketAddress (Ipv6Address::GetAllNodesMulticast (), 0)); */
110
      m_recvSocket->SetAttribute ("Protocol", UintegerValue (Ipv6Header::IPV6_ICMPV6));
96
      m_socket->SetAttribute ("Protocol", UintegerValue (Ipv6Header::IPV6_ICMPV6));
111
      m_recvSocket->SetRecvCallback (MakeCallback (&Radvd::HandleRead, this));
97
      m_socket->SetRecvCallback (MakeCallback (&Radvd::HandleRead, this));
112
      m_recvSocket->ShutdownSend ();
113
      m_recvSocket->SetRecvPktInfo (true);
98
    }
114
    }
99
115
100
  for (RadvdInterfaceListCI it = m_configurations.begin (); it != m_configurations.end (); it++)
116
  for (RadvdInterfaceListCI it = m_configurations.begin (); it != m_configurations.end (); it++)
101
    {
117
    {
102
      m_eventIds[(*it)->GetInterface ()] = EventId ();
118
      if ((*it)->IsSendAdvert ())
103
      ScheduleTransmit (Seconds (0.), (*it), m_eventIds[(*it)->GetInterface ()], Ipv6Address::GetAllNodesMulticast (), true); 
119
        {
120
          m_eventIds[(*it)->GetInterface ()] = EventId ();
121
          ScheduleTransmit (Seconds (0.), (*it), m_eventIds[(*it)->GetInterface ()], Ipv6Address::GetAllNodesMulticast (), true);
122
        }
123
124
      Ptr<Ipv6L3Protocol> ipv6 = GetNode ()->GetObject<Ipv6L3Protocol> ();
125
      Ptr<Ipv6Interface> iFace = ipv6->GetInterface ((*it)->GetInterface ());
126
127
      m_sendSockets[(*it)->GetInterface ()] = Socket::CreateSocket (GetNode (), tid);
128
      m_sendSockets[(*it)->GetInterface ()]->Bind (Inet6SocketAddress (iFace->GetLinkLocalAddress ().GetAddress (), 0));
129
      m_sendSockets[(*it)->GetInterface ()]->SetAttribute ("Protocol", UintegerValue (Ipv6Header::IPV6_ICMPV6));
130
      m_sendSockets[(*it)->GetInterface ()]->ShutdownRecv ();
104
    }
131
    }
105
}
132
}
106
133
 Lines 108-116    Link Here 
108
{
135
{
109
  NS_LOG_FUNCTION (this);
136
  NS_LOG_FUNCTION (this);
110
137
111
  if (m_socket)
138
  if (m_recvSocket)
112
    {
139
    {
113
      m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
140
      m_recvSocket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
114
    }
141
    }
115
142
116
  for (EventIdMapI it = m_eventIds.begin (); it != m_eventIds.end (); ++it)
143
  for (EventIdMapI it = m_eventIds.begin (); it != m_eventIds.end (); ++it)
 Lines 143-159    Link Here 
143
void Radvd::Send (Ptr<RadvdInterface> config, Ipv6Address dst, bool reschedule)
170
void Radvd::Send (Ptr<RadvdInterface> config, Ipv6Address dst, bool reschedule)
144
{
171
{
145
  NS_LOG_FUNCTION (this << dst << reschedule);
172
  NS_LOG_FUNCTION (this << dst << reschedule);
146
  NS_ASSERT (m_eventIds[config->GetInterface ()].IsExpired ());
173
147
  Icmpv6RA raHdr;
174
  Icmpv6RA raHdr;
148
  Icmpv6OptionLinkLayerAddress llaHdr;
175
  Icmpv6OptionLinkLayerAddress llaHdr;
149
  Icmpv6OptionMtu mtuHdr;
176
  Icmpv6OptionMtu mtuHdr;
150
  Icmpv6OptionPrefixInformation prefixHdr;
177
  Icmpv6OptionPrefixInformation prefixHdr;
151
178
152
  if (m_eventIds.size () == 0)
153
    {
154
      return;
155
    }
156
157
  std::list<Ptr<RadvdPrefix> > prefixes = config->GetPrefixes ();
179
  std::list<Ptr<RadvdPrefix> > prefixes = config->GetPrefixes ();
158
  Ptr<Packet> p = Create<Packet> ();
180
  Ptr<Packet> p = Create<Packet> ();
159
  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
181
  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
 Lines 212-220    Link Here 
212
      p->AddHeader (prefixHdr);
234
      p->AddHeader (prefixHdr);
213
    }
235
    }
214
236
215
  Ipv6Address src = ipv6->GetAddress (config->GetInterface (), 0).GetAddress ();
237
  Address sockAddr;
216
  m_socket->Bind (Inet6SocketAddress (src, 0));
238
  m_sendSockets[config->GetInterface ()]->GetSockName (sockAddr);
217
  m_socket->Connect (Inet6SocketAddress (dst, 0));
239
  Ipv6Address src = Inet6SocketAddress::ConvertFrom (sockAddr).GetIpv6 ();
218
240
219
  /* as we know interface index that will be used to send RA and 
241
  /* as we know interface index that will be used to send RA and 
220
   * we always send RA with router's link-local address, we can 
242
   * we always send RA with router's link-local address, we can 
 Lines 231-238    Link Here 
231
  p->AddPacketTag (ttl);
253
  p->AddPacketTag (ttl);
232
254
233
  /* send RA */
255
  /* send RA */
234
  NS_LOG_LOGIC ("Send RA");
256
  NS_LOG_LOGIC ("Send RA to " << dst);
235
  m_socket->Send (p, 0);
257
  m_sendSockets[config->GetInterface ()]->SendTo (p, 0, Inet6SocketAddress (dst, 0));
236
258
237
  if (reschedule)
259
  if (reschedule)
238
    {
260
    {
 Lines 253-258    Link Here 
253
    {
275
    {
254
      if (Inet6SocketAddress::IsMatchingType (from))
276
      if (Inet6SocketAddress::IsMatchingType (from))
255
        {
277
        {
278
          Ipv6PacketInfoTag interfaceInfo;
279
          if (!packet->RemovePacketTag (interfaceInfo))
280
            {
281
              NS_ABORT_MSG ("No incoming interface on RADVD message, aborting.");
282
            }
283
          uint32_t incomingIf = interfaceInfo.GetRecvIf ();
284
          Ptr<NetDevice> dev = GetNode ()->GetDevice (incomingIf);
285
          Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
286
          uint32_t ipInterfaceIndex = ipv6->GetInterfaceForDevice (dev);
287
256
          Ipv6Header hdr;
288
          Ipv6Header hdr;
257
          Icmpv6RS rsHdr;
289
          Icmpv6RS rsHdr;
258
          Inet6SocketAddress address = Inet6SocketAddress::ConvertFrom (from);
290
          Inet6SocketAddress address = Inet6SocketAddress::ConvertFrom (from);
 Lines 269-288    Link Here 
269
              packet->RemoveHeader (rsHdr);
301
              packet->RemoveHeader (rsHdr);
270
              NS_LOG_INFO ("Received ICMPv6 Router Solicitation from " << hdr.GetSourceAddress () << " code = " << (uint32_t)rsHdr.GetCode ());
302
              NS_LOG_INFO ("Received ICMPv6 Router Solicitation from " << hdr.GetSourceAddress () << " code = " << (uint32_t)rsHdr.GetCode ());
271
303
272
              /* XXX advertise just prefix(es) for the interface not all */
273
              for (RadvdInterfaceListCI it = m_configurations.begin (); it != m_configurations.end (); it++)
304
              for (RadvdInterfaceListCI it = m_configurations.begin (); it != m_configurations.end (); it++)
274
                {
305
                {
275
                  /* calculate minimum delay between RA */
306
                  if (ipInterfaceIndex == (*it)->GetInterface ())
276
                  delay = static_cast<uint64_t> (m_jitter->GetValue (0, MAX_RA_DELAY_TIME) + 0.5); 
307
                    {
277
                  t = Simulator::Now () + MilliSeconds (delay); /* absolute time of solicited RA */
308
                      /* calculate minimum delay between RA */
309
                      delay = static_cast<uint64_t> (m_jitter->GetValue (0, MAX_RA_DELAY_TIME) + 0.5);
310
                      t = Simulator::Now () + MilliSeconds (delay); /* absolute time of solicited RA */
278
311
279
                  /* if our solicited RA is before the next periodic RA, we schedule it */
312
                      /* if our solicited RA is before the next periodic RA, we schedule it */
280
                  if (t.GetTimeStep () < static_cast<int64_t> (m_eventIds[(*it)->GetInterface ()].GetTs ()))
313
                      bool scheduleSingle = true;
281
                    {
314
                      if ( m_eventIds.find ((*it)->GetInterface ()) != m_eventIds.end ())
282
                      NS_LOG_INFO ("schedule new RA");
315
                        {
283
                      EventId ei;
316
                          if (t.GetTimeStep () > static_cast<int64_t> (m_eventIds[(*it)->GetInterface ()].GetTs ()))
284
317
                            {
285
                      ScheduleTransmit (MilliSeconds (delay), (*it), ei, address.GetIpv6 (), false);
318
                              scheduleSingle = false;
319
                            }
320
                        }
321
                      if (scheduleSingle)
322
                        {
323
                          NS_LOG_INFO ("schedule new RA");
324
                          Simulator::Schedule (MilliSeconds (delay), &Radvd::Send, this, (*it), address.GetIpv6 (), false);
325
                        }
286
                    }
326
                    }
287
                }
327
                }
288
              break;
328
              break;
(-)a/src/applications/model/radvd.h (-1 / +13 lines)
 Lines 105-110    Link Here 
105
  /// Container Const Iterator: interface number, EventId
105
  /// Container Const Iterator: interface number, EventId
106
  typedef std::map<uint32_t, EventId>::const_iterator EventIdMapCI;
106
  typedef std::map<uint32_t, EventId>::const_iterator EventIdMapCI;
107
107
108
  /// Container: interface number, Socket
109
  typedef std::map<uint32_t, Ptr<Socket> > SocketMap;
110
  /// Container Iterator: interface number, Socket
111
  typedef std::map<uint32_t, Ptr<Socket> >::iterator SocketMapI;
112
  /// Container Const Iterator: interface number, Socket
113
  typedef std::map<uint32_t, Ptr<Socket> >::const_iterator SocketMapCI;
114
108
  /**
115
  /**
109
   * \brief Start the application.
116
   * \brief Start the application.
110
   */
117
   */
 Lines 140-148    Link Here 
140
  void HandleRead (Ptr<Socket> socket);
147
  void HandleRead (Ptr<Socket> socket);
141
148
142
  /**
149
  /**
150
   * \brief Raw socket to receive RS.
151
   */
152
  Ptr<Socket> m_recvSocket;
153
154
  /**
143
   * \brief Raw socket to send RA.
155
   * \brief Raw socket to send RA.
144
   */
156
   */
145
  Ptr<Socket> m_socket;
157
  SocketMap m_sendSockets;
146
158
147
  /**
159
  /**
148
   * \brief List of configuration for interface.
160
   * \brief List of configuration for interface.

Return to bug 2016