bug 1047: Multicast routes on nodes with >16 interfaces
parent
2e9964060c
commit
6642899baa
|
@ -114,6 +114,13 @@ Time result = Time (tmp * 5);
|
||||||
</pre>
|
</pre>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
|
<li><b>Multicast GetOutputTtl() commands</b>
|
||||||
|
<p> As part of bug 1047 rework to enable multicast routes on nodes with
|
||||||
|
more than 16 interfaces, the methods Ipv4MulticastRoute::GetOutputTtl ()
|
||||||
|
and Ipv6MulticastRoute::GetOutputTtl () have been modified to return
|
||||||
|
a std::map of interface IDs and TTLs for the route.
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>Changed behavior:</h2>
|
<h2>Changed behavior:</h2>
|
||||||
|
|
|
@ -77,6 +77,7 @@ since ns-3.10, in many cases referencing the Bugzilla bug number.
|
||||||
- bug 1054 - ipv6 InternetStackHelper EnablePcapIpv6All() broken
|
- bug 1054 - ipv6 InternetStackHelper EnablePcapIpv6All() broken
|
||||||
- bug 1042 - AODV RERR implosion (missing RERR_RATELIMIT)
|
- bug 1042 - AODV RERR implosion (missing RERR_RATELIMIT)
|
||||||
- bug 1097 - AODV routing entry set to be VALID mistakenly
|
- bug 1097 - AODV routing entry set to be VALID mistakenly
|
||||||
|
- bug 1047 - Multicast routes on nodes with >16 interfaces
|
||||||
|
|
||||||
Known issues
|
Known issues
|
||||||
------------
|
------------
|
||||||
|
|
|
@ -739,30 +739,32 @@ Ipv4L3Protocol::IpMulticastForward (Ptr<Ipv4MulticastRoute> mrtentry, Ptr<const
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION (this << mrtentry << p << header);
|
NS_LOG_FUNCTION (this << mrtentry << p << header);
|
||||||
NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
|
NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
|
||||||
// The output interfaces we could forward this onto are encoded
|
|
||||||
// in the OutputTtl of the Ipv4MulticastRoute
|
std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap();
|
||||||
for (uint32_t i = 0; i < Ipv4MulticastRoute::MAX_INTERFACES; i++)
|
std::map<uint32_t, uint32_t>::iterator mapIter;
|
||||||
|
|
||||||
|
for (mapIter = ttlMap.begin(); mapIter != ttlMap.end(); mapIter++)
|
||||||
{
|
{
|
||||||
if (mrtentry->GetOutputTtl (i) < Ipv4MulticastRoute::MAX_TTL)
|
uint32_t interfaceId = mapIter->first;
|
||||||
|
//uint32_t outputTtl = mapIter->second; // Unused for now
|
||||||
|
|
||||||
|
Ptr<Packet> packet = p->Copy ();
|
||||||
|
Ipv4Header h = header;
|
||||||
|
h.SetTtl (header.GetTtl () - 1);
|
||||||
|
if (h.GetTtl () == 0)
|
||||||
{
|
{
|
||||||
Ptr<Packet> packet = p->Copy ();
|
NS_LOG_WARN ("TTL exceeded. Drop.");
|
||||||
Ipv4Header h = header;
|
m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv4> (), interfaceId);
|
||||||
h.SetTtl (header.GetTtl () - 1);
|
return;
|
||||||
if (h.GetTtl () == 0)
|
|
||||||
{
|
|
||||||
NS_LOG_WARN ("TTL exceeded. Drop.");
|
|
||||||
m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv4> (), i);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NS_LOG_LOGIC ("Forward multicast via interface " << i);
|
|
||||||
Ptr<Ipv4Route> rtentry = Create<Ipv4Route> ();
|
|
||||||
rtentry->SetSource (h.GetSource ());
|
|
||||||
rtentry->SetDestination (h.GetDestination ());
|
|
||||||
rtentry->SetGateway (Ipv4Address::GetAny ());
|
|
||||||
rtentry->SetOutputDevice (GetNetDevice (i));
|
|
||||||
SendRealOut (rtentry, packet, h);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
NS_LOG_LOGIC ("Forward multicast via interface " << interfaceId);
|
||||||
|
Ptr<Ipv4Route> rtentry = Create<Ipv4Route> ();
|
||||||
|
rtentry->SetSource (h.GetSource ());
|
||||||
|
rtentry->SetDestination (h.GetDestination ());
|
||||||
|
rtentry->SetGateway (Ipv4Address::GetAny ());
|
||||||
|
rtentry->SetOutputDevice (GetNetDevice (interfaceId));
|
||||||
|
SendRealOut (rtentry, packet, h);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,12 +82,7 @@ std::ostream& operator<< (std::ostream& os, Ipv4Route const& route)
|
||||||
|
|
||||||
Ipv4MulticastRoute::Ipv4MulticastRoute ()
|
Ipv4MulticastRoute::Ipv4MulticastRoute ()
|
||||||
{
|
{
|
||||||
uint32_t initial_ttl = MAX_TTL;
|
m_ttls.clear();
|
||||||
// Initialize array to MAX_TTL, which means that all interfaces are "off"
|
|
||||||
for (uint32_t i = 0; i < MAX_INTERFACES; i++)
|
|
||||||
{
|
|
||||||
m_ttls.push_back(initial_ttl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -129,13 +124,36 @@ Ipv4MulticastRoute::GetParent (void) const
|
||||||
void
|
void
|
||||||
Ipv4MulticastRoute::SetOutputTtl (uint32_t oif, uint32_t ttl)
|
Ipv4MulticastRoute::SetOutputTtl (uint32_t oif, uint32_t ttl)
|
||||||
{
|
{
|
||||||
m_ttls[oif] = ttl;
|
if (ttl >= MAX_TTL)
|
||||||
|
{
|
||||||
|
// This TTL value effectively disables the interface
|
||||||
|
std::map<uint32_t, uint32_t>::iterator iter;
|
||||||
|
iter = m_ttls.find(oif);
|
||||||
|
if (iter != m_ttls.end())
|
||||||
|
{
|
||||||
|
m_ttls.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ttls[oif] = ttl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
Ipv4MulticastRoute::GetOutputTtl (uint32_t oif) const
|
Ipv4MulticastRoute::GetOutputTtl (uint32_t oif)
|
||||||
{
|
{
|
||||||
return m_ttls[oif];
|
// We keep this interface around for compatibility (for now)
|
||||||
|
std::map<uint32_t, uint32_t>::const_iterator iter = m_ttls.find(oif);
|
||||||
|
if (iter == m_ttls.end())
|
||||||
|
return((uint32_t)MAX_TTL);
|
||||||
|
return(iter->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<uint32_t, uint32_t>
|
||||||
|
Ipv4MulticastRoute::GetOutputTtlMap() const
|
||||||
|
{
|
||||||
|
return(m_ttls);
|
||||||
}
|
}
|
||||||
|
|
||||||
}//namespace ns3
|
}//namespace ns3
|
||||||
|
|
|
@ -20,11 +20,12 @@
|
||||||
#define IPV4_ROUTE_H
|
#define IPV4_ROUTE_H
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <map>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
#include "ns3/simple-ref-count.h"
|
#include "ns3/simple-ref-count.h"
|
||||||
#include "ns3/ipv4-address.h"
|
#include "ns3/ipv4-address.h"
|
||||||
|
#include "ns3/deprecated.h"
|
||||||
|
|
||||||
namespace ns3 {
|
namespace ns3 {
|
||||||
|
|
||||||
|
@ -145,7 +146,12 @@ public:
|
||||||
* \param oif outgoing interface
|
* \param oif outgoing interface
|
||||||
* \return TTL for this route
|
* \return TTL for this route
|
||||||
*/
|
*/
|
||||||
uint32_t GetOutputTtl (uint32_t oif) const;
|
uint32_t GetOutputTtl (uint32_t oif) NS_DEPRECATED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \return map of output interface Ids and TTLs for this route
|
||||||
|
*/
|
||||||
|
std::map<uint32_t, uint32_t> GetOutputTtlMap() const;
|
||||||
|
|
||||||
static const uint32_t MAX_INTERFACES = 16; // Maximum number of multicast interfaces on a router
|
static const uint32_t MAX_INTERFACES = 16; // Maximum number of multicast interfaces on a router
|
||||||
static const uint32_t MAX_TTL = 255; // Maximum time-to-live (TTL)
|
static const uint32_t MAX_TTL = 255; // Maximum time-to-live (TTL)
|
||||||
|
@ -154,7 +160,7 @@ private:
|
||||||
Ipv4Address m_group; // Group
|
Ipv4Address m_group; // Group
|
||||||
Ipv4Address m_origin; // Source of packet
|
Ipv4Address m_origin; // Source of packet
|
||||||
uint32_t m_parent; // Source interface
|
uint32_t m_parent; // Source interface
|
||||||
std::vector<uint32_t> m_ttls;
|
std::map<uint32_t, uint32_t> m_ttls;
|
||||||
};
|
};
|
||||||
|
|
||||||
}//namespace ns3
|
}//namespace ns3
|
||||||
|
|
|
@ -910,31 +910,30 @@ void Ipv6L3Protocol::IpMulticastForward (Ptr<Ipv6MulticastRoute> mrtentry, Ptr<c
|
||||||
NS_LOG_FUNCTION (this << mrtentry << p << header);
|
NS_LOG_FUNCTION (this << mrtentry << p << header);
|
||||||
NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
|
NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
|
||||||
|
|
||||||
// The output interfaces we could forward this onto are encoded
|
std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap();
|
||||||
// in the OutputTtl of the Ipv6MulticastRoute
|
std::map<uint32_t, uint32_t>::iterator mapIter;
|
||||||
for (uint32_t i = 0 ; i < Ipv6MulticastRoute::MAX_INTERFACES ; i++)
|
|
||||||
{
|
|
||||||
if (mrtentry->GetOutputTtl (i) < Ipv6MulticastRoute::MAX_TTL)
|
|
||||||
{
|
|
||||||
Ptr<Packet> packet = p->Copy ();
|
|
||||||
Ipv6Header h = header;
|
|
||||||
h.SetHopLimit (header.GetHopLimit () - 1);
|
|
||||||
if (h.GetHopLimit () == 0)
|
|
||||||
{
|
|
||||||
NS_LOG_WARN ("TTL exceeded. Drop.");
|
|
||||||
m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv6> (), i);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_LOG_LOGIC ("Forward multicast via interface " << i);
|
for (mapIter = ttlMap.begin(); mapIter != ttlMap.end(); mapIter++)
|
||||||
Ptr<Ipv6Route> rtentry = Create<Ipv6Route> ();
|
{
|
||||||
rtentry->SetSource (h.GetSourceAddress ());
|
uint32_t interfaceId = mapIter->first;
|
||||||
rtentry->SetDestination (h.GetDestinationAddress ());
|
//uint32_t outputTtl = mapIter->second; // Unused for now
|
||||||
rtentry->SetGateway (Ipv6Address::GetAny ());
|
Ptr<Packet> packet = p->Copy ();
|
||||||
rtentry->SetOutputDevice (GetNetDevice (i));
|
Ipv6Header h = header;
|
||||||
SendRealOut (rtentry, packet, h);
|
h.SetHopLimit (header.GetHopLimit () - 1);
|
||||||
continue;
|
if (h.GetHopLimit () == 0)
|
||||||
|
{
|
||||||
|
NS_LOG_WARN ("TTL exceeded. Drop.");
|
||||||
|
m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv6> (), interfaceId);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
NS_LOG_LOGIC ("Forward multicast via interface " << interfaceId);
|
||||||
|
Ptr<Ipv6Route> rtentry = Create<Ipv6Route> ();
|
||||||
|
rtentry->SetSource (h.GetSourceAddress ());
|
||||||
|
rtentry->SetDestination (h.GetDestinationAddress ());
|
||||||
|
rtentry->SetGateway (Ipv6Address::GetAny ());
|
||||||
|
rtentry->SetOutputDevice (GetNetDevice (interfaceId));
|
||||||
|
SendRealOut (rtentry, packet, h);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,13 +82,7 @@ std::ostream& operator<< (std::ostream& os, Ipv6Route const& route)
|
||||||
|
|
||||||
Ipv6MulticastRoute::Ipv6MulticastRoute ()
|
Ipv6MulticastRoute::Ipv6MulticastRoute ()
|
||||||
{
|
{
|
||||||
uint32_t initial_ttl = MAX_TTL;
|
m_ttls.clear();
|
||||||
|
|
||||||
/* Initialize array to MAX_TTL, which means that all interfaces are "off" */
|
|
||||||
for (uint32_t i = 0; i < MAX_INTERFACES; i++)
|
|
||||||
{
|
|
||||||
m_ttls.push_back (initial_ttl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ipv6MulticastRoute::~Ipv6MulticastRoute ()
|
Ipv6MulticastRoute::~Ipv6MulticastRoute ()
|
||||||
|
@ -127,12 +121,34 @@ uint32_t Ipv6MulticastRoute::GetParent () const
|
||||||
|
|
||||||
void Ipv6MulticastRoute::SetOutputTtl (uint32_t oif, uint32_t ttl)
|
void Ipv6MulticastRoute::SetOutputTtl (uint32_t oif, uint32_t ttl)
|
||||||
{
|
{
|
||||||
m_ttls[oif] = ttl;
|
if (ttl >= MAX_TTL)
|
||||||
|
{
|
||||||
|
// This TTL value effectively disables the interface
|
||||||
|
std::map<uint32_t, uint32_t>::iterator iter;
|
||||||
|
iter = m_ttls.find(oif);
|
||||||
|
if (iter != m_ttls.end())
|
||||||
|
{
|
||||||
|
m_ttls.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ttls[oif] = ttl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Ipv6MulticastRoute::GetOutputTtl (uint32_t oif) const
|
uint32_t Ipv6MulticastRoute::GetOutputTtl (uint32_t oif)
|
||||||
{
|
{
|
||||||
return m_ttls[oif];
|
// We keep this interface around for compatibility (for now)
|
||||||
|
std::map<uint32_t, uint32_t>::const_iterator iter = m_ttls.find(oif);
|
||||||
|
if (iter == m_ttls.end())
|
||||||
|
return((uint32_t)MAX_TTL);
|
||||||
|
return(iter->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<uint32_t, uint32_t> Ipv6MulticastRoute::GetOutputTtlMap() const
|
||||||
|
{
|
||||||
|
return(m_ttls);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoute const& route)
|
std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoute const& route)
|
||||||
|
|
|
@ -22,12 +22,13 @@
|
||||||
#define IPV6_ROUTE_H
|
#define IPV6_ROUTE_H
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <map>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
#include "ns3/simple-ref-count.h"
|
#include "ns3/simple-ref-count.h"
|
||||||
|
|
||||||
#include "ns3/ipv6-address.h"
|
#include "ns3/ipv6-address.h"
|
||||||
|
#include "ns3/deprecated.h"
|
||||||
|
|
||||||
namespace ns3
|
namespace ns3
|
||||||
{
|
{
|
||||||
|
@ -200,7 +201,12 @@ public:
|
||||||
* \param oif outgoing interface
|
* \param oif outgoing interface
|
||||||
* \return TTL for this route
|
* \return TTL for this route
|
||||||
*/
|
*/
|
||||||
uint32_t GetOutputTtl (uint32_t oif) const;
|
uint32_t GetOutputTtl (uint32_t oif) NS_DEPRECATED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \return map of output interface Ids and TTLs for this route
|
||||||
|
*/
|
||||||
|
std::map<uint32_t, uint32_t> GetOutputTtlMap() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -221,7 +227,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* \brief TTLs.
|
* \brief TTLs.
|
||||||
*/
|
*/
|
||||||
std::vector<uint32_t> m_ttls;
|
std::map<uint32_t, uint32_t> m_ttls;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoute const& route);
|
std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoute const& route);
|
||||||
|
|
Loading…
Reference in New Issue