diff --git a/ns-3.10/src/internet-stack/ipv4-l3-protocol.cc b/ns-3.10/src/internet-stack/ipv4-l3-protocol.cc index eefcbb5..dc9c48d 100644 --- a/ns-3.10/src/internet-stack/ipv4-l3-protocol.cc +++ b/ns-3.10/src/internet-stack/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; // We never use this, do we? + + 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/ns-3.10/src/internet-stack/ipv6-l3-protocol.cc b/ns-3.10/src/internet-stack/ipv6-l3-protocol.cc index 0286b14..76c7a92 100644 --- a/ns-3.10/src/internet-stack/ipv6-l3-protocol.cc +++ b/ns-3.10/src/internet-stack/ipv6-l3-protocol.cc @@ -910,31 +910,31 @@ 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++) + std::map ttlMap = mrtentry->GetOutputTtlMap(); + std::map::iterator mapIter; + + for (mapIter = ttlMap.begin(); mapIter != ttlMap.end(); mapIter++) { - 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, i); - return; - } + uint32_t interfaceId = mapIter->first; + //uint32_t outputTtl = mapIter->second; // We never use this, do we? - 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; + 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, 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/ns-3.10/src/node/ipv4-route.cc b/ns-3.10/src/node/ipv4-route.cc index d4134ae..74ed73a 100644 --- a/ns-3.10/src/node/ipv4-route.cc +++ b/ns-3.10/src/node/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 { - 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/ns-3.10/src/node/ipv4-route.h b/ns-3.10/src/node/ipv4-route.h index db89413..3dfb9cc 100644 --- a/ns-3.10/src/node/ipv4-route.h +++ b/ns-3.10/src/node/ipv4-route.h @@ -20,7 +20,7 @@ #define IPV4_ROUTE_H #include -#include +#include #include #include "ns3/simple-ref-count.h" @@ -146,6 +146,11 @@ public: * \return TTL for this route */ uint32_t GetOutputTtl (uint32_t oif) const; + + /** + * \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 +159,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/ns-3.10/src/node/ipv6-route.cc b/ns-3.10/src/node/ipv6-route.cc index c4de3fc..414b846 100644 --- a/ns-3.10/src/node/ipv6-route.cc +++ b/ns-3.10/src/node/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 { - 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/ns-3.10/src/node/ipv6-route.h b/ns-3.10/src/node/ipv6-route.h index e87e678..68747e2 100644 --- a/ns-3.10/src/node/ipv6-route.h +++ b/ns-3.10/src/node/ipv6-route.h @@ -22,7 +22,7 @@ #define IPV6_ROUTE_H #include -#include +#include #include #include "ns3/simple-ref-count.h" @@ -202,6 +202,11 @@ public: */ uint32_t GetOutputTtl (uint32_t oif) const; + /** + * \return map of output interface Ids and TTLs for this route + */ + std::map GetOutputTtlMap() const; + private: /** * \brief IPv6 group. @@ -221,7 +226,7 @@ private: /** * \brief TTLs. */ - std::vector m_ttls; + std::map m_ttls; }; std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoute const& route);