diff --git a/CHANGES.html b/CHANGES.html index eb6bd65a5..4e77e38d0 100644 --- a/CHANGES.html +++ b/CHANGES.html @@ -113,6 +113,13 @@ The API of the LTE module has undergone a significant redesign with the merge of the code from the LENA project. The new API is not backwards compatible with the previous version of the LTE module. +
  • The Ipv6AddressHelper API has been aligned with the Ipv4AddressHelper API. +The helper can be set with a call to Ipv6AddressHelper::SetBase +(Ipv6Address network, Ipv6Prefix prefix) instead of NewNetwork +(Ipv6Address network, Ipv6Prefix prefix). A new NewAddress (void) method +has been added. Typical usage will involve calls to SetBase (), NewNetwork (), +and NewAddress (), as in class Ipv4AddressHelper. +
  • Changes to build system:

    diff --git a/examples/ipv6/fragmentation-ipv6.cc b/examples/ipv6/fragmentation-ipv6.cc index dd0ad41b8..40f1333b6 100644 --- a/examples/ipv6/fragmentation-ipv6.cc +++ b/examples/ipv6/fragmentation-ipv6.cc @@ -127,10 +127,10 @@ int main (int argc, char** argv) NS_LOG_INFO ("Create networks and assign IPv6 Addresses."); Ipv6AddressHelper ipv6; - ipv6.NewNetwork (Ipv6Address ("2001:1::"), 64); + ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64)); Ipv6InterfaceContainer i1 = ipv6.Assign (d1); i1.SetRouter (1, true); - ipv6.NewNetwork (Ipv6Address ("2001:2::"), 64); + ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64)); Ipv6InterfaceContainer i2 = ipv6.Assign (d2); i2.SetRouter (0, true); diff --git a/examples/ipv6/icmpv6-redirect.cc b/examples/ipv6/icmpv6-redirect.cc index 1ac5e4bc0..2353a984b 100644 --- a/examples/ipv6/icmpv6-redirect.cc +++ b/examples/ipv6/icmpv6-redirect.cc @@ -146,12 +146,12 @@ int main (int argc, char **argv) NS_LOG_INFO ("Assign IPv6 Addresses."); Ipv6AddressHelper ipv6; - ipv6.NewNetwork (Ipv6Address ("2001:1::"), 64); + ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64)); Ipv6InterfaceContainer iic1 = ipv6.Assign (ndc1); iic1.SetRouter (2, true); iic1.SetRouter (1, true); - ipv6.NewNetwork (Ipv6Address ("2001:2::"), 64); + ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64)); Ipv6InterfaceContainer iic2 = ipv6.Assign (ndc2); iic2.SetRouter (0, true); diff --git a/examples/ipv6/loose-routing-ipv6.cc b/examples/ipv6/loose-routing-ipv6.cc index 1cdb88b31..53a912745 100644 --- a/examples/ipv6/loose-routing-ipv6.cc +++ b/examples/ipv6/loose-routing-ipv6.cc @@ -104,30 +104,30 @@ int main (int argc, char **argv) NS_LOG_INFO ("Create networks and assign IPv6 Addresses."); Ipv6AddressHelper ipv6; - ipv6.NewNetwork (Ipv6Address ("2001:1::"), 64); + ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64)); Ipv6InterfaceContainer i1 = ipv6.Assign (d1); i1.SetRouter (1, true); - ipv6.NewNetwork (Ipv6Address ("2001:2::"), 64); + ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64)); Ipv6InterfaceContainer i2 = ipv6.Assign (d2); i2.SetRouter (1, true); - ipv6.NewNetwork (Ipv6Address ("2001:3::"), 64); + ipv6.SetBase (Ipv6Address ("2001:3::"), Ipv6Prefix (64)); Ipv6InterfaceContainer i3 = ipv6.Assign (d3); i3.SetRouter (0, true); i3.SetRouter (1, true); - ipv6.NewNetwork (Ipv6Address ("2001:4::"), 64); + ipv6.SetBase (Ipv6Address ("2001:4::"), Ipv6Prefix (64)); Ipv6InterfaceContainer i4 = ipv6.Assign (d4); i4.SetRouter (0, true); i4.SetRouter (1, true); - ipv6.NewNetwork (Ipv6Address ("2001:5::"), 64); + ipv6.SetBase (Ipv6Address ("2001:5::"), Ipv6Prefix (64)); Ipv6InterfaceContainer i5 = ipv6.Assign (d5); i5.SetRouter (0, true); i5.SetRouter (1, true); - ipv6.NewNetwork (Ipv6Address ("2001:6::"), 64); + ipv6.SetBase (Ipv6Address ("2001:6::"), Ipv6Prefix (64)); Ipv6InterfaceContainer i6 = ipv6.Assign (d6); i6.SetRouter (0, true); i6.SetRouter (1, true); diff --git a/examples/ipv6/radvd-two-prefix.cc b/examples/ipv6/radvd-two-prefix.cc index 0e3d037f9..ca58cddf2 100644 --- a/examples/ipv6/radvd-two-prefix.cc +++ b/examples/ipv6/radvd-two-prefix.cc @@ -137,7 +137,7 @@ int main (int argc, char** argv) Ipv6AddressHelper ipv6; /* first subnet */ - ipv6.NewNetwork (Ipv6Address ("2001:1::"), 64); + ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64)); NetDeviceContainer tmp; tmp.Add (d1.Get (0)); /* n0 */ Ipv6InterfaceContainer iic1 = ipv6.AssignWithoutAddress (tmp); /* n0 interface */ @@ -152,7 +152,7 @@ int main (int argc, char** argv) stackHelper.AddAddress (r, iic1.GetInterfaceIndex (1), Ipv6Address ("2001:ABCD::2")); /* second subnet R - n1 */ - ipv6.NewNetwork (Ipv6Address ("2001:2::"), 64); + ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64)); NetDeviceContainer tmp3; tmp3.Add (d2.Get (0)); /* R */ Ipv6InterfaceContainer iicr2 = ipv6.Assign (tmp3); /* R interface */ diff --git a/examples/ipv6/radvd.cc b/examples/ipv6/radvd.cc index 11f7751ee..56f508836 100644 --- a/examples/ipv6/radvd.cc +++ b/examples/ipv6/radvd.cc @@ -84,7 +84,7 @@ int main (int argc, char** argv) Ipv6AddressHelper ipv6; /* first subnet */ - ipv6.NewNetwork (Ipv6Address ("2001:1::"), 64); + ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64)); NetDeviceContainer tmp; tmp.Add (d1.Get (0)); /* n0 */ Ipv6InterfaceContainer iic1 = ipv6.AssignWithoutAddress (tmp); /* n0 interface */ @@ -96,7 +96,7 @@ int main (int argc, char** argv) iic1.Add (iicr1); /* second subnet R - n1 */ - ipv6.NewNetwork (Ipv6Address ("2001:2::"), 64); + ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64)); NetDeviceContainer tmp3; tmp3.Add (d2.Get (0)); /* R */ Ipv6InterfaceContainer iicr2 = ipv6.Assign (tmp3); /* R interface */ diff --git a/examples/routing/simple-routing-ping6.cc b/examples/routing/simple-routing-ping6.cc index 5eb7158e0..fc56aa1b2 100644 --- a/examples/routing/simple-routing-ping6.cc +++ b/examples/routing/simple-routing-ping6.cc @@ -128,10 +128,10 @@ int main (int argc, char** argv) NS_LOG_INFO ("Create networks and assign IPv6 Addresses."); Ipv6AddressHelper ipv6; - ipv6.NewNetwork (Ipv6Address ("2001:1::"), 64); + ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64)); Ipv6InterfaceContainer i1 = ipv6.Assign (d1); i1.SetRouter (1, true); - ipv6.NewNetwork (Ipv6Address ("2001:2::"), 64); + ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64)); Ipv6InterfaceContainer i2 = ipv6.Assign (d2); i2.SetRouter (0, true); diff --git a/examples/udp-client-server/udp-client-server.cc b/examples/udp-client-server/udp-client-server.cc index 9f1bc4bc2..68485e276 100644 --- a/examples/udp-client-server/udp-client-server.cc +++ b/examples/udp-client-server/udp-client-server.cc @@ -84,7 +84,7 @@ main (int argc, char *argv[]) else { Ipv6AddressHelper ipv6; - ipv6.NewNetwork ("2001:0000:f00d:cafe::", 64); + ipv6.SetBase ("2001:0000:f00d:cafe::", Ipv6Prefix (64)); Ipv6InterfaceContainer i6 = ipv6.Assign (d); serverAddress = Address(i6.GetAddress (1,1)); } diff --git a/examples/udp-client-server/udp-trace-client-server.cc b/examples/udp-client-server/udp-trace-client-server.cc index caa2f7754..cfbbd6262 100644 --- a/examples/udp-client-server/udp-trace-client-server.cc +++ b/examples/udp-client-server/udp-trace-client-server.cc @@ -83,7 +83,7 @@ main (int argc, char *argv[]) else { Ipv6AddressHelper ipv6; - ipv6.NewNetwork ("2001:0000:f00d:cafe::", 64); + ipv6.SetBase ("2001:0000:f00d:cafe::", Ipv6Prefix (64)); Ipv6InterfaceContainer i6 = ipv6.Assign (d); serverAddress = Address(i6.GetAddress (1,1)); } diff --git a/examples/udp/udp-echo.cc b/examples/udp/udp-echo.cc index e3936e32f..a8824cf73 100644 --- a/examples/udp/udp-echo.cc +++ b/examples/udp/udp-echo.cc @@ -91,7 +91,7 @@ main (int argc, char *argv[]) else { Ipv6AddressHelper ipv6; - ipv6.NewNetwork ("2001:0000:f00d:cafe::", 64); + ipv6.SetBase ("2001:0000:f00d:cafe::", Ipv6Prefix (64)); Ipv6InterfaceContainer i6 = ipv6.Assign (d); serverAddress = Address(i6.GetAddress (1,1)); } diff --git a/src/csma-layout/examples/csma-star.cc b/src/csma-layout/examples/csma-star.cc index 2430fe1df..3f20b9455 100644 --- a/src/csma-layout/examples/csma-star.cc +++ b/src/csma-layout/examples/csma-star.cc @@ -142,7 +142,7 @@ main (int argc, char *argv[]) { Ipv6AddressGenerator::Init (ipv6AddressBase, ipv6AddressPrefix); Ipv6Address v6network = Ipv6AddressGenerator::GetNetwork (ipv6AddressPrefix); - address6.NewNetwork(v6network, ipv6AddressPrefix); + address6.SetBase (v6network, ipv6AddressPrefix); for (uint32_t j = 0; j < nFill; ++j) { diff --git a/src/csma-layout/model/csma-star-helper.cc b/src/csma-layout/model/csma-star-helper.cc index d866ce97a..f2faaf7c5 100644 --- a/src/csma-layout/model/csma-star-helper.cc +++ b/src/csma-layout/model/csma-star-helper.cc @@ -129,7 +129,7 @@ CsmaStarHelper::AssignIpv6Addresses (Ipv6Address network, Ipv6Prefix prefix) for (uint32_t i = 0; i < m_spokes.GetN (); ++i) { v6network = Ipv6AddressGenerator::GetNetwork (prefix); - addressHelper.NewNetwork(v6network, prefix); + addressHelper.SetBase (v6network, prefix); Ipv6InterfaceContainer ic = addressHelper.Assign (m_hubDevices.Get (i)); m_hubInterfaces6.Add (ic); diff --git a/src/internet/helper/ipv6-address-helper.cc b/src/internet/helper/ipv6-address-helper.cc index 6557b17ba..929af6ee5 100644 --- a/src/internet/helper/ipv6-address-helper.cc +++ b/src/internet/helper/ipv6-address-helper.cc @@ -25,6 +25,7 @@ #include "ns3/net-device.h" #include "ns3/mac48-address.h" #include "ns3/ipv6.h" +#include "ns3/ipv6-address-generator.h" #include "ipv6-address-helper.h" @@ -35,37 +36,73 @@ NS_LOG_COMPONENT_DEFINE ("Ipv6AddressHelper"); Ipv6AddressHelper::Ipv6AddressHelper () { - NS_LOG_FUNCTION_NOARGS (); - m_network = Ipv6Address ("2001::"); - m_prefix = Ipv6Prefix (64); + NS_LOG_FUNCTION (this); + Ipv6AddressGenerator::Init (Ipv6Address ("2001:db8::"), Ipv6Prefix (64)); } +Ipv6AddressHelper::Ipv6AddressHelper (Ipv6Address network, Ipv6Prefix prefix, + Ipv6Address base) +{ + NS_LOG_FUNCTION (this << network << prefix << base); + Ipv6AddressGenerator::Init (network, prefix, base); +} + +void Ipv6AddressHelper::SetBase (Ipv6Address network, Ipv6Prefix prefix, + Ipv6Address base) +{ + NS_LOG_FUNCTION (this << network << prefix << base); + // XXX for now we do not enforce the prefix because the underlying + // Ipv6AddressGenerator does not handle prefixes well that are not 64 bits + Ipv6AddressGenerator::Init (network, Ipv6Prefix (64), base); +} + + Ipv6Address Ipv6AddressHelper::NewAddress (Address addr) { NS_LOG_FUNCTION (this << addr); - - switch (addr.GetLength ()) + if (Mac48Address::IsMatchingType (addr)) { - case 6: - return Ipv6Address::MakeAutoconfiguredAddress (Mac48Address::ConvertFrom (addr), m_network); - default: - return Ipv6Address ("::"); + Ipv6Address network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix (64)); + Ipv6Address address = Ipv6Address::MakeAutoconfiguredAddress (Mac48Address::ConvertFrom (addr), network); + Ipv6AddressGenerator::AddAllocated (address); + return address; + } + else + { + NS_FATAL_ERROR ("Did not pass in a Mac48Address"); } /* never reached */ return Ipv6Address ("::"); } +Ipv6Address Ipv6AddressHelper::NewAddress (void) +{ + NS_LOG_FUNCTION (this); +// +// The way this is expected to be used is that an address and network number +// are initialized, and then NewAddress() is called repeatedly to allocate and +// get new addresses on a given subnet. The client will expect that the first +// address she gets back is the one she used to initialize the generator with. +// This implies that this operation is a post-increment. +// + return Ipv6AddressGenerator::NextAddress (Ipv6Prefix (64)); +} + void Ipv6AddressHelper::NewNetwork (Ipv6Address network, Ipv6Prefix prefix) { NS_LOG_FUNCTION (this << network << prefix); + SetBase (network, Ipv6Prefix (64)); +} - m_network = network; - m_prefix = prefix; +void Ipv6AddressHelper::NewNetwork (void) +{ + NS_LOG_FUNCTION (this); + Ipv6AddressGenerator::NextNetwork (Ipv6Prefix (64)); } Ipv6InterfaceContainer Ipv6AddressHelper::Assign (const NetDeviceContainer &c) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (this); Ipv6InterfaceContainer retval; for (uint32_t i = 0; i < c.GetN (); ++i) @@ -87,10 +124,10 @@ Ipv6InterfaceContainer Ipv6AddressHelper::Assign (const NetDeviceContainer &c) NS_ASSERT_MSG (ifIndex >= 0, "Ipv6AddressHelper::Allocate (): " "Interface index not found"); - Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (NewAddress (device->GetAddress ()), m_prefix); + Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (NewAddress (device->GetAddress ()), Ipv6Prefix (64)); ipv6->SetMetric (ifIndex, 1); - ipv6->SetUp (ifIndex); ipv6->AddAddress (ifIndex, ipv6Addr); + ipv6->SetUp (ifIndex); retval.Add (ipv6, ifIndex); } @@ -99,7 +136,7 @@ Ipv6InterfaceContainer Ipv6AddressHelper::Assign (const NetDeviceContainer &c) Ipv6InterfaceContainer Ipv6AddressHelper::Assign (const NetDeviceContainer &c, std::vector withConfiguration) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (this); Ipv6InterfaceContainer retval; for (uint32_t i = 0; i < c.GetN (); ++i) { @@ -120,47 +157,29 @@ Ipv6InterfaceContainer Ipv6AddressHelper::Assign (const NetDeviceContainer &c, s "Interface index not found"); ipv6->SetMetric (ifIndex, 1); - ipv6->SetUp (ifIndex); if (withConfiguration.at (i)) { - Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (NewAddress (device->GetAddress ()), m_prefix); + Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (NewAddress (device->GetAddress ()), Ipv6Prefix (64)); ipv6->AddAddress (ifIndex, ipv6Addr); } + ipv6->SetUp (ifIndex); retval.Add (ipv6, ifIndex); } return retval; } +// Helper API that is redundant with Assign (c, false); Ipv6InterfaceContainer Ipv6AddressHelper::AssignWithoutAddress (const NetDeviceContainer &c) { - NS_LOG_FUNCTION_NOARGS (); - Ipv6InterfaceContainer retval; + NS_LOG_FUNCTION (this); + std::vector withConfiguration; for (uint32_t i = 0; i < c.GetN (); ++i) { - Ptr device = c.Get (i); - - Ptr node = device->GetNode (); - NS_ASSERT_MSG (node, "Ipv6AddressHelper::Allocate (): Bad node"); - - Ptr ipv6 = node->GetObject (); - NS_ASSERT_MSG (ipv6, "Ipv6AddressHelper::Allocate (): Bad ipv6"); - - int32_t ifIndex = ipv6->GetInterfaceForDevice (device); - if (ifIndex == -1) - { - ifIndex = ipv6->AddInterface (device); - } - NS_ASSERT_MSG (ifIndex >= 0, "Ipv6AddressHelper::Allocate (): " - "Interface index not found"); - - ipv6->SetMetric (ifIndex, 1); - ipv6->SetUp (ifIndex); - - retval.Add (ipv6, ifIndex); + withConfiguration.push_back (false); } - return retval; + return Assign (c, withConfiguration); } } /* namespace ns3 */ diff --git a/src/internet/helper/ipv6-address-helper.h b/src/internet/helper/ipv6-address-helper.h index d02329ba4..0c3f4c944 100644 --- a/src/internet/helper/ipv6-address-helper.h +++ b/src/internet/helper/ipv6-address-helper.h @@ -16,24 +16,63 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Sebastien Vincent + * modified by Tom Henderson for ns-3.14 release */ -#ifndef IPV6_ADDRESS_STATIC_HELPER_H -#define IPV6_ADDRESS_STATIC_HELPER_H +#ifndef IPV6_ADDRESS_HELPER_H +#define IPV6_ADDRESS_HELPER_H #include #include "ns3/ipv6-address.h" - #include "ns3/net-device-container.h" #include "ipv6-interface-container.h" +#include "ns3/deprecated.h" -namespace ns3 -{ +namespace ns3 { /** * \class Ipv6AddressHelper - * \brief Helper class to assign IPv6 address statically. + * \brief Helper class to auto-assign global IPv6 unicast addresses + * + * Assign global unicast IPv6 addresses based on RFC 4291 definition. + * + * | n bits | 64-n bits | 64 bits | + * +-------------------------+-----------+----------------------------+ + * | global routing prefix | subnet ID | interface ID | + * +-------------------------+-----------+----------------------------+ + * <-------------network----------------> + * + * 11111111111111111111111111000000000000 + * <---prefix of length n---> + * + * This class handles the following quantities. + * 1) The "network" which covers the 64 bit union of the global routing + * prefix and the subnet ID + * 2) the "prefix" length "n" which demarcates the global routing prefix + * and the subnet ID + * 3) the "base" which is the initial 64-bit interface ID. + * + * The names "network", "prefix" and "base" are chosen to be consistent + * with a similar address helper for IPv4. + * + * This helper class allows users to set or reset the network and + * interface components, and call "NewAddress ()" to sequentially increment + * the interface ID, and call "NewNetwork ()" to allocate a new subnet + * (until the subnet ID quantity rolls over). A call to NewNetwork () + * that causes the subnet ID to roll over will trigger an assertion. + * + * By default, the prefix is 32 bits and the network is '2001:db8::/32' + * (RFC 5156 section 2.6 Documentation prefix). The prefix may range + * from length 0 to 64, with the value 64 having a special meaning that + * no subnet ID boundary is enforced (equivalent to value 0). + * + * There are two variants of interface ID supported (RFC 4291, Sec. 2.5.1) + * The default is a "local" scope, but a "universal" scoped ID may be + * formed by calling "NewAddress (Address addr)" with a 48-bit MAC address. + * If this method is called, the addressed returned will include a + * modified EUI-64-format identifier created from the MAC address as + * specified in RFC 4291. */ class Ipv6AddressHelper { @@ -43,37 +82,93 @@ public: */ Ipv6AddressHelper (); + /** + * \brief Constructor. + * \param network The IPv6 network + * \param prefix The prefix + * \param base The base interface ID + */ + Ipv6AddressHelper (Ipv6Address network, Ipv6Prefix prefix, + Ipv6Address base = Ipv6Address ("::1")); + + /** + * \brief Set the base network number, network prefix, and base interface ID + * + * \param network The IPv6 network + * \param prefix The prefix + * \param base The base interface ID + */ + void SetBase (Ipv6Address network, Ipv6Prefix prefix, + Ipv6Address base = Ipv6Address ("::1")); + /** * \brief Allocate a new network. + * + * This method will reset the network for future + * network IDs, and resets the interface ID to the previously used + * base. + * * \param network The IPv6 network * \param prefix The prefix */ - void NewNetwork (Ipv6Address network, Ipv6Prefix prefix); + void NewNetwork (Ipv6Address network, Ipv6Prefix prefix) NS_DEPRECATED; /** - * \brief Allocate a new address. - * \param addr L2 address (currently only ethernet address is supported) + * \brief Allocate a new network. + * + * This method will cause the subnet prefix to increment, for future + * network IDs, and resets the interface ID to the previously used + * base. + */ + void NewNetwork (void); + + /** + * \brief Allocate a new Ipv6Address. + * + * If a Mac48Address is passed in, an Ipv6 autoconfigured address + * according to the current subnet prefix is returned. If something + * other than Mac48 address is passed in, the program will terminate. + * + * \param addr address used to generate the interface ID of the IPv6 address * \return newly created Ipv6Address */ Ipv6Address NewAddress (Address addr); /** - * \brief Allocate an Ipv6InterfaceContainer. + * \brief Allocate a new Ipv6Address with interface ID equal to the + * next one in the underlying generator. + * + * \return newly created Ipv6Address + */ + Ipv6Address NewAddress (void); + + /** + * \brief Allocate an Ipv6InterfaceContainer with auto-assigned addresses. * \param c netdevice container * \return newly created Ipv6InterfaceContainer */ Ipv6InterfaceContainer Assign (const NetDeviceContainer &c); /** - * \brief Allocate an Ipv6InterfaceContainer. + * \brief Allocate an Ipv6InterfaceContainer, and control whether the + * interfaces have addresses auto-assigned to them + * * \param c netdevice container - * \param withConfiguration true : interface statically configured, false : no static configuration + * \param withConfiguration a vector of values for which, for a + * given device, true : interface automatically addressed, + * false : no automatic address * \return newly created Ipv6InterfaceContainer */ Ipv6InterfaceContainer Assign (const NetDeviceContainer &c, std::vector withConfiguration); /** - * \brief Allocate an Ipv6InterfaceContainer without static IPv6 configuration. + * \brief Allocate an Ipv6InterfaceContainer but do not assign any IPv6 addresses + * + * This method is used when IPv6 address assignment may occur later + * (such as dynamic address assignment) + * + * Equivalent to AssignWithoutAddress (c, std::vector of false); + * * \param c netdevice container * \return newly created Ipv6InterfaceContainer */ @@ -84,16 +179,27 @@ private: * \internal * \brief The IPv6 network. */ - Ipv6Address m_network; + uint8_t m_network[16]; /** * \internal - * \brief IPv6 The prefix (mask). + * \brief The prefix (mask). */ - Ipv6Prefix m_prefix; + uint8_t m_prefix[16]; + + /** + * \internal + * \brief The base interface ID + */ + uint64_t m_base; + /** + * \internal + * \brief The current interface ID + */ + uint64_t m_iid; }; } /* namespace ns3 */ -#endif /* IPV6_ADDRESS_STATIC_HELPER_H */ +#endif /* IPV6_ADDRESS_STATIC_H */ diff --git a/src/internet/model/ipv6-address-generator.cc b/src/internet/model/ipv6-address-generator.cc index 541e11d43..715c7b3fd 100644 --- a/src/internet/model/ipv6-address-generator.cc +++ b/src/internet/model/ipv6-address-generator.cc @@ -160,6 +160,7 @@ Ipv6AddressGeneratorImpl::Init ( // network number at bit zero of the int that holds it). // uint32_t index = PrefixToIndex (prefix); + NS_LOG_DEBUG ("Index " << index); uint32_t a = m_netTable[index].shift / 8; uint32_t b = m_netTable[index].shift % 8; for (int32_t j = 15 - a; j >= 0; j--) diff --git a/src/internet/test/ipv4-address-helper-test-suite.cc b/src/internet/test/ipv4-address-helper-test-suite.cc index 167fa301d..670498213 100644 --- a/src/internet/test/ipv4-address-helper-test-suite.cc +++ b/src/internet/test/ipv4-address-helper-test-suite.cc @@ -179,6 +179,74 @@ ResetAllocatorHelperTestCase::DoTeardown (void) Simulator::Destroy (); } +class IpAddressHelperTestCasev4 : public TestCase +{ +public: + IpAddressHelperTestCasev4 (); + virtual ~IpAddressHelperTestCasev4 (); + +private: + virtual void DoRun (void); +}; + +IpAddressHelperTestCasev4::IpAddressHelperTestCasev4 () + : TestCase ("IpAddressHelper Ipv4 test case (similar to IPv6)") +{ +} + +IpAddressHelperTestCasev4::~IpAddressHelperTestCasev4 () +{ +} + +void +IpAddressHelperTestCasev4::DoRun (void) +{ + Ipv4AddressHelper ip1; + Ipv4Address ipAddr1; + ipAddr1 = ip1.NewAddress (); + // Ipv4AddressHelper that is unconfigured + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv4Address ("255.255.255.255"), "Ipv4AddressHelper failure"); + + ip1.SetBase ("192.168.0.0", "255.255.255.0"); + ipAddr1 = ip1.NewAddress (); + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv4Address ("192.168.0.1"), "Ipv4AddressHelper failure"); + ipAddr1 = ip1.NewAddress (); + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv4Address ("192.168.0.2"), "Ipv4AddressHelper failure"); + ip1.NewNetwork (); + ipAddr1 = ip1.NewAddress (); + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv4Address ("192.168.1.1"), "Ipv4AddressHelper failure"); + ip1.NewNetwork (); // 192.168.2 + ip1.NewNetwork (); // 192.168.3 + ip1.NewNetwork (); // 192.168.4 + ipAddr1 = ip1.NewAddress (); // 4.1 + ipAddr1 = ip1.NewAddress (); // 4.2 + ipAddr1 = ip1.NewAddress (); // 4.3 + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv4Address ("192.168.4.3"), "Ipv4AddressHelper failure"); + + // reset base to start at 192.168.0.100 + ip1.SetBase ("192.168.0.0", "255.255.255.0", "0.0.0.100"); + ipAddr1 = ip1.NewAddress (); + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv4Address ("192.168.0.100"), "Ipv4AddressHelper failure"); + + // rollover + ip1.SetBase ("192.168.0.0", "255.255.255.0", "0.0.0.254"); + ipAddr1 = ip1.NewAddress (); // .254 + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv4Address ("192.168.0.254"), "Ipv4AddressHelper failure"); + // The below will overflow and assert, so it is commented out + // ipAddr1 = ip1.NewAddress (); // .255 + + // create with arguments + Ipv4AddressHelper ip2 = Ipv4AddressHelper ("192.168.1.0", "255.255.255.0", "0.0.0.1"); + // duplicate assignment + ip2.NewNetwork (); // 192.168.2 + ip2.NewNetwork (); // 192.168.3 + ip2.NewNetwork (); // 192.168.4 + // Uncomment below, and 192.168.4.1 will crash since it was allocated above + // ipAddr1 = ip2.NewAddress (); // 4.1 + +} + + static class Ipv4AddressHelperTestSuite : public TestSuite { public: @@ -188,6 +256,7 @@ public: AddTestCase (new NetworkAllocatorHelperTestCase ()); AddTestCase (new AddressAllocatorHelperTestCase ()); AddTestCase (new ResetAllocatorHelperTestCase ()); + AddTestCase (new IpAddressHelperTestCasev4 ()); } } g_ipv4AddressHelperTestSuite; diff --git a/src/internet/test/ipv6-address-helper-test-suite.cc b/src/internet/test/ipv6-address-helper-test-suite.cc new file mode 100644 index 000000000..e2941b35d --- /dev/null +++ b/src/internet/test/ipv6-address-helper-test-suite.cc @@ -0,0 +1,145 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2012 University of Washington + * + * 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 + */ + +#include "ns3/ipv6-address-helper.h" +#include "ns3/ipv4-address-helper.h" +#include "ns3/simple-net-device.h" +#include "ns3/net-device-container.h" +#include "ns3/node-container.h" +#include "ns3/internet-stack-helper.h" +#include "ns3/test.h" +#include "ns3/log.h" + +using namespace ns3; + +class IpAddressHelperTestCasev6 : public TestCase +{ +public: + IpAddressHelperTestCasev6 (); + virtual ~IpAddressHelperTestCasev6 (); + +private: + virtual void DoRun (void); +}; + +IpAddressHelperTestCasev6::IpAddressHelperTestCasev6 () + : TestCase ("IpAddressHelper Ipv6 test case") +{ +} + +IpAddressHelperTestCasev6::~IpAddressHelperTestCasev6 () +{ +} + +void +IpAddressHelperTestCasev6::DoRun (void) +{ + Ipv6AddressHelper ip1; + Ipv6Address ipAddr1; + ipAddr1 = ip1.NewAddress (); + // Ipv6AddressHelper that is unconfigured + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:db8::1"), "Ipv6AddressHelper failure"); + ipAddr1 = ip1.NewAddress (); + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:db8::2"), "Ipv6AddressHelper failure"); + ip1.NewNetwork (); + ipAddr1 = ip1.NewAddress (); + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:db8:0:1:0:0:0:1"), "Ipv6AddressHelper failure"); + + // Reset + ip1.SetBase (Ipv6Address ("2001:db81::"), Ipv6Prefix (32), Ipv6Address ("::1")); + ipAddr1 = ip1.NewAddress (); + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:db81::1"), "Ipv6AddressHelper failure"); + // Skip a few addresses + ip1.SetBase (Ipv6Address ("2001:db81::"), Ipv6Prefix (32), Ipv6Address ("::15")); + ipAddr1 = ip1.NewAddress (); + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:db81::15"), "Ipv6AddressHelper failure"); + ipAddr1 = ip1.NewAddress (); + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:db81::16"), "Ipv6AddressHelper failure"); + // Increment network + ip1.NewNetwork (); + ipAddr1 = ip1.NewAddress (); + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:db81:0:1::15"), "Ipv6AddressHelper failure"); + // Reset + ip1.SetBase (Ipv6Address ("2001:dddd::"), Ipv6Prefix (32), Ipv6Address ("::1")); + ipAddr1 = ip1.NewAddress (); // ::1 + ipAddr1 = ip1.NewAddress (); // ::2 + ipAddr1 = ip1.NewAddress (); // ::3 + ip1.NewNetwork (); // 0:1 + ip1.NewNetwork (); // 0:2 + ipAddr1 = ip1.NewAddress (); // ::1 again + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:dddd:0:2::1"), "Ipv6AddressHelper failure"); + + // Set again + ip1.SetBase (Ipv6Address ("2001:db82::1"), Ipv6Prefix (32)); + ipAddr1 = ip1.NewAddress (); + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:db82::1"), "Ipv6AddressHelper failure"); + + // Test container assignment + NodeContainer n; + n.Create (2); + + /* Install IPv4/IPv6 stack */ + InternetStackHelper internetv6; + internetv6.SetIpv4StackInstall (false); + internetv6.Install (n); + + NetDeviceContainer d; + Ptr s1 = CreateObject (); + s1->SetAddress (Mac48Address::Allocate ()); + n.Get (0)->AddDevice (s1); + + Ptr s2 = CreateObject (); + s2->SetAddress (Mac48Address::Allocate ()); + n.Get (1)->AddDevice (s2); + d.Add (s1); + d.Add (s2); + + ip1.SetBase (Ipv6Address ("2001:00aa::"), Ipv6Prefix (56)); + Ipv6InterfaceContainer ic; + ic = ip1.Assign (d); + + // Check that d got intended addresses + Ipv6InterfaceAddress d1addr; + Ipv6InterfaceAddress d2addr; + // Interface 0 is loopback, interface 1 is s1, and the 0th addr is linklocal + // so we look at address (1,1) + d1addr = n.Get (0)->GetObject ()->GetAddress (1, 1); + NS_TEST_ASSERT_MSG_EQ (d1addr.GetAddress (), Ipv6Address ("2001:00aa:0000:0000:0200:00ff:fe00:0001"), "Ipv6AddressHelper failure"); + // Look also at the interface container (device 0, address 1) + NS_TEST_ASSERT_MSG_EQ (ic.GetAddress (0,1), Ipv6Address ("2001:00aa:0000:0000:0200:00ff:fe00:0001"), "Ipv6AddressHelper failure"); + d2addr = n.Get (1)->GetObject ()->GetAddress (1, 1); + // Look at second container + NS_TEST_ASSERT_MSG_EQ (d2addr.GetAddress (), Ipv6Address ("2001:00aa:0000:0000:0200:00ff:fe00:0002"), "Ipv6AddressHelper failure"); + // Look also at the interface container (device 0, address 1) + NS_TEST_ASSERT_MSG_EQ (ic.GetAddress (1,1), Ipv6Address ("2001:00aa:0000:0000:0200:00ff:fe00:0002"), "Ipv6AddressHelper failure"); +} + +class Ipv6AddressHelperTestSuite : public TestSuite +{ +public: + Ipv6AddressHelperTestSuite (); +}; + +Ipv6AddressHelperTestSuite::Ipv6AddressHelperTestSuite () + : TestSuite ("ipv6-address-helper", UNIT) +{ + AddTestCase (new IpAddressHelperTestCasev6); +} + +// Do not forget to allocate an instance of this TestSuite +static Ipv6AddressHelperTestSuite ipv6AddressHelperTestSuite; diff --git a/src/internet/wscript b/src/internet/wscript index e250a1e24..219758a3b 100644 --- a/src/internet/wscript +++ b/src/internet/wscript @@ -207,6 +207,7 @@ def build(bld): 'test/ipv6-address-generator-test-suite.cc', 'test/ipv6-dual-stack-test-suite.cc', 'test/ipv6-fragmentation-test.cc', + 'test/ipv6-address-helper-test-suite.cc', ] headers = bld.new_task_gen(features=['ns3header']) diff --git a/src/network/test/ipv6-address-test-suite.cc b/src/network/test/ipv6-address-test-suite.cc new file mode 100644 index 000000000..fb35d4f2f --- /dev/null +++ b/src/network/test/ipv6-address-test-suite.cc @@ -0,0 +1,107 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * 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 + */ + +#include "ns3/test.h" +#include "ns3/ipv6-address.h" + +using namespace ns3; + +class Ipv6AddressTestCase1 : public TestCase +{ +public: + Ipv6AddressTestCase1 (); + virtual ~Ipv6AddressTestCase1 (); + +private: + virtual void DoRun (void); +}; + +Ipv6AddressTestCase1::Ipv6AddressTestCase1 () + : TestCase ("serialization code") +{ +} + +Ipv6AddressTestCase1::~Ipv6AddressTestCase1 () +{ +} + +void +Ipv6AddressTestCase1::DoRun (void) +{ + Ipv6Address ip = Ipv6Address ("2001:db8::1"); + uint8_t ipBytes[16]; + ip.Serialize (ipBytes); + NS_TEST_ASSERT_MSG_EQ (ipBytes[0], 0x20, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[1], 0x01, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[2], 0x0d, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[3], 0xb8, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[15], 1, "Failed string conversion"); + + ip = Ipv6Address ("2001:db8:1::1"); + ip.Serialize (ipBytes); + NS_TEST_ASSERT_MSG_EQ (ipBytes[0], 0x20, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[1], 0x01, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[2], 0x0d, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[3], 0xb8, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[5], 0x01, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[15], 1, "Failed string conversion"); + + // Zero padding + ip = Ipv6Address ("2001:0db8:0001::1"); + ip.Serialize (ipBytes); + NS_TEST_ASSERT_MSG_EQ (ipBytes[0], 0x20, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[1], 0x01, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[2], 0x0d, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[3], 0xb8, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[5], 0x01, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[15], 1, "Failed string conversion"); + + ip = Ipv6Address ("2001:db8:0:1::1"); + ip.Serialize (ipBytes); + NS_TEST_ASSERT_MSG_EQ (ipBytes[0], 0x20, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[1], 0x01, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[2], 0x0d, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[3], 0xb8, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[7], 0x01, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[15], 1, "Failed string conversion"); + + ip = Ipv6Address ("2001:db8:0:1:0:0:0:1"); + ip.Serialize (ipBytes); + NS_TEST_ASSERT_MSG_EQ (ipBytes[0], 0x20, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[1], 0x01, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[2], 0x0d, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[3], 0xb8, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[7], 0x01, "Failed string conversion"); + NS_TEST_ASSERT_MSG_EQ (ipBytes[15], 1, "Failed string conversion"); + + // Please add more tests below + +} + +class Ipv6AddressTestSuite : public TestSuite +{ +public: + Ipv6AddressTestSuite (); +}; + +Ipv6AddressTestSuite::Ipv6AddressTestSuite () + : TestSuite ("ipv6-address", UNIT) +{ + AddTestCase (new Ipv6AddressTestCase1); +} + +static Ipv6AddressTestSuite ipv6AddressTestSuite; + diff --git a/src/network/wscript b/src/network/wscript index 5745b43a7..b587ff0db 100644 --- a/src/network/wscript +++ b/src/network/wscript @@ -61,6 +61,7 @@ def build(bld): network_test.source = [ 'test/buffer-test.cc', 'test/drop-tail-queue-test-suite.cc', + 'test/ipv6-address-test-suite.cc', 'test/packetbb-test-suite.cc', 'test/packet-test-suite.cc', 'test/packet-metadata-test.cc', diff --git a/src/point-to-point-layout/model/point-to-point-dumbbell.cc b/src/point-to-point-layout/model/point-to-point-dumbbell.cc index 9738560b4..b8cff18f6 100644 --- a/src/point-to-point-layout/model/point-to-point-dumbbell.cc +++ b/src/point-to-point-layout/model/point-to-point-dumbbell.cc @@ -166,7 +166,7 @@ void PointToPointDumbbellHelper::AssignIpv6Addresses (Ipv6Address addrBase, Ipv6 Ipv6AddressHelper addressHelper; v6network = Ipv6AddressGenerator::GetNetwork (prefix); - addressHelper.NewNetwork (v6network, prefix); + addressHelper.SetBase (v6network, prefix); m_routerInterfaces6 = addressHelper.Assign (m_routerDevices); Ipv6AddressGenerator::NextNetwork (prefix); @@ -174,7 +174,7 @@ void PointToPointDumbbellHelper::AssignIpv6Addresses (Ipv6Address addrBase, Ipv6 for (uint32_t i = 0; i < LeftCount (); ++i) { v6network = Ipv6AddressGenerator::GetNetwork (prefix); - addressHelper.NewNetwork (v6network, prefix); + addressHelper.SetBase (v6network, prefix); NetDeviceContainer ndc; ndc.Add (m_leftLeafDevices.Get (i)); @@ -190,7 +190,7 @@ void PointToPointDumbbellHelper::AssignIpv6Addresses (Ipv6Address addrBase, Ipv6 for (uint32_t i = 0; i < RightCount (); ++i) { v6network = Ipv6AddressGenerator::GetNetwork (prefix); - addressHelper.NewNetwork (v6network, prefix); + addressHelper.SetBase (v6network, prefix); NetDeviceContainer ndc; ndc.Add (m_rightLeafDevices.Get (i)); diff --git a/src/point-to-point-layout/model/point-to-point-grid.cc b/src/point-to-point-layout/model/point-to-point-grid.cc index e252c6eca..19549861a 100644 --- a/src/point-to-point-layout/model/point-to-point-grid.cc +++ b/src/point-to-point-layout/model/point-to-point-grid.cc @@ -148,7 +148,7 @@ PointToPointGridHelper::AssignIpv6Addresses(Ipv6Address addrBase, Ipv6Prefix pre for (uint32_t j = 0; j < rowContainer.GetN (); j+=2) { v6network = Ipv6AddressGenerator::GetNetwork (prefix); - addrHelper.NewNetwork(v6network, prefix); + addrHelper.SetBase(v6network, prefix); Ipv6InterfaceContainer ic = addrHelper.Assign (rowContainer.Get (j)); rowInterfaces.Add (ic); ic = addrHelper.Assign (rowContainer.Get (j+1)); @@ -169,7 +169,7 @@ PointToPointGridHelper::AssignIpv6Addresses(Ipv6Address addrBase, Ipv6Prefix pre for (uint32_t j = 0; j < colContainer.GetN (); j+=2) { v6network = Ipv6AddressGenerator::GetNetwork (prefix); - addrHelper.NewNetwork(v6network, prefix); + addrHelper.SetBase(v6network, prefix); Ipv6InterfaceContainer ic = addrHelper.Assign (colContainer.Get (j)); colInterfaces.Add (ic); ic = addrHelper.Assign (colContainer.Get (j+1)); diff --git a/src/point-to-point-layout/model/point-to-point-star.cc b/src/point-to-point-layout/model/point-to-point-star.cc index bc09fbf53..364f07840 100644 --- a/src/point-to-point-layout/model/point-to-point-star.cc +++ b/src/point-to-point-layout/model/point-to-point-star.cc @@ -119,7 +119,7 @@ PointToPointStarHelper::AssignIpv6Addresses (Ipv6Address addrBase, Ipv6Prefix pr for (uint32_t i = 0; i < m_spokes.GetN (); ++i) { v6network = Ipv6AddressGenerator::GetNetwork (prefix); - addressHelper.NewNetwork(v6network, prefix); + addressHelper.SetBase (v6network, prefix); Ipv6InterfaceContainer ic = addressHelper.Assign (m_hubDevices.Get (i)); m_hubInterfaces6.Add (ic);