Bug 2073 - NDisc cache entries update timer might be stuck in a loop

This commit is contained in:
Tommaso Pecorella
2015-02-28 15:16:47 +01:00
parent ac61b6229a
commit 17e5e203b3
6 changed files with 48 additions and 190 deletions

View File

@@ -24,6 +24,7 @@ New user-visible features
Bugs fixed
----------
- Bug 2073 - NDisc cache entries update timer might be stuck in a loop
Known issues
------------

View File

@@ -5328,7 +5328,6 @@ def register_Ns3Empty_methods(root_module, cls):
return
def register_Ns3Int64x64_t_methods(root_module, cls):
cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('!=')
cls.add_inplace_numeric_operator('+=', param('ns3::int64x64_t const &', u'right'))
cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('ns3::int64x64_t const &', u'right'))
@@ -5342,6 +5341,7 @@ def register_Ns3Int64x64_t_methods(root_module, cls):
cls.add_inplace_numeric_operator('-=', param('ns3::int64x64_t const &', u'right'))
cls.add_inplace_numeric_operator('/=', param('ns3::int64x64_t const &', u'right'))
cls.add_output_stream_operator()
cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('==')
cls.add_binary_comparison_operator('>=')
## int64x64-double.h (module 'core'): ns3::int64x64_t::int64x64_t() [constructor]
@@ -10096,7 +10096,6 @@ def register_Ns3TcpWestwood_methods(root_module, cls):
return
def register_Ns3Time_methods(root_module, cls):
cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('!=')
cls.add_inplace_numeric_operator('+=', param('ns3::Time const &', u'right'))
cls.add_binary_numeric_operator('*', root_module['ns3::Time'], root_module['ns3::Time'], param('int64_t const &', u'right'))
@@ -10107,6 +10106,7 @@ def register_Ns3Time_methods(root_module, cls):
cls.add_binary_comparison_operator('>')
cls.add_inplace_numeric_operator('-=', param('ns3::Time const &', u'right'))
cls.add_output_stream_operator()
cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('==')
cls.add_binary_comparison_operator('>=')
## nstime.h (module 'core'): ns3::Time::Time() [constructor]
@@ -14584,15 +14584,6 @@ def register_Ns3NdiscCacheEntry_methods(root_module, cls):
'ns3::Address',
[],
is_const=True)
## ndisc-cache.h (module 'internet'): uint8_t ns3::NdiscCache::Entry::GetNSRetransmit() const [member function]
cls.add_method('GetNSRetransmit',
'uint8_t',
[],
is_const=True)
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::IncNSRetransmit() [member function]
cls.add_method('IncNSRetransmit',
'void',
[])
## ndisc-cache.h (module 'internet'): bool ns3::NdiscCache::Entry::IsDelay() const [member function]
cls.add_method('IsDelay',
'bool',
@@ -14651,10 +14642,6 @@ def register_Ns3NdiscCacheEntry_methods(root_module, cls):
cls.add_method('MarkStale',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::ResetNSRetransmit() [member function]
cls.add_method('ResetNSRetransmit',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::SetIpv6Address(ns3::Ipv6Address ipv6Address) [member function]
cls.add_method('SetIpv6Address',
'void',
@@ -14683,20 +14670,8 @@ def register_Ns3NdiscCacheEntry_methods(root_module, cls):
cls.add_method('StartRetransmitTimer',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::StopDelayTimer() [member function]
cls.add_method('StopDelayTimer',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::StopProbeTimer() [member function]
cls.add_method('StopProbeTimer',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::StopReachableTimer() [member function]
cls.add_method('StopReachableTimer',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::StopRetransmitTimer() [member function]
cls.add_method('StopRetransmitTimer',
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::StopNudTimer() [member function]
cls.add_method('StopNudTimer',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::UpdateLastReachabilityconfirmation() [member function]

View File

@@ -5328,7 +5328,6 @@ def register_Ns3Empty_methods(root_module, cls):
return
def register_Ns3Int64x64_t_methods(root_module, cls):
cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('!=')
cls.add_inplace_numeric_operator('+=', param('ns3::int64x64_t const &', u'right'))
cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('ns3::int64x64_t const &', u'right'))
@@ -5342,6 +5341,7 @@ def register_Ns3Int64x64_t_methods(root_module, cls):
cls.add_inplace_numeric_operator('-=', param('ns3::int64x64_t const &', u'right'))
cls.add_inplace_numeric_operator('/=', param('ns3::int64x64_t const &', u'right'))
cls.add_output_stream_operator()
cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('==')
cls.add_binary_comparison_operator('>=')
## int64x64-double.h (module 'core'): ns3::int64x64_t::int64x64_t() [constructor]
@@ -10096,7 +10096,6 @@ def register_Ns3TcpWestwood_methods(root_module, cls):
return
def register_Ns3Time_methods(root_module, cls):
cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('!=')
cls.add_inplace_numeric_operator('+=', param('ns3::Time const &', u'right'))
cls.add_binary_numeric_operator('*', root_module['ns3::Time'], root_module['ns3::Time'], param('int64_t const &', u'right'))
@@ -10107,6 +10106,7 @@ def register_Ns3Time_methods(root_module, cls):
cls.add_binary_comparison_operator('>')
cls.add_inplace_numeric_operator('-=', param('ns3::Time const &', u'right'))
cls.add_output_stream_operator()
cls.add_binary_comparison_operator('<=')
cls.add_binary_comparison_operator('==')
cls.add_binary_comparison_operator('>=')
## nstime.h (module 'core'): ns3::Time::Time() [constructor]
@@ -14584,15 +14584,6 @@ def register_Ns3NdiscCacheEntry_methods(root_module, cls):
'ns3::Address',
[],
is_const=True)
## ndisc-cache.h (module 'internet'): uint8_t ns3::NdiscCache::Entry::GetNSRetransmit() const [member function]
cls.add_method('GetNSRetransmit',
'uint8_t',
[],
is_const=True)
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::IncNSRetransmit() [member function]
cls.add_method('IncNSRetransmit',
'void',
[])
## ndisc-cache.h (module 'internet'): bool ns3::NdiscCache::Entry::IsDelay() const [member function]
cls.add_method('IsDelay',
'bool',
@@ -14651,10 +14642,6 @@ def register_Ns3NdiscCacheEntry_methods(root_module, cls):
cls.add_method('MarkStale',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::ResetNSRetransmit() [member function]
cls.add_method('ResetNSRetransmit',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::SetIpv6Address(ns3::Ipv6Address ipv6Address) [member function]
cls.add_method('SetIpv6Address',
'void',
@@ -14683,20 +14670,8 @@ def register_Ns3NdiscCacheEntry_methods(root_module, cls):
cls.add_method('StartRetransmitTimer',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::StopDelayTimer() [member function]
cls.add_method('StopDelayTimer',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::StopProbeTimer() [member function]
cls.add_method('StopProbeTimer',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::StopReachableTimer() [member function]
cls.add_method('StopReachableTimer',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::StopRetransmitTimer() [member function]
cls.add_method('StopRetransmitTimer',
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::StopNudTimer() [member function]
cls.add_method('StopNudTimer',
'void',
[])
## ndisc-cache.h (module 'internet'): void ns3::NdiscCache::Entry::UpdateLastReachabilityconfirmation() [member function]

View File

@@ -379,10 +379,9 @@ void Icmpv6L4Protocol::ReceiveLLA (Icmpv6OptionLinkLayerAddress lla, Ipv6Address
std::list<Ptr<Packet> > waiting;
if (entry->IsIncomplete ())
{
entry->StopRetransmitTimer ();
entry->StopNudTimer ();
// mark it to reachable
waiting = entry->MarkReachable (lla.GetAddress ());
entry->StopReachableTimer ();
entry->StartReachableTimer ();
// send out waiting packet
for (std::list<Ptr<Packet> >::const_iterator it = waiting.begin (); it != waiting.end (); it++)
@@ -403,8 +402,7 @@ void Icmpv6L4Protocol::ReceiveLLA (Icmpv6OptionLinkLayerAddress lla, Ipv6Address
{
if (!entry->IsReachable ())
{
entry->StopProbeTimer ();
entry->StopDelayTimer ();
entry->StopNudTimer ();
waiting = entry->MarkReachable (lla.GetAddress ());
if (entry->IsProbe ())
{
@@ -413,7 +411,6 @@ void Icmpv6L4Protocol::ReceiveLLA (Icmpv6OptionLinkLayerAddress lla, Ipv6Address
cache->GetInterface ()->Send (*it, src);
}
}
entry->StopReachableTimer ();
entry->StartReachableTimer ();
}
}
@@ -664,13 +661,12 @@ void Icmpv6L4Protocol::HandleNA (Ptr<Packet> packet, Ipv6Address const &src, Ipv
if (entry->IsIncomplete ())
{
/* we receive a NA so stop the retransmission timer */
entry->StopRetransmitTimer ();
entry->StopNudTimer ();
if (naHeader.GetFlagS ())
{
/* mark it to reachable */
waiting = entry->MarkReachable (lla.GetAddress ());
entry->StopReachableTimer ();
entry->StartReachableTimer ();
/* send out waiting packet */
for (std::list<Ptr<Packet> >::const_iterator it = waiting.begin (); it != waiting.end (); it++)
@@ -692,8 +688,7 @@ void Icmpv6L4Protocol::HandleNA (Ptr<Packet> packet, Ipv6Address const &src, Ipv
else
{
/* we receive a NA so stop the probe timer or delay timer if any */
entry->StopProbeTimer ();
entry->StopDelayTimer ();
entry->StopNudTimer ();
/* if the Flag O is clear and mac address differs from the cache */
if (!naHeader.GetFlagO () && lla.GetAddress () != entry->GetMacAddress ())
@@ -728,7 +723,6 @@ void Icmpv6L4Protocol::HandleNA (Ptr<Packet> packet, Ipv6Address const &src, Ipv
entry->MarkReachable (lla.GetAddress ());
}
}
entry->StopReachableTimer ();
entry->StartReachableTimer ();
}
else if (lla.GetAddress () != entry->GetMacAddress ())

View File

@@ -197,10 +197,7 @@ NdiscCache::Entry::Entry (NdiscCache* nd)
: m_ndCache (nd),
m_waiting (),
m_router (false),
m_reachableTimer (Timer::CANCEL_ON_DESTROY),
m_retransTimer (Timer::CANCEL_ON_DESTROY),
m_probeTimer (Timer::CANCEL_ON_DESTROY),
m_delayTimer (Timer::CANCEL_ON_DESTROY),
m_nudTimer (Timer::CANCEL_ON_DESTROY),
m_lastReachabilityConfirmation (Seconds (0.0)),
m_nsRetransmit (0)
{
@@ -268,9 +265,9 @@ void NdiscCache::Entry::FunctionRetransmitTimeout ()
}
}
if (GetNSRetransmit () < icmpv6->MAX_MULTICAST_SOLICIT)
if (m_nsRetransmit < icmpv6->MAX_MULTICAST_SOLICIT)
{
IncNSRetransmit ();
m_nsRetransmit++;
icmpv6->SendNS (addr, Ipv6Address::MakeSolicitedAddress (m_ipv6Address), m_ipv6Address, m_ndCache->GetDevice ()->GetAddress ());
/* arm the timer again */
@@ -323,8 +320,7 @@ void NdiscCache::Entry::FunctionDelayTimeout ()
Ptr<Packet> p = icmpv6->ForgeNS (addr, m_ipv6Address, m_ipv6Address, m_ndCache->GetDevice ()->GetAddress ());
m_ndCache->GetDevice ()->Send (p, this->GetMacAddress (), Ipv6L3Protocol::PROT_NUMBER);
ResetNSRetransmit ();
IncNSRetransmit ();
m_nsRetransmit = 1;
StartProbeTimer ();
}
@@ -334,8 +330,10 @@ void NdiscCache::Entry::FunctionProbeTimeout ()
Ptr<Ipv6L3Protocol> ipv6 = m_ndCache->GetDevice ()->GetNode ()->GetObject<Ipv6L3Protocol> ();
Ptr<Icmpv6L4Protocol> icmpv6 = ipv6->GetIcmpv6 ();
if (GetNSRetransmit () < icmpv6->MAX_UNICAST_SOLICIT)
if (m_nsRetransmit < icmpv6->MAX_UNICAST_SOLICIT)
{
m_nsRetransmit++;
Ipv6Address addr;
if (m_ipv6Address.IsLinkLocal ())
@@ -358,7 +356,6 @@ void NdiscCache::Entry::FunctionProbeTimeout ()
return;
}
IncNSRetransmit ();
/* icmpv6->SendNS (m_ndCache->GetInterface ()->GetLinkLocalAddress (), m_ipv6Address, m_ipv6Address, m_ndCache->GetDevice ()->GetAddress ()); */
Ptr<Packet> p = icmpv6->ForgeNS (addr, m_ipv6Address, m_ipv6Address, m_ndCache->GetDevice ()->GetAddress ());
m_ndCache->GetDevice ()->Send (p, this->GetMacAddress (), Ipv6L3Protocol::PROT_NUMBER);
@@ -379,24 +376,6 @@ void NdiscCache::Entry::SetIpv6Address (Ipv6Address ipv6Address)
m_ipv6Address = ipv6Address;
}
uint8_t NdiscCache::Entry::GetNSRetransmit () const
{
NS_LOG_FUNCTION_NOARGS ();
return m_nsRetransmit;
}
void NdiscCache::Entry::IncNSRetransmit ()
{
NS_LOG_FUNCTION_NOARGS ();
m_nsRetransmit++;
}
void NdiscCache::Entry::ResetNSRetransmit ()
{
NS_LOG_FUNCTION_NOARGS ();
m_nsRetransmit = 0;
}
Time NdiscCache::Entry::GetLastReachabilityConfirmation () const
{
NS_LOG_FUNCTION_NOARGS ();
@@ -411,77 +390,57 @@ void NdiscCache::Entry::UpdateLastReachabilityconfirmation ()
void NdiscCache::Entry::StartReachableTimer ()
{
NS_LOG_FUNCTION_NOARGS ();
if (m_reachableTimer.IsRunning ())
if (m_nudTimer.IsRunning ())
{
m_reachableTimer.Cancel ();
m_nudTimer.Cancel ();
}
m_reachableTimer.SetFunction (&NdiscCache::Entry::FunctionReachableTimeout, this);
m_reachableTimer.SetDelay (MilliSeconds (Icmpv6L4Protocol::REACHABLE_TIME));
m_reachableTimer.Schedule ();
}
void NdiscCache::Entry::StopReachableTimer ()
{
NS_LOG_FUNCTION_NOARGS ();
m_reachableTimer.Cancel ();
m_nudTimer.SetFunction (&NdiscCache::Entry::FunctionReachableTimeout, this);
m_nudTimer.SetDelay (MilliSeconds (Icmpv6L4Protocol::REACHABLE_TIME));
m_nudTimer.Schedule ();
}
void NdiscCache::Entry::StartProbeTimer ()
{
NS_LOG_FUNCTION_NOARGS ();
if (m_probeTimer.IsRunning ())
if (m_nudTimer.IsRunning ())
{
m_probeTimer.Cancel ();
m_nudTimer.Cancel ();
}
m_probeTimer.SetFunction (&NdiscCache::Entry::FunctionProbeTimeout, this);
m_probeTimer.SetDelay (MilliSeconds (Icmpv6L4Protocol::RETRANS_TIMER));
m_probeTimer.Schedule ();
m_nudTimer.SetFunction (&NdiscCache::Entry::FunctionProbeTimeout, this);
m_nudTimer.SetDelay (MilliSeconds (Icmpv6L4Protocol::RETRANS_TIMER));
m_nudTimer.Schedule ();
}
void NdiscCache::Entry::StopProbeTimer ()
{
NS_LOG_FUNCTION_NOARGS ();
m_probeTimer.Cancel ();
ResetNSRetransmit ();
}
void NdiscCache::Entry::StartDelayTimer ()
{
NS_LOG_FUNCTION_NOARGS ();
if (m_delayTimer.IsRunning ())
if (m_nudTimer.IsRunning ())
{
m_delayTimer.Cancel ();
m_nudTimer.Cancel ();
}
m_delayTimer.SetFunction (&NdiscCache::Entry::FunctionDelayTimeout, this);
m_delayTimer.SetDelay (Seconds (Icmpv6L4Protocol::DELAY_FIRST_PROBE_TIME));
m_delayTimer.Schedule ();
}
void NdiscCache::Entry::StopDelayTimer ()
{
NS_LOG_FUNCTION_NOARGS ();
m_delayTimer.Cancel ();
ResetNSRetransmit ();
m_nudTimer.SetFunction (&NdiscCache::Entry::FunctionDelayTimeout, this);
m_nudTimer.SetDelay (Seconds (Icmpv6L4Protocol::DELAY_FIRST_PROBE_TIME));
m_nudTimer.Schedule ();
}
void NdiscCache::Entry::StartRetransmitTimer ()
{
NS_LOG_FUNCTION_NOARGS ();
if (m_retransTimer.IsRunning ())
if (m_nudTimer.IsRunning ())
{
m_retransTimer.Cancel ();
m_nudTimer.Cancel ();
}
m_retransTimer.SetFunction (&NdiscCache::Entry::FunctionRetransmitTimeout, this);
m_retransTimer.SetDelay (MilliSeconds (Icmpv6L4Protocol::RETRANS_TIMER));
m_retransTimer.Schedule ();
m_nudTimer.SetFunction (&NdiscCache::Entry::FunctionRetransmitTimeout, this);
m_nudTimer.SetDelay (MilliSeconds (Icmpv6L4Protocol::RETRANS_TIMER));
m_nudTimer.Schedule ();
}
void NdiscCache::Entry::StopRetransmitTimer ()
void NdiscCache::Entry::StopNudTimer ()
{
NS_LOG_FUNCTION_NOARGS ();
m_retransTimer.Cancel ();
ResetNSRetransmit ();
m_nudTimer.Cancel ();
m_nsRetransmit = 0;
}
void NdiscCache::Entry::MarkIncomplete (Ptr<Packet> p)
@@ -573,7 +532,7 @@ Address NdiscCache::Entry::GetMacAddress () const
void NdiscCache::Entry::SetMacAddress (Address mac)
{
NS_LOG_FUNCTION (this << mac);
NS_LOG_FUNCTION (this << mac << int(m_state));
m_macAddress = mac;
}

View File

@@ -249,22 +249,6 @@ public:
*/
void SetRouter (bool router);
/**
* \brief Get the number of NS retransmit.
* \return number of NS that have been retransmit
*/
uint8_t GetNSRetransmit () const;
/**
* \brief Increment NS retransmit.
*/
void IncNSRetransmit ();
/**
* \brief Reset NS retransmit (=0).
*/
void ResetNSRetransmit ();
/**
* \brief Get the time of last reachability confirmation.
* \return time
@@ -281,40 +265,25 @@ public:
*/
void StartReachableTimer ();
/**
* \brief Stop the reachable timer.
*/
void StopReachableTimer ();
/**
* \brief Start retransmit timer.
*/
void StartRetransmitTimer ();
/**
* \brief Stop retransmit timer.
*/
void StopRetransmitTimer ();
/**
* \brief Start probe timer.
*/
void StartProbeTimer ();
/**
* \brief Stop probe timer.
*/
void StopProbeTimer ();
/**
* \brief Start delay timer.
*/
void StartDelayTimer ();
/**
* \brief Stop delay timer.
* \brief Stop NUD timer and reset the NUD retransmission counter
*/
void StopDelayTimer ();
void StopNudTimer ();
/**
* \brief Function called when reachable timer timeout.
@@ -388,24 +357,9 @@ private:
bool m_router;
/**
* \brief Reachable timer (used for NUD in REACHABLE state).
* \brief Timer (used for NUD).
*/
Timer m_reachableTimer;
/**
* \brief Retransmission timer (used for NUD in INCOMPLETE state).
*/
Timer m_retransTimer;
/**
* \brief Probe timer (used for NUD in PROBE state).
*/
Timer m_probeTimer;
/**
* \brief Delay timer (used for NUD when in DELAY state).
*/
Timer m_delayTimer;
Timer m_nudTimer;
/**
* \brief Last time we see a reachability confirmation.