Includes cleanup + layer 2 link failure detection (untested)
This commit is contained in:
@@ -42,7 +42,8 @@ Ipv4Interface::GetTypeId (void)
|
||||
.AddAttribute ("ArpCache",
|
||||
"The arp cache for this ipv4 interface",
|
||||
PointerValue (0),
|
||||
MakePointerAccessor (&Ipv4Interface::m_cache),
|
||||
MakePointerAccessor (&Ipv4Interface::SetArpCache,
|
||||
&Ipv4Interface::GetArpCache),
|
||||
MakePointerChecker<ArpCache> ())
|
||||
;
|
||||
;
|
||||
@@ -128,6 +129,18 @@ Ipv4Interface::GetMetric (void) const
|
||||
return m_metric;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Interface::SetArpCache (Ptr<ArpCache> a)
|
||||
{
|
||||
m_cache = a;
|
||||
}
|
||||
|
||||
Ptr<ArpCache>
|
||||
Ipv4Interface::GetArpCache () const
|
||||
{
|
||||
return m_cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* These are IP interface states and may be distinct from
|
||||
* NetDevice states, such as found in real implementations
|
||||
|
||||
@@ -56,12 +56,17 @@ public:
|
||||
|
||||
void SetNode (Ptr<Node> node);
|
||||
void SetDevice (Ptr<NetDevice> device);
|
||||
void SetArpCache (Ptr<ArpCache>);
|
||||
|
||||
/**
|
||||
* \returns the underlying NetDevice. This method cannot return zero.
|
||||
*/
|
||||
Ptr<NetDevice> GetDevice (void) const;
|
||||
|
||||
/**
|
||||
* \return ARP cache used by this interface
|
||||
*/
|
||||
Ptr<ArpCache> GetArpCache () const;
|
||||
|
||||
/**
|
||||
* \param metric configured routing metric (cost) of this interface
|
||||
*
|
||||
|
||||
@@ -108,6 +108,11 @@ def build(bld):
|
||||
'tcp-header.h',
|
||||
'sequence-number.h',
|
||||
'icmpv4.h',
|
||||
# used by routing
|
||||
'ipv4-interface.h',
|
||||
'ipv4-l3-protocol.h',
|
||||
'arp-cache.h',
|
||||
'sgi-hashmap.h',
|
||||
]
|
||||
|
||||
if bld.env['NSC_ENABLED']:
|
||||
|
||||
@@ -31,15 +31,17 @@
|
||||
#include "ns3/log.h"
|
||||
#include <algorithm>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("AodvNeighbors");
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
namespace aodv
|
||||
{
|
||||
|
||||
Neighbors::Neighbors (Time delay) : m_ntimer (Timer::CANCEL_ON_DESTROY)
|
||||
{
|
||||
m_ntimer.SetDelay(delay);
|
||||
m_ntimer.SetFunction(&Neighbors::Purge, this);
|
||||
m_txErrorCallback = MakeCallback (& Neighbors::ProcessTxError, this);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -62,7 +64,6 @@ Neighbors::GetExpireTime (Ipv4Address addr)
|
||||
return Seconds(0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Neighbors::Update (Ipv4Address addr, Time expire )
|
||||
{
|
||||
@@ -72,8 +73,20 @@ Neighbors::Update (Ipv4Address addr, Time expire )
|
||||
i->m_expireTime = std::max(expire + Simulator::Now (), i->m_expireTime);
|
||||
return;
|
||||
}
|
||||
struct Neighbor neighbor =
|
||||
{ addr, expire + Simulator::Now () };
|
||||
|
||||
// Lookup mac address
|
||||
Mac48Address hwaddr;
|
||||
for (std::vector<Ptr<ArpCache> >::const_iterator i = m_arp.begin(); i != m_arp.end(); ++i)
|
||||
{
|
||||
ArpCache::Entry * entry = (*i)->Lookup (addr);
|
||||
if (entry != 0 && entry->IsAlive () && ! entry->IsExpired ())
|
||||
{
|
||||
hwaddr = Mac48Address::ConvertFrom(entry->GetMacAddress ());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Neighbor neighbor (addr, hwaddr, expire + Simulator::Now ());
|
||||
m_nb.push_back (neighbor);
|
||||
Purge ();
|
||||
}
|
||||
@@ -102,6 +115,32 @@ Neighbors::ScheduleTimer ()
|
||||
m_ntimer.Schedule();
|
||||
}
|
||||
|
||||
void
|
||||
Neighbors::AddArpCache (Ptr<ArpCache> a)
|
||||
{
|
||||
m_arp.push_back(a);
|
||||
}
|
||||
|
||||
void
|
||||
Neighbors::DelArpCache (Ptr<ArpCache> a)
|
||||
{
|
||||
m_arp.erase(std::remove(m_arp.begin(), m_arp.end(), a), m_arp.end());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Neighbors::ProcessTxError (WifiMacHeader const & hdr)
|
||||
{
|
||||
Mac48Address addr = hdr.GetAddr1();
|
||||
|
||||
for (std::vector<Neighbor>::iterator i = m_nb.begin (); i != m_nb.end (); ++i)
|
||||
if (i->m_hardwareAddress == addr)
|
||||
{
|
||||
NS_LOG_LOGIC ("Close link to " << i->m_neighborAddress << " because of layer 2 TX error notification");
|
||||
i->m_expireTime = Simulator::Now();
|
||||
}
|
||||
Purge();
|
||||
}
|
||||
|
||||
#ifdef RUN_SELF_TESTS
|
||||
/// Unit test for neighbors
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
#include "ns3/timer.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/wifi-mac-header.h"
|
||||
#include "ns3/arp-cache.h"
|
||||
#include <vector>
|
||||
#
|
||||
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
@@ -52,10 +52,14 @@ class Neighbors
|
||||
public:
|
||||
/// c-tor
|
||||
Neighbors (Time delay);
|
||||
/// Neighbor description
|
||||
struct Neighbor
|
||||
{
|
||||
Ipv4Address m_neighborAddress;
|
||||
Mac48Address m_hardwareAddress;
|
||||
Time m_expireTime;
|
||||
|
||||
Neighbor(Ipv4Address ip, Mac48Address mac, Time t) : m_neighborAddress(ip), m_hardwareAddress(mac), m_expireTime(t) {}
|
||||
};
|
||||
/// Return expire time for neighbor node with address addr, if exists, else return 0.
|
||||
Time GetExpireTime (Ipv4Address addr);
|
||||
@@ -69,6 +73,14 @@ public:
|
||||
void ScheduleTimer ();
|
||||
/// Remove all entries
|
||||
void Clear () { m_nb.clear (); }
|
||||
|
||||
/// Add ARP cache to be used to allow layer 2 notifications processing
|
||||
void AddArpCache (Ptr<ArpCache>);
|
||||
/// Don't use given ARP cache any more (interface is down)
|
||||
void DelArpCache (Ptr<ArpCache>);
|
||||
/// Get callback to ProcessTxError
|
||||
Callback<void, WifiMacHeader const &> GetTxErrorCallback () const { return m_txErrorCallback; }
|
||||
|
||||
///\name Handle link failure callback
|
||||
//\{
|
||||
void SetCallback (Callback<void, Ipv4Address> cb) { m_handleLinleFailure = cb;}
|
||||
@@ -79,15 +91,22 @@ private:
|
||||
{
|
||||
bool operator()(const struct Neighbor & nb) const
|
||||
{
|
||||
return (nb.m_expireTime < Simulator::Now());
|
||||
return (nb.m_expireTime <= Simulator::Now()); /*<= is important here*/
|
||||
}
|
||||
};
|
||||
/// link failure callback
|
||||
Callback<void, Ipv4Address> m_handleLinleFailure;
|
||||
/// TX error callback
|
||||
Callback<void, WifiMacHeader const &> m_txErrorCallback;
|
||||
/// Timer for neighbor's list. Schedule Purge().
|
||||
Timer m_ntimer;
|
||||
/// vector of entries
|
||||
std::vector<Neighbor> m_nb;
|
||||
/// list of ARP cached to be used for layer 2 notifications processing
|
||||
std::vector<Ptr<ArpCache> > m_arp;
|
||||
|
||||
/// Process layer 2 TX error notification
|
||||
void ProcessTxError (WifiMacHeader const &);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
#include "ns3/udp-header.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/net-device.h"
|
||||
|
||||
#include "ns3/udp-socket-factory.h"
|
||||
#include "src/internet-stack/udp-l4-protocol.h"
|
||||
#include "ns3/wifi-net-device.h"
|
||||
#include "ns3/adhoc-wifi-mac.h"
|
||||
#include <algorithm>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("AodvRoutingProtocol");
|
||||
@@ -369,6 +369,7 @@ RoutingProtocol::NotifyInterfaceUp (uint32_t i )
|
||||
Ipv4InterfaceAddress iface = interface->GetAddress (0);
|
||||
if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
|
||||
return;
|
||||
|
||||
// Create a socket to listen only on this interface
|
||||
Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (), UdpSocketFactory::GetTypeId());
|
||||
NS_ASSERT (socket != 0);
|
||||
@@ -382,12 +383,38 @@ RoutingProtocol::NotifyInterfaceUp (uint32_t i )
|
||||
RoutingTableEntry rt (/*device=*/dev, /*dst=*/iface.GetBroadcast (), /*know seqno=*/true, /*seqno=*/0, /*iface=*/iface,
|
||||
/*hops=*/1, /*next hop=*/iface.GetBroadcast (), /*lifetime=*/Seconds (1e9)); // TODO use infty
|
||||
m_routingTable.AddRoute (rt);
|
||||
|
||||
// Allow neighbor manager use this interface for layer 2 feedback if possible
|
||||
Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
|
||||
if (wifi == 0) return;
|
||||
Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
|
||||
if (mac == 0) return;
|
||||
|
||||
mac->TraceConnectWithoutContext("TxErrHeader", m_nb.GetTxErrorCallback());
|
||||
m_nb.AddArpCache (interface->GetArpCache());
|
||||
}
|
||||
|
||||
void
|
||||
RoutingProtocol::NotifyInterfaceDown (uint32_t i )
|
||||
{
|
||||
NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
|
||||
|
||||
// Discable layer 2 link state monitoring (if possible)
|
||||
Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
|
||||
Ptr<Ipv4Interface> interface = l3->GetInterface (i);
|
||||
Ptr<NetDevice> dev = interface->GetDevice();
|
||||
Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
|
||||
if (wifi != 0)
|
||||
{
|
||||
Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
|
||||
if (mac != 0)
|
||||
{
|
||||
mac->TraceDisconnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback());
|
||||
m_nb.DelArpCache (interface->GetArpCache());
|
||||
}
|
||||
}
|
||||
|
||||
// Close socket
|
||||
Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
|
||||
NS_ASSERT (socket);
|
||||
socket->Close ();
|
||||
@@ -1173,8 +1200,6 @@ RoutingProtocol::SendHello ()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
RoutingProtocol::SendPacketFromQueue (Ipv4Address dst, Ptr<Ipv4Route> route )
|
||||
{
|
||||
@@ -1330,7 +1355,7 @@ RoutingProtocol::SendRerrMessage (Ptr<Packet> packet, std::vector<Ipv4Address> p
|
||||
{
|
||||
Ptr<Socket> socket = FindSocketWithInterfaceAddress (*i);
|
||||
NS_ASSERT (socket);
|
||||
NS_LOG_LOGIC ("broadcast RERR meassage from interface " << i->GetLocal());
|
||||
NS_LOG_LOGIC ("broadcast RERR message from interface " << i->GetLocal());
|
||||
socket->Send (packet);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
#include "id-cache.h"
|
||||
#include "aodv-neighbor.h"
|
||||
|
||||
#include "src/internet-stack/ipv4-l3-protocol.h"
|
||||
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/node.h"
|
||||
@@ -43,6 +41,8 @@
|
||||
#include "ns3/timer.h"
|
||||
#include "ns3/ipv4.h"
|
||||
#include "ns3/ipv4-routing-protocol.h"
|
||||
#include "ns3/ipv4-interface.h"
|
||||
#include "ns3/ipv4-l3-protocol.h"
|
||||
#include <map>
|
||||
|
||||
namespace ns3
|
||||
|
||||
Reference in New Issue
Block a user