diff --git a/CHANGES.html b/CHANGES.html index b0b02084c..de2073243 100644 --- a/CHANGES.html +++ b/CHANGES.html @@ -114,6 +114,13 @@ Time result = Time (tmp * 5);

+
  • Multicast GetOutputTtl() commands +

    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. +

    +
  • Changed behavior:

    diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 4933cb980..482f93e89 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -77,6 +77,7 @@ since ns-3.10, in many cases referencing the Bugzilla bug number. - 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 ------------ diff --git a/src/internet/model/ipv4-l3-protocol.cc b/src/internet/model/ipv4-l3-protocol.cc index eefcbb5b1..6edf8bdfb 100644 --- a/src/internet/model/ipv4-l3-protocol.cc +++ b/src/internet/model/ipv4-l3-protocol.cc @@ -739,30 +739,32 @@ Ipv4L3Protocol::IpMulticastForward (Ptr mrtentry, PtrGetId ()); - // 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 ttlMap = mrtentry->GetOutputTtlMap(); + std::map::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 = p->Copy (); + Ipv4Header h = header; + h.SetTtl (header.GetTtl () - 1); + if (h.GetTtl () == 0) { - Ptr 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 (), i); - return; - } - NS_LOG_LOGIC ("Forward multicast via interface " << i); - Ptr rtentry = Create (); - 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 (), interfaceId); + return; } + NS_LOG_LOGIC ("Forward multicast via interface " << interfaceId); + Ptr rtentry = Create (); + rtentry->SetSource (h.GetSource ()); + rtentry->SetDestination (h.GetDestination ()); + rtentry->SetGateway (Ipv4Address::GetAny ()); + rtentry->SetOutputDevice (GetNetDevice (interfaceId)); + SendRealOut (rtentry, packet, h); + continue; } } diff --git a/src/internet/model/ipv4-route.cc b/src/internet/model/ipv4-route.cc index a58d0c9f7..44aee4250 100644 --- a/src/internet/model/ipv4-route.cc +++ b/src/internet/model/ipv4-route.cc @@ -82,12 +82,7 @@ std::ostream& operator<< (std::ostream& os, Ipv4Route const& route) 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 @@ Ipv4MulticastRoute::GetParent (void) const 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::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::const_iterator iter = m_ttls.find(oif); + if (iter == m_ttls.end()) + return((uint32_t)MAX_TTL); + return(iter->second); +} + +std::map +Ipv4MulticastRoute::GetOutputTtlMap() const +{ + return(m_ttls); } }//namespace ns3 diff --git a/src/internet/model/ipv4-route.h b/src/internet/model/ipv4-route.h index 6a59d62d1..9530c7cf7 100644 --- a/src/internet/model/ipv4-route.h +++ b/src/internet/model/ipv4-route.h @@ -20,11 +20,12 @@ #define IPV4_ROUTE_H #include -#include +#include #include #include "ns3/simple-ref-count.h" #include "ns3/ipv4-address.h" +#include "ns3/deprecated.h" namespace ns3 { @@ -145,7 +146,12 @@ public: * \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 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 @@ private: Ipv4Address m_group; // Group Ipv4Address m_origin; // Source of packet uint32_t m_parent; // Source interface - std::vector m_ttls; + std::map m_ttls; }; }//namespace ns3 diff --git a/src/internet/model/ipv6-l3-protocol.cc b/src/internet/model/ipv6-l3-protocol.cc index 3551a4e58..41118bb8d 100644 --- a/src/internet/model/ipv6-l3-protocol.cc +++ b/src/internet/model/ipv6-l3-protocol.cc @@ -910,31 +910,30 @@ void Ipv6L3Protocol::IpMulticastForward (Ptr mrtentry, PtrGetId ()); - // 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++) - { - if (mrtentry->GetOutputTtl (i) < Ipv6MulticastRoute::MAX_TTL) - { - Ptr 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 (), i); - return; - } + std::map ttlMap = mrtentry->GetOutputTtlMap(); + std::map::iterator mapIter; - NS_LOG_LOGIC ("Forward multicast via interface " << i); - Ptr rtentry = Create (); - rtentry->SetSource (h.GetSourceAddress ()); - rtentry->SetDestination (h.GetDestinationAddress ()); - rtentry->SetGateway (Ipv6Address::GetAny ()); - rtentry->SetOutputDevice (GetNetDevice (i)); - SendRealOut (rtentry, packet, h); - continue; + for (mapIter = ttlMap.begin(); mapIter != ttlMap.end(); mapIter++) + { + uint32_t interfaceId = mapIter->first; + //uint32_t outputTtl = mapIter->second; // Unused for now + Ptr 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 (), interfaceId); + return; } + NS_LOG_LOGIC ("Forward multicast via interface " << interfaceId); + Ptr rtentry = Create (); + rtentry->SetSource (h.GetSourceAddress ()); + rtentry->SetDestination (h.GetDestinationAddress ()); + rtentry->SetGateway (Ipv6Address::GetAny ()); + rtentry->SetOutputDevice (GetNetDevice (interfaceId)); + SendRealOut (rtentry, packet, h); + continue; } } diff --git a/src/internet/model/ipv6-route.cc b/src/internet/model/ipv6-route.cc index c865276dc..0d47564fa 100644 --- a/src/internet/model/ipv6-route.cc +++ b/src/internet/model/ipv6-route.cc @@ -82,13 +82,7 @@ std::ostream& operator<< (std::ostream& os, Ipv6Route const& route) 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 @@ uint32_t Ipv6MulticastRoute::GetParent () const 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::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::const_iterator iter = m_ttls.find(oif); + if (iter == m_ttls.end()) + return((uint32_t)MAX_TTL); + return(iter->second); +} + +std::map Ipv6MulticastRoute::GetOutputTtlMap() const +{ + return(m_ttls); } std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoute const& route) diff --git a/src/internet/model/ipv6-route.h b/src/internet/model/ipv6-route.h index b90cc673f..24997078b 100644 --- a/src/internet/model/ipv6-route.h +++ b/src/internet/model/ipv6-route.h @@ -22,12 +22,13 @@ #define IPV6_ROUTE_H #include -#include +#include #include #include "ns3/simple-ref-count.h" #include "ns3/ipv6-address.h" +#include "ns3/deprecated.h" namespace ns3 { @@ -200,7 +201,12 @@ public: * \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 GetOutputTtlMap() const; private: /** @@ -221,7 +227,7 @@ private: /** * \brief TTLs. */ - std::vector m_ttls; + std::map m_ttls; }; std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoute const& route);