Bug 1702 - A router should't aways add itself as the default router

This commit is contained in:
Tommaso Pecorella
2013-08-07 23:18:48 +02:00
parent 3f302f67cf
commit 54564e2fa6
13 changed files with 287 additions and 36 deletions

View File

@@ -77,6 +77,11 @@ us a note on ns-developers mailing list.</p>
<h2>Changes to existing API:</h2>
<ul>
<li> The Ipv6InterfaceContainer functions to set a node in forwarding state (i.e., a router)
and to install a default router in a group of nodes have been extensively changed.
The old function "void Ipv6InterfaceContainer::SetRouter (uint32_t i, bool router)"
is now DEPRECATED.
</li>
<li> The documentation's IPv6 addresses (2001:db8::/32, RFC 3849) are now
dropped by routers.
</li>
@@ -88,7 +93,7 @@ us a note on ns-developers mailing list.</p>
include it from the core module.
</li>
<li> The Ipv6 UnicastForwardCallback and MulticastForwardCallback
have a new parmater, the NetDevice the packet has been received from.
have a new parameter, the NetDevice the packet has been received from.
Existing Ipv6RoutingProtocols should update their RouteInput function
accordingly. E.g., from ucb (rtentry, p, header); to ucb (idev, rtentry, p, header);
</li>

View File

@@ -63,6 +63,7 @@ Bugs fixed
- Bug 1698 - mobility.SetPositionAllocator misses prefix "ns3::"
- Bug 1700 - Ipv6RawSocket does not honor the bound address when sending packets
- Bug 1701 - Ipv6StaticRouting: the source address should match the destination scope
- Bug 1702 - Ipv6InterfaceContainer::SetRouter should not always add the router as the default router.
- Bug 1703 - Nodes don't react to a DAD
- Bug 1712 - The IP (v4 and v6) forwarding needs a test
- Bug 1718 - Ipv4StaticRouting log component is misspelled

View File

@@ -129,10 +129,12 @@ int main (int argc, char** argv)
Ipv6AddressHelper ipv6;
ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64));
Ipv6InterfaceContainer i1 = ipv6.Assign (d1);
i1.SetRouter (1, true);
i1.SetForwarding (1, true);
i1.SetDefaultRouteInAllNodes (1);
ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
Ipv6InterfaceContainer i2 = ipv6.Assign (d2);
i2.SetRouter (0, true);
i2.SetForwarding (0, true);
i2.SetDefaultRouteInAllNodes (0);
stackHelper.PrintRoutingTable (n0);

View File

@@ -148,12 +148,14 @@ int main (int argc, char **argv)
ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64));
Ipv6InterfaceContainer iic1 = ipv6.Assign (ndc1);
iic1.SetRouter (2, true);
iic1.SetRouter (1, true);
iic1.SetForwarding (2, true);
iic1.SetForwarding (1, true);
iic1.SetDefaultRouteInAllNodes (1);
ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
Ipv6InterfaceContainer iic2 = ipv6.Assign (ndc2);
iic2.SetRouter (0, true);
iic2.SetForwarding (0, true);
iic2.SetDefaultRouteInAllNodes (0);
stackHelper.AddHostRouteTo (r1, iic2.GetAddress (1, 1), iic1.GetAddress (2, 0), iic1.GetInterfaceIndex (1));

View File

@@ -106,31 +106,41 @@ int main (int argc, char **argv)
ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64));
Ipv6InterfaceContainer i1 = ipv6.Assign (d1);
i1.SetRouter (1, true);
i1.SetForwarding (1, true);
i1.SetDefaultRouteInAllNodes (1);
ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
Ipv6InterfaceContainer i2 = ipv6.Assign (d2);
i2.SetRouter (1, true);
i2.SetForwarding (1, true);
i2.SetDefaultRouteInAllNodes (1);
ipv6.SetBase (Ipv6Address ("2001:3::"), Ipv6Prefix (64));
Ipv6InterfaceContainer i3 = ipv6.Assign (d3);
i3.SetRouter (0, true);
i3.SetRouter (1, true);
i3.SetForwarding (0, true);
i3.SetDefaultRouteInAllNodes (0);
i3.SetForwarding (1, true);
i3.SetDefaultRouteInAllNodes (1);
ipv6.SetBase (Ipv6Address ("2001:4::"), Ipv6Prefix (64));
Ipv6InterfaceContainer i4 = ipv6.Assign (d4);
i4.SetRouter (0, true);
i4.SetRouter (1, true);
i4.SetForwarding (0, true);
i4.SetDefaultRouteInAllNodes (0);
i4.SetForwarding (1, true);
i4.SetDefaultRouteInAllNodes (1);
ipv6.SetBase (Ipv6Address ("2001:5::"), Ipv6Prefix (64));
Ipv6InterfaceContainer i5 = ipv6.Assign (d5);
i5.SetRouter (0, true);
i5.SetRouter (1, true);
i5.SetForwarding (0, true);
i5.SetDefaultRouteInAllNodes (0);
i5.SetForwarding (1, true);
i5.SetDefaultRouteInAllNodes (1);
ipv6.SetBase (Ipv6Address ("2001:6::"), Ipv6Prefix (64));
Ipv6InterfaceContainer i6 = ipv6.Assign (d6);
i6.SetRouter (0, true);
i6.SetRouter (1, true);
i6.SetForwarding (0, true);
i6.SetDefaultRouteInAllNodes (0);
i6.SetForwarding (1, true);
i6.SetDefaultRouteInAllNodes (1);
NS_LOG_INFO ("Create Applications.");

View File

@@ -166,7 +166,8 @@ int main (int argc, char** argv)
NetDeviceContainer tmp2;
tmp2.Add (d1.Get (1)); /* R */
Ipv6InterfaceContainer iicr1 = ipv6.Assign (tmp2); /* R interface to the first subnet is just statically assigned */
iicr1.SetRouter (0, true);
iicr1.SetForwarding (0, true);
iicr1.SetDefaultRouteInAllNodes (0);
iic1.Add (iicr1);
/* add another IPv6 address for second prefix advertised on first subnet */
@@ -177,7 +178,8 @@ int main (int argc, char** argv)
NetDeviceContainer tmp3;
tmp3.Add (d2.Get (0)); /* R */
Ipv6InterfaceContainer iicr2 = ipv6.Assign (tmp3); /* R interface */
iicr2.SetRouter (0, true);
iicr2.SetForwarding (0, true);
iicr2.SetDefaultRouteInAllNodes (0);
NetDeviceContainer tmp4;
tmp4.Add (d2.Get (1)); /* n1 */

View File

@@ -92,7 +92,8 @@ int main (int argc, char** argv)
NetDeviceContainer tmp2;
tmp2.Add (d1.Get (1)); /* R */
Ipv6InterfaceContainer iicr1 = ipv6.Assign (tmp2); /* R interface to the first subnet is just statically assigned */
iicr1.SetRouter (0, true);
iicr1.SetForwarding (0, true);
iicr1.SetDefaultRouteInAllNodes (0);
iic1.Add (iicr1);
/* second subnet R - n1 */
@@ -100,7 +101,8 @@ int main (int argc, char** argv)
NetDeviceContainer tmp3;
tmp3.Add (d2.Get (0)); /* R */
Ipv6InterfaceContainer iicr2 = ipv6.Assign (tmp3); /* R interface */
iicr2.SetRouter (0, true);
iicr2.SetForwarding (0, true);
iicr2.SetDefaultRouteInAllNodes (0);
NetDeviceContainer tmp4;
tmp4.Add (d2.Get (1)); /* n1 */

View File

@@ -130,10 +130,12 @@ int main (int argc, char** argv)
Ipv6AddressHelper ipv6;
ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64));
Ipv6InterfaceContainer i1 = ipv6.Assign (d1);
i1.SetRouter (1, true);
i1.SetForwarding (1, true);
i1.SetDefaultRouteInAllNodes (1);
ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
Ipv6InterfaceContainer i2 = ipv6.Assign (d2);
i2.SetRouter (0, true);
i2.SetForwarding (0, true);
i2.SetDefaultRouteInAllNodes (0);
stackHelper.PrintRoutingTable (n0);

View File

@@ -102,7 +102,8 @@ main (int argc, char *argv[])
ipv6.SetBase (Ipv6Address ("2001:0DB8:1::"), Ipv6Prefix (64));
Ipv6InterfaceContainer i1 = ipv6.Assign (devs);
i1.SetRouter (1, true);
i1.SetForwarding (1, true);
i1.SetDefaultRouteInAllNodes (1);
ipv6.SetBase (Ipv6Address ("2001:0DB8:2::"), Ipv6Prefix (64));
Ipv6Address tapAddr = ipv6.NewAddress ();
@@ -124,7 +125,8 @@ main (int argc, char *argv[])
Ptr<FdNetDevice> fdevice = device->GetObject<FdNetDevice> ();
fdevice-> SetIsMulticast (true);
Ipv6InterfaceContainer i2 = ipv6.Assign (fdevs);
i2.SetRouter (0, true);
i2.SetForwarding (0, true);
i2.SetDefaultRouteInAllNodes (0);
//
// Create the Ping6 application.

View File

@@ -1,6 +1,7 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008-2009 Strasbourg University
* 2013 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
@@ -16,6 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
* Tommaso Pecorella <tommaso.pecorella@unifi.it>
*/
#include "ns3/node-list.h"
@@ -24,20 +26,19 @@
#include "ipv6-interface-container.h"
#include "ns3/ipv6-static-routing-helper.h"
namespace ns3
{
namespace ns3 {
Ipv6InterfaceContainer::Ipv6InterfaceContainer ()
{
}
Ipv6InterfaceContainer::Iterator
Ipv6InterfaceContainer::Iterator
Ipv6InterfaceContainer::Begin (void) const
{
return m_interfaces.begin ();
}
Ipv6InterfaceContainer::Iterator
Ipv6InterfaceContainer::Iterator
Ipv6InterfaceContainer::End (void) const
{
return m_interfaces.end ();
@@ -81,6 +82,10 @@ void Ipv6InterfaceContainer::Add (Ipv6InterfaceContainer& c)
void Ipv6InterfaceContainer::SetRouter (uint32_t i, bool router)
{
// This function is deprecated and should be substituted by:
// SetForwarding (RouterInterfaceIndex, true);
// SetDefaultRouteInAllNodes (RouterInterfaceIndex);
Ptr<Ipv6> ipv6 = m_interfaces[i].first;
ipv6->SetForwarding (m_interfaces[i].second, router);
@@ -105,11 +110,82 @@ void Ipv6InterfaceContainer::SetRouter (uint32_t i, bool router)
}
}
void Ipv6InterfaceContainer::SetDefaultRoute (uint32_t i, uint32_t router)
void Ipv6InterfaceContainer::SetForwarding (uint32_t i, bool router)
{
Ptr<Ipv6> ipv6 = m_interfaces[i].first;
Ptr<Ipv6> ipv6Router = m_interfaces[router].first;
Ipv6Address routerAddress = ipv6Router->GetAddress (m_interfaces[router].second, 0).GetAddress ();
ipv6->SetForwarding (m_interfaces[i].second, router);
}
void Ipv6InterfaceContainer::SetDefaultRouteInAllNodes (uint32_t router)
{
Ptr<Ipv6> ipv6 = m_interfaces[router].first;
uint32_t other;
Ipv6Address routerAddress = GetLinkLocalAddress (router);
NS_ASSERT_MSG (routerAddress != Ipv6Address::GetAny (), "No link-local address found on router, aborting");
for (other = 0; other < m_interfaces.size (); other++)
{
if (other != router)
{
Ptr<Ipv6StaticRouting> routing = 0;
Ipv6StaticRoutingHelper routingHelper;
ipv6 = m_interfaces[other].first;
routing = routingHelper.GetStaticRouting (ipv6);
routing->SetDefaultRoute (routerAddress, m_interfaces[other].second);
}
}
}
void Ipv6InterfaceContainer::SetDefaultRouteInAllNodes (Ipv6Address routerAddress)
{
uint32_t routerIndex;
bool found = false;
for (uint32_t index = 0; index < m_interfaces.size (); index++)
{
Ptr<Ipv6> ipv6 = m_interfaces[index].first;
for (uint32_t i = 0; i < ipv6->GetNAddresses (m_interfaces[index].second); i++)
{
Ipv6Address addr = ipv6->GetAddress (m_interfaces[index].second, i).GetAddress ();
if (addr == routerAddress)
{
routerIndex = index;
found = true;
break;
}
}
if (found)
{
break;
}
}
NS_ASSERT_MSG (found != true, "No such address in the interfaces. Aborting.");
for (uint32_t other = 0; other < m_interfaces.size (); other++)
{
if (other != routerIndex)
{
Ptr<Ipv6StaticRouting> routing = 0;
Ipv6StaticRoutingHelper routingHelper;
Ptr<Ipv6> ipv6 = m_interfaces[other].first;
routing = routingHelper.GetStaticRouting (ipv6);
routing->SetDefaultRoute (routerAddress, m_interfaces[other].second);
}
}
}
void Ipv6InterfaceContainer::SetDefaultRoute (uint32_t i, uint32_t router)
{
NS_ASSERT_MSG (i != router, "A node shouldn't set itself as the default router, isn't it? Aborting.");
Ptr<Ipv6> ipv6 = m_interfaces[i].first;
Ipv6Address routerAddress = GetLinkLocalAddress (router);
NS_ASSERT_MSG (routerAddress != Ipv6Address::GetAny (), "No link-local address found on router, aborting");
Ptr<Ipv6StaticRouting> routing = 0;
Ipv6StaticRoutingHelper routingHelper;
@@ -117,5 +193,100 @@ void Ipv6InterfaceContainer::SetDefaultRoute (uint32_t i, uint32_t router)
routing->SetDefaultRoute (routerAddress, m_interfaces[i].second);
}
void Ipv6InterfaceContainer::SetDefaultRoute (uint32_t i, Ipv6Address routerAddr)
{
uint32_t routerIndex;
bool found = false;
for (uint32_t index = 0; index < m_interfaces.size (); index++)
{
Ptr<Ipv6> ipv6 = m_interfaces[index].first;
for (uint32_t i = 0; i < ipv6->GetNAddresses (m_interfaces[index].second); i++)
{
Ipv6Address addr = ipv6->GetAddress (m_interfaces[index].second, i).GetAddress ();
if (addr == routerAddr)
{
routerIndex = index;
found = true;
break;
}
}
if (found)
{
break;
}
}
NS_ASSERT_MSG (found != true, "No such address in the interfaces. Aborting.");
NS_ASSERT_MSG (i != routerIndex, "A node shouldn't set itself as the default router, isn't it? Aborting.");
Ptr<Ipv6> ipv6 = m_interfaces[i].first;
Ipv6Address routerLinkLocalAddress = GetLinkLocalAddress (routerIndex);
Ptr<Ipv6StaticRouting> routing = 0;
Ipv6StaticRoutingHelper routingHelper;
routing = routingHelper.GetStaticRouting (ipv6);
routing->SetDefaultRoute (routerLinkLocalAddress, m_interfaces[i].second);
}
Ipv6Address Ipv6InterfaceContainer::GetLinkLocalAddress (uint32_t index)
{
Ptr<Ipv6> ipv6 = m_interfaces[index].first;
for (uint32_t i = 0; i < ipv6->GetNAddresses (m_interfaces[index].second); i++)
{
Ipv6InterfaceAddress iAddress;
iAddress = ipv6->GetAddress (m_interfaces[index].second, i);
if (iAddress.GetScope () == Ipv6InterfaceAddress::LINKLOCAL)
{
return iAddress.GetAddress ();
}
}
return Ipv6Address::GetAny ();
}
Ipv6Address Ipv6InterfaceContainer::GetLinkLocalAddress (Ipv6Address address)
{
if (address.IsLinkLocal ())
{
return address;
}
uint32_t nodeIndex;
bool found = false;
for (uint32_t index = 0; index < m_interfaces.size (); index++)
{
Ptr<Ipv6> ipv6 = m_interfaces[index].first;
for (uint32_t i = 0; i < ipv6->GetNAddresses (m_interfaces[index].second); i++)
{
Ipv6Address addr = ipv6->GetAddress (m_interfaces[index].second, i).GetAddress ();
if (addr == address)
{
nodeIndex = index;
found = true;
break;
}
}
if (found)
{
break;
}
}
NS_ASSERT_MSG (found != true, "No such address in the interfaces. Aborting.");
Ptr<Ipv6> ipv6 = m_interfaces[nodeIndex].first;
for (uint32_t i = 0; i < ipv6->GetNAddresses (m_interfaces[nodeIndex].second); i++)
{
Ipv6InterfaceAddress iAddress;
iAddress = ipv6->GetAddress (m_interfaces[nodeIndex].second, i);
if (iAddress.GetScope () == Ipv6InterfaceAddress::LINKLOCAL)
{
return iAddress.GetAddress ();
}
}
return Ipv6Address::GetAny ();
}
} /* namespace ns3 */

View File

@@ -1,6 +1,7 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008-2009 Strasbourg University
* 2013 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
@@ -16,6 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
* Tommaso Pecorella <tommaso.pecorella@unifi.it>
*/
#ifndef IPV6_INTERFACE_CONTAINER_H
@@ -27,6 +29,7 @@
#include "ns3/ipv6.h"
#include "ns3/ipv6-address.h"
#include "ns3/deprecated.h"
namespace ns3
{
@@ -80,6 +83,20 @@ public:
*/
Ipv6Address GetAddress (uint32_t i, uint32_t j) const;
/**
* \brief Get the link-local address for the specified index.
* \param i index
* \return the link-local address, or "::" if the interface has no link local address.
*/
Ipv6Address GetLinkLocalAddress (uint32_t i);
/**
* \brief Get the link-local address for the node with the specified global address.
* \param address the address to find.
* \return the link-local address, or "::" if the interface has no link local address.
*/
Ipv6Address GetLinkLocalAddress (Ipv6Address address);
/**
* \brief Add a couple IPv6/interface.
* \param ipv6 IPv6 address
@@ -149,7 +166,28 @@ public:
* \param i index
* \param router true : is a router, false : is an host
*/
void SetRouter (uint32_t i, bool router);
void SetRouter (uint32_t i, bool router) NS_DEPRECATED;
/**
* \brief Set the state of the stack (act as a router or as an host) for the specified index.
* This automatically sets all the node's interfaces to the same forwarding state.
* \param i index
* \param state true : is a router, false : is an host
*/
void SetForwarding (uint32_t i, bool state);
/**
* \brief Set the default route for all the devices (except the router itself).
* \param router the default router index
*/
void SetDefaultRouteInAllNodes (uint32_t router);
/**
* \brief Set the default route for all the devices (except the router itself).
* Note that the route will be set to the link-local address of the node with the specified address.
* \param routerAddr the default router address
*/
void SetDefaultRouteInAllNodes (Ipv6Address routerAddr);
/**
* \brief Set the default route for the specified index.
@@ -158,6 +196,14 @@ public:
*/
void SetDefaultRoute (uint32_t i, uint32_t router);
/**
* \brief Set the default route for the specified index.
* Note that the route will be set to the link-local address of the node with the specified address.
* \param i index
* \param routerAddr the default router address
*/
void SetDefaultRoute (uint32_t i, Ipv6Address routerAddr);
private:
typedef std::vector<std::pair<Ptr<Ipv6>, uint32_t> > InterfaceVector;

View File

@@ -97,7 +97,10 @@ Ipv6StaticRouting::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
{
NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse << metric);
NS_ASSERT_MSG(nextHop.IsLinkLocal(), "Ipv6StaticRouting::AddHostRouteTo - Next hop must be link-local");
if (nextHop.IsLinkLocal())
{
NS_LOG_WARN ("Ipv6StaticRouting::AddHostRouteTo - Next hop should be link-local");
}
AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse, metric);
}
@@ -119,7 +122,10 @@ void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix netwo
void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
{
NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse << metric);
NS_ASSERT_MSG(nextHop.IsLinkLocal(), "Ipv6StaticRouting::AddNetworkRouteTo - Next hop must be link-local");
if (nextHop.IsLinkLocal())
{
NS_LOG_WARN ("Ipv6StaticRouting::AddNetworkRouteTo - Next hop should be link-local");
}
Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
*route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);

View File

@@ -74,7 +74,7 @@ public:
/**
* \brief Add route to host.
* \param dest destination address
* \param nextHop next hop address to route the packet. Must be a link-local address
* \param nextHop next hop address to route the packet.
* \param interface interface index
* \param prefixToUse prefix that should be used for source address for this destination
* \param metric metric of route in case of multiple routes to same destination
@@ -103,7 +103,7 @@ public:
* \brief Add route to network.
* \param network network address
* \param networkPrefix network prefix*
* \param nextHop next hop address to route the packet. Must be a link-local address
* \param nextHop next hop address to route the packet.
* \param interface interface index
* \param prefixToUse prefix that should be used for source address for this destination
* \param metric metric of route in case of multiple routes to same destination