--- a/RELEASE_NOTES Tue Jul 09 19:15:20 2013 +0200
+++ b/RELEASE_NOTES Tue Jul 09 19:21:07 2013 +0200
@@ -25,6 +25,7 @@
Bugs fixed
----------
+- Bug 760 - IP address removal can be painful
- Bug 1390 - ICMPv6 Redirect are handled correctly only for /64 networks
- Bug 1643 - NdiscCache creation and existence checks
- Bug 1646 - ICMPv6 Redirect are sent from global address instead of link-local
--- a/src/internet/model/ipv4-interface.cc Tue Jul 09 19:15:20 2013 +0200
+++ b/src/internet/model/ipv4-interface.cc Tue Jul 09 19:21:07 2013 +0200
@@ -346,5 +346,28 @@
return (addr); // quiet compiler
}
+Ipv4InterfaceAddress
+Ipv4Interface::RemoveAddress(Ipv4Address address)
+{
+ NS_LOG_FUNCTION(this << address);
+
+ if (address == address.GetLoopback())
+ {
+ NS_LOG_WARN ("Cannot remove loopback address.");
+ return Ipv4InterfaceAddress();
+ }
+
+ for(Ipv4InterfaceAddressListI it = m_ifaddrs.begin(); it != m_ifaddrs.end(); it++)
+ {
+ if((*it).GetLocal() == address)
+ {
+ Ipv4InterfaceAddress ifAddr = *it;
+ m_ifaddrs.erase(it);
+ return ifAddr;
+ }
+ }
+ return Ipv4InterfaceAddress();
+}
+
} // namespace ns3
--- a/src/internet/model/ipv4-interface.h Tue Jul 09 19:15:20 2013 +0200
+++ b/src/internet/model/ipv4-interface.h Tue Jul 09 19:21:07 2013 +0200
@@ -152,6 +152,15 @@
*/
Ipv4InterfaceAddress RemoveAddress (uint32_t index);
+ /**
+ * \brief Remove the given Ipv4 address from the interface.
+ * \param address The Ipv4 address to remove
+ * \returns The removed Ipv4 interface address
+ * \returns The null interface address if the interface did not contain the
+ * address or if loopback address was passed as argument
+ */
+ Ipv4InterfaceAddress RemoveAddress (Ipv4Address address);
+
protected:
virtual void DoDispose (void);
private:
--- a/src/internet/model/ipv4-l3-protocol.cc Tue Jul 09 19:15:20 2013 +0200
+++ b/src/internet/model/ipv4-l3-protocol.cc Tue Jul 09 19:21:07 2013 +0200
@@ -979,6 +979,29 @@
return false;
}
+bool
+Ipv4L3Protocol::RemoveAddress (uint32_t i, Ipv4Address address)
+{
+ NS_LOG_FUNCTION (this << i << address);
+
+ if (address == Ipv4Address::GetLoopback())
+ {
+ NS_LOG_WARN ("Cannot remove loopback address.");
+ return false;
+ }
+ Ptr<Ipv4Interface> interface = GetInterface (i);
+ Ipv4InterfaceAddress ifAddr = interface->RemoveAddress (address);
+ if (ifAddr != Ipv4InterfaceAddress ())
+ {
+ if (m_routingProtocol != 0)
+ {
+ m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
+ }
+ return true;
+ }
+ return false;
+}
+
Ipv4Address
Ipv4L3Protocol::SelectSourceAddress (Ptr<const NetDevice> device,
Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope)
--- a/src/internet/model/ipv4-l3-protocol.h Tue Jul 09 19:15:20 2013 +0200
+++ b/src/internet/model/ipv4-l3-protocol.h Tue Jul 09 19:21:07 2013 +0200
@@ -194,6 +194,7 @@
Ipv4InterfaceAddress GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const;
uint32_t GetNAddresses (uint32_t interface) const;
bool RemoveAddress (uint32_t interfaceIndex, uint32_t addressIndex);
+ bool RemoveAddress (uint32_t interface, Ipv4Address address);
Ipv4Address SelectSourceAddress (Ptr<const NetDevice> device,
Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope);
--- a/src/internet/model/ipv4.h Tue Jul 09 19:15:20 2013 +0200
+++ b/src/internet/model/ipv4.h Tue Jul 09 19:21:07 2013 +0200
@@ -248,6 +248,15 @@
*/
virtual bool RemoveAddress (uint32_t interface, uint32_t addressIndex) = 0;
+ /**
+ * \brief Remove the given address on named Ipv4 interface
+ *
+ * \param interface Interface number of an Ipv4 interface
+ * \param address The address to remove
+ * \returns true if the operation succeeded
+ */
+ virtual bool RemoveAddress (uint32_t interface, Ipv4Address address) = 0;
+
/**
* \brief Return the first primary source address with scope less than
* or equal to the requested scope, to use in sending a packet to
--- a/src/internet/model/ipv6-interface.cc Tue Jul 09 19:15:20 2013 +0200
+++ b/src/internet/model/ipv6-interface.cc Tue Jul 09 19:21:07 2013 +0200
@@ -291,6 +291,29 @@
return addr; /* quiet compiler */
}
+Ipv6InterfaceAddress
+Ipv6Interface::RemoveAddress(Ipv6Address address)
+{
+ NS_LOG_FUNCTION(this << address);
+
+ if (address == address.GetLoopback())
+ {
+ NS_LOG_WARN ("Cannot remove loopback address.");
+ return Ipv6InterfaceAddress();
+ }
+
+ for (Ipv6InterfaceAddressListI it = m_addresses.begin (); it != m_addresses.end (); ++it)
+ {
+ if((*it).GetAddress() == address)
+ {
+ Ipv6InterfaceAddress iface = (*it);
+ m_addresses.erase(it);
+ return iface;
+ }
+ }
+ return Ipv6InterfaceAddress();
+}
+
Ipv6InterfaceAddress Ipv6Interface::GetAddressMatchingDestination (Ipv6Address dst)
{
NS_LOG_FUNCTION (this << dst);
--- a/src/internet/model/ipv6-interface.h Tue Jul 09 19:15:20 2013 +0200
+++ b/src/internet/model/ipv6-interface.h Tue Jul 09 19:21:07 2013 +0200
@@ -228,6 +228,15 @@
Ipv6InterfaceAddress RemoveAddress (uint32_t index);
/**
+ * \brief Remove the given Ipv6 address from the interface.
+ * \param address The Ipv6 address to remove
+ * \returns The removed Ipv6 interface address
+ * \returns The null interface address if the interface did not contain the
+ * address or if loopback address was passed as argument
+ */
+ Ipv6InterfaceAddress RemoveAddress (Ipv6Address address);
+
+ /**
* \brief Update state of an interface address.
* \param address IPv6 address
* \param state new state
--- a/src/internet/model/ipv6-l3-protocol.cc Tue Jul 09 19:15:20 2013 +0200
+++ b/src/internet/model/ipv6-l3-protocol.cc Tue Jul 09 19:21:07 2013 +0200
@@ -381,6 +381,29 @@
return false;
}
+bool
+Ipv6L3Protocol::RemoveAddress (uint32_t i, Ipv6Address address)
+{
+ NS_LOG_FUNCTION (this << i << address);
+
+ if (address == Ipv6Address::GetLoopback())
+ {
+ NS_LOG_WARN ("Cannot remove loopback address.");
+ return false;
+ }
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+ Ipv6InterfaceAddress ifAddr = interface->RemoveAddress (address);
+ if (ifAddr != Ipv6InterfaceAddress ())
+ {
+ if (m_routingProtocol != 0)
+ {
+ m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
+ }
+ return true;
+ }
+ return false;
+}
+
void Ipv6L3Protocol::SetMetric (uint32_t i, uint16_t metric)
{
NS_LOG_FUNCTION (this << i << metric);
--- a/src/internet/model/ipv6-l3-protocol.h Tue Jul 09 19:15:20 2013 +0200
+++ b/src/internet/model/ipv6-l3-protocol.h Tue Jul 09 19:21:07 2013 +0200
@@ -249,6 +249,14 @@
bool RemoveAddress (uint32_t interfaceIndex, uint32_t addressIndex);
/**
+ * \brief Remove a specified Ipv6 address from an interface.
+ * \param interfaceIndex interface index
+ * \param address Ipv6Address to be removed from the interface
+ * \returns true if the operation succeeded
+ */
+ bool RemoveAddress (uint32_t interface, Ipv6Address address);
+
+ /**
* \brief Set metric for an interface.
* \param i index
* \param metric
--- a/src/internet/model/ipv6.h Tue Jul 09 19:15:20 2013 +0200
+++ b/src/internet/model/ipv6.h Tue Jul 09 19:21:07 2013 +0200
@@ -218,6 +218,15 @@
virtual bool RemoveAddress (uint32_t interface, uint32_t addressIndex) = 0;
/**
+ * \brief Remove the given address on named Ipv6 interface
+ *
+ * \param interface Interface number of an IPv6 interface
+ * \param address the address to remove
+ * \returns true if the operation succeeded
+ */
+ virtual bool RemoveAddress (uint32_t interface, Ipv6Address address) = 0;
+
+ /**
* \brief Set metric on specified Ipv6 interface.
*
* \param interface The interface number of an IPv6 interface
--- a/src/internet/test/ipv4-test.cc Tue Jul 09 19:15:20 2013 +0200
+++ b/src/internet/test/ipv4-test.cc Tue Jul 09 19:21:07 2013 +0200
@@ -94,9 +94,53 @@
Ipv4InterfaceAddress output = interface->GetAddress (2);
NS_TEST_ASSERT_MSG_EQ (ifaceAddr4, output,
"The addresses should be identical");
+
+ /* Test Ipv4Interface()::RemoveAddress(address) */
+ output = interface->RemoveAddress (Ipv4Address ("250.0.0.1"));
+ NS_TEST_ASSERT_MSG_EQ (ifaceAddr4, output,
+ "Wrong Interface Address Removed??");
+ num = interface->GetNAddresses ();
+ NS_TEST_ASSERT_MSG_EQ (num, 2, "Should find 2 addresses??");
+
+ /* Remove a non-existent Address */
+ output = interface->RemoveAddress (Ipv4Address ("253.123.9.81"));
+ NS_TEST_ASSERT_MSG_EQ (Ipv4InterfaceAddress (), output,
+ "Removed non-existent address??");
+ num = interface->GetNAddresses ();
+ NS_TEST_ASSERT_MSG_EQ (num, 2, "Should find 2 addresses??");
+
+ /* Remove a Loopback Address */
+ output = interface->RemoveAddress (Ipv4Address::GetLoopback ());
+ NS_TEST_ASSERT_MSG_EQ (Ipv4InterfaceAddress (), output,
+ "Able to remove loopback address??");
+ num = interface->GetNAddresses ();
+ NS_TEST_ASSERT_MSG_EQ (num, 2, "Should find 2 addresses??");
+
+ /* Test Ipv4Address::RemoveAddress(i, addresss) */
+ bool result = ipv4->RemoveAddress (index, Ipv4Address
+("192.168.0.2"));
+ NS_TEST_ASSERT_MSG_EQ (true, result, "Unable to remove Address??");
+ num = interface->GetNAddresses ();
+ NS_TEST_ASSERT_MSG_EQ (num, 1, "Should find 1 addresses??");
+
+ /* Remove a non-existent Address */
+ result = ipv4->RemoveAddress (index, Ipv4Address ("189.0.0.1"));
+ NS_TEST_ASSERT_MSG_EQ (false, result,
+ "Removed non-existent address??");
+ num = interface->GetNAddresses ();
+ NS_TEST_ASSERT_MSG_EQ (num, 1, "Should find 1 addresses??");
+
+ /* Remove a loopback Address */
+ result = ipv4->RemoveAddress (index, Ipv4Address::GetLoopback ());
+ NS_TEST_ASSERT_MSG_EQ (false, result,
+ "Able to remove loopback address??");
+ num = interface->GetNAddresses ();
+ NS_TEST_ASSERT_MSG_EQ (num, 1, "Should find 1 addresses??");
+
Simulator::Destroy ();
}
+
static class IPv4L3ProtocolTestSuite : public TestSuite
{
public:
--- a/src/internet/test/ipv6-test.cc Tue Jul 09 19:15:20 2013 +0200
+++ b/src/internet/test/ipv6-test.cc Tue Jul 09 19:21:07 2013 +0200
@@ -136,6 +136,48 @@
index = ipv6->GetInterfaceForAddress ("2001:ffff:5678:9000::1"); /* address we just remove */
NS_TEST_ASSERT_MSG_EQ (index, (uint32_t) -1, "Address should not be found??");
+
+ /* Test Ipv6Interface()::RemoveAddress(address) */
+ output = interface->RemoveAddress (Ipv6Address ("2001:1234:5678:9000::1"));
+ NS_TEST_ASSERT_MSG_EQ (ifaceAddr1, output, "Wrong Interface Address Removed??");
+ num = interface->GetNAddresses ();
+ NS_TEST_ASSERT_MSG_EQ (num, 1, "Number of addresses should be 1??");
+
+ /* Remove a non-existent Address */
+ output = interface->RemoveAddress (Ipv6Address ("2001:1234:5678:9000::1"));
+ NS_TEST_ASSERT_MSG_EQ (Ipv6InterfaceAddress (), output,
+ "Removed non-existent address??");
+ num = interface->GetNAddresses ();
+ NS_TEST_ASSERT_MSG_EQ (num, 1, "Number of addresses should be 1??");
+
+ /* Remove a loopback Address */
+ output = interface->RemoveAddress (Ipv6Address::GetLoopback ());
+ NS_TEST_ASSERT_MSG_EQ (Ipv6InterfaceAddress (), output,
+ "Able to remove loopback address??");
+ num = interface->GetNAddresses ();
+ NS_TEST_ASSERT_MSG_EQ (num, 1, "Number of addresses should be 1??");
+
+ /* Test Ipv6Address::RemoveAddress(index, addresss) */
+ index = ipv6->GetInterfaceForAddress ("2001:ffff:5678:9001::2");
+ bool result = ipv6->RemoveAddress (index, Ipv6Address
+ ("2001:ffff:5678:9001::2"));
+ NS_TEST_ASSERT_MSG_EQ (result, true, "Unable to remove Address??");
+ num = interface2->GetNAddresses ();
+ NS_TEST_ASSERT_MSG_EQ (num, 1, "Number of addresses should be 1??");
+
+ /* Remove a non-existent Address */
+ result = ipv6->RemoveAddress (index, Ipv6Address
+ ("2001:ffff:5678:9001::2"));
+ NS_TEST_ASSERT_MSG_EQ (result, false, "Removed Non-existent address??");
+ num = interface2->GetNAddresses ();
+ NS_TEST_ASSERT_MSG_EQ (num, 1, "Number of addresses should be 1??");
+
+ /* Remove a loopback Address */
+ result = ipv6->RemoveAddress (index, Ipv6Address::GetLoopback ());
+ NS_TEST_ASSERT_MSG_EQ (result, false, "Able to remove loopback address??");
+ num = interface2->GetNAddresses ();
+ NS_TEST_ASSERT_MSG_EQ (num, 1, "Number of addresses should be 1??");
+
Simulator::Destroy ();
} //end DoRun
static class IPv6L3ProtocolTestSuite : public TestSuite