bug 1047: Multicast routes on nodes with >16 interfaces
authorKen Renard <kenneth.renard@arl.army.mil>
Fri, 13 May 2011 00:21:25 -0700
changeset 7161 7cc4506fb853
parent 7160 4082270126b5
child 7162 c29fbeddbc04
bug 1047: Multicast routes on nodes with >16 interfaces
CHANGES.html
RELEASE_NOTES
src/internet/model/ipv4-l3-protocol.cc
src/internet/model/ipv4-route.cc
src/internet/model/ipv4-route.h
src/internet/model/ipv6-l3-protocol.cc
src/internet/model/ipv6-route.cc
src/internet/model/ipv6-route.h
--- 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);