--- a/CHANGES.html Thu May 12 23:14:54 2011 -0700
+++ b/CHANGES.html Fri May 13 00:21:25 2011 -0700
@@ -114,6 +114,13 @@
</pre>
</p>
</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>
<h2>Changed behavior:</h2>
--- a/RELEASE_NOTES Thu May 12 23:14:54 2011 -0700
+++ b/RELEASE_NOTES Fri May 13 00:21:25 2011 -0700
@@ -77,6 +77,7 @@
- bug 1054 - ipv6 InternetStackHelper EnablePcapIpv6All() broken
- bug 1042 - AODV RERR implosion (missing RERR_RATELIMIT)
- bug 1097 - AODV routing entry set to be VALID mistakenly
+ - bug 1047 - Multicast routes on nodes with >16 interfaces
Known issues
------------
--- a/src/internet/model/ipv4-l3-protocol.cc Thu May 12 23:14:54 2011 -0700
+++ b/src/internet/model/ipv4-l3-protocol.cc Fri May 13 00:21:25 2011 -0700
@@ -739,30 +739,32 @@
{
NS_LOG_FUNCTION (this << mrtentry << p << header);
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
- for (uint32_t i = 0; i < Ipv4MulticastRoute::MAX_INTERFACES; i++)
+
+ std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap();
+ 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 ();
- Ipv4Header h = header;
- h.SetTtl (header.GetTtl () - 1);
- 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_WARN ("TTL exceeded. Drop.");
+ m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv4> (), interfaceId);
+ return;
}
+ 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;
}
}
--- a/src/internet/model/ipv4-route.cc Thu May 12 23:14:54 2011 -0700
+++ b/src/internet/model/ipv4-route.cc Fri May 13 00:21:25 2011 -0700
@@ -82,12 +82,7 @@
Ipv4MulticastRoute::Ipv4MulticastRoute ()
{
- uint32_t initial_ttl = MAX_TTL;
- // 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);
- }
+ m_ttls.clear();
}
void
@@ -129,13 +124,36 @@
void
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
-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
--- a/src/internet/model/ipv4-route.h Thu May 12 23:14:54 2011 -0700
+++ b/src/internet/model/ipv4-route.h Fri May 13 00:21:25 2011 -0700
@@ -20,11 +20,12 @@
#define IPV4_ROUTE_H
#include <list>
-#include <vector>
+#include <map>
#include <ostream>
#include "ns3/simple-ref-count.h"
#include "ns3/ipv4-address.h"
+#include "ns3/deprecated.h"
namespace ns3 {
@@ -145,7 +146,12 @@
* \param oif outgoing interface
* \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_TTL = 255; // Maximum time-to-live (TTL)
@@ -154,7 +160,7 @@
Ipv4Address m_group; // Group
Ipv4Address m_origin; // Source of packet
uint32_t m_parent; // Source interface
- std::vector<uint32_t> m_ttls;
+ std::map<uint32_t, uint32_t> m_ttls;
};
}//namespace ns3
--- a/src/internet/model/ipv6-l3-protocol.cc Thu May 12 23:14:54 2011 -0700
+++ b/src/internet/model/ipv6-l3-protocol.cc Fri May 13 00:21:25 2011 -0700
@@ -910,31 +910,30 @@
NS_LOG_FUNCTION (this << mrtentry << p << header);
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 Ipv6MulticastRoute
- for (uint32_t i = 0 ; i < Ipv6MulticastRoute::MAX_INTERFACES ; i++)
+ std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap();
+ std::map<uint32_t, uint32_t>::iterator mapIter;
+
+ for (mapIter = ttlMap.begin(); mapIter != ttlMap.end(); mapIter++)
{
- if (mrtentry->GetOutputTtl (i) < Ipv6MulticastRoute::MAX_TTL)
+ uint32_t interfaceId = mapIter->first;
+ //uint32_t outputTtl = mapIter->second; // Unused for now
+ Ptr<Packet> packet = p->Copy ();
+ Ipv6Header h = header;
+ h.SetHopLimit (header.GetHopLimit () - 1);
+ if (h.GetHopLimit () == 0)
{
- 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);
- Ptr<Ipv6Route> rtentry = Create<Ipv6Route> ();
- rtentry->SetSource (h.GetSourceAddress ());
- rtentry->SetDestination (h.GetDestinationAddress ());
- rtentry->SetGateway (Ipv6Address::GetAny ());
- rtentry->SetOutputDevice (GetNetDevice (i));
- SendRealOut (rtentry, packet, h);
- continue;
+ 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;
}
}
--- a/src/internet/model/ipv6-route.cc Thu May 12 23:14:54 2011 -0700
+++ b/src/internet/model/ipv6-route.cc Fri May 13 00:21:25 2011 -0700
@@ -82,13 +82,7 @@
Ipv6MulticastRoute::Ipv6MulticastRoute ()
{
- uint32_t initial_ttl = MAX_TTL;
-
- /* 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);
- }
+ m_ttls.clear();
}
Ipv6MulticastRoute::~Ipv6MulticastRoute ()
@@ -127,12 +121,34 @@
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)
--- a/src/internet/model/ipv6-route.h Thu May 12 23:14:54 2011 -0700
+++ b/src/internet/model/ipv6-route.h Fri May 13 00:21:25 2011 -0700
@@ -22,12 +22,13 @@
#define IPV6_ROUTE_H
#include <list>
-#include <vector>
+#include <map>
#include <ostream>
#include "ns3/simple-ref-count.h"
#include "ns3/ipv6-address.h"
+#include "ns3/deprecated.h"
namespace ns3
{
@@ -200,7 +201,12 @@
* \param oif outgoing interface
* \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:
/**
@@ -221,7 +227,7 @@
/**
* \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);