# HG changeset patch # Parent f6a0e074b6fc643c31a357ffbccd02b51f7e15c1 # User Tommaso Pecorella # Date 1399214821 -7200 Bug 1911 - AODV can not work on nodes with more than one NetDevice diff -r f6a0e074b6fc src/aodv/bindings/modulegen__gcc_ILP32.py --- a/src/aodv/bindings/modulegen__gcc_ILP32.py Sat May 03 15:56:25 2014 -0700 +++ b/src/aodv/bindings/modulegen__gcc_ILP32.py Sun May 04 16:52:03 2014 +0200 @@ -142,6 +142,8 @@ module.add_class('Tag', import_from_module='ns.network', parent=root_module['ns3::ObjectBase']) ## tag-buffer.h (module 'network'): ns3::TagBuffer [class] module.add_class('TagBuffer', import_from_module='ns.network') + ## nstime.h (module 'core'): ns3::TimeWithUnit [class] + module.add_class('TimeWithUnit', import_from_module='ns.core') ## timer.h (module 'core'): ns3::Timer [class] module.add_class('Timer', import_from_module='ns.core') ## timer.h (module 'core'): ns3::Timer::DestroyPolicy [enumeration] @@ -494,6 +496,7 @@ register_Ns3Simulator_methods(root_module, root_module['ns3::Simulator']) register_Ns3Tag_methods(root_module, root_module['ns3::Tag']) register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer']) + register_Ns3TimeWithUnit_methods(root_module, root_module['ns3::TimeWithUnit']) register_Ns3Timer_methods(root_module, root_module['ns3::Timer']) register_Ns3TimerImpl_methods(root_module, root_module['ns3::TimerImpl']) register_Ns3TypeId_methods(root_module, root_module['ns3::TypeId']) @@ -2452,6 +2455,14 @@ [param('uint8_t', 'v')]) return +def register_Ns3TimeWithUnit_methods(root_module, cls): + cls.add_output_stream_operator() + ## nstime.h (module 'core'): ns3::TimeWithUnit::TimeWithUnit(ns3::TimeWithUnit const & arg0) [copy constructor] + cls.add_constructor([param('ns3::TimeWithUnit const &', 'arg0')]) + ## nstime.h (module 'core'): ns3::TimeWithUnit::TimeWithUnit(ns3::Time const time, ns3::Time::Unit const unit) [constructor] + cls.add_constructor([param('ns3::Time const', 'time'), param('ns3::Time::Unit const', 'unit')]) + return + def register_Ns3Timer_methods(root_module, cls): ## timer.h (module 'core'): ns3::Timer::Timer(ns3::Timer const & arg0) [copy constructor] cls.add_constructor([param('ns3::Timer const &', 'arg0')]) @@ -2733,7 +2744,6 @@ return def register_Ns3Int64x64_t_methods(root_module, cls): - cls.add_binary_comparison_operator('<=') cls.add_binary_comparison_operator('!=') cls.add_inplace_numeric_operator('+=', param('ns3::int64x64_t const &', u'right')) cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('ns3::int64x64_t const &', u'right')) @@ -2747,6 +2757,7 @@ cls.add_inplace_numeric_operator('-=', param('ns3::int64x64_t const &', u'right')) cls.add_inplace_numeric_operator('/=', param('ns3::int64x64_t const &', u'right')) cls.add_output_stream_operator() + cls.add_binary_comparison_operator('<=') cls.add_binary_comparison_operator('==') cls.add_binary_comparison_operator('>=') ## int64x64-double.h (module 'core'): ns3::int64x64_t::int64x64_t() [constructor] @@ -3956,7 +3967,6 @@ return def register_Ns3Time_methods(root_module, cls): - cls.add_binary_comparison_operator('<=') cls.add_binary_comparison_operator('!=') cls.add_inplace_numeric_operator('+=', param('ns3::Time const &', u'right')) cls.add_binary_numeric_operator('*', root_module['ns3::Time'], root_module['ns3::Time'], param('int64_t const &', u'right')) @@ -3967,6 +3977,7 @@ cls.add_binary_comparison_operator('>') cls.add_inplace_numeric_operator('-=', param('ns3::Time const &', u'right')) cls.add_output_stream_operator() + cls.add_binary_comparison_operator('<=') cls.add_binary_comparison_operator('==') cls.add_binary_comparison_operator('>=') ## nstime.h (module 'core'): ns3::Time::Time() [constructor] @@ -3991,6 +4002,11 @@ cls.add_constructor([param('std::string const &', 's')]) ## nstime.h (module 'core'): ns3::Time::Time(ns3::int64x64_t const & value) [constructor] cls.add_constructor([param('ns3::int64x64_t const &', 'value')]) + ## nstime.h (module 'core'): ns3::TimeWithUnit ns3::Time::As(ns3::Time::Unit const unit) const [member function] + cls.add_method('As', + 'ns3::TimeWithUnit', + [param('ns3::Time::Unit const', 'unit')], + is_const=True) ## nstime.h (module 'core'): int ns3::Time::Compare(ns3::Time const & o) const [member function] cls.add_method('Compare', 'int', @@ -5867,6 +5883,11 @@ 'bool', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + ## ipv4-l3-protocol.h (module 'internet'): bool ns3::Ipv4L3Protocol::IsUnicast(ns3::Ipv4Address ad) const [member function] + cls.add_method('IsUnicast', + 'bool', + [param('ns3::Ipv4Address', 'ad')], + is_const=True) ## ipv4-l3-protocol.h (module 'internet'): bool ns3::Ipv4L3Protocol::IsUp(uint32_t i) const [member function] cls.add_method('IsUp', 'bool', @@ -6854,10 +6875,10 @@ 'uint32_t', [param('uint8_t *', 'buffer'), param('uint32_t', 'maxSize')], is_const=True) - ## packet.h (module 'network'): void ns3::Packet::SetNixVector(ns3::Ptr arg0) [member function] + ## packet.h (module 'network'): void ns3::Packet::SetNixVector(ns3::Ptr nixVector) [member function] cls.add_method('SetNixVector', 'void', - [param('ns3::Ptr< ns3::NixVector >', 'arg0')]) + [param('ns3::Ptr< ns3::NixVector >', 'nixVector')]) return def register_Ns3ParetoRandomVariable_methods(root_module, cls): diff -r f6a0e074b6fc src/aodv/bindings/modulegen__gcc_LP64.py --- a/src/aodv/bindings/modulegen__gcc_LP64.py Sat May 03 15:56:25 2014 -0700 +++ b/src/aodv/bindings/modulegen__gcc_LP64.py Sun May 04 16:52:03 2014 +0200 @@ -142,6 +142,8 @@ module.add_class('Tag', import_from_module='ns.network', parent=root_module['ns3::ObjectBase']) ## tag-buffer.h (module 'network'): ns3::TagBuffer [class] module.add_class('TagBuffer', import_from_module='ns.network') + ## nstime.h (module 'core'): ns3::TimeWithUnit [class] + module.add_class('TimeWithUnit', import_from_module='ns.core') ## timer.h (module 'core'): ns3::Timer [class] module.add_class('Timer', import_from_module='ns.core') ## timer.h (module 'core'): ns3::Timer::DestroyPolicy [enumeration] @@ -494,6 +496,7 @@ register_Ns3Simulator_methods(root_module, root_module['ns3::Simulator']) register_Ns3Tag_methods(root_module, root_module['ns3::Tag']) register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer']) + register_Ns3TimeWithUnit_methods(root_module, root_module['ns3::TimeWithUnit']) register_Ns3Timer_methods(root_module, root_module['ns3::Timer']) register_Ns3TimerImpl_methods(root_module, root_module['ns3::TimerImpl']) register_Ns3TypeId_methods(root_module, root_module['ns3::TypeId']) @@ -2452,6 +2455,14 @@ [param('uint8_t', 'v')]) return +def register_Ns3TimeWithUnit_methods(root_module, cls): + cls.add_output_stream_operator() + ## nstime.h (module 'core'): ns3::TimeWithUnit::TimeWithUnit(ns3::TimeWithUnit const & arg0) [copy constructor] + cls.add_constructor([param('ns3::TimeWithUnit const &', 'arg0')]) + ## nstime.h (module 'core'): ns3::TimeWithUnit::TimeWithUnit(ns3::Time const time, ns3::Time::Unit const unit) [constructor] + cls.add_constructor([param('ns3::Time const', 'time'), param('ns3::Time::Unit const', 'unit')]) + return + def register_Ns3Timer_methods(root_module, cls): ## timer.h (module 'core'): ns3::Timer::Timer(ns3::Timer const & arg0) [copy constructor] cls.add_constructor([param('ns3::Timer const &', 'arg0')]) @@ -2733,7 +2744,6 @@ return def register_Ns3Int64x64_t_methods(root_module, cls): - cls.add_binary_comparison_operator('<=') cls.add_binary_comparison_operator('!=') cls.add_inplace_numeric_operator('+=', param('ns3::int64x64_t const &', u'right')) cls.add_binary_numeric_operator('*', root_module['ns3::int64x64_t'], root_module['ns3::int64x64_t'], param('ns3::int64x64_t const &', u'right')) @@ -2747,6 +2757,7 @@ cls.add_inplace_numeric_operator('-=', param('ns3::int64x64_t const &', u'right')) cls.add_inplace_numeric_operator('/=', param('ns3::int64x64_t const &', u'right')) cls.add_output_stream_operator() + cls.add_binary_comparison_operator('<=') cls.add_binary_comparison_operator('==') cls.add_binary_comparison_operator('>=') ## int64x64-double.h (module 'core'): ns3::int64x64_t::int64x64_t() [constructor] @@ -3956,7 +3967,6 @@ return def register_Ns3Time_methods(root_module, cls): - cls.add_binary_comparison_operator('<=') cls.add_binary_comparison_operator('!=') cls.add_inplace_numeric_operator('+=', param('ns3::Time const &', u'right')) cls.add_binary_numeric_operator('*', root_module['ns3::Time'], root_module['ns3::Time'], param('int64_t const &', u'right')) @@ -3967,6 +3977,7 @@ cls.add_binary_comparison_operator('>') cls.add_inplace_numeric_operator('-=', param('ns3::Time const &', u'right')) cls.add_output_stream_operator() + cls.add_binary_comparison_operator('<=') cls.add_binary_comparison_operator('==') cls.add_binary_comparison_operator('>=') ## nstime.h (module 'core'): ns3::Time::Time() [constructor] @@ -3991,6 +4002,11 @@ cls.add_constructor([param('std::string const &', 's')]) ## nstime.h (module 'core'): ns3::Time::Time(ns3::int64x64_t const & value) [constructor] cls.add_constructor([param('ns3::int64x64_t const &', 'value')]) + ## nstime.h (module 'core'): ns3::TimeWithUnit ns3::Time::As(ns3::Time::Unit const unit) const [member function] + cls.add_method('As', + 'ns3::TimeWithUnit', + [param('ns3::Time::Unit const', 'unit')], + is_const=True) ## nstime.h (module 'core'): int ns3::Time::Compare(ns3::Time const & o) const [member function] cls.add_method('Compare', 'int', @@ -5867,6 +5883,11 @@ 'bool', [param('uint32_t', 'i')], is_const=True, is_virtual=True) + ## ipv4-l3-protocol.h (module 'internet'): bool ns3::Ipv4L3Protocol::IsUnicast(ns3::Ipv4Address ad) const [member function] + cls.add_method('IsUnicast', + 'bool', + [param('ns3::Ipv4Address', 'ad')], + is_const=True) ## ipv4-l3-protocol.h (module 'internet'): bool ns3::Ipv4L3Protocol::IsUp(uint32_t i) const [member function] cls.add_method('IsUp', 'bool', @@ -6854,10 +6875,10 @@ 'uint32_t', [param('uint8_t *', 'buffer'), param('uint32_t', 'maxSize')], is_const=True) - ## packet.h (module 'network'): void ns3::Packet::SetNixVector(ns3::Ptr arg0) [member function] + ## packet.h (module 'network'): void ns3::Packet::SetNixVector(ns3::Ptr nixVector) [member function] cls.add_method('SetNixVector', 'void', - [param('ns3::Ptr< ns3::NixVector >', 'arg0')]) + [param('ns3::Ptr< ns3::NixVector >', 'nixVector')]) return def register_Ns3ParetoRandomVariable_methods(root_module, cls): diff -r f6a0e074b6fc src/aodv/model/aodv-routing-protocol.cc --- a/src/aodv/model/aodv-routing-protocol.cc Sat May 03 15:56:25 2014 -0700 +++ b/src/aodv/model/aodv-routing-protocol.cc Sun May 04 16:52:03 2014 +0200 @@ -283,6 +283,12 @@ iter->first->Close (); } m_socketAddresses.clear (); + for (std::map, Ipv4InterfaceAddress>::iterator iter = + m_socketSubnetBroadcastAddresses.begin (); iter != m_socketSubnetBroadcastAddresses.end (); iter++) + { + iter->first->Close (); + } + m_socketSubnetBroadcastAddresses.clear (); Ipv4RoutingProtocol::DoDispose (); } @@ -613,18 +619,34 @@ UdpSocketFactory::GetTypeId ()); NS_ASSERT (socket != 0); socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this)); + socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT)); socket->BindToNetDevice (l3->GetNetDevice (i)); - socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), AODV_PORT)); socket->SetAllowBroadcast (true); socket->SetAttribute ("IpTtl", UintegerValue (1)); m_socketAddresses.insert (std::make_pair (socket, iface)); + // create also a subnet broadcast socket + socket = Socket::CreateSocket (GetObject (), + UdpSocketFactory::GetTypeId ()); + NS_ASSERT (socket != 0); + socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this)); + socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT)); + socket->BindToNetDevice (l3->GetNetDevice (i)); + socket->SetAllowBroadcast (true); + socket->SetAttribute ("IpTtl", UintegerValue (1)); + m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface)); + // Add local broadcast record to the routing table Ptr dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ())); RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface, /*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ()); m_routingTable.AddRoute (rt); + if (l3->GetInterface (i)->GetArpCache ()) + { + m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ()); + } + // Allow neighbor manager use this interface for layer 2 feedback if possible Ptr wifi = dev->GetObject (); if (wifi == 0) @@ -634,7 +656,6 @@ return; mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ()); - m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ()); } void @@ -662,6 +683,13 @@ NS_ASSERT (socket); socket->Close (); m_socketAddresses.erase (socket); + + // Close socket + socket = FindSubnetBroadcastSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0)); + NS_ASSERT (socket); + socket->Close (); + m_socketSubnetBroadcastAddresses.erase (socket); + if (m_socketAddresses.empty ()) { NS_LOG_LOGIC ("No aodv interfaces"); @@ -693,12 +721,22 @@ UdpSocketFactory::GetTypeId ()); NS_ASSERT (socket != 0); socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv,this)); + socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT)); socket->BindToNetDevice (l3->GetNetDevice (i)); - // Bind to any IP address so that broadcasts can be received - socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), AODV_PORT)); socket->SetAllowBroadcast (true); m_socketAddresses.insert (std::make_pair (socket, iface)); + // create also a subnet directed broadcast socket + socket = Socket::CreateSocket (GetObject (), + UdpSocketFactory::GetTypeId ()); + NS_ASSERT (socket != 0); + socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this)); + socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT)); + socket->BindToNetDevice (l3->GetNetDevice (i)); + socket->SetAllowBroadcast (true); + socket->SetAttribute ("IpTtl", UintegerValue (1)); + m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface)); + // Add local broadcast record to the routing table Ptr dev = m_ipv4->GetNetDevice ( m_ipv4->GetInterfaceForAddress (iface.GetLocal ())); @@ -722,7 +760,16 @@ if (socket) { m_routingTable.DeleteAllRoutesFromInterface (address); + socket->Close (); m_socketAddresses.erase (socket); + + Ptr unicastSocket = FindSubnetBroadcastSocketWithInterfaceAddress (address); + if (unicastSocket) + { + unicastSocket->Close (); + m_socketAddresses.erase (unicastSocket); + } + Ptr l3 = m_ipv4->GetObject (); if (l3->GetNAddresses (i)) { @@ -733,10 +780,23 @@ NS_ASSERT (socket != 0); socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this)); // Bind to any IP address so that broadcasts can be received - socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), AODV_PORT)); + socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT)); + socket->BindToNetDevice (l3->GetNetDevice (i)); socket->SetAllowBroadcast (true); + socket->SetAttribute ("IpTtl", UintegerValue (1)); m_socketAddresses.insert (std::make_pair (socket, iface)); + // create also a unicast socket + socket = Socket::CreateSocket (GetObject (), + UdpSocketFactory::GetTypeId ()); + NS_ASSERT (socket != 0); + socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this)); + socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT)); + socket->BindToNetDevice (l3->GetNetDevice (i)); + socket->SetAllowBroadcast (true); + socket->SetAttribute ("IpTtl", UintegerValue (1)); + m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface)); + // Add local broadcast record to the routing table Ptr dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ())); RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface, @@ -937,7 +997,20 @@ Ptr packet = socket->RecvFrom (sourceAddress); InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress); Ipv4Address sender = inetSourceAddr.GetIpv4 (); - Ipv4Address receiver = m_socketAddresses[socket].GetLocal (); + Ipv4Address receiver; + + if (m_socketAddresses.find (socket) != m_socketAddresses.end ()) + { + receiver = m_socketAddresses[socket].GetLocal (); + } + else if(m_socketSubnetBroadcastAddresses.find (socket) != m_socketSubnetBroadcastAddresses.end ()) + { + receiver = m_socketSubnetBroadcastAddresses[socket].GetLocal (); + } + else + { + NS_ASSERT_MSG (false, "Received a packet from an unknown socket"); + } NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver); UpdateRouteToNeighbor (sender, receiver); @@ -1832,5 +1905,21 @@ return socket; } +Ptr +RoutingProtocol::FindSubnetBroadcastSocketWithInterfaceAddress (Ipv4InterfaceAddress addr ) const +{ + NS_LOG_FUNCTION (this << addr); + for (std::map, Ipv4InterfaceAddress>::const_iterator j = + m_socketSubnetBroadcastAddresses.begin (); j != m_socketSubnetBroadcastAddresses.end (); ++j) + { + Ptr socket = j->first; + Ipv4InterfaceAddress iface = j->second; + if (iface == addr) + return socket; + } + Ptr socket; + return socket; } + } +} diff -r f6a0e074b6fc src/aodv/model/aodv-routing-protocol.h --- a/src/aodv/model/aodv-routing-protocol.h Sat May 03 15:56:25 2014 -0700 +++ b/src/aodv/model/aodv-routing-protocol.h Sun May 04 16:52:03 2014 +0200 @@ -140,8 +140,10 @@ /// IP protocol Ptr m_ipv4; - /// Raw socket per each IP interface, map socket -> iface address (IP + mask) + /// Raw unicast socket per each IP interface, map socket -> iface address (IP + mask) std::map< Ptr, Ipv4InterfaceAddress > m_socketAddresses; + /// Raw subnet directed broadcast socket per each IP interface, map socket -> iface address (IP + mask) + std::map< Ptr, Ipv4InterfaceAddress > m_socketSubnetBroadcastAddresses; /// Loopback device used to defer RREQ until packet will be fully formed Ptr m_lo; @@ -191,8 +193,10 @@ void UpdateRouteToNeighbor (Ipv4Address sender, Ipv4Address receiver); /// Check that packet is send from own interface bool IsMyOwnAddress (Ipv4Address src); - /// Find socket with local interface address iface + /// Find unicast socket with local interface address iface Ptr FindSocketWithInterfaceAddress (Ipv4InterfaceAddress iface) const; + /// Find subnet directed broadcast socket with local interface address iface + Ptr FindSubnetBroadcastSocketWithInterfaceAddress (Ipv4InterfaceAddress iface) const; /// Process hello message void ProcessHello (RrepHeader const & rrepHeader, Ipv4Address receiverIfaceAddr); /// Create loopback route for given header