diff --git a/src/internet/helper/ipv6-address-helper.cc b/src/internet/helper/ipv6-address-helper.cc index 20c97b4ac..7112ddf28 100644 --- a/src/internet/helper/ipv6-address-helper.cc +++ b/src/internet/helper/ipv6-address-helper.cc @@ -231,6 +231,9 @@ Ipv6InterfaceContainer Ipv6AddressHelper::Assign (const NetDeviceContainer &c) NS_ASSERT_MSG (ifIndex >= 0, "Ipv6AddressHelper::Allocate (): " "Interface index not found"); + // the first round is to make sure that the interface is set up, including its link-local addresses. + ipv6->SetUp (ifIndex); + Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (NewAddress (device->GetAddress ()), Ipv6Prefix (64)); ipv6->SetMetric (ifIndex, 1); ipv6->AddAddress (ifIndex, ipv6Addr); @@ -284,6 +287,9 @@ Ipv6InterfaceContainer Ipv6AddressHelper::Assign (const NetDeviceContainer &c, s NS_ASSERT_MSG (ifIndex >= 0, "Ipv6AddressHelper::Allocate (): " "Interface index not found"); + // the first round is to make sure that the interface is set up, including its link-local addresses. + ipv6->SetUp (ifIndex); + ipv6->SetMetric (ifIndex, 1); if (withConfiguration.at (i)) diff --git a/src/internet/model/icmpv6-l4-protocol.cc b/src/internet/model/icmpv6-l4-protocol.cc index 0b8fa0274..0ee94a378 100644 --- a/src/internet/model/icmpv6-l4-protocol.cc +++ b/src/internet/model/icmpv6-l4-protocol.cc @@ -32,7 +32,6 @@ #include "ns3/string.h" #include "ns3/integer.h" -#include "ipv6-raw-socket-factory-impl.h" #include "ipv6-l3-protocol.h" #include "ipv6-interface.h" #include "icmpv6-l4-protocol.h" @@ -99,6 +98,12 @@ TypeId Icmpv6L4Protocol::GetTypeId () return tid; } +TypeId Icmpv6L4Protocol::GetInstanceTypeId () const +{ + NS_LOG_FUNCTION (this); + return Icmpv6L4Protocol::GetTypeId (); +} + Icmpv6L4Protocol::Icmpv6L4Protocol () : m_node (0) { @@ -146,8 +151,6 @@ void Icmpv6L4Protocol::NotifyNewAggregate () { SetNode (node); ipv6->Insert (this); - Ptr rawFactory = CreateObject (); - ipv6->AggregateObject (rawFactory); SetDownTarget6 (MakeCallback (&Ipv6::Send, ipv6)); } } @@ -161,6 +164,12 @@ void Icmpv6L4Protocol::SetNode (Ptr node) m_node = node; } +Ptr Icmpv6L4Protocol::GetNode () +{ + NS_LOG_FUNCTION (this); + return m_node; +} + uint16_t Icmpv6L4Protocol::GetStaticProtocolNumber () { NS_LOG_FUNCTION_NOARGS (); @@ -199,7 +208,7 @@ void Icmpv6L4Protocol::DoDAD (Ipv6Address target, Ptr interface) } /** \todo disable multicast loopback to prevent NS probing to be received by the sender */ - + NdiscCache::Ipv6PayloadHeaderPair p = ForgeNS ("::",Ipv6Address::MakeSolicitedAddress (target), target, interface->GetDevice ()->GetAddress ()); /* update last packet UID */ @@ -1277,7 +1286,7 @@ Ptr Icmpv6L4Protocol::FindCache (Ptr device) } } - NS_ASSERT (false); + NS_ASSERT_MSG (false, "Icmpv6L4Protocol can not find a NDIS Cache for device " << device); /* quiet compiler */ return 0; } diff --git a/src/internet/model/icmpv6-l4-protocol.h b/src/internet/model/icmpv6-l4-protocol.h index fd549a744..268f88a22 100644 --- a/src/internet/model/icmpv6-l4-protocol.h +++ b/src/internet/model/icmpv6-l4-protocol.h @@ -57,6 +57,7 @@ public: * \return the object TypeId */ static TypeId GetTypeId (); + virtual TypeId GetInstanceTypeId (void) const; /** * \brief ICMPv6 protocol number (58). @@ -115,6 +116,12 @@ public: */ void SetNode (Ptr node); + /** + * \brief Get the node. + * \return node + */ + Ptr GetNode (); + /** * \brief This method is called by AggregateObject and completes the aggregation * by setting the node in the ICMPv6 stack and adding ICMPv6 factory to @@ -199,7 +206,7 @@ public: * \param target target IPv6 address * \param hardwareAddress our mac address */ - void SendNS (Ipv6Address src, Ipv6Address dst, Ipv6Address target, Address hardwareAddress); + virtual void SendNS (Ipv6Address src, Ipv6Address dst, Ipv6Address target, Address hardwareAddress); /** * \brief Send an error Destination Unreachable. @@ -345,7 +352,7 @@ public: /** * \brief Send a Router Solicitation. * \param src link-local source address - * \param dst destination address (usealy ff02::2 i.e all-routers) + * \param dst destination address (usually ff02::2 i.e all-routers) * \param hardwareAddress link-layer address (SHOULD be included if src is not ::) */ void SendRS (Ipv6Address src, Ipv6Address dst, Address hardwareAddress); @@ -356,7 +363,7 @@ public: * \param interface the IPv6 interface * \return a smart pointer of NdCache or 0 if problem */ - Ptr CreateCache (Ptr device, Ptr interface); + virtual Ptr CreateCache (Ptr device, Ptr interface); /** * \brief Is the node must do DAD. @@ -380,55 +387,8 @@ protected: */ virtual void DoDispose (); -private: typedef std::list > CacheList; //!< container of NdiscCaches - - /** - * \brief Neighbor Discovery node constants: max multicast solicitations. - */ - uint8_t m_maxMulticastSolicit; - - /** - * \brief Neighbor Discovery node constants: max unicast solicitations. - */ - uint8_t m_maxUnicastSolicit; - - /** - * \brief Neighbor Discovery node constants: reachable time. - */ - Time m_reachableTime; - - /** - * \brief Neighbor Discovery node constants: retransmission timer. - */ - Time m_retransmissionTime; - - /** - * \brief Neighbor Discovery node constants: delay for the first probe. - */ - Time m_delayFirstProbe; - - /** - * \brief The node. - */ - Ptr m_node; - - /** - * \brief A list of cache by device. - */ - CacheList m_cacheList; - - /** - * \brief Always do DAD ? - */ - bool m_alwaysDad; - - /** - * \brief Random jitter before sending solicitations - */ - Ptr m_solicitationJitter; - /** * \brief Notify an ICMPv6 reception to upper layers (if requested). * \param source the ICMP source @@ -554,6 +514,52 @@ private: virtual IpL4Protocol::DownTargetCallback GetDownTarget (void) const; virtual IpL4Protocol::DownTargetCallback6 GetDownTarget6 (void) const; + /** + * \brief Always do DAD ? + */ + bool m_alwaysDad; + + /** + * \brief A list of cache by device. + */ + CacheList m_cacheList; + +private: + /** + * \brief Neighbor Discovery node constants: max multicast solicitations. + */ + uint8_t m_maxMulticastSolicit; + + /** + * \brief Neighbor Discovery node constants: max unicast solicitations. + */ + uint8_t m_maxUnicastSolicit; + + /** + * \brief Neighbor Discovery node constants: reachable time. + */ + Time m_reachableTime; + + /** + * \brief Neighbor Discovery node constants: retransmission timer. + */ + Time m_retransmissionTime; + + /** + * \brief Neighbor Discovery node constants: delay for the first probe. + */ + Time m_delayFirstProbe; + + /** + * \brief The node. + */ + Ptr m_node; + + /** + * \brief Random jitter before sending solicitations + */ + Ptr m_solicitationJitter; + IpL4Protocol::DownTargetCallback6 m_downTarget; //!< callback to Ipv6::Send }; diff --git a/src/internet/model/ipv6-interface.cc b/src/internet/model/ipv6-interface.cc index 049f51bfc..8bd74b571 100644 --- a/src/internet/model/ipv6-interface.cc +++ b/src/internet/model/ipv6-interface.cc @@ -128,13 +128,9 @@ void Ipv6Interface::DoSetup () { return; /* no NDISC cache for ip6-localhost */ } + int32_t interfaceId = m_node->GetObject ()->GetInterfaceForDevice (m_device); + Ptr icmpv6 = DynamicCast (m_node->GetObject ()->GetProtocol (Icmpv6L4Protocol::GetStaticProtocolNumber (), interfaceId)); - Ptr proto = m_node->GetObject ()->GetProtocol (Icmpv6L4Protocol::GetStaticProtocolNumber ()); - Ptr icmpv6; - if (proto) - { - icmpv6 = proto->GetObject (); - } if (icmpv6 && !m_ndCache) { m_ndCache = icmpv6->CreateCache (m_device, this); @@ -145,14 +141,12 @@ void Ipv6Interface::SetNode (Ptr node) { NS_LOG_FUNCTION (this << node); m_node = node; - DoSetup (); } void Ipv6Interface::SetDevice (Ptr device) { NS_LOG_FUNCTION (this << device); m_device = device; - DoSetup (); } void @@ -246,17 +240,21 @@ bool Ipv6Interface::AddAddress (Ipv6InterfaceAddress iface) if (!addr.IsAny () || !addr.IsLocalhost ()) { /* DAD handling */ - Ptr proto = m_node->GetObject ()->GetProtocol (Icmpv6L4Protocol::GetStaticProtocolNumber ()); - Ptr icmpv6; - if (proto) - { - icmpv6 = proto->GetObject (); - } + + int32_t interfaceId = m_node->GetObject ()->GetInterfaceForDevice (m_device); + Ptr icmpv6 = DynamicCast (m_node->GetObject ()->GetProtocol (Icmpv6L4Protocol::GetStaticProtocolNumber (), interfaceId)); if (icmpv6 && icmpv6->IsAlwaysDad ()) { - Simulator::Schedule (Seconds (0.), &Icmpv6L4Protocol::DoDAD, icmpv6, addr, this); - Simulator::Schedule (Seconds (1.), &Icmpv6L4Protocol::FunctionDadTimeout, icmpv6, this, addr); + if (icmpv6->IsAlwaysDad ()) + { + Simulator::Schedule (Seconds (0.), &Icmpv6L4Protocol::DoDAD, icmpv6, addr, this); + Simulator::Schedule (Seconds (1.), &Icmpv6L4Protocol::FunctionDadTimeout, icmpv6, this, addr); + } + else + { + Simulator::Schedule (Seconds (0.), &Icmpv6L4Protocol::FunctionDadTimeout, icmpv6, this, addr); + } } } return true; @@ -430,8 +428,11 @@ void Ipv6Interface::Send (Ptr p, const Ipv6Header & hdr, Ipv6Address des /* other address */ if (m_device->NeedsArp ()) { - NS_LOG_LOGIC ("Needs ARP" << " " << dest); - Ptr icmpv6 = ipv6->GetIcmpv6 (); + NS_LOG_LOGIC ("Needs NDISC " << dest); + + int32_t interfaceId = m_node->GetObject ()->GetInterfaceForDevice (m_device); + Ptr icmpv6 = DynamicCast (m_node->GetObject ()->GetProtocol (Icmpv6L4Protocol::GetStaticProtocolNumber (), interfaceId)); + Address hardwareDestination; bool found = false; @@ -459,7 +460,7 @@ void Ipv6Interface::Send (Ptr p, const Ipv6Header & hdr, Ipv6Address des } else { - NS_LOG_LOGIC ("Doesn't need ARP"); + NS_LOG_LOGIC ("Doesn't need NDISC"); m_tc->Send (m_device, Create (p, m_device->GetBroadcast (), Ipv6L3Protocol::PROT_NUMBER, hdr)); } } diff --git a/src/internet/model/ipv6-l3-protocol.cc b/src/internet/model/ipv6-l3-protocol.cc index 8523b70e1..6931782f6 100644 --- a/src/internet/model/ipv6-l3-protocol.cc +++ b/src/internet/model/ipv6-l3-protocol.cc @@ -44,6 +44,7 @@ #include "ipv6-option.h" #include "icmpv6-l4-protocol.h" #include "ndisc-cache.h" +#include "ipv6-raw-socket-factory-impl.h" /// Minimum IPv6 MTU, as defined by \RFC{2460} #define IPV6_MIN_MTU 1280 @@ -127,6 +128,9 @@ Ipv6L3Protocol::Ipv6L3Protocol () { NS_LOG_FUNCTION_NOARGS (); m_pmtuCache = CreateObject (); + + Ptr rawFactoryImpl = CreateObject (); + AggregateObject (rawFactoryImpl); } Ipv6L3Protocol::~Ipv6L3Protocol () @@ -702,6 +706,7 @@ void Ipv6L3Protocol::NotifyNewAggregate () this->SetNode (node); } } + Ipv6::NotifyNewAggregate (); } diff --git a/src/internet/test/ipv6-test.cc b/src/internet/test/ipv6-test.cc index 54ddc2c1f..8ef2819c6 100644 --- a/src/internet/test/ipv6-test.cc +++ b/src/internet/test/ipv6-test.cc @@ -88,16 +88,16 @@ Ipv6L3ProtocolTestCase::DoRun () index = ipv6->AddIpv6Interface (interface2); NS_TEST_ASSERT_MSG_EQ (index, 2, "The index is not 2??"); + interface->SetUp (); + interface2->SetUp (); + Ipv6InterfaceAddress ifaceAddr = interface->GetLinkLocalAddress (); NS_TEST_ASSERT_MSG_EQ (ifaceAddr.GetAddress ().IsLinkLocal (), true, "Should be link local??"); - interface->SetUp (); NS_TEST_ASSERT_MSG_EQ (interface->GetNAddresses (), 1, "interface has always a link-local address"); /* interface has always a link-local address */ - interface2->SetUp (); - Ipv6InterfaceAddress ifaceAddr1 = Ipv6InterfaceAddress ( "2001:1234:5678:9000::1", Ipv6Prefix (64)); interface->AddAddress (ifaceAddr1);