--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/aodv-with-interface-down.cc Mon Aug 17 10:58:09 2009 +0400
@@ -0,0 +1,213 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 IITP RAS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This is an example script for AODV manet routing protocol.
+ *
+ * Authors: Pavel Boyko <boyko@iitp.ru>
+ */
+
+#include "ns3/aodv-module.h"
+#include "ns3/core-module.h"
+#include "ns3/common-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/contrib-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/v4ping-helper.h"
+#include <iostream>
+#include <cmath>
+
+using namespace ns3;
+
+/**
+ * \brief Test script.
+ *
+ * This script creates 1-dimensional grid topology and then ping last node from the first one:
+ *
+ * [10.0.0.1] <-- step --> [10.0.0.2] <-- step --> [10.0.0.3] <-- step --> [10.0.04]
+ *
+ * ping 10.0.0.4
+ */
+class AodvExample
+{
+public:
+ AodvExample ();
+ /// Configure script parameters, \return true on successful configuration
+ bool Configure (int argc, char **argv);
+ /// Run simulation
+ void Run ();
+ /// Report results
+ void Report (std::ostream & os);
+
+private:
+ ///\name parameters
+ //\{
+ /// Number of nodes
+ uint32_t size;
+ /// Distance between nodes, meters
+ double step;
+ /// Simulation time, seconds
+ double totalTime;
+ /// Write per-device PCAP traces if true
+ bool pcap;
+ //\}
+
+ ///\name network
+ //\{
+ NodeContainer nodes;
+ NetDeviceContainer devices;
+ Ipv4InterfaceContainer interfaces;
+ //\}
+
+private:
+ void CreateNodes ();
+ void CreateDevices ();
+ void InstallInternetStack ();
+ void InstallApplications ();
+};
+
+int main (int argc, char **argv)
+{
+ AodvExample test;
+ if (! test.Configure(argc, argv))
+ NS_FATAL_ERROR ("Configuration failed. Aborted.");
+
+ test.Run ();
+ test.Report (std::cout);
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+AodvExample::AodvExample () :
+ size (4),
+ step (120),
+ totalTime (10),
+ pcap (true)
+{
+}
+
+bool
+AodvExample::Configure (int argc, char **argv)
+{
+ // Enable AODV logs by default. Comment this if too noisy
+ // LogComponentEnable("AodvRoutingProtocol", LOG_LEVEL_ALL);
+
+ SeedManager::SetSeed(12345);
+ CommandLine cmd;
+
+ cmd.AddValue ("pcap", "Write PCAP traces.", pcap);
+ cmd.AddValue ("size", "Number of nodes.", size);
+ cmd.AddValue ("time", "Simulation time, s.", totalTime);
+ cmd.AddValue ("step", "Grid step, m", step);
+
+ cmd.Parse (argc, argv);
+ return true;
+}
+
+void
+AodvExample::Run ()
+{
+// Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue (1)); // enable rts cts all the time.
+ CreateNodes ();
+ CreateDevices ();
+ InstallInternetStack ();
+ InstallApplications ();
+
+ std::cout << "Starting simulation for " << totalTime << " s ...\n";
+
+ Simulator::Stop (Seconds (totalTime));
+ Simulator::Run ();
+ Simulator::Destroy ();
+}
+
+void
+AodvExample::Report (std::ostream &)
+{
+}
+
+void
+AodvExample::CreateNodes ()
+{
+ std::cout << "Creating " << (unsigned)size << " nodes " << step << " m apart.\n";
+ nodes.Create (size);
+ // Name nodes
+ for (uint32_t i = 0; i < size; ++i)
+ {
+ std::ostringstream os;
+ os << "node-" << i;
+ Names::Add (os.str (), nodes.Get (i));
+ }
+ // Create static grid
+ MobilityHelper mobility;
+ mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
+ "MinX", DoubleValue (0.0),
+ "MinY", DoubleValue (0.0),
+ "DeltaX", DoubleValue (step),
+ "DeltaY", DoubleValue (0),
+ "GridWidth", UintegerValue (size),
+ "LayoutType", StringValue ("RowFirst"));
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+ mobility.Install (nodes);
+}
+
+void
+AodvExample::CreateDevices ()
+{
+ NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
+ wifiMac.SetType ("ns3::AdhocWifiMac");
+ YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+ YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
+ wifiPhy.SetChannel (wifiChannel.Create ());
+ WifiHelper wifi = WifiHelper::Default ();
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("wifia-6mbs"), "RtsCtsThreshold", UintegerValue (0));
+ devices = wifi.Install (wifiPhy, wifiMac, nodes);
+
+ if (pcap)
+ {
+ wifiPhy.EnablePcapAll (std::string ("aodv"));
+ }
+}
+
+void
+AodvExample::InstallInternetStack ()
+{
+ AodvHelper aodv;
+ // you can configure AODV attributes here using aodv.Set(name, value)
+ InternetStackHelper stack;
+ stack.SetRoutingHelper (aodv);
+ stack.Install (nodes);
+ Ipv4AddressHelper address;
+ address.SetBase ("10.0.0.0", "255.0.0.0");
+ interfaces = address.Assign (devices);
+}
+
+void
+AodvExample::InstallApplications ()
+{
+ V4PingHelper ping (interfaces.GetAddress(size - 1));
+ ping.SetAttribute ("Verbose", BooleanValue (true));
+
+ ApplicationContainer p = ping.Install (nodes.Get (0));
+ p.Start (Seconds (0));
+ p.Stop (Seconds (totalTime));
+
+ Ptr<Node> node = nodes.Get (size/2);
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+ Simulator::Schedule (Seconds (1), &Ipv4::SetDown, ipv4, 1);
+}
+
--- a/src/routing/aodv/aodv-packet.cc Fri Aug 14 18:14:16 2009 +0400
+++ b/src/routing/aodv/aodv-packet.cc Mon Aug 17 10:58:09 2009 +0400
@@ -712,9 +712,9 @@
bool
RerrHeader::RemoveUnDestination (std::pair<Ipv4Address, uint32_t> & un )
{
- if (GetDestCount () == 0)
+ if (m_unreachableDstSeqNo.empty ())
return false;
- std::map<Ipv4Address, uint32_t>::iterator i = m_unreachableDstSeqNo.end ();
+ std::map<Ipv4Address, uint32_t>::iterator i = m_unreachableDstSeqNo.begin ();
un = *i;
m_unreachableDstSeqNo.erase (i);
return true;
--- a/src/routing/aodv/aodv-routing-protocol.cc Fri Aug 14 18:14:16 2009 +0400
+++ b/src/routing/aodv/aodv-routing-protocol.cc Mon Aug 17 10:58:09 2009 +0400
@@ -442,6 +442,9 @@
RoutingProtocol::NotifyInterfaceDown (uint32_t i )
{
NS_LOG_FUNCTION (this << m_ipv4->GetAddress (i, 0).GetLocal ());
+// Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
+// m_socketAddresses.erase (socket);
+// m_routingTable.DeleteAllRouteFromInterface (m_ipv4->GetAddress (i, 0));
// TODO
}
@@ -980,11 +983,20 @@
m_routingTable.LookupRoute (rrepHeader.GetDst (), toDst);
toDst.InsertPrecursor (toOrigin.GetNextHop ());
m_routingTable.Update (toDst);
+
RoutingTableEntry toNextHopToDst;
m_routingTable.LookupRoute (toDst.GetNextHop (), toNextHopToDst);
toNextHopToDst.InsertPrecursor (toOrigin.GetNextHop ());
m_routingTable.Update (toNextHopToDst);
+ toOrigin.InsertPrecursor (toDst.GetNextHop ());
+ m_routingTable.Update (toOrigin);
+
+ RoutingTableEntry toNextHopToOrigin;
+ m_routingTable.LookupRoute (toOrigin.GetNextHop (), toNextHopToOrigin);
+ toNextHopToOrigin.InsertPrecursor (toDst.GetNextHop ());
+ m_routingTable.Update (toNextHopToOrigin);
+
Ptr<Packet> packet = Create<Packet> ();
packet->AddHeader (rrepHeader);
TypeHeader tHeader (AODVTYPE_RREP);
@@ -1040,9 +1052,14 @@
void
RoutingProtocol::RecvError (Ptr<Packet> p, Ipv4Address src )
{
+ NS_LOG_FUNCTION (this << " from " << src);
RerrHeader rerrHeader;
p->RemoveHeader (rerrHeader);
bool noDelete = rerrHeader.GetNoDelete ();
+ if (noDelete)
+ {
+
+ }
std::map<Ipv4Address, uint32_t> dstWithNextHopSrc;
std::map<Ipv4Address, uint32_t> unreachable;
m_routingTable.GetListOfDestinationWithNextHop (src, dstWithNextHopSrc);
@@ -1081,6 +1098,8 @@
}
if (!noDelete)
m_routingTable.InvalidateRoutesWithDst (unreachable);
+ NS_LOG_LOGIC ("After receive RERR");
+ m_routingTable.Print (std::cout);
}
void
@@ -1237,6 +1256,10 @@
void
RoutingProtocol::SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop )
{
+ NS_LOG_FUNCTION (this << nextHop);
+ NS_LOG_LOGIC ("Before send RERR");
+ m_routingTable.Print(std::cout);
+
RerrHeader rerrHeader;
std::vector<Ipv4Address> precursors;
std::map<Ipv4Address, uint32_t> unreachable;
@@ -1247,6 +1270,7 @@
toNextHop.GetPrecursors (precursors);
rerrHeader.AddUnDestination (nextHop, toNextHop.GetSeqNo ());
m_routingTable.GetListOfDestinationWithNextHop (nextHop, unreachable);
+ NS_LOG_LOGIC ("number of unreachable destination " << unreachable.size ());
for (std::map<Ipv4Address, uint32_t>::const_iterator i = unreachable.begin (); i != unreachable.end ();)
{
if (!rerrHeader.AddUnDestination (i->first, i->second))
@@ -1266,8 +1290,20 @@
++i;
}
}
+ if (rerrHeader.GetDestCount () != 0)
+ {
+ TypeHeader typeHeader (AODVTYPE_RERR);
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (rerrHeader);
+ packet->AddHeader (typeHeader);
+ NS_LOG_DEBUG ("RERR header");
+ rerrHeader.Print(std::cout);
+ SendRerrMessage (packet, precursors);
+ }
unreachable.insert (std::make_pair (nextHop, toNextHop.GetSeqNo ()));
m_routingTable.InvalidateRoutesWithDst (unreachable);
+ NS_LOG_LOGIC ("After send RERR");
+ m_routingTable.Print(std::cout);
}
void
@@ -1293,7 +1329,10 @@
NS_LOG_FUNCTION(this);
if (precursors.empty ())
- return; // TODO too many unreachable destinations, but no precursors
+ {
+ NS_LOG_LOGIC ("No precursors");
+ return; // TODO too many unreachable destinations, but no precursors
+ }
// If there is only one precursor, RERR SHOULD be unicast toward that precursor
if (precursors.size () == 1)
{
@@ -1301,6 +1340,7 @@
m_routingTable.LookupRoute (precursors.front (), toPrecursor);
Ptr<Socket> socket = FindSocketWithInterfaceAddress (toPrecursor.GetInterface ());
NS_ASSERT (socket);
+ NS_LOG_LOGIC ("one precursor => unicast RERR to " << toPrecursor.GetDestination() << " from " << toPrecursor.GetInterface ().GetLocal ());
SendPacketViaRawSocket (/*packet*/packet, /*pair<Ptr<Socket> , Ipv4InterfaceAddress>*/ std::make_pair(socket, toPrecursor.GetInterface ()),
/*dst*/precursors.front (), /*TTL*/ 1, /*id*/0);
return;
@@ -1328,6 +1368,7 @@
{
Ptr<Socket> socket = FindSocketWithInterfaceAddress (*i);
NS_ASSERT (socket);
+ NS_LOG_LOGIC ("broadcast RERR meassage from interface " << i->GetLocal());
SendPacketViaRawSocket (/*packet*/packet, /*pair<Ptr<Socket> , Ipv4InterfaceAddress>*/ std::make_pair(socket, toPrecursor.GetInterface ()),
/*dst*/m_socketAddresses[socket].GetBroadcast (), /*TTL*/ 1, /*id*/0);
}
--- a/src/routing/aodv/aodv-rtable.cc Fri Aug 14 18:14:16 2009 +0400
+++ b/src/routing/aodv/aodv-rtable.cc Mon Aug 17 10:58:09 2009 +0400
@@ -318,13 +318,15 @@
}
void
-RoutingTable::GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> unreachable )
+RoutingTable::GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> & unreachable )
{
Purge ();
unreachable.clear ();
for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = m_ipv4AddressEntry.begin (); i != m_ipv4AddressEntry.end (); ++i)
- if ((i->second.GetNextHop () == nextHop) && (i->second.GetFlag () == VALID) && (!i->second.IsPrecursorListEmpty ()))
- unreachable.insert (std::make_pair (i->first, i->second.GetSeqNo ()));
+ if ((i->second.GetNextHop () == nextHop) && (i->second.GetFlag () == VALID) /*&& (!i->second.IsPrecursorListEmpty ())*/)
+ {
+ unreachable.insert (std::make_pair (i->first, i->second.GetSeqNo ()));
+ }
}
void
--- a/src/routing/aodv/aodv-rtable.h Fri Aug 14 18:14:16 2009 +0400
+++ b/src/routing/aodv/aodv-rtable.h Mon Aug 17 10:58:09 2009 +0400
@@ -220,7 +220,7 @@
/**
* Lookup valid routing entries with next hop Address dst and not empty list of precursors.
*/
- void GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> unreachable);
+ void GetListOfDestinationWithNextHop (Ipv4Address nextHop, std::map<Ipv4Address, uint32_t> & unreachable);
/**
* Update routing entries with this destinations as follows:
* 1. The destination sequence number of this routing entry, if it