Add support for removing entries and marking permanent (static) entries in ArpCache
authorSaswat Mishra <clicksaswat@gmail.com>
Sun, 06 Sep 2015 22:57:37 -0700
changeset 11651 feff0e88048b
parent 11650 7f374ac3b2f8
child 11652 af6897a9e544
Add support for removing entries and marking permanent (static) entries in ArpCache
src/internet/model/arp-cache.cc
src/internet/model/arp-cache.h
src/internet/model/arp-l3-protocol.cc
--- a/src/internet/model/arp-cache.cc	Sun Sep 06 22:19:22 2015 -0700
+++ b/src/internet/model/arp-cache.cc	Sun Sep 06 22:57:37 2015 -0700
@@ -282,6 +282,10 @@
         {
           *os << " DELAY\n";
         }
+      else if (i->second->IsPermanent ())
+	{
+	  *os << " PERMANENT\n";
+	}
       else
         {
           *os << " STALE\n";
@@ -313,6 +317,24 @@
   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 @@
   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 @@
   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<Packet> waiting)
 {
@@ -395,13 +432,19 @@
   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 @@
       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 @@
     }
 }
 void 
+ArpCache::Entry::ClearPendingPacket (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_pending.clear ();
+}
+void 
 ArpCache::Entry::UpdateSeen (void)
 {
   NS_LOG_FUNCTION (this);
--- a/src/internet/model/arp-cache.h	Sun Sep 06 22:19:22 2015 -0700
+++ b/src/internet/model/arp-cache.h	Sun Sep 06 22:57:37 2015 -0700
@@ -151,6 +151,11 @@
    */
   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
    */
   void Flush (void);
@@ -186,6 +191,12 @@
      */
     void MarkWaitReply (Ptr<Packet> 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 @@
      * \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
      */
@@ -212,6 +226,10 @@
      */
     Ipv4Address GetIpv4Address (void) const;
     /**
+     * \param macAddress The MacAddress for this entry
+     */
+    void SetMacAddresss (Address macAddress);
+    /**
      * \param destination The Ipv4Address for this entry
      */
     void SetIpv4Address (Ipv4Address destination);
@@ -228,6 +246,10 @@
      */
     Ptr<Packet> 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 @@
     enum ArpCacheEntryState_e {
       ALIVE,
       WAIT_REPLY,
-      DEAD
+      DEAD,
+      PERMANENT
     };
 
     /**
--- a/src/internet/model/arp-l3-protocol.cc	Sun Sep 06 22:19:22 2015 -0700
+++ b/src/internet/model/arp-l3-protocol.cc	Sun Sep 06 22:57:37 2015 -0700
@@ -289,7 +289,7 @@
               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 @@
                   m_dropTrace (packet);
                 }
             }
+          else if (entry-> IsPermanent ())
+            {
+              NS_LOG_LOGIC ("node="<<m_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