internet: Allow InternetStackHelper to be called on a node with IPv4 or IPv6 already installed
This commit is contained in:
@@ -55,6 +55,7 @@ Changes from ns-3.38 to ns-3-dev
|
||||
* (internet) The function signature of `Ipv4RoutingProtocol::RouteInput` and `Ipv6RoutingProtocol::RouteInput` have changed. The `UnicastForwardCallback` (ucb), `MulticastForwardCallback` (mcb), `LocalDeliverCallback` (lcb) and `ErrorCallback` (ecb) should now be passed as const references.
|
||||
* (olsr) The defines `OLSR_WILL_*` have been replaced by enum `Willingness`.
|
||||
* (wifi) The `WifiCodeRate` typedef was converted to an enum.
|
||||
* (internet) `InternetStackHelper` can be now used on nodes with an `InternetStack` already installed (it will not install IPv[4,6] twice).
|
||||
|
||||
### Changes to build system
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ This release has discontinued support for g++-8 compilers.
|
||||
- (wifi) Added 802.11ax dual NAV (basic NAV and intra-BSS NAV)
|
||||
- (wifi) Added 802.11ax Uplink Multi-User Carrier Sense (UL MU CS) mechanism and have it used by non-AP STAs when determining if they can reply to a received Trigger Frame
|
||||
- (wifi) Added support for 802.11ax MU-RTS/CTS protection
|
||||
- (internet) InternetStackHelper can be now used on nodes with an InternetStack already installed (it will not install IPv[4,6] twice).
|
||||
|
||||
### Bugs fixed
|
||||
|
||||
|
||||
@@ -262,6 +262,7 @@ endif()
|
||||
set(test_sources
|
||||
test/global-route-manager-impl-test-suite.cc
|
||||
test/icmp-test.cc
|
||||
test/internet-stack-helper-test-suite.cc
|
||||
test/ipv4-address-generator-test-suite.cc
|
||||
test/ipv4-address-helper-test-suite.cc
|
||||
test/ipv4-deduplication-test.cc
|
||||
|
||||
@@ -290,6 +290,12 @@ InternetStackHelper::InstallAll() const
|
||||
void
|
||||
InternetStackHelper::CreateAndAggregateObjectFromTypeId(Ptr<Node> node, const std::string typeId)
|
||||
{
|
||||
TypeId tid = TypeId::LookupByName(typeId);
|
||||
if (node->GetObject<Object>(tid))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectFactory factory;
|
||||
factory.SetTypeId(typeId);
|
||||
Ptr<Object> protocol = factory.Create<Object>();
|
||||
@@ -301,13 +307,7 @@ InternetStackHelper::Install(Ptr<Node> node) const
|
||||
{
|
||||
if (m_ipv4Enabled)
|
||||
{
|
||||
if (node->GetObject<Ipv4>())
|
||||
{
|
||||
NS_FATAL_ERROR("InternetStackHelper::Install (): Aggregating "
|
||||
"an InternetStack to a node with an existing Ipv4 object");
|
||||
return;
|
||||
}
|
||||
|
||||
/* IPv4 stack */
|
||||
CreateAndAggregateObjectFromTypeId(node, "ns3::ArpL3Protocol");
|
||||
CreateAndAggregateObjectFromTypeId(node, "ns3::Ipv4L3Protocol");
|
||||
CreateAndAggregateObjectFromTypeId(node, "ns3::Icmpv4L4Protocol");
|
||||
@@ -318,22 +318,19 @@ InternetStackHelper::Install(Ptr<Node> node) const
|
||||
arp->SetAttribute("RequestJitter",
|
||||
StringValue("ns3::ConstantRandomVariable[Constant=0.0]"));
|
||||
}
|
||||
|
||||
// Set routing
|
||||
Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
|
||||
if (!ipv4->GetRoutingProtocol())
|
||||
{
|
||||
Ptr<Ipv4RoutingProtocol> ipv4Routing = m_routing->Create(node);
|
||||
ipv4->SetRoutingProtocol(ipv4Routing);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ipv6Enabled)
|
||||
{
|
||||
/* IPv6 stack */
|
||||
if (node->GetObject<Ipv6>())
|
||||
{
|
||||
NS_FATAL_ERROR("InternetStackHelper::Install (): Aggregating "
|
||||
"an InternetStack to a node with an existing Ipv6 object");
|
||||
return;
|
||||
}
|
||||
|
||||
CreateAndAggregateObjectFromTypeId(node, "ns3::Ipv6L3Protocol");
|
||||
CreateAndAggregateObjectFromTypeId(node, "ns3::Icmpv6L4Protocol");
|
||||
if (m_ipv6NsRsJitterEnabled == false)
|
||||
@@ -345,9 +342,11 @@ InternetStackHelper::Install(Ptr<Node> node) const
|
||||
}
|
||||
// Set routing
|
||||
Ptr<Ipv6> ipv6 = node->GetObject<Ipv6>();
|
||||
if (!ipv6->GetRoutingProtocol())
|
||||
{
|
||||
Ptr<Ipv6RoutingProtocol> ipv6Routing = m_routingv6->Create(node);
|
||||
ipv6->SetRoutingProtocol(ipv6Routing);
|
||||
|
||||
}
|
||||
/* register IPv6 extensions and options */
|
||||
ipv6->RegisterExtensions();
|
||||
ipv6->RegisterOptions();
|
||||
@@ -357,10 +356,18 @@ InternetStackHelper::Install(Ptr<Node> node) const
|
||||
{
|
||||
CreateAndAggregateObjectFromTypeId(node, "ns3::TrafficControlLayer");
|
||||
CreateAndAggregateObjectFromTypeId(node, "ns3::UdpL4Protocol");
|
||||
// note: the following could be changed to
|
||||
// CreateAndAggregateObjectFromTypeId(node, "ns3::TcpL4Protocol");
|
||||
if (!node->GetObject<TcpL4Protocol>())
|
||||
{
|
||||
node->AggregateObject(m_tcpFactory.Create<Object>());
|
||||
}
|
||||
if (!node->GetObject<PacketSocketFactory>())
|
||||
{
|
||||
Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory>();
|
||||
node->AggregateObject(factory);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ipv4Enabled)
|
||||
{
|
||||
|
||||
@@ -144,8 +144,8 @@ class InternetStackHelper : public PcapHelperForIpv4,
|
||||
|
||||
/**
|
||||
* Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes
|
||||
* onto the provided node. This method will assert if called on a node that
|
||||
* already has an Ipv4 object aggregated to it.
|
||||
* onto the provided node. This method will do nothing if the stacks are already installed,
|
||||
* and will not overwrite existing stacks parameters.
|
||||
*
|
||||
* \param nodeName The name of the node on which to install the stack.
|
||||
*/
|
||||
@@ -153,8 +153,8 @@ class InternetStackHelper : public PcapHelperForIpv4,
|
||||
|
||||
/**
|
||||
* Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes
|
||||
* onto the provided node. This method will assert if called on a node that
|
||||
* already has an Ipv4 object aggregated to it.
|
||||
* onto the provided node. This method will do nothing if the stacks are already installed,
|
||||
* and will not overwrite existing stacks parameters.
|
||||
*
|
||||
* \param node The node on which to install the stack.
|
||||
*/
|
||||
@@ -162,9 +162,8 @@ class InternetStackHelper : public PcapHelperForIpv4,
|
||||
|
||||
/**
|
||||
* For each node in the input container, aggregate implementations of the
|
||||
* ns3::Ipv4, ns3::Ipv6, ns3::Udp, and, ns3::Tcp classes. The program will assert
|
||||
* if this method is called on a container with a node that already has
|
||||
* an Ipv4 object aggregated to it.
|
||||
* ns3::Ipv4, ns3::Ipv6, ns3::Udp, and, ns3::Tcp classes. This method will do nothing if the
|
||||
* stacks are already installed, and will not overwrite existing stacks parameters.
|
||||
*
|
||||
* \param c NodeContainer that holds the set of nodes on which to install the
|
||||
* new stacks.
|
||||
@@ -306,7 +305,8 @@ class InternetStackHelper : public PcapHelperForIpv4,
|
||||
const Ipv6RoutingHelper* m_routingv6;
|
||||
|
||||
/**
|
||||
* \brief create an object from its TypeId and aggregates it to the node
|
||||
* \brief create an object from its TypeId and aggregates it to the node. Does nothing if
|
||||
* an object of the same type is already aggregated to the node.
|
||||
* \param node the node
|
||||
* \param typeId the object TypeId
|
||||
*/
|
||||
|
||||
@@ -1650,6 +1650,10 @@ Ipv6L3Protocol::BuildHeader(Ipv6Address src,
|
||||
void
|
||||
Ipv6L3Protocol::RegisterExtensions()
|
||||
{
|
||||
if (m_node->GetObject<Ipv6ExtensionDemux>())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux>();
|
||||
ipv6ExtensionDemux->SetNode(m_node);
|
||||
|
||||
@@ -1686,6 +1690,10 @@ Ipv6L3Protocol::RegisterExtensions()
|
||||
void
|
||||
Ipv6L3Protocol::RegisterOptions()
|
||||
{
|
||||
if (m_node->GetObject<Ipv6OptionDemux>())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux>();
|
||||
ipv6OptionDemux->SetNode(m_node);
|
||||
|
||||
|
||||
@@ -368,14 +368,7 @@ class Ipv6L3Protocol : public Ipv6
|
||||
Ipv6Prefix mask,
|
||||
Ipv6Address defaultRouter);
|
||||
|
||||
/**
|
||||
* \brief Register the IPv6 Extensions.
|
||||
*/
|
||||
void RegisterExtensions() override;
|
||||
|
||||
/**
|
||||
* \brief Register the IPv6 Options.
|
||||
*/
|
||||
void RegisterOptions() override;
|
||||
|
||||
/**
|
||||
|
||||
@@ -383,12 +383,14 @@ class Ipv6 : public Object
|
||||
Ptr<Ipv6Route> route) = 0;
|
||||
|
||||
/**
|
||||
* \brief Register the IPv6 Extensions.
|
||||
* \brief Register the IPv6 Extensions. Does nothing if the Extensions have been already
|
||||
* registered.
|
||||
*/
|
||||
virtual void RegisterExtensions() = 0;
|
||||
|
||||
/**
|
||||
* \brief Register the IPv6 Options.
|
||||
* \brief Register the IPv6 Options. Does nothing if the Options have been already
|
||||
* registered.
|
||||
*/
|
||||
virtual void RegisterOptions() = 0;
|
||||
|
||||
|
||||
158
src/internet/test/internet-stack-helper-test-suite.cc
Normal file
158
src/internet/test/internet-stack-helper-test-suite.cc
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Universita' di Firenze
|
||||
*
|
||||
* 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: Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
*/
|
||||
|
||||
#include "ns3/internet-stack-helper.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/test.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE("InternetStackHelperTestSuite");
|
||||
|
||||
/**
|
||||
* \ingroup internet-test
|
||||
*
|
||||
* \brief InternetStackHelper Test
|
||||
*/
|
||||
class InternetStackHelperTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
InternetStackHelperTestCase();
|
||||
|
||||
private:
|
||||
void DoRun() override;
|
||||
void DoTeardown() override;
|
||||
};
|
||||
|
||||
InternetStackHelperTestCase::InternetStackHelperTestCase()
|
||||
: TestCase("InternetStackHelperTestCase")
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
InternetStackHelperTestCase::DoRun()
|
||||
{
|
||||
// Checks:
|
||||
// 1. IPv4 only, add IPv4 + IPv6 (result, IPv4 + IPv6)
|
||||
// 2. IPv6 only, add IPv4 + IPv6 (result, IPv4 + IPv6)
|
||||
// 3. IPv4 + IPv6, add IPv4 + IPv6 (result, IPv4 + IPv6)
|
||||
|
||||
Ptr<Node> nodeIpv4Only = CreateObject<Node>();
|
||||
Ptr<Node> nodeIpv6Only = CreateObject<Node>();
|
||||
Ptr<Node> nodeIpv46 = CreateObject<Node>();
|
||||
|
||||
InternetStackHelper internet;
|
||||
|
||||
internet.SetIpv4StackInstall(true);
|
||||
internet.SetIpv6StackInstall(false);
|
||||
internet.Install(nodeIpv4Only);
|
||||
|
||||
internet.SetIpv4StackInstall(false);
|
||||
internet.SetIpv6StackInstall(true);
|
||||
internet.Install(nodeIpv6Only);
|
||||
|
||||
internet.SetIpv4StackInstall(true);
|
||||
internet.SetIpv6StackInstall(true);
|
||||
internet.Install(nodeIpv46);
|
||||
|
||||
// Check that the three nodes have only the intended IP stack.
|
||||
NS_TEST_EXPECT_MSG_NE(nodeIpv4Only->GetObject<Ipv4>(),
|
||||
nullptr,
|
||||
"IPv4 not found on IPv4-only node (should have been there)");
|
||||
NS_TEST_EXPECT_MSG_EQ(nodeIpv4Only->GetObject<Ipv6>(),
|
||||
nullptr,
|
||||
"IPv6 found on IPv4-only node (should not have been there)");
|
||||
|
||||
NS_TEST_EXPECT_MSG_EQ(nodeIpv6Only->GetObject<Ipv4>(),
|
||||
nullptr,
|
||||
"IPv4 found on IPv6-only node (should not have been there)");
|
||||
NS_TEST_EXPECT_MSG_NE(nodeIpv6Only->GetObject<Ipv6>(),
|
||||
nullptr,
|
||||
"IPv6 not found on IPv6-only node (should have been there)");
|
||||
|
||||
NS_TEST_EXPECT_MSG_NE(nodeIpv46->GetObject<Ipv4>(),
|
||||
nullptr,
|
||||
"IPv4 not found on dual stack node (should have been there)");
|
||||
NS_TEST_EXPECT_MSG_NE(nodeIpv46->GetObject<Ipv6>(),
|
||||
nullptr,
|
||||
"IPv6 not found on dual stack node (should have been there)");
|
||||
|
||||
// Now we install IPv4 and IPv6 on the IPv4-only node
|
||||
// IPv4 is already there, no error should happen.
|
||||
internet.Install(nodeIpv4Only);
|
||||
// Now we install IPv4 and IPv6 on the IPv6-only node,
|
||||
// IPv6 is already there, no error should happen.
|
||||
internet.Install(nodeIpv6Only);
|
||||
// Now we install IPv4 and IPv6 on the dual stack node
|
||||
// IPv4 and IPv6 are already there, no error should happen.
|
||||
internet.Install(nodeIpv46);
|
||||
|
||||
// Check that the three nodes have both IPv4 and IPv6.
|
||||
NS_TEST_EXPECT_MSG_NE(
|
||||
nodeIpv4Only->GetObject<Ipv4>(),
|
||||
nullptr,
|
||||
"IPv4 not found on IPv4-only, now dual stack node (should have been there)");
|
||||
NS_TEST_EXPECT_MSG_NE(
|
||||
nodeIpv4Only->GetObject<Ipv6>(),
|
||||
nullptr,
|
||||
"IPv6 not found on IPv4-only, now dual stack node (should have been there)");
|
||||
|
||||
NS_TEST_EXPECT_MSG_NE(
|
||||
nodeIpv6Only->GetObject<Ipv4>(),
|
||||
nullptr,
|
||||
"IPv4 not found on IPv6-only, now dual stack node (should have been there)");
|
||||
NS_TEST_EXPECT_MSG_NE(
|
||||
nodeIpv6Only->GetObject<Ipv6>(),
|
||||
nullptr,
|
||||
"IPv6 not found on IPv6-only, now dual stack node (should have been there)");
|
||||
|
||||
NS_TEST_EXPECT_MSG_NE(nodeIpv46->GetObject<Ipv4>(),
|
||||
nullptr,
|
||||
"IPv4 not found on dual stack node (should have been there)");
|
||||
NS_TEST_EXPECT_MSG_NE(nodeIpv46->GetObject<Ipv6>(),
|
||||
nullptr,
|
||||
"IPv6 not found on dual stack node (should have been there)");
|
||||
}
|
||||
|
||||
void
|
||||
InternetStackHelperTestCase::DoTeardown()
|
||||
{
|
||||
Simulator::Destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup internet-test
|
||||
*
|
||||
* \brief InternetStackHelper TestSuite
|
||||
*/
|
||||
class InternetStackHelperTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
InternetStackHelperTestSuite()
|
||||
: TestSuite("internet-stack-helper", UNIT)
|
||||
{
|
||||
AddTestCase(new InternetStackHelperTestCase(), TestCase::QUICK);
|
||||
}
|
||||
};
|
||||
|
||||
static InternetStackHelperTestSuite
|
||||
g_internetStackHelperTestSuite; //!< Static variable for test initialization
|
||||
Reference in New Issue
Block a user