Files
unison/src/internet/model/ndisc-cache.cc

743 lines
16 KiB
C++
Raw Normal View History

/*
* Copyright (c) 2007-2009 Strasbourg University
*
2024-06-17 16:17:10 +02:00
* SPDX-License-Identifier: GPL-2.0-only
*
* Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
*/
2022-10-07 20:08:35 +00:00
#include "ndisc-cache.h"
#include "icmpv6-l4-protocol.h"
#include "ipv6-interface.h"
2022-10-07 20:08:35 +00:00
#include "ipv6-l3-protocol.h"
#include "ns3/log.h"
#include "ns3/names.h"
#include "ns3/node.h"
#include "ns3/uinteger.h"
namespace ns3
{
2022-10-07 20:08:35 +00:00
NS_LOG_COMPONENT_DEFINE("NdiscCache");
2022-10-07 20:08:35 +00:00
NS_OBJECT_ENSURE_REGISTERED(NdiscCache);
2010-06-29 20:24:20 -04:00
2022-10-07 20:08:35 +00:00
TypeId
NdiscCache::GetTypeId()
{
2022-10-07 20:08:35 +00:00
static TypeId tid = TypeId("ns3::NdiscCache")
.SetParent<Object>()
.SetGroupName("Internet")
.AddAttribute("UnresolvedQueueSize",
"Size of the queue for packets pending an NA reply.",
UintegerValue(DEFAULT_UNRES_QLEN),
MakeUintegerAccessor(&NdiscCache::m_unresQlen),
MakeUintegerChecker<uint32_t>());
return tid;
}
2022-10-07 20:08:35 +00:00
NdiscCache::NdiscCache()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
}
2022-10-07 20:08:35 +00:00
NdiscCache::~NdiscCache()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
Flush();
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::DoDispose()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
for (auto& iter : m_ndCache)
{
delete iter.second; /* delete the pointer NdiscCache::Entry */
}
m_ndCache.clear();
2022-10-07 20:08:35 +00:00
m_device = nullptr;
m_interface = nullptr;
m_icmpv6 = nullptr;
Object::DoDispose();
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::SetDevice(Ptr<NetDevice> device,
Ptr<Ipv6Interface> interface,
Ptr<Icmpv6L4Protocol> icmpv6)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << device << interface);
m_device = device;
m_interface = interface;
m_icmpv6 = icmpv6;
}
2022-10-07 20:08:35 +00:00
Ptr<Ipv6Interface>
NdiscCache::GetInterface() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return m_interface;
}
2022-10-07 20:08:35 +00:00
Ptr<NetDevice>
NdiscCache::GetDevice() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return m_device;
}
2022-10-07 20:08:35 +00:00
NdiscCache::Entry*
NdiscCache::Lookup(Ipv6Address dst)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << dst);
2022-10-07 20:08:35 +00:00
if (m_ndCache.find(dst) != m_ndCache.end())
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
NdiscCache::Entry* entry = m_ndCache[dst];
NS_LOG_LOGIC("Found an entry: " << *entry);
2022-10-07 20:08:35 +00:00
return entry;
2009-12-30 14:22:25 +01:00
}
2022-10-07 20:08:35 +00:00
NS_LOG_LOGIC("Nothing found");
return nullptr;
}
2022-10-07 20:08:35 +00:00
std::list<NdiscCache::Entry*>
NdiscCache::LookupInverse(Address dst)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << dst);
2022-10-07 20:08:35 +00:00
std::list<NdiscCache::Entry*> entryList;
for (auto i = m_ndCache.begin(); i != m_ndCache.end(); i++)
{
2022-10-07 20:08:35 +00:00
NdiscCache::Entry* entry = (*i).second;
if (entry->GetMacAddress() == dst)
{
2022-10-07 20:08:35 +00:00
NS_LOG_LOGIC("Found an entry:" << (*entry));
entryList.push_back(entry);
}
}
2022-10-07 20:08:35 +00:00
return entryList;
}
2022-10-07 20:08:35 +00:00
NdiscCache::Entry*
NdiscCache::Add(Ipv6Address to)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << to);
NS_ASSERT(m_ndCache.find(to) == m_ndCache.end());
auto entry = new NdiscCache::Entry(this);
2022-10-07 20:08:35 +00:00
entry->SetIpv6Address(to);
m_ndCache[to] = entry;
return entry;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Remove(NdiscCache::Entry* entry)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << entry);
2009-12-30 14:22:25 +01:00
for (auto i = m_ndCache.begin(); i != m_ndCache.end(); i++)
{
2022-10-07 20:08:35 +00:00
if ((*i).second == entry)
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
m_ndCache.erase(i);
entry->ClearWaitingPacket();
delete entry;
return;
2009-12-30 14:22:25 +01:00
}
}
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Flush()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
2009-12-30 14:22:25 +01:00
for (auto i = m_ndCache.begin(); i != m_ndCache.end();)
2009-12-30 14:22:25 +01:00
{
if (!i->second->IsAutoGenerated())
{
i->second->ClearWaitingPacket();
delete i->second;
i = m_ndCache.erase(i);
}
else
{
i++;
}
2009-12-30 14:22:25 +01:00
}
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::SetUnresQlen(uint32_t unresQlen)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << unresQlen);
m_unresQlen = unresQlen;
}
2022-10-07 20:08:35 +00:00
uint32_t
NdiscCache::GetUnresQlen()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return m_unresQlen;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::PrintNdiscCache(Ptr<OutputStreamWrapper> stream)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << stream);
std::ostream* os = stream->GetStream();
for (auto i = m_ndCache.begin(); i != m_ndCache.end(); i++)
{
2022-10-07 20:08:35 +00:00
*os << i->first << " dev ";
std::string found = Names::FindName(m_device);
if (!Names::FindName(m_device).empty())
{
2022-10-07 20:08:35 +00:00
*os << found;
}
2022-10-07 20:08:35 +00:00
else
{
2022-10-07 20:08:35 +00:00
*os << static_cast<int>(m_device->GetIfIndex());
}
2022-10-07 20:08:35 +00:00
*os << " lladdr " << i->second->GetMacAddress();
2022-10-07 20:08:35 +00:00
if (i->second->IsReachable())
{
2022-10-07 20:08:35 +00:00
*os << " REACHABLE\n";
}
2022-10-07 20:08:35 +00:00
else if (i->second->IsDelay())
{
2022-10-07 20:08:35 +00:00
*os << " DELAY\n";
}
2022-10-07 20:08:35 +00:00
else if (i->second->IsIncomplete())
{
2022-10-07 20:08:35 +00:00
*os << " INCOMPLETE\n";
}
2022-10-07 20:08:35 +00:00
else if (i->second->IsProbe())
{
2022-10-07 20:08:35 +00:00
*os << " PROBE\n";
}
2022-10-07 20:08:35 +00:00
else if (i->second->IsStale())
{
2022-10-07 20:08:35 +00:00
*os << " STALE\n";
}
2022-10-07 20:08:35 +00:00
else if (i->second->IsPermanent())
{
2022-10-07 20:08:35 +00:00
*os << " PERMANENT\n";
}
2022-10-07 20:08:35 +00:00
else if (i->second->IsAutoGenerated())
{
2022-10-07 20:08:35 +00:00
*os << " STATIC_AUTOGENERATED\n";
}
2022-10-07 20:08:35 +00:00
else
{
2022-10-07 20:08:35 +00:00
NS_FATAL_ERROR("Test for possibly unreachable code-- please file a bug report, with a "
"test case, if this is ever hit");
}
}
}
2022-10-07 20:08:35 +00:00
NdiscCache::Entry::Entry(NdiscCache* nd)
: m_ndCache(nd),
m_waiting(),
m_router(false),
m_nudTimer(Timer::CANCEL_ON_DESTROY),
m_lastReachabilityConfirmation(),
2022-10-07 20:08:35 +00:00
m_nsRetransmit(0)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::SetRouter(bool router)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << router);
m_router = router;
}
2022-10-07 20:08:35 +00:00
bool
NdiscCache::Entry::IsRouter() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return m_router;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::AddWaitingPacket(Ipv6PayloadHeaderPair p)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << p.second << p.first);
2022-10-07 20:08:35 +00:00
if (m_waiting.size() >= m_ndCache->GetUnresQlen())
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
/* we store only m_unresQlen packet => first packet in first packet remove */
2024-11-08 18:05:46 +00:00
/** @todo report packet as 'dropped' */
2022-10-07 20:08:35 +00:00
m_waiting.pop_front();
2009-12-30 14:22:25 +01:00
}
2022-10-07 20:08:35 +00:00
m_waiting.push_back(p);
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::ClearWaitingPacket()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
2024-11-08 18:05:46 +00:00
/** @todo report packets as 'dropped' */
2022-10-07 20:08:35 +00:00
m_waiting.clear();
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::FunctionReachableTimeout()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
this->MarkStale();
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::FunctionRetransmitTimeout()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
Ipv6Address addr;
2022-10-07 20:08:35 +00:00
/* determine source address */
if (m_ipv6Address.IsLinkLocal())
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
addr = m_ndCache->GetInterface()->GetLinkLocalAddress().GetAddress();
2009-12-30 14:22:25 +01:00
}
2022-10-07 20:08:35 +00:00
else if (!m_ipv6Address.IsAny())
{
2022-10-07 20:08:35 +00:00
addr = m_ndCache->GetInterface()->GetAddressMatchingDestination(m_ipv6Address).GetAddress();
2009-12-30 14:22:25 +01:00
2022-10-07 20:08:35 +00:00
if (addr.IsAny()) /* maybe address has expired */
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
/* delete the entry */
m_ndCache->Remove(this);
return;
2009-12-30 14:22:25 +01:00
}
}
2022-10-07 20:08:35 +00:00
if (m_nsRetransmit < m_ndCache->m_icmpv6->GetMaxMulticastSolicit())
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
m_nsRetransmit++;
m_ndCache->m_icmpv6->SendNS(addr,
Ipv6Address::MakeSolicitedAddress(m_ipv6Address),
m_ipv6Address,
m_ndCache->GetDevice()->GetAddress());
/* arm the timer again */
StartRetransmitTimer();
2009-12-30 14:22:25 +01:00
}
2022-10-07 20:08:35 +00:00
else
{
2022-10-07 20:08:35 +00:00
Ipv6PayloadHeaderPair malformedPacket = m_waiting.front();
if (!malformedPacket.first)
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
malformedPacket.first = Create<Packet>();
}
2022-10-07 20:08:35 +00:00
else
{
2022-10-07 20:08:35 +00:00
malformedPacket.first->AddHeader(malformedPacket.second);
2009-12-30 14:22:25 +01:00
}
2022-10-07 20:08:35 +00:00
m_ndCache->m_icmpv6->SendErrorDestinationUnreachable(malformedPacket.first,
addr,
Icmpv6Header::ICMPV6_ADDR_UNREACHABLE);
2009-12-30 14:22:25 +01:00
2022-10-07 20:08:35 +00:00
/* delete the entry */
m_ndCache->Remove(this);
2009-12-30 14:22:25 +01:00
}
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::FunctionDelayTimeout()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
Ipv6Address addr;
2022-10-07 20:08:35 +00:00
this->MarkProbe();
2022-10-07 20:08:35 +00:00
if (m_ipv6Address.IsLinkLocal())
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
addr = m_ndCache->GetInterface()->GetLinkLocalAddress().GetAddress();
2009-12-30 14:22:25 +01:00
}
2022-10-07 20:08:35 +00:00
else if (!m_ipv6Address.IsAny())
{
2022-10-07 20:08:35 +00:00
addr = m_ndCache->GetInterface()->GetAddressMatchingDestination(m_ipv6Address).GetAddress();
if (addr.IsAny()) /* maybe address has expired */
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
/* delete the entry */
m_ndCache->Remove(this);
return;
2009-12-30 14:22:25 +01:00
}
}
2022-10-07 20:08:35 +00:00
else
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
/* should not happen */
return;
2009-12-30 14:22:25 +01:00
}
2022-10-07 20:08:35 +00:00
Ipv6PayloadHeaderPair p = m_ndCache->m_icmpv6->ForgeNS(addr,
m_ipv6Address,
m_ipv6Address,
m_ndCache->GetDevice()->GetAddress());
p.first->AddHeader(p.second);
m_ndCache->GetDevice()->Send(p.first, this->GetMacAddress(), Ipv6L3Protocol::PROT_NUMBER);
2022-10-07 20:08:35 +00:00
m_nsRetransmit = 1;
StartProbeTimer();
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::FunctionProbeTimeout()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
2022-10-07 20:08:35 +00:00
if (m_nsRetransmit < m_ndCache->m_icmpv6->GetMaxUnicastSolicit())
{
2022-10-07 20:08:35 +00:00
m_nsRetransmit++;
2022-10-07 20:08:35 +00:00
Ipv6Address addr;
2009-12-30 14:22:25 +01:00
2022-10-07 20:08:35 +00:00
if (m_ipv6Address.IsLinkLocal())
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
addr = m_ndCache->GetInterface()->GetLinkLocalAddress().GetAddress();
2009-12-30 14:22:25 +01:00
}
2022-10-07 20:08:35 +00:00
else if (!m_ipv6Address.IsAny())
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
addr = m_ndCache->GetInterface()
->GetAddressMatchingDestination(m_ipv6Address)
.GetAddress();
if (addr.IsAny()) /* maybe address has expired */
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
/* delete the entry */
m_ndCache->Remove(this);
return;
2009-12-30 14:22:25 +01:00
}
}
2022-10-07 20:08:35 +00:00
else
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
/* should not happen */
return;
2009-12-30 14:22:25 +01:00
}
2022-10-07 20:08:35 +00:00
/* icmpv6->SendNS (m_ndCache->GetInterface ()->GetLinkLocalAddress (), m_ipv6Address,
* m_ipv6Address, m_ndCache->GetDevice ()->GetAddress ()); */
Ipv6PayloadHeaderPair p =
m_ndCache->m_icmpv6->ForgeNS(addr,
m_ipv6Address,
m_ipv6Address,
m_ndCache->GetDevice()->GetAddress());
p.first->AddHeader(p.second);
m_ndCache->GetDevice()->Send(p.first, this->GetMacAddress(), Ipv6L3Protocol::PROT_NUMBER);
/* arm the timer again */
StartProbeTimer();
}
2022-10-07 20:08:35 +00:00
else
{
2022-10-07 20:08:35 +00:00
/* delete the entry */
m_ndCache->Remove(this);
}
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::SetIpv6Address(Ipv6Address ipv6Address)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << ipv6Address);
m_ipv6Address = ipv6Address;
}
2022-10-07 20:08:35 +00:00
Ipv6Address
NdiscCache::Entry::GetIpv6Address() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return m_ipv6Address;
}
2022-10-07 20:08:35 +00:00
Time
NdiscCache::Entry::GetLastReachabilityConfirmation() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return m_lastReachabilityConfirmation;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::StartReachableTimer()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
if (m_nudTimer.IsRunning())
{
2022-10-07 20:08:35 +00:00
m_nudTimer.Cancel();
}
2022-10-07 20:08:35 +00:00
m_lastReachabilityConfirmation = Simulator::Now();
m_nudTimer.SetFunction(&NdiscCache::Entry::FunctionReachableTimeout, this);
m_nudTimer.SetDelay(m_ndCache->m_icmpv6->GetReachableTime());
m_nudTimer.Schedule();
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::UpdateReachableTimer()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
2022-10-07 20:08:35 +00:00
if (m_state == REACHABLE)
{
2022-10-07 20:08:35 +00:00
m_lastReachabilityConfirmation = Simulator::Now();
if (m_nudTimer.IsRunning())
{
2022-10-07 20:08:35 +00:00
m_nudTimer.Cancel();
}
2022-10-07 20:08:35 +00:00
m_nudTimer.Schedule();
}
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::StartProbeTimer()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
if (m_nudTimer.IsRunning())
{
2022-10-07 20:08:35 +00:00
m_nudTimer.Cancel();
}
2022-10-07 20:08:35 +00:00
m_nudTimer.SetFunction(&NdiscCache::Entry::FunctionProbeTimeout, this);
m_nudTimer.SetDelay(m_ndCache->m_icmpv6->GetRetransmissionTime());
m_nudTimer.Schedule();
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::StartDelayTimer()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
if (m_nudTimer.IsRunning())
{
2022-10-07 20:08:35 +00:00
m_nudTimer.Cancel();
}
2022-10-07 20:08:35 +00:00
m_nudTimer.SetFunction(&NdiscCache::Entry::FunctionDelayTimeout, this);
m_nudTimer.SetDelay(m_ndCache->m_icmpv6->GetDelayFirstProbe());
m_nudTimer.Schedule();
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::StartRetransmitTimer()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
if (m_nudTimer.IsRunning())
{
2022-10-07 20:08:35 +00:00
m_nudTimer.Cancel();
}
2022-10-07 20:08:35 +00:00
m_nudTimer.SetFunction(&NdiscCache::Entry::FunctionRetransmitTimeout, this);
m_nudTimer.SetDelay(m_ndCache->m_icmpv6->GetRetransmissionTime());
m_nudTimer.Schedule();
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::StopNudTimer()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
m_nudTimer.Cancel();
m_nsRetransmit = 0;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::MarkIncomplete(Ipv6PayloadHeaderPair p)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << p.second << p.first);
m_state = INCOMPLETE;
2022-10-07 20:08:35 +00:00
if (p.first)
2009-12-30 14:22:25 +01:00
{
2022-10-07 20:08:35 +00:00
m_waiting.push_back(p);
2009-12-30 14:22:25 +01:00
}
}
2022-10-07 20:08:35 +00:00
std::list<NdiscCache::Ipv6PayloadHeaderPair>
NdiscCache::Entry::MarkReachable(Address mac)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << mac);
m_state = REACHABLE;
m_macAddress = mac;
return m_waiting;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::MarkProbe()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
m_state = PROBE;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::MarkStale()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
m_state = STALE;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::MarkReachable()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
m_state = REACHABLE;
}
2022-10-07 20:08:35 +00:00
std::list<NdiscCache::Ipv6PayloadHeaderPair>
NdiscCache::Entry::MarkStale(Address mac)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << mac);
m_state = STALE;
m_macAddress = mac;
return m_waiting;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::MarkDelay()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
m_state = DELAY;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::MarkPermanent()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
StopNudTimer();
m_state = PERMANENT;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::MarkAutoGenerated()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
StopNudTimer();
m_state = STATIC_AUTOGENERATED;
}
2022-10-07 20:08:35 +00:00
bool
NdiscCache::Entry::IsStale() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return (m_state == STALE);
}
2022-10-07 20:08:35 +00:00
bool
NdiscCache::Entry::IsReachable() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return (m_state == REACHABLE);
}
2022-10-07 20:08:35 +00:00
bool
NdiscCache::Entry::IsDelay() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return (m_state == DELAY);
}
2022-10-07 20:08:35 +00:00
bool
NdiscCache::Entry::IsIncomplete() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return (m_state == INCOMPLETE);
}
2022-10-07 20:08:35 +00:00
bool
NdiscCache::Entry::IsProbe() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return (m_state == PROBE);
}
2022-10-07 20:08:35 +00:00
bool
NdiscCache::Entry::IsPermanent() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return (m_state == PERMANENT);
}
2022-10-07 20:08:35 +00:00
bool
NdiscCache::Entry::IsAutoGenerated() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return (m_state == STATIC_AUTOGENERATED);
}
2022-10-07 20:08:35 +00:00
Address
NdiscCache::Entry::GetMacAddress() const
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
return m_macAddress;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::SetMacAddress(Address mac)
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this << mac << int(m_state));
m_macAddress = mac;
}
2022-10-07 20:08:35 +00:00
void
NdiscCache::Entry::Print(std::ostream& os) const
{
2022-10-07 20:08:35 +00:00
os << m_ipv6Address << " lladdr " << m_macAddress << " state ";
switch (m_state)
{
2022-10-07 20:08:35 +00:00
case INCOMPLETE:
os << "INCOMPLETE";
break;
2022-10-07 20:08:35 +00:00
case REACHABLE:
os << "REACHABLE";
break;
2022-10-07 20:08:35 +00:00
case STALE:
os << "STALE";
break;
2022-10-07 20:08:35 +00:00
case DELAY:
os << "DELAY";
break;
2022-10-07 20:08:35 +00:00
case PROBE:
os << "PROBE";
break;
2022-10-07 20:08:35 +00:00
case PERMANENT:
os << "PERMANENT";
break;
2022-10-07 20:08:35 +00:00
case STATIC_AUTOGENERATED:
os << "STATIC_AUTOGENERATED";
break;
}
}
void
2022-10-07 20:08:35 +00:00
NdiscCache::RemoveAutoGeneratedEntries()
{
2022-10-07 20:08:35 +00:00
NS_LOG_FUNCTION(this);
for (auto i = m_ndCache.begin(); i != m_ndCache.end();)
{
2022-10-07 20:08:35 +00:00
if (i->second->IsAutoGenerated())
{
2022-10-07 20:08:35 +00:00
i->second->ClearWaitingPacket();
delete i->second;
i = m_ndCache.erase(i);
}
else
{
i++;
}
}
}
2022-10-07 20:08:35 +00:00
std::ostream&
operator<<(std::ostream& os, const NdiscCache::Entry& entry)
{
2022-10-07 20:08:35 +00:00
entry.Print(os);
return os;
}
} /* namespace ns3 */