internet: GSoC-22 update automatic ARP/NDISC cache when network changes
This commit is contained in:
committed by
Tommaso Pecorella
parent
24ee65fb23
commit
90d6e08bb4
@@ -26,6 +26,11 @@ Changes from ns-3.36 to ns-3.37
|
||||
* `WifiPhyListener::NotifyMaybeCcaBusyStart` has been renamed to `WifiPhyListener::NotifyCcaBusyStart` and has two additional parameters: the channel type that indicates for which subchannel the CCA-BUSY is reported and a vector of CCA-BUSY durations for each 20 MHz subchannel. A duration of zero indicates CCA is IDLE, and the vector of CCA-BUSY durations is not empty if the PHY supports 802.11ax and the operational channel width is larger than 20 MHz.
|
||||
* Added a new attribute **CcaSensitivity** in WifiPhy for configuring the threshold that corresponds to the minimum received power of a PPDU, that occupies the primary channel, should have to report a CCA-BUSY indication.
|
||||
* Added a new attribute **SecondaryCcaSensitivityThresholds** in VhtConfiguration for configuring the thresholds that corresponds to the minimum received power of a PPDU, that does not occupy the primary 20 MHz channel, should have to report a CCA-BUSY indication. This is made of a tuple, where the first threshold is used for 20 MHz PPDUs, the second one is used for 40 MHz PPDUs and the third one is used for 80 MHz PPDUs.
|
||||
* In `src/internet`, several changes were made to enable auto-generated neighbor cache:
|
||||
* A new helper (NeighborCacheHelper) was added to set up auto-generated neighbor cache.
|
||||
* New NUD_STATE `STATIC_AUTOGENERATED` was added to help the user manage auto-generated entries in Arp cache and Ndisc cache.
|
||||
* Add new callbacks RemoveAddressCallback and AddAddressCallback to dynamically update neighbor cache during addresses are removed/added.
|
||||
* Add NeighborCacheTestSuite to test auto-generated neighbor cache.
|
||||
|
||||
### Changes to existing API
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ Release 3-dev
|
||||
- (lr-wpan) !997 - Adds MAC ACTIVE and PASSIVE scan support
|
||||
- (wifi) CCA has been reworked to report the channel type in the CCA-BUSY indication and the per-20 MHz CCA bitmap for 802.11ax.
|
||||
- (wifi) PPDUs are transmitted on the largest primary channel that is found to be idle (according to the CCA-BUSY indication provided by the PHY) when gaining a TXOP.
|
||||
- (internet) Add auto-generate ARP/NDISC cache, as the outcome of GSoC 2022 project.
|
||||
|
||||
### Bugs fixed
|
||||
|
||||
|
||||
@@ -244,6 +244,13 @@ address resolution in simulations that are focused on other performance aspects.
|
||||
The state of entries which are generated by NeighborCacheHelper is ``STATIC_AUTOGENERATED``,
|
||||
which is similar to ``PERMANENT``, but they are not manually added or removed by user, they
|
||||
will be managed by NeighborCacheHelper when user need pre-generate cache.
|
||||
When user is generating neighbor caches globally, neighbor caches will update dynamically when
|
||||
IPv4 addresses are removed or added; when user is generating neighbor caches partially,
|
||||
NeighborCacheHelper will take care of address removal, for adding address user may rerun a
|
||||
reduced-scope PopulateNeighbor() again to pick up the new IP address or manually
|
||||
add an entry to keep the neighbor cache up-to-date, the reason is that: when PopulateNeighborCache()
|
||||
has previously been run with a scope less than global, the code does not know whether it was previously
|
||||
run with a scope of Channel, NetDeviceContainer, or Ip interface container.
|
||||
The source code for NeighborCache is located in ``src/internet/helper/neighbor-cache-helper``
|
||||
A complete example is in ``src/internet/examples/neighbor-cache-example.cc``.
|
||||
|
||||
|
||||
@@ -501,6 +501,13 @@ neighbor discovery in simulations that are focused on other performance aspects.
|
||||
The state of entries generate by NeighborCacheHelper is ``STATIC_AUTOGENERATED``,
|
||||
which is similar to ``PERMANENT``, but they are not manually added or removed by user, they
|
||||
will be managed by NeighborCacheHelper when user need pre-generate cache.
|
||||
When user is generating neighbor caches globally, neighbor caches will update dynamically when
|
||||
IPv6 addresses are removed or added; when user is generating neighbor caches partially,
|
||||
NeighborCacheHelper will take care of address removal, for adding address user may rerun a
|
||||
reduced-scope PopulateNeighbor() again to pick up the new IP address or manually
|
||||
add an entry to keep the neighbor cache up-to-date, the reason is that: when PopulateNeighborCache()
|
||||
has previously been run with a scope less than global, the code does not know whether it was previously
|
||||
run with a scope of Channel, NetDeviceContainer, or Ip interface container.
|
||||
The source code for NeighborCache is located in ``src/internet/helper/neighbor-cache-helper``
|
||||
A complete example is in ``src/internet/examples/neighbor-cache-example.cc``.
|
||||
|
||||
|
||||
@@ -16,3 +16,12 @@ build_lib_example(
|
||||
${libinternet}
|
||||
${libnetwork}
|
||||
)
|
||||
|
||||
build_lib_example(
|
||||
NAME neighbor-cache-dynamic
|
||||
SOURCE_FILES neighbor-cache-dynamic.cc
|
||||
LIBRARIES_TO_LINK
|
||||
${libcsma}
|
||||
${libinternet}
|
||||
${libnetwork}
|
||||
)
|
||||
|
||||
270
src/internet/examples/neighbor-cache-dynamic.cc
Normal file
270
src/internet/examples/neighbor-cache-dynamic.cc
Normal file
@@ -0,0 +1,270 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2022 ZHIHENG DONG
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Zhiheng Dong <dzh2077@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* This example shows how neighbor caches generate dynamically, when
|
||||
* user is generating neighbor caches globally, neighbor caches will
|
||||
* update dynamically when IPv4/IPv6 addresses are removed or added;
|
||||
* when user is generating neighbor caches partially, NeighborCacheHelper
|
||||
* will take care of address removal, for adding address user may manually
|
||||
* add entry to keep the neighbor cache up-to-date.
|
||||
*
|
||||
* IPv4 Network Topology
|
||||
* \verbatim
|
||||
n1 n2 n3
|
||||
| | |
|
||||
===========
|
||||
LAN 10.1.1.0
|
||||
\endverbatim
|
||||
*
|
||||
* IPv6 Network Topology
|
||||
* \verbatim
|
||||
n1 n2 n3
|
||||
| | |
|
||||
===========
|
||||
LAN 2001:1::/64
|
||||
\endverbatim
|
||||
*
|
||||
* Expected Outputs:
|
||||
* IPv4 (default):
|
||||
* \verbatim
|
||||
ARP Cache of node 0 at time 0
|
||||
10.1.1.2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
10.1.1.3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
ARP Cache of node 1 at time 0
|
||||
10.1.1.1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
10.1.1.3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
ARP Cache of node 2 at time 0
|
||||
10.1.1.1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
10.1.1.2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
|
||||
Arp caches after add address 10.1.1.4 to n1
|
||||
ARP Cache of node 0 at time 1
|
||||
10.1.1.2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
10.1.1.3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
ARP Cache of node 1 at time 1
|
||||
10.1.1.1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
10.1.1.3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
10.1.1.4 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
ARP Cache of node 2 at time 1
|
||||
10.1.1.1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
10.1.1.2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
10.1.1.4 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
|
||||
Arp caches after remove the first address (10.1.1.1) from n1
|
||||
ARP Cache of node 0 at time 2
|
||||
10.1.1.2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
10.1.1.3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
ARP Cache of node 1 at time 2
|
||||
10.1.1.3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
10.1.1.4 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
ARP Cache of node 2 at time 2
|
||||
10.1.1.2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
10.1.1.4 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
\endverbatim
|
||||
*
|
||||
* IPv6 (--useIPv6):
|
||||
* \verbatim
|
||||
NDISC Cache of node 0 at time +0s
|
||||
2001:1::200:ff:fe00:2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
2001:1::200:ff:fe00:3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
NDISC Cache of node 1 at time +0s
|
||||
2001:1::200:ff:fe00:1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
2001:1::200:ff:fe00:3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
NDISC Cache of node 2 at time +0s
|
||||
2001:1::200:ff:fe00:1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
2001:1::200:ff:fe00:2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
|
||||
Ndisc caches after add address 2001:1::200:ff:fe00:4 n1
|
||||
NDISC Cache of node 0 at time +1s
|
||||
2001:1::200:ff:fe00:2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
2001:1::200:ff:fe00:3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
NDISC Cache of node 1 at time +1s
|
||||
2001:1::200:ff:fe00:1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
2001:1::200:ff:fe00:3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
2001:1::200:ff:fe00:4 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
NDISC Cache of node 2 at time +1s
|
||||
2001:1::200:ff:fe00:1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
2001:1::200:ff:fe00:2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
2001:1::200:ff:fe00:4 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
|
||||
Arp caches after remove the second address (2001:1::200:ff:fe00:1) from n1
|
||||
NDISC Cache of node 0 at time +2s
|
||||
2001:1::200:ff:fe00:2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
2001:1::200:ff:fe00:3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
NDISC Cache of node 1 at time +2s
|
||||
2001:1::200:ff:fe00:3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
2001:1::200:ff:fe00:4 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:3 dev 0 lladdr 02-06-00:00:00:00:00:03 STATIC_AUTOGENERATED
|
||||
NDISC Cache of node 2 at time +2s
|
||||
2001:1::200:ff:fe00:2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
2001:1::200:ff:fe00:4 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:1 dev 0 lladdr 02-06-00:00:00:00:00:01 STATIC_AUTOGENERATED
|
||||
fe80::200:ff:fe00:2 dev 0 lladdr 02-06-00:00:00:00:00:02 STATIC_AUTOGENERATED
|
||||
\endverbatim
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/network-module.h"
|
||||
#include "ns3/csma-module.h"
|
||||
#include "ns3/internet-module.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("NeighborCacheDynamic");
|
||||
|
||||
void AddIpv4Address (Ptr<Ipv4Interface> ipv4Interface, Ipv4InterfaceAddress ifaceAddr)
|
||||
{
|
||||
ipv4Interface->AddAddress (ifaceAddr);
|
||||
std::cout << "\nArp caches after add address 10.1.1.4 to n1" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void AddIpv6Address (Ptr<Ipv6Interface> ipv6Interface, Ipv6InterfaceAddress ifaceAddr)
|
||||
{
|
||||
ipv6Interface->AddAddress (ifaceAddr);
|
||||
std::cout << "\nNdisc caches after add address 2001:1::200:ff:fe00:4 n1" << std::endl;
|
||||
}
|
||||
|
||||
void RemoveIpv4Address (Ptr<Ipv4Interface> ipv4Interface, uint32_t index)
|
||||
{
|
||||
ipv4Interface->RemoveAddress (index);
|
||||
std::cout << "\nArp caches after remove the first address (10.1.1.1) from n1" << std::endl;
|
||||
}
|
||||
|
||||
void RemoveIpv6Address (Ptr<Ipv6Interface> ipv6Interface, uint32_t index)
|
||||
{
|
||||
ipv6Interface->RemoveAddress (index);
|
||||
std::cout << "\nArp caches after remove the second address (2001:1::200:ff:fe00:1) from n1" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
bool useIpv6 = false;
|
||||
bool enableLog = false;
|
||||
|
||||
CommandLine cmd (__FILE__);
|
||||
cmd.AddValue ("useIPv6", "Use IPv6 instead of IPv4", useIpv6);
|
||||
cmd.AddValue ("enableLog", "Enable ArpL3Protocol and Icmpv6L4Protocol logging", enableLog);
|
||||
cmd.Parse (argc,argv);
|
||||
|
||||
if (enableLog)
|
||||
{
|
||||
LogComponentEnable ("ArpL3Protocol", LOG_LEVEL_LOGIC);
|
||||
LogComponentEnable ("Icmpv6L4Protocol", LOG_LEVEL_LOGIC);
|
||||
}
|
||||
|
||||
uint32_t nCsma = 3;
|
||||
NodeContainer csmaNodes;
|
||||
csmaNodes.Create (nCsma);
|
||||
|
||||
CsmaHelper csma;
|
||||
csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
|
||||
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
|
||||
|
||||
NetDeviceContainer csmaDevices;
|
||||
csmaDevices = csma.Install (csmaNodes);
|
||||
|
||||
InternetStackHelper stack;
|
||||
stack.Install (csmaNodes);
|
||||
|
||||
if (!useIpv6)
|
||||
{
|
||||
Ipv4AddressHelper address;
|
||||
address.SetBase ("10.1.1.0", "255.255.255.0");
|
||||
Ipv4InterfaceContainer csmaInterfaces;
|
||||
csmaInterfaces = address.Assign (csmaDevices);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ipv6AddressHelper address;
|
||||
address.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64));
|
||||
Ipv6InterfaceContainer csmaInterfaces;
|
||||
csmaInterfaces = address.Assign (csmaDevices);
|
||||
}
|
||||
|
||||
// Populate neighbor caches for all devices
|
||||
NeighborCacheHelper neighborCache;
|
||||
neighborCache.SetDynamicNeighborCache (true);
|
||||
neighborCache.PopulateNeighborCache ();
|
||||
|
||||
if (!useIpv6)
|
||||
{
|
||||
// Add address 10.1.1.4 to interface 1 in 0.5 seconds
|
||||
Ptr<Node> n1 = csmaNodes.Get (0);
|
||||
uint32_t ipv4ifIndex = 1;
|
||||
Ptr<Ipv4Interface> ipv4Interface = n1->GetObject<Ipv4L3Protocol> ()->GetInterface (ipv4ifIndex);
|
||||
Ipv4InterfaceAddress ifaceAddr = Ipv4InterfaceAddress ("10.1.1.4","255.255.255.0");
|
||||
Simulator::Schedule (Seconds (0.5),&AddIpv4Address,ipv4Interface, ifaceAddr);
|
||||
|
||||
// Remove the first address (10.1.1.1) from interface 1 in 1.5 seconds
|
||||
uint32_t addressIndex = 0;
|
||||
Simulator::Schedule (Seconds (1.5),&RemoveIpv4Address,ipv4Interface, addressIndex);
|
||||
|
||||
Ptr<OutputStreamWrapper> outputStream = Create<OutputStreamWrapper> (&std::cout);
|
||||
Ipv4RoutingHelper::PrintNeighborCacheAllAt (Seconds (0), outputStream);
|
||||
Ipv4RoutingHelper::PrintNeighborCacheAllAt (Seconds (1), outputStream);
|
||||
Ipv4RoutingHelper::PrintNeighborCacheAllAt (Seconds (2), outputStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add address 2001:1::200:ff:fe00:4 to interface 1 in 0.5 seconds
|
||||
Ptr<Node> n1 = csmaNodes.Get (0);
|
||||
uint32_t ipv6ifIndex = 1;
|
||||
Ptr<Ipv6Interface> ipv6Interface = n1->GetObject<Ipv6L3Protocol> ()->GetInterface (ipv6ifIndex);
|
||||
Ipv6InterfaceAddress ifaceAddr = Ipv6InterfaceAddress ( "2001:1::200:ff:fe00:4", Ipv6Prefix (64));
|
||||
Simulator::Schedule (Seconds (0.5),&AddIpv6Address,ipv6Interface, ifaceAddr);
|
||||
|
||||
// Remove the second address (2001:1::200:ff:fe00:1) from interface 1 in 1.5 seconds
|
||||
uint32_t addressIndex = 1;
|
||||
Simulator::Schedule (Seconds (1.5),&RemoveIpv6Address,ipv6Interface, addressIndex);
|
||||
|
||||
Ptr<OutputStreamWrapper> outputStream = Create<OutputStreamWrapper> (&std::cout);
|
||||
Ipv6RoutingHelper::PrintNeighborCacheAllAt (Seconds (0), outputStream);
|
||||
Ipv6RoutingHelper::PrintNeighborCacheAllAt (Seconds (1), outputStream);
|
||||
Ipv6RoutingHelper::PrintNeighborCacheAllAt (Seconds (2), outputStream);
|
||||
|
||||
}
|
||||
|
||||
Simulator::Stop (Seconds (10.0));
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
return 0;
|
||||
}
|
||||
@@ -43,9 +43,10 @@ NeighborCacheHelper::~NeighborCacheHelper ()
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
void
|
||||
NeighborCacheHelper::PopulateNeighborCache (void) const
|
||||
NeighborCacheHelper::PopulateNeighborCache (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_globalNeighborCache = true;
|
||||
for (uint32_t i = 0; i < ChannelList::GetNChannels (); ++i)
|
||||
{
|
||||
Ptr<Channel> channel = ChannelList::GetChannel (i);
|
||||
@@ -205,6 +206,14 @@ NeighborCacheHelper::PopulateNeighborEntriesIpv4 (Ptr<Ipv4Interface> ipv4Interfa
|
||||
{
|
||||
uint32_t netDeviceAddresses = ipv4Interface->GetNAddresses ();
|
||||
uint32_t neighborDeviceAddresses = neighborDeviceInterface->GetNAddresses ();
|
||||
if (m_dynamicNeighborCache)
|
||||
{
|
||||
ipv4Interface->RemoveAddressCallback (MakeCallback (&NeighborCacheHelper::UpdateCacheByIpv4AddressRemoved, this));
|
||||
if (m_globalNeighborCache)
|
||||
{
|
||||
ipv4Interface->AddAddressCallback (MakeCallback (&NeighborCacheHelper::UpdateCacheByIpv4AddressAdded, this));
|
||||
}
|
||||
}
|
||||
for (uint32_t n = 0; n < netDeviceAddresses; ++n)
|
||||
{
|
||||
Ipv4InterfaceAddress netDeviceIfAddr = ipv4Interface->GetAddress (n);
|
||||
@@ -226,6 +235,14 @@ NeighborCacheHelper::PopulateNeighborEntriesIpv6 (Ptr<Ipv6Interface> ipv6Interfa
|
||||
{
|
||||
uint32_t netDeviceAddresses = ipv6Interface->GetNAddresses ();
|
||||
uint32_t neighborDeviceAddresses = neighborDeviceInterface->GetNAddresses ();
|
||||
if (m_dynamicNeighborCache)
|
||||
{
|
||||
ipv6Interface->RemoveAddressCallback (MakeCallback (&NeighborCacheHelper::UpdateCacheByIpv6AddressRemoved, this));
|
||||
if (m_globalNeighborCache)
|
||||
{
|
||||
ipv6Interface->AddAddressCallback (MakeCallback (&NeighborCacheHelper::UpdateCacheByIpv6AddressAdded, this));
|
||||
}
|
||||
}
|
||||
for (uint32_t n = 0; n < netDeviceAddresses; ++n)
|
||||
{
|
||||
Ipv6InterfaceAddress netDeviceIfAddr = ipv6Interface->GetAddress (n);
|
||||
@@ -333,7 +350,133 @@ NeighborCacheHelper::FlushAutoGenerated (void) const
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
NeighborCacheHelper::UpdateCacheByIpv4AddressRemoved (const Ptr<Ipv4Interface> interface, const Ipv4InterfaceAddress ifAddr) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
Ptr<NetDevice> netDevice = interface->GetDevice ();
|
||||
Ptr<Channel> channel = netDevice->GetChannel ();
|
||||
for (std::size_t i = 0; i < channel->GetNDevices (); ++i)
|
||||
{
|
||||
Ptr<NetDevice> neighborDevice = channel->GetDevice (i);
|
||||
Ptr<Node> neighborNode = neighborDevice->GetNode ();
|
||||
int32_t neighborInterfaceIndex = neighborNode->GetObject<Ipv4> ()->GetInterfaceForDevice (neighborDevice);
|
||||
if (neighborInterfaceIndex != -1)
|
||||
{
|
||||
Ptr<Ipv4Interface> neighborInterface = neighborNode->GetObject<Ipv4L3Protocol> ()->GetInterface (neighborInterfaceIndex);
|
||||
Ptr<ArpCache> arpCache = neighborInterface->GetArpCache ();
|
||||
if (!arpCache)
|
||||
{
|
||||
NS_LOG_LOGIC ("ArpCache doesn't exist");
|
||||
return;
|
||||
}
|
||||
ArpCache::Entry *entry = arpCache->Lookup (ifAddr.GetLocal ());
|
||||
if (entry)
|
||||
{
|
||||
arpCache->Remove (entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NeighborCacheHelper::UpdateCacheByIpv4AddressAdded (const Ptr<Ipv4Interface> interface, const Ipv4InterfaceAddress ifAddr) const
|
||||
{
|
||||
|
||||
NS_LOG_FUNCTION (this);
|
||||
Ptr<NetDevice> netDevice = interface->GetDevice ();
|
||||
Ptr<Channel> channel = netDevice->GetChannel ();
|
||||
for (std::size_t i = 0; i < channel->GetNDevices (); ++i)
|
||||
{
|
||||
Ptr<NetDevice> neighborDevice = channel->GetDevice (i);
|
||||
if (neighborDevice != netDevice)
|
||||
{
|
||||
Ptr<Node> neighborNode = neighborDevice->GetNode ();
|
||||
int32_t neighborInterfaceIndex = neighborNode->GetObject<Ipv4> ()->GetInterfaceForDevice (neighborDevice);
|
||||
if (neighborInterfaceIndex != -1)
|
||||
{
|
||||
Ptr<Ipv4Interface> neighborInterface = neighborNode->GetObject<Ipv4L3Protocol> ()->GetInterface (neighborInterfaceIndex);
|
||||
uint32_t neighborDeviceAddresses = neighborInterface->GetNAddresses ();
|
||||
for (uint32_t m = 0; m < neighborDeviceAddresses; ++m)
|
||||
{
|
||||
Ipv4InterfaceAddress neighborDeviceIfAddr = neighborInterface->GetAddress (m);
|
||||
if (ifAddr.IsInSameSubnet (neighborDeviceIfAddr.GetLocal ()))
|
||||
{
|
||||
// Add Arp entity of current interface to its neighbor's Arp cache
|
||||
AddEntry (neighborInterface, ifAddr.GetAddress (),netDevice->GetAddress () );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NeighborCacheHelper::UpdateCacheByIpv6AddressRemoved (const Ptr<Ipv6Interface> interface, const Ipv6InterfaceAddress ifAddr) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
Ptr<NetDevice> netDevice = interface->GetDevice ();
|
||||
Ptr<Channel> channel = netDevice->GetChannel ();
|
||||
for (std::size_t i = 0; i < channel->GetNDevices (); ++i)
|
||||
{
|
||||
Ptr<NetDevice> neighborDevice = channel->GetDevice (i);
|
||||
Ptr<Node> neighborNode = neighborDevice->GetNode ();
|
||||
int32_t neighborInterfaceIndex = neighborNode->GetObject<Ipv6> ()->GetInterfaceForDevice (neighborDevice);
|
||||
if (neighborInterfaceIndex != -1)
|
||||
{
|
||||
Ptr<Ipv6Interface> neighborInterface = neighborNode->GetObject<Ipv6L3Protocol> ()->GetInterface (neighborInterfaceIndex);
|
||||
Ptr<NdiscCache> ndiscCache = neighborInterface->GetNdiscCache ();
|
||||
if (!ndiscCache)
|
||||
{
|
||||
NS_LOG_LOGIC ("ndiscCache doesn't exist");
|
||||
return;
|
||||
}
|
||||
NdiscCache::Entry *entry = ndiscCache->Lookup (ifAddr.GetAddress ());
|
||||
if (entry)
|
||||
{
|
||||
ndiscCache->Remove (entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NeighborCacheHelper::UpdateCacheByIpv6AddressAdded (const Ptr<Ipv6Interface> interface, const Ipv6InterfaceAddress ifAddr) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
Ptr<NetDevice> netDevice = interface->GetDevice ();
|
||||
Ptr<Channel> channel = netDevice->GetChannel ();
|
||||
for (std::size_t i = 0; i < channel->GetNDevices (); ++i)
|
||||
{
|
||||
Ptr<NetDevice> neighborDevice = channel->GetDevice (i);
|
||||
if (neighborDevice != netDevice)
|
||||
{
|
||||
Ptr<Node> neighborNode = neighborDevice->GetNode ();
|
||||
int32_t neighborInterfaceIndex = neighborNode->GetObject<Ipv6> ()->GetInterfaceForDevice (neighborDevice);
|
||||
if (neighborInterfaceIndex != -1)
|
||||
{
|
||||
Ptr<Ipv6Interface> neighborInterface = neighborNode->GetObject<Ipv6L3Protocol> ()->GetInterface (neighborInterfaceIndex);
|
||||
uint32_t neighborDeviceAddresses = neighborInterface->GetNAddresses ();
|
||||
for (uint32_t m = 0; m < neighborDeviceAddresses; ++m)
|
||||
{
|
||||
Ipv6InterfaceAddress neighborDeviceIfAddr = neighborInterface->GetAddress (m);
|
||||
if (ifAddr.IsInSameSubnet (neighborDeviceIfAddr.GetAddress ()))
|
||||
{
|
||||
// Add Arp entity of current interface to its neighbor's Arp cache
|
||||
AddEntry (neighborInterface, ifAddr.GetAddress (),netDevice->GetAddress () );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NeighborCacheHelper::SetDynamicNeighborCache (bool enable)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_dynamicNeighborCache = enable;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
* \brief Populate neighbor ARP and NDISC caches for all devices.
|
||||
* This method walks the global ChannelList.
|
||||
*/
|
||||
void PopulateNeighborCache (void) const;
|
||||
void PopulateNeighborCache (void);
|
||||
|
||||
/**
|
||||
* \brief Populate neighbor ARP and NDISC caches for all devices in the given
|
||||
@@ -94,6 +94,15 @@ public:
|
||||
*/
|
||||
void FlushAutoGenerated (void) const;
|
||||
|
||||
/**
|
||||
* \brief Enable/diable dynamic neighbor cache, auto-generated neighbor cache will update
|
||||
* by IP addresses changed when dynamic neighbor cache enabled. User should ensure that
|
||||
* the NeighborCacheHelper object persists for the duration of the simulation when dynamic
|
||||
* neighbor cache is enabled.
|
||||
* \param enable enable state
|
||||
*/
|
||||
void SetDynamicNeighborCache (bool enable);
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Populate neighbor ARP entries for given IPv4 interface.
|
||||
@@ -125,6 +134,39 @@ private:
|
||||
*/
|
||||
void AddEntry (Ptr<Ipv6Interface> netDeviceInterface, Ipv6Address ipv6Address, Address macAddress) const;
|
||||
|
||||
/**
|
||||
* \brief Update neighbor caches when an address is removed from a Ipv4Interface with auto generated neighbor cache.
|
||||
* \param interface the Ipv4Interface that address removed from.
|
||||
* \param ifAddr the removed IPv4 interface address .
|
||||
*/
|
||||
void UpdateCacheByIpv4AddressRemoved (const Ptr<Ipv4Interface> interface, const Ipv4InterfaceAddress ifAddr) const;
|
||||
|
||||
/**
|
||||
* \brief Update neighbor caches when an address is added to a Ipv4Interface with auto generated neighbor cache.
|
||||
* \param interface the Ipv4Interface that address added to.
|
||||
* \param ifAddr the added IPv4 interface address.
|
||||
*/
|
||||
void UpdateCacheByIpv4AddressAdded (const Ptr<Ipv4Interface> interface, const Ipv4InterfaceAddress ifAddr) const;
|
||||
|
||||
/**
|
||||
* \brief Update neighbor caches when an address is removed from a Ipv6Interface with auto generated neighbor cache.
|
||||
* \param interface the Ipv6Interface that address removed from.
|
||||
* \param ifAddr the removed IPv6 interface address.
|
||||
*/
|
||||
void UpdateCacheByIpv6AddressRemoved (const Ptr<Ipv6Interface> interface, const Ipv6InterfaceAddress ifAddr) const;
|
||||
|
||||
/**
|
||||
* \brief Update neighbor cache when an address is added to a Ipv6Interface with auto generated neighbor cache.
|
||||
* \param interface the Ipv6Interface that address added to.
|
||||
* \param ifAddr the added IPv6 interface address.
|
||||
*/
|
||||
void UpdateCacheByIpv6AddressAdded (const Ptr<Ipv6Interface> interface, const Ipv6InterfaceAddress ifAddr) const;
|
||||
|
||||
bool m_globalNeighborCache {false}; //!< flag will set true if neighbor caches were generated for all devices
|
||||
|
||||
bool m_dynamicNeighborCache {false}; //!< flag will set true if dynamic neighbor cache is enabled.
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -310,6 +310,10 @@ Ipv4Interface::AddAddress (Ipv4InterfaceAddress addr)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << addr);
|
||||
m_ifaddrs.push_back (addr);
|
||||
if (!m_addAddressCallback.IsNull ())
|
||||
{
|
||||
m_addAddressCallback(this, addr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -353,6 +357,10 @@ Ipv4Interface::RemoveAddress (uint32_t index)
|
||||
{
|
||||
Ipv4InterfaceAddress addr = *i;
|
||||
m_ifaddrs.erase (i);
|
||||
if (!m_removeAddressCallback.IsNull ())
|
||||
{
|
||||
m_removeAddressCallback(this, addr);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
++tmp;
|
||||
@@ -380,11 +388,29 @@ Ipv4Interface::RemoveAddress(Ipv4Address address)
|
||||
{
|
||||
Ipv4InterfaceAddress ifAddr = *it;
|
||||
m_ifaddrs.erase(it);
|
||||
if (!m_removeAddressCallback.IsNull ())
|
||||
{
|
||||
m_removeAddressCallback(this, ifAddr);
|
||||
}
|
||||
return ifAddr;
|
||||
}
|
||||
}
|
||||
return Ipv4InterfaceAddress();
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Interface::RemoveAddressCallback (Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> removeAddressCallback)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << &removeAddressCallback);
|
||||
m_removeAddressCallback = removeAddressCallback;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Interface::AddAddressCallback (Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> addAddressCallback)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << &addAddressCallback);
|
||||
m_addAddressCallback = addAddressCallback;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
@@ -192,6 +192,25 @@ public:
|
||||
*/
|
||||
Ipv4InterfaceAddress RemoveAddress (Ipv4Address address);
|
||||
|
||||
/**
|
||||
* This callback is set when an address is removed from an interface with
|
||||
* auto-generated Arp cache and it allow the neighbor cache helper to update
|
||||
* neighbor's Arp cache
|
||||
*
|
||||
* \param removeAddressCallback Callback when remove an address.
|
||||
*/
|
||||
void RemoveAddressCallback (Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> removeAddressCallback);
|
||||
|
||||
/**
|
||||
* This callback is set when an address is added from an interface with
|
||||
* auto-generated Arp cache and it allow the neighbor cache helper to update
|
||||
* neighbor's Arp cache
|
||||
*
|
||||
* \param addAddressCallback Callback when remove an address.
|
||||
*/
|
||||
void AddAddressCallback (Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> addAddressCallback);
|
||||
|
||||
|
||||
protected:
|
||||
virtual void DoDispose (void);
|
||||
|
||||
@@ -227,6 +246,9 @@ private:
|
||||
Ptr<NetDevice> m_device; //!< The associated NetDevice
|
||||
Ptr<TrafficControlLayer> m_tc; //!< The associated TrafficControlLayer
|
||||
Ptr<ArpCache> m_cache; //!< ARP cache
|
||||
Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> m_removeAddressCallback; //!< remove address callback
|
||||
Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> m_addAddressCallback; //!< add address callback
|
||||
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -209,6 +209,10 @@ bool Ipv6Interface::AddAddress (Ipv6InterfaceAddress iface)
|
||||
|
||||
Ipv6Address solicited = Ipv6Address::MakeSolicitedAddress (iface.GetAddress ());
|
||||
m_addresses.push_back (std::make_pair (iface, solicited));
|
||||
if (!m_addAddressCallback.IsNull ())
|
||||
{
|
||||
m_addAddressCallback(this, addr);
|
||||
}
|
||||
|
||||
if (!addr.IsAny () || !addr.IsLocalhost ())
|
||||
{
|
||||
@@ -307,6 +311,10 @@ Ipv6InterfaceAddress Ipv6Interface::RemoveAddress (uint32_t index)
|
||||
{
|
||||
Ipv6InterfaceAddress iface = it->first;
|
||||
m_addresses.erase (it);
|
||||
if (!m_removeAddressCallback.IsNull ())
|
||||
{
|
||||
m_removeAddressCallback(this, iface);
|
||||
}
|
||||
return iface;
|
||||
}
|
||||
|
||||
@@ -334,6 +342,10 @@ Ipv6Interface::RemoveAddress(Ipv6Address address)
|
||||
{
|
||||
Ipv6InterfaceAddress iface = it->first;
|
||||
m_addresses.erase(it);
|
||||
if (!m_removeAddressCallback.IsNull ())
|
||||
{
|
||||
m_removeAddressCallback(this, iface);
|
||||
}
|
||||
return iface;
|
||||
}
|
||||
}
|
||||
@@ -522,5 +534,20 @@ Ptr<NdiscCache> Ipv6Interface::GetNdiscCache () const
|
||||
return m_ndCache;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv6Interface::RemoveAddressCallback (Callback<void, Ptr<Ipv6Interface>, Ipv6InterfaceAddress> removeAddressCallback)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << &removeAddressCallback);
|
||||
m_removeAddressCallback = removeAddressCallback;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv6Interface::AddAddressCallback (Callback<void, Ptr<Ipv6Interface>, Ipv6InterfaceAddress> addAddressCallback)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << &addAddressCallback);
|
||||
m_addAddressCallback = addAddressCallback;
|
||||
}
|
||||
|
||||
|
||||
} /* namespace ns3 */
|
||||
|
||||
|
||||
@@ -275,6 +275,24 @@ public:
|
||||
*/
|
||||
Ptr<NdiscCache> GetNdiscCache () const;
|
||||
|
||||
/**
|
||||
* This callback is set when an address is removed from an interface with
|
||||
* auto-generated Ndisc cache and it allow the neighbor cache helper to update
|
||||
* neighbor's Ndisc cache
|
||||
*
|
||||
* \param removeAddressCallback Callback when remove an address.
|
||||
*/
|
||||
void RemoveAddressCallback (Callback<void, Ptr<Ipv6Interface>, Ipv6InterfaceAddress> removeAddressCallback);
|
||||
|
||||
/**
|
||||
* This callback is set when an address is added from an interface with
|
||||
* auto-generated Ndisc cache and it allow the neighbor cache helper to update
|
||||
* neighbor's Ndisc cache
|
||||
*
|
||||
* \param addAddressCallback Callback when remove an address.
|
||||
*/
|
||||
void AddAddressCallback (Callback<void, Ptr<Ipv6Interface>, Ipv6InterfaceAddress> addAddressCallback);
|
||||
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -369,6 +387,10 @@ private:
|
||||
* Time between retransmission of NS.
|
||||
*/
|
||||
uint16_t m_retransTimer;
|
||||
|
||||
Callback<void, Ptr<Ipv6Interface>, Ipv6InterfaceAddress> m_removeAddressCallback; //!< remove address callback
|
||||
|
||||
Callback<void, Ptr<Ipv6Interface>, Ipv6InterfaceAddress> m_addAddressCallback; //!< add address callback
|
||||
};
|
||||
|
||||
} /* namespace ns3 */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user