internet: (fixes #851) Avoid flushing auto-generated entries on link status changes
This commit is contained in:
@@ -27,6 +27,7 @@ The wimax module was removed and moved to the ns-3 App Store.
|
||||
* (antenna) Reformatted documentation.
|
||||
* (documentation) Improve models documentation look and feel
|
||||
* (internet) Added check for longest prefix match in GlobalRouting.
|
||||
* (internet) ArpCache::Flush() and NdiscCache::Flush() no longer remove autogenerated entries
|
||||
* (lr-wpan) Debloat MAC PD-DATA.indication and reduce packet copies.
|
||||
* (zigbee) Added group table.
|
||||
* (zigbee) Added Groupcast (Multicast) support.
|
||||
|
||||
@@ -43,6 +43,7 @@ The wimax module was removed and moved to the ns-3 App Store.
|
||||
|
||||
### Bugs fixed
|
||||
|
||||
- (internet) #851 - NeighborCacheHelper entries are no longer removed due to LinkUp events
|
||||
- (internet) #1251 - Added check for longest prefix match in GlobalRouting
|
||||
- (wifi) Block transmission on other EMLSR links as soon as it is detected that the main PHY is receiving an A-MPDU, to prevent that the EMLSR client starts an UL TXOP before the end of the A-MPDU
|
||||
- (wifi) EMLSR clients can switch to listening operations when receiving the MAC header of a broadcast frame that is not a Trigger Frame nor a Multi-STA BA
|
||||
|
||||
@@ -286,3 +286,8 @@ The typical usages are::
|
||||
|
||||
NeighborCacheHelper neighborCache;
|
||||
neighborCache.PopulateNeighborCache(interfaces); // interfaces is the Ipv4InterfaceContainer want to generate ARP caches
|
||||
|
||||
Neighbor cache entries are not removed by calls to ``ArpCache::Flush()``,
|
||||
which may be called during the process of bringing IPv4 interfaces up
|
||||
or down. Instead, to remove them, users must call
|
||||
``ArpCache::RemoveAutoGenerated()``.
|
||||
|
||||
@@ -523,3 +523,8 @@ The usages for generating NDISC cache is almost the same as generating ARP cache
|
||||
|
||||
NeighborCacheHelper neighborCache;
|
||||
neighborCache.PopulateNeighborCache(interfaces); // interfaces is the Ipv6InterfaceContainer want to generate ARP caches
|
||||
|
||||
Neighbor cache entries are not removed by calls to ``NdiscCache::Flush()``,
|
||||
which may be called during the process of bringing IPv6 interfaces up
|
||||
or down. Instead, to remove them, users must call
|
||||
``NdiscCache::RemoveAutoGenerated()``.
|
||||
|
||||
@@ -234,11 +234,19 @@ void
|
||||
ArpCache::Flush()
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
for (auto i = m_arpCache.begin(); i != m_arpCache.end(); i++)
|
||||
for (auto i = m_arpCache.begin(); i != m_arpCache.end();)
|
||||
{
|
||||
delete (*i).second;
|
||||
if (!i->second->IsAutoGenerated())
|
||||
{
|
||||
i->second->ClearPendingPacket(); // clear the pending packets for entry's ipaddress
|
||||
delete i->second;
|
||||
i = m_arpCache.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
m_arpCache.erase(m_arpCache.begin(), m_arpCache.end());
|
||||
if (m_waitReplyTimer.IsPending())
|
||||
{
|
||||
NS_LOG_LOGIC("Stopping WaitReplyTimer at " << Simulator::Now().GetSeconds()
|
||||
@@ -301,10 +309,12 @@ ArpCache::RemoveAutoGeneratedEntries()
|
||||
{
|
||||
i->second->ClearPendingPacket(); // clear the pending packets for entry's ipaddress
|
||||
delete i->second;
|
||||
m_arpCache.erase(i++);
|
||||
continue;
|
||||
i = m_arpCache.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +145,12 @@ class ArpCache : public Object
|
||||
*/
|
||||
void Remove(ArpCache::Entry* entry);
|
||||
/**
|
||||
* @brief Clear the ArpCache of all entries
|
||||
* @brief Clear the ArpCache of all entries except auto-generated entries
|
||||
*
|
||||
* If you wish to remove all entries, including auto-generated entries,
|
||||
* call this method and then also call RemoveAutoGeneratedEntries().
|
||||
*
|
||||
* @see RemoveAutoGenerated
|
||||
*/
|
||||
void Flush();
|
||||
|
||||
|
||||
@@ -153,12 +153,19 @@ NdiscCache::Flush()
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
|
||||
for (auto i = m_ndCache.begin(); i != m_ndCache.end(); i++)
|
||||
for (auto i = m_ndCache.begin(); i != m_ndCache.end();)
|
||||
{
|
||||
delete (*i).second; /* delete the pointer NdiscCache::Entry */
|
||||
if (!i->second->IsAutoGenerated())
|
||||
{
|
||||
i->second->ClearWaitingPacket();
|
||||
delete i->second;
|
||||
i = m_ndCache.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
m_ndCache.erase(m_ndCache.begin(), m_ndCache.end());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -712,10 +719,12 @@ NdiscCache::RemoveAutoGeneratedEntries()
|
||||
{
|
||||
i->second->ClearWaitingPacket();
|
||||
delete i->second;
|
||||
m_ndCache.erase(i++);
|
||||
continue;
|
||||
i = m_ndCache.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,12 @@ class NdiscCache : public Object
|
||||
void Remove(NdiscCache::Entry* entry);
|
||||
|
||||
/**
|
||||
* @brief Flush the cache.
|
||||
* @brief Clear the cache of all entries except auto-generated entries
|
||||
*
|
||||
* If you wish to remove all entries, including auto-generated entries,
|
||||
* call this method and then also call RemoveAutoGeneratedEntries().
|
||||
*
|
||||
* @see RemoveAutoGenerated
|
||||
*/
|
||||
void Flush();
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* Author: Zhiheng Dong <dzh2077@gmail.com>
|
||||
*/
|
||||
|
||||
#include "ns3/arp-cache.h"
|
||||
#include "ns3/icmpv4-l4-protocol.h"
|
||||
#include "ns3/icmpv6-l4-protocol.h"
|
||||
#include "ns3/internet-stack-helper.h"
|
||||
@@ -15,6 +16,7 @@
|
||||
#include "ns3/ipv6-address-helper.h"
|
||||
#include "ns3/ipv6-l3-protocol.h"
|
||||
#include "ns3/ipv6-routing-helper.h"
|
||||
#include "ns3/ndisc-cache.h"
|
||||
#include "ns3/neighbor-cache-helper.h"
|
||||
#include "ns3/simple-channel.h"
|
||||
#include "ns3/simple-net-device-helper.h"
|
||||
@@ -882,11 +884,42 @@ FlushTest::DoRun()
|
||||
std::ostringstream stringStream1v6;
|
||||
Ptr<OutputStreamWrapper> ndiscStream = Create<OutputStreamWrapper>(&stringStream1v6);
|
||||
|
||||
// Print cache.
|
||||
// Print cache at time 0.
|
||||
Ipv4RoutingHelper::PrintNeighborCacheAllAt(Seconds(0), arpStream);
|
||||
Ipv6RoutingHelper::PrintNeighborCacheAllAt(Seconds(0), ndiscStream);
|
||||
|
||||
// Flush cache at time 1 s.
|
||||
Simulator::Schedule(Seconds(1), &ArpCache::Flush, arpCache);
|
||||
Simulator::Schedule(Seconds(1), &NdiscCache::Flush, ndiscCache);
|
||||
|
||||
// Print cache again at time 2 s.
|
||||
std::ostringstream stringStream2v4;
|
||||
Ptr<OutputStreamWrapper> arpStream2 = Create<OutputStreamWrapper>(&stringStream2v4);
|
||||
std::ostringstream stringStream2v6;
|
||||
Ptr<OutputStreamWrapper> ndiscStream2 = Create<OutputStreamWrapper>(&stringStream2v6);
|
||||
Ipv4RoutingHelper::PrintNeighborCacheAllAt(Seconds(2), arpStream2);
|
||||
Ipv6RoutingHelper::PrintNeighborCacheAllAt(Seconds(2), ndiscStream2);
|
||||
|
||||
// Add autogenerated entries at time 3 s again.
|
||||
Simulator::Schedule(Seconds(3), [&neighborCache]() { neighborCache.PopulateNeighborCache(); });
|
||||
|
||||
// Flush cache again at time 4 s.
|
||||
Simulator::Schedule(Seconds(4), &ArpCache::Flush, arpCache);
|
||||
Simulator::Schedule(Seconds(4), &NdiscCache::Flush, ndiscCache);
|
||||
|
||||
// Print cache again at time 5 s.
|
||||
// Check that the autogenerated entries survived the Flush
|
||||
std::ostringstream stringStream5v4;
|
||||
Ptr<OutputStreamWrapper> arpStream5 = Create<OutputStreamWrapper>(&stringStream5v4);
|
||||
std::ostringstream stringStream5v6;
|
||||
Ptr<OutputStreamWrapper> ndiscStream5 = Create<OutputStreamWrapper>(&stringStream5v6);
|
||||
// Limit the printed output to node 0
|
||||
Ipv4RoutingHelper::PrintNeighborCacheAt(Seconds(5), m_nodes.Get(0), arpStream5);
|
||||
Ipv6RoutingHelper::PrintNeighborCacheAt(Seconds(5), m_nodes.Get(0), ndiscStream5);
|
||||
|
||||
Simulator::Run();
|
||||
|
||||
// Check the time zero output
|
||||
// Check if the STATIC_AUTOGENERATED entries are flushed and the PERMANENT entry is left.
|
||||
constexpr auto ArpCache = "ARP Cache of node 0 at time 0\n"
|
||||
"10.1.1.4 dev 0 lladdr 04-06-00:00:00:00:00:01 PERMANENT\n"
|
||||
@@ -901,6 +934,38 @@ FlushTest::DoRun()
|
||||
"NDISC Cache of node 1 at time +0s\n"
|
||||
"NDISC Cache of node 2 at time +0s\n";
|
||||
NS_TEST_EXPECT_MSG_EQ(stringStream1v6.str(), NdiscCache, "Ndisc cache is incorrect.");
|
||||
|
||||
// Check output after the first flush-- should be empty
|
||||
constexpr auto ArpCache2 = "ARP Cache of node 0 at time 2\n"
|
||||
"ARP Cache of node 1 at time 2\n"
|
||||
"ARP Cache of node 2 at time 2\n";
|
||||
NS_TEST_EXPECT_MSG_EQ(stringStream2v4.str(),
|
||||
ArpCache2,
|
||||
"Arp cache is incorrect after Flush().");
|
||||
constexpr auto NdiscCache2 = "NDISC Cache of node 0 at time +2s\n"
|
||||
"NDISC Cache of node 1 at time +2s\n"
|
||||
"NDISC Cache of node 2 at time +2s\n";
|
||||
NS_TEST_EXPECT_MSG_EQ(stringStream2v6.str(),
|
||||
NdiscCache2,
|
||||
"Ndisc cache is incorrect after Flush().");
|
||||
|
||||
// Check output after the second flush-- node 0 should still have two
|
||||
// static autogenerated entries for IPv6 and one for IPv4.
|
||||
// This behavior was added in the ns-3.46 release (see issue #851).
|
||||
constexpr auto ArpCache5 =
|
||||
"ARP Cache of node 0 at time 5\n"
|
||||
"10.1.1.2 dev 0 lladdr 04-06-00:00:00:00:00:02 STATIC_AUTOGENERATED\n";
|
||||
constexpr auto NdiscCache5 =
|
||||
"NDISC Cache of node 0 at time +5s\n"
|
||||
"2001::200:ff:fe00:2 dev 0 lladdr 04-06-00:00:00:00:00:02 STATIC_AUTOGENERATED\n"
|
||||
"fe80::200:ff:fe00:2 dev 0 lladdr 04-06-00:00:00:00:00:02 STATIC_AUTOGENERATED\n";
|
||||
NS_TEST_EXPECT_MSG_EQ(stringStream5v4.str(),
|
||||
ArpCache5,
|
||||
"Arp cache is incorrect after second Flush().");
|
||||
NS_TEST_EXPECT_MSG_EQ(stringStream5v6.str(),
|
||||
NdiscCache5,
|
||||
"Ndisc cache is incorrect after second Flush().");
|
||||
|
||||
Simulator::Destroy();
|
||||
}
|
||||
|
||||
@@ -975,7 +1040,8 @@ DuplicateTest::DoRun()
|
||||
Ipv6RoutingHelper::PrintNeighborCacheAllAt(Seconds(0), ndiscStream);
|
||||
|
||||
Simulator::Run();
|
||||
// Check if the STATIC_AUTOGENERATED entries are flushed and the PERMANENT entry is left.
|
||||
// Check if the overlapped scope of PopulateNeighborCache() calls did
|
||||
// not lead to duplicate entries.
|
||||
constexpr auto ArpCache =
|
||||
"ARP Cache of node 0 at time 0\n"
|
||||
"10.1.1.2 dev 0 lladdr 04-06-00:00:00:00:00:02 STATIC_AUTOGENERATED\n"
|
||||
@@ -986,7 +1052,8 @@ DuplicateTest::DoRun()
|
||||
"10.1.2.1 dev 0 lladdr 04-06-00:00:00:00:00:03 STATIC_AUTOGENERATED\n";
|
||||
NS_TEST_EXPECT_MSG_EQ(stringStream1v4.str(), ArpCache, "Arp cache is incorrect.");
|
||||
|
||||
// Check if the STATIC_AUTOGENERATED entries are flushed and the PERMANENT entry is left.
|
||||
// Check if the overlapped scope of PopulateNeighborCache() calls did
|
||||
// not lead to duplicate entries.
|
||||
constexpr auto NdiscCache =
|
||||
"NDISC Cache of node 0 at time +0s\n"
|
||||
"2001::200:ff:fe00:2 dev 0 lladdr 04-06-00:00:00:00:00:02 STATIC_AUTOGENERATED\n"
|
||||
|
||||
Reference in New Issue
Block a user