diff --git a/src/internet/model/arp-cache.cc b/src/internet/model/arp-cache.cc index 322a50444..0d1134a33 100644 --- a/src/internet/model/arp-cache.cc +++ b/src/internet/model/arp-cache.cc @@ -282,6 +282,10 @@ ArpCache::PrintArpCache (Ptr stream) { *os << " DELAY\n"; } + else if (i->second->IsPermanent ()) + { + *os << " PERMANENT\n"; + } else { *os << " STALE\n"; @@ -313,6 +317,24 @@ ArpCache::Add (Ipv4Address to) return entry; } +void +ArpCache::Remove (ArpCache::Entry *entry) +{ + NS_LOG_FUNCTION (this << entry); + + for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++) + { + if ((*i).second == entry) + { + m_arpCache.erase (i); + entry->ClearPendingPacket (); //clear the pending packets for entry's ipaddress + delete entry; + return; + } + } + NS_LOG_WARN ("Entry not found in this ARP Cache"); +} + ArpCache::Entry::Entry (ArpCache *arp) : m_arp (arp), m_state (ALIVE), @@ -340,12 +362,19 @@ ArpCache::Entry::IsWaitReply (void) NS_LOG_FUNCTION (this); return (m_state == WAIT_REPLY) ? true : false; } +bool +ArpCache::Entry::IsPermanent (void) +{ + NS_LOG_FUNCTION (this); + return (m_state == PERMANENT) ? true : false; +} void ArpCache::Entry::MarkDead (void) { NS_LOG_FUNCTION (this); + NS_ASSERT (m_state == ALIVE || m_state == WAIT_REPLY || m_state == DEAD); m_state = DEAD; ClearRetries (); UpdateSeen (); @@ -360,7 +389,15 @@ ArpCache::Entry::MarkAlive (Address macAddress) ClearRetries (); UpdateSeen (); } - +void +ArpCache::Entry::MarkPermanent (void) +{ + NS_LOG_FUNCTION (this); + NS_ASSERT (!m_macAddress.IsInvalid ()); + m_state = PERMANENT; + ClearRetries (); + UpdateSeen (); +} bool ArpCache::Entry::UpdateWaitReply (Ptr waiting) { @@ -395,13 +432,19 @@ ArpCache::Entry::GetMacAddress (void) const NS_LOG_FUNCTION (this); return m_macAddress; } +void +ArpCache::Entry::SetMacAddresss (Address macAddress) +{ + NS_LOG_FUNCTION (this); + m_macAddress = macAddress; +} Ipv4Address ArpCache::Entry::GetIpv4Address (void) const { NS_LOG_FUNCTION (this); return m_ipv4Address; } -void +void ArpCache::Entry::SetIpv4Address (Ipv4Address destination) { NS_LOG_FUNCTION (this << destination); @@ -418,6 +461,8 @@ ArpCache::Entry::GetTimeout (void) const return m_arp->GetDeadTimeout (); case ArpCache::Entry::ALIVE: return m_arp->GetAliveTimeout (); + case ArpCache::Entry::PERMANENT: + return Time::Max (); default: NS_ASSERT (false); return Seconds (0); @@ -453,6 +498,12 @@ ArpCache::Entry::DequeuePending (void) } } void +ArpCache::Entry::ClearPendingPacket (void) +{ + NS_LOG_FUNCTION (this); + m_pending.clear (); +} +void ArpCache::Entry::UpdateSeen (void) { NS_LOG_FUNCTION (this); diff --git a/src/internet/model/arp-cache.h b/src/internet/model/arp-cache.h index f9a69e675..96904c867 100644 --- a/src/internet/model/arp-cache.h +++ b/src/internet/model/arp-cache.h @@ -150,6 +150,11 @@ public: * \brief Add an Ipv4Address to this ARP cache */ ArpCache::Entry *Add (Ipv4Address to); + /** + * \brief Remove an entry. + * \param entry pointer to delete it from the list + */ + void Remove (ArpCache::Entry *entry); /** * \brief Clear the ArpCache of all entries */ @@ -185,6 +190,12 @@ public: * \param waiting */ void MarkWaitReply (Ptr waiting); + /** + * \brief Changes the state of this entry to Permanent. + * + * The entry must have a valid MacAddress. + */ + void MarkPermanent (void); /** * \param waiting * \return @@ -202,7 +213,10 @@ public: * \return True if the state of this entry is wait_reply; false otherwise. */ bool IsWaitReply (void); - + /** + * \return True if the state of this entry is permanent; false otherwise. + */ + bool IsPermanent (void); /** * \return The MacAddress of this entry */ @@ -211,6 +225,10 @@ public: * \return The Ipv4Address for this entry */ Ipv4Address GetIpv4Address (void) const; + /** + * \param macAddress The MacAddress for this entry + */ + void SetMacAddresss (Address macAddress); /** * \param destination The Ipv4Address for this entry */ @@ -227,6 +245,10 @@ public: * packets are pending. */ Ptr DequeuePending (void); + /** + * \brief Clear the pending packet list + */ + void ClearPendingPacket (void); /** * \returns number of retries that have been sent for an ArpRequest * in WaitReply state. @@ -248,7 +270,8 @@ private: enum ArpCacheEntryState_e { ALIVE, WAIT_REPLY, - DEAD + DEAD, + PERMANENT }; /** diff --git a/src/internet/model/arp-l3-protocol.cc b/src/internet/model/arp-l3-protocol.cc index f3d7cbe50..90bb1ce0c 100644 --- a/src/internet/model/arp-l3-protocol.cc +++ b/src/internet/model/arp-l3-protocol.cc @@ -289,7 +289,7 @@ ArpL3Protocol::Lookup (Ptr packet, Ipv4Address destination, entry->MarkWaitReply (packet); Simulator::Schedule (Time (MilliSeconds (m_requestJitter->GetValue ())), &ArpL3Protocol::SendArpRequest, this, cache, destination); } - else if (entry->IsWaitReply ()) + else { NS_FATAL_ERROR ("Test for possibly unreachable code-- please file a bug report, with a test case, if this is ever hit"); } @@ -318,6 +318,17 @@ ArpL3Protocol::Lookup (Ptr packet, Ipv4Address destination, m_dropTrace (packet); } } + else if (entry-> IsPermanent ()) + { + NS_LOG_LOGIC ("node="<GetId ()<< + ", permanent for " << destination << "valid -- send"); + *hardwareDestination = entry->GetMacAddress (); + return true; + } + else + { + NS_LOG_LOGIC ("Test for possibly unreachable code-- please file a bug report, with a test case, if this is ever hit"); + } } } else