--- a/src/internet-stack/ipv4-interface.cc Tue Aug 18 12:02:20 2009 +0400
+++ b/src/internet-stack/ipv4-interface.cc Tue Aug 18 15:07:25 2009 +0400
@@ -42,7 +42,8 @@
.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 @@
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
--- a/src/internet-stack/ipv4-interface.h Tue Aug 18 12:02:20 2009 +0400
+++ b/src/internet-stack/ipv4-interface.h Tue Aug 18 15:07:25 2009 +0400
@@ -56,12 +56,17 @@
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
*
--- a/src/internet-stack/wscript Tue Aug 18 12:02:20 2009 +0400
+++ b/src/internet-stack/wscript Tue Aug 18 15:07:25 2009 +0400
@@ -108,6 +108,11 @@
'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']:
--- a/src/routing/aodv/aodv-neighbor.cc Tue Aug 18 12:02:20 2009 +0400
+++ b/src/routing/aodv/aodv-neighbor.cc Tue Aug 18 15:07:25 2009 +0400
@@ -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 @@
return Seconds(0);
}
-
void
Neighbors::Update (Ipv4Address addr, Time expire )
{
@@ -72,8 +73,20 @@
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 @@
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
--- a/src/routing/aodv/aodv-neighbor.h Tue Aug 18 12:02:20 2009 +0400
+++ b/src/routing/aodv/aodv-neighbor.h Tue Aug 18 15:07:25 2009 +0400
@@ -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 @@
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 @@
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 @@
{
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 &);
};
}
--- a/src/routing/aodv/aodv-routing-protocol.cc Tue Aug 18 12:02:20 2009 +0400
+++ b/src/routing/aodv/aodv-routing-protocol.cc Tue Aug 18 15:07:25 2009 +0400
@@ -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 @@
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 @@
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 @@
}
}
-
-
void
RoutingProtocol::SendPacketFromQueue (Ipv4Address dst, Ptr<Ipv4Route> route )
{
@@ -1330,7 +1355,7 @@
{
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);
}
--- a/src/routing/aodv/aodv-routing-protocol.h Tue Aug 18 12:02:20 2009 +0400
+++ b/src/routing/aodv/aodv-routing-protocol.h Tue Aug 18 15:07:25 2009 +0400
@@ -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