Bug 1883 - IPv6 don't consider the prefix and network when choosing output address
This commit is contained in:
@@ -50,6 +50,7 @@ Bugs fixed
|
||||
- Bug 1870 - Remove unnecessary AsInt functions
|
||||
- Bug 1874 - Ipv4L3Protocol::ProcessFragment: addressCombination and idProto identifiers not properly computed
|
||||
- Bug 1882 - int64x64 tests trigger valgrind bug
|
||||
- Bug 1883 - IPv6 don't consider the prefix and network when choosing output address
|
||||
|
||||
Release 3.19
|
||||
=============
|
||||
|
||||
@@ -171,13 +171,14 @@ void Ping6::Send ()
|
||||
/* hack to have ifIndex in Ipv6RawSocketImpl
|
||||
* maybe add a SetIfIndex in Ipv6RawSocketImpl directly
|
||||
*/
|
||||
Ipv6InterfaceAddress dstIa (m_peerAddress);
|
||||
for (uint32_t i = 0; i < GetNode ()->GetObject<Ipv6> ()->GetNAddresses (m_ifIndex); i++)
|
||||
{
|
||||
src = GetNode ()->GetObject<Ipv6> ()->GetAddress (m_ifIndex, i).GetAddress ();
|
||||
Ipv6InterfaceAddress srcIa (src);
|
||||
if ( srcIa.GetScope() == dstIa.GetScope() )
|
||||
Ipv6InterfaceAddress srcIa;
|
||||
srcIa = GetNode ()->GetObject<Ipv6> ()->GetAddress (m_ifIndex, i);
|
||||
|
||||
if (srcIa.IsInSameSubnet (m_peerAddress))
|
||||
{
|
||||
src = srcIa.GetAddress ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +137,29 @@ Ipv6InterfaceAddress::Scope_e Ipv6InterfaceAddress::GetScope () const
|
||||
return m_scope;
|
||||
}
|
||||
|
||||
bool Ipv6InterfaceAddress::IsInSameSubnet (Ipv6Address b) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
|
||||
Ipv6Address aAddr = m_address;
|
||||
aAddr = aAddr.CombinePrefix (m_prefix);
|
||||
Ipv6Address bAddr = b;
|
||||
bAddr = bAddr.CombinePrefix (m_prefix);
|
||||
|
||||
if (aAddr == bAddr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((bAddr.IsLinkLocalMulticast () && aAddr.IsLinkLocal ()) ||
|
||||
(aAddr.IsLinkLocalMulticast () && bAddr.IsLinkLocal ()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, const Ipv6InterfaceAddress &addr)
|
||||
{
|
||||
os << "address: " << addr.GetAddress () << addr.GetPrefix () << "; scope: ";
|
||||
|
||||
@@ -133,6 +133,13 @@ public:
|
||||
*/
|
||||
Ipv6InterfaceAddress::Scope_e GetScope () const;
|
||||
|
||||
/**
|
||||
* \brief Checks if the address is in the same subnet.
|
||||
* \param b the address to check
|
||||
* \return true if the address is in the same subnet.
|
||||
*/
|
||||
bool IsInSameSubnet (Ipv6Address b) const;
|
||||
|
||||
/**
|
||||
* \brief Set the latest DAD probe packet UID.
|
||||
* \param uid packet uid
|
||||
|
||||
@@ -309,7 +309,7 @@ Ptr<Ipv6Route> Ipv6StaticRouting::LookupStatic (Ipv6Address dst, Ptr<NetDevice>
|
||||
|
||||
if (mask.IsMatch (dst, entry))
|
||||
{
|
||||
NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << maskLen << ", metric " << metric);
|
||||
NS_LOG_LOGIC ("Found global network route " << *j << ", mask length " << maskLen << ", metric " << metric);
|
||||
|
||||
/* if interface is given, check the route will output on this interface */
|
||||
if (!interface || interface == m_ipv6->GetNetDevice (j->GetInterface ()))
|
||||
@@ -798,27 +798,37 @@ Ipv6Address Ipv6StaticRouting::SourceAddressSelection (uint32_t interface, Ipv6A
|
||||
NS_LOG_FUNCTION (this << interface << dest);
|
||||
Ipv6Address ret;
|
||||
|
||||
/* first address of an IPv6 interface is link-local ones */
|
||||
ret = m_ipv6->GetAddress (interface, 0).GetAddress ();
|
||||
|
||||
if (dest == Ipv6Address::GetAllNodesMulticast () || dest == Ipv6Address::GetAllRoutersMulticast () || dest == Ipv6Address::GetAllHostsMulticast ())
|
||||
if (dest.IsLinkLocal () || dest.IsLinkLocalMulticast ())
|
||||
{
|
||||
return ret;
|
||||
for (uint32_t i = 0; i < m_ipv6->GetNAddresses (interface); i++)
|
||||
{
|
||||
Ipv6InterfaceAddress test = m_ipv6->GetAddress (interface, i);
|
||||
if (test.GetScope () == Ipv6InterfaceAddress::LINKLOCAL)
|
||||
{
|
||||
return test.GetAddress ();
|
||||
}
|
||||
}
|
||||
NS_ASSERT_MSG (false, "No link-local address found on interface " << interface);
|
||||
}
|
||||
|
||||
/* usually IPv6 interfaces have one link-local address and one global address */
|
||||
|
||||
for (uint32_t i = 1; i < m_ipv6->GetNAddresses (interface); i++)
|
||||
for (uint32_t i = 0; i < m_ipv6->GetNAddresses (interface); i++)
|
||||
{
|
||||
Ipv6InterfaceAddress test = m_ipv6->GetAddress (interface, i);
|
||||
Ipv6InterfaceAddress dst(dest);
|
||||
|
||||
if (test.GetScope() == dst.GetScope())
|
||||
if (test.GetScope () == Ipv6InterfaceAddress::GLOBAL)
|
||||
{
|
||||
return test.GetAddress ();
|
||||
if (test.IsInSameSubnet (dest))
|
||||
{
|
||||
return test.GetAddress ();
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = test.GetAddress ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no specific match found. Use a global address (any useful is fine).
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user