Includes cleanup + layer 2 link failure detection (untested)

This commit is contained in:
Pavel Boyko
2009-08-18 15:07:25 +04:00
parent 04a0d79e09
commit 522bd8dbcc
7 changed files with 122 additions and 16 deletions

View File

@@ -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

View File

@@ -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
*

View File

@@ -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']:

View File

@@ -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

View File

@@ -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 &);
};
}

View File

@@ -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);
}

View File

@@ -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