From 0c62ac293213c4632f158a2cbedc86e321a324d4 Mon Sep 17 00:00:00 2001 From: Navarrop Date: Tue, 13 Sep 2011 14:31:58 +0200 Subject: [PATCH] Add RED protocole for ns3. Download ns3 patch here : http://code.google.com/p/ns-3-red/source/checkout --- buildtools/Cmake/DefinePackages.cmake | 13 + buildtools/Cmake/MakeLib.cmake | 5 + buildtools/Cmake/Modules/FindNS3.cmake | 28 +- src/surf/network_ns3.c | 6 +- src/surf/ns3/my-point-to-point-helper.cc | 440 +++++++++++++++++++++++ src/surf/ns3/my-point-to-point-helper.h | 205 +++++++++++ src/surf/ns3/ns3_interface.cc | 18 +- src/surf/ns3/ns3_interface.h | 4 +- src/surf/ns3/ns3_simulator.h | 4 + 9 files changed, 716 insertions(+), 7 deletions(-) create mode 100644 src/surf/ns3/my-point-to-point-helper.cc create mode 100644 src/surf/ns3/my-point-to-point-helper.h diff --git a/buildtools/Cmake/DefinePackages.cmake b/buildtools/Cmake/DefinePackages.cmake index 814e0f242b..62b7b4ea34 100644 --- a/buildtools/Cmake/DefinePackages.cmake +++ b/buildtools/Cmake/DefinePackages.cmake @@ -103,6 +103,7 @@ set(EXTRA_DIST src/surf/network_ns3_private.h src/surf/ns3/ns3_interface.h src/surf/ns3/ns3_simulator.h + src/surf/ns3/my-point-to-point-helper.h ) set(XBT_RL_SRC @@ -201,6 +202,18 @@ set(NS3_SRC src/surf/ns3/ns3_interface.cc src/surf/ns3/ns3_simulator.cc ) + +if(HAVE_RED_QUEUE_H) + set(NS3_SRC + ${NS3_SRC} + src/surf/ns3/my-point-to-point-helper.cc + ) +else(HAVE_RED_QUEUE_H) + set(EXTRA_DIST + ${EXTRA_DIST} + src/surf/ns3/my-point-to-point-helper.cc + ) +endif(HAVE_RED_QUEUE_H) set(SURF_SRC src/surf/surf_model.c diff --git a/buildtools/Cmake/MakeLib.cmake b/buildtools/Cmake/MakeLib.cmake index 3432d7f428..146444f441 100644 --- a/buildtools/Cmake/MakeLib.cmake +++ b/buildtools/Cmake/MakeLib.cmake @@ -127,6 +127,11 @@ if(HAVE_NS3) endif(${NS3_VERSION} EQUAL 310) endif(HAVE_NS3) +if(HAVE_NS3 AND HAVE_RED_QUEUE_H) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_HAVE_NS3_RED") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_HAVE_NS3_RED") +endif(HAVE_NS3 AND HAVE_RED_QUEUE_H) + if(HAVE_POSIX_GETTIME) SET(SIMGRID_DEP "${SIMGRID_DEP} -lrt") endif(HAVE_POSIX_GETTIME) diff --git a/buildtools/Cmake/Modules/FindNS3.cmake b/buildtools/Cmake/Modules/FindNS3.cmake index b7faf9fe64..7b04300b9e 100644 --- a/buildtools/Cmake/Modules/FindNS3.cmake +++ b/buildtools/Cmake/Modules/FindNS3.cmake @@ -42,6 +42,20 @@ find_path(HAVE_CORE_MODULE_H ${ns3_path} ) +find_path(HAVE_RED_QUEUE_H + NAME ns3/red-queue.h + HINTS + $ENV{HOME} + PATH_SUFFIXES include ns3/include + PATHS + /opt + /opt/local + /opt/csw + /sw + /usr + ${ns3_path} +) + message(STATUS "Looking for core-module.h") if(HAVE_CORE_MODULE_H) message(STATUS "Looking for core-module.h - found") @@ -50,6 +64,14 @@ message(STATUS "Looking for core-module.h - not found") endif(HAVE_CORE_MODULE_H) mark_as_advanced(HAVE_CORE_MODULE_H) +message(STATUS "Looking for red-queue.h") +if(HAVE_RED_QUEUE_H) +message(STATUS "Looking for red-queue.h - found") +else(HAVE_RED_QUEUE_H) +message(STATUS "Looking for red-queue.h - not found") +endif(HAVE_RED_QUEUE_H) +mark_as_advanced(HAVE_RED_QUEUE_H) + message(STATUS "Looking for lib ns3") if(HAVE_NS3_LIB) message(STATUS "Looking for lib ns3 - found") @@ -103,4 +125,8 @@ if(HAVE_NS3) endif(NOT operation) else(HAVE_NS3) message(STATUS "Warning: To use NS-3 Please install ns3 at least version 3.10 (http://www.nsnam.org/releases/)") -endif(HAVE_NS3) \ No newline at end of file +endif(HAVE_NS3) + +if(HAVE_NS3 AND enable_supernovae) + set(enable_supernovae OFF) +endif(HAVE_NS3 AND enable_supernovae) \ No newline at end of file diff --git a/src/surf/network_ns3.c b/src/surf/network_ns3.c index 898f9c2176..0b56f0fb7a 100644 --- a/src/surf/network_ns3.c +++ b/src/surf/network_ns3.c @@ -216,7 +216,9 @@ void parse_ns3_add_cluster(void) if(host_src && host_dst){} else xbt_die("\tns3_add_link from %d to %d",host_src->node_num,host_dst->node_num); - ns3_add_link(host_src->node_num,host_dst->node_num,bw,lat); + ns3_add_link(host_src->node_num,host_src->type, + host_dst->node_num,host_dst->type, + bw,lat); free(router_id); free(host_id); @@ -302,7 +304,7 @@ void create_ns3_topology() if(host_src && host_dst){} else xbt_die("\tns3_add_link from %d to %d",host_src->node_num,host_dst->node_num); - ns3_add_link(host_src->node_num,host_dst->node_num,link_bdw,link_lat); + ns3_add_link(host_src->node_num,host_src->type,host_dst->node_num,host_dst->type,link_bdw,link_lat); xbt_free(link_bdw); xbt_free(link_lat); diff --git a/src/surf/ns3/my-point-to-point-helper.cc b/src/surf/ns3/my-point-to-point-helper.cc new file mode 100644 index 0000000000..f59149a353 --- /dev/null +++ b/src/surf/ns3/my-point-to-point-helper.cc @@ -0,0 +1,440 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * + * 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 + * + * Author: Mathieu Lacage + */ + +#include "ns3/abort.h" +#include "ns3/log.h" +#include "ns3/simulator.h" +#include "ns3/point-to-point-net-device.h" +#include "ns3/point-to-point-channel.h" +#include "ns3/point-to-point-remote-channel.h" +#include "ns3/queue.h" +#include "ns3/config.h" +#include "ns3/packet.h" +#include "ns3/names.h" +#include "ns3/string.h" +#include "ns3/mpi-interface.h" +#include "ns3/mpi-receiver.h" + +#include "ns3/trace-helper.h" +#include "my-point-to-point-helper.h" + +NS_LOG_COMPONENT_DEFINE ("MyPointToPointHelper"); + +///> RED Parameters see src/node/red-queue.* for details +//.AddAttribute ("Mode", +// "Whether to use Bytes (see MaxBytes) or Packets (see MaxPackets) as the maximum queue size metric.", +// EnumValue (BYTES), ///> currently supports BYTES only +// MakeEnumAccessor (&RedQueue::SetMode), +// MakeEnumChecker (BYTES, "Bytes", +// PACKETS, "Packets")) +// .AddAttribute ("MaxPackets", +// "The maximum number of packets accepted by this RedQueue.", +// UintegerValue (100), +// MakeUintegerAccessor (&RedQueue::m_maxPackets), +// MakeUintegerChecker ()) +// .AddAttribute ("MaxBytes", +// "The maximum number of bytes accepted by this RedQueue.", +// UintegerValue (100000), +// MakeUintegerAccessor (&RedQueue::m_maxBytes), +// MakeUintegerChecker ()) +// .AddAttribute ("m_burst", +// "maximum number of m_burst packets accepted by this queue", +// UintegerValue (6), ///> bursts must be > minTh/avpkt +// MakeUintegerAccessor (&RedQueue::m_burst), +// MakeUintegerChecker ()) +// .AddAttribute ("m_avPkt", +// "In bytes, use with m_burst to determine the time constant for average queue size calculations", +// UintegerValue (1024), ///> average packet size +// MakeUintegerAccessor (&RedQueue::m_avPkt), +// MakeUintegerChecker ()) +// .AddAttribute ("m_minTh", +// "Average queue size at which marking becomes a m_prob", +// UintegerValue (5120), ///> in bytes 1024x5 +// MakeUintegerAccessor (&RedQueue::m_minTh), +// MakeUintegerChecker ()) +// .AddAttribute ("m_maxTh", +// "Maximal marking m_prob, should be at least twice min to prevent synchronous retransmits", +// UintegerValue (15360), ///> in bytes 1024x15 +// MakeUintegerAccessor (&RedQueue::m_maxTh), +// MakeUintegerChecker ()) +// .AddAttribute ("m_rate", +// "this m_rate is used for calculating the average queue size after some idle time.", +// UintegerValue (1500000), ///> in bps, should be set to bandwidth of interface +// MakeUintegerAccessor (&RedQueue::m_rate), +// MakeUintegerChecker ()) +// .AddAttribute ("m_prob", +// "Probability for marking, suggested values are 0.01 and 0.02", +// DoubleValue (0.02), +// MakeDoubleAccessor (&RedQueue::m_prob), +// MakeDoubleChecker ()) +std::string qMode = "Bytes"; +std::string qBurst = "6"; +std::string qAvPkt = "1024"; +std::string qLimit = "25600"; //"100000"; +std::string qthMin = "5120"; // 1024 x 5 bytes +std::string qthMax = "15360"; // 1024 x 15 bytes +std::string qIdleRate = "1500000"; //1.5 Mbps +std::string qProb = "0.02"; + +namespace ns3 { + +MyPointToPointHelper::MyPointToPointHelper () +{ + m_queueFactory.SetTypeId ("ns3::DropTailQueue"); + m_queueFactory_red.SetTypeId ("ns3::RedQueue"); +// m_queueFactory_red.Set ("Mode", StringValue (qMode)); +// m_queueFactory_red.Set ("MaxBytes",StringValue (qLimit)); +// m_queueFactory_red.Set ("m_burst", StringValue (qBurst)); +// m_queueFactory_red.Set ("m_avPkt", StringValue (qAvPkt)); +// m_queueFactory_red.Set ("m_minTh", StringValue (qthMin)); +// m_queueFactory_red.Set ("m_maxTh", StringValue (qthMax)); +// m_queueFactory_red.Set ("m_rate", StringValue (qIdleRate)); +// m_queueFactory_red.Set ("m_prob", StringValue (qProb)); + m_deviceFactory.SetTypeId ("ns3::PointToPointNetDevice"); + m_channelFactory.SetTypeId ("ns3::PointToPointChannel"); + m_remoteChannelFactory.SetTypeId ("ns3::PointToPointRemoteChannel"); +} + +void +MyPointToPointHelper::SetQueue (std::string type, + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4, + std::string n5, const AttributeValue &v5, + std::string n6, const AttributeValue &v6, + std::string n7, const AttributeValue &v7, + std::string n8, const AttributeValue &v8) +{ + m_queueFactory.SetTypeId (type); + m_queueFactory.Set (n1, v1); + m_queueFactory.Set (n2, v2); + m_queueFactory.Set (n3, v3); + m_queueFactory.Set (n4, v4); + m_queueFactory.Set (n5, v5); + m_queueFactory.Set (n6, v6); + m_queueFactory.Set (n7, v7); + m_queueFactory.Set (n8, v8); +} + +void +MyPointToPointHelper::SetDeviceAttribute (std::string n1, const AttributeValue &v1) +{ + m_deviceFactory.Set (n1, v1); +} + +void +MyPointToPointHelper::SetChannelAttribute (std::string n1, const AttributeValue &v1) +{ + m_channelFactory.Set (n1, v1); + m_remoteChannelFactory.Set (n1, v1); +} + +void +MyPointToPointHelper::EnablePcapInternal (std::string prefix, Ptr nd, bool promiscuous, bool explicitFilename) +{ + // + // All of the Pcap enable functions vector through here including the ones + // that are wandering through all of devices on perhaps all of the nodes in + // the system. We can only deal with devices of type PointToPointNetDevice. + // + Ptr device = nd->GetObject (); + if (device == 0) + { + NS_LOG_INFO ("MyPointToPointHelper::EnablePcapInternal(): Device " << device << " not of type ns3::PointToPointNetDevice"); + return; + } + + PcapHelper pcapHelper; + + std::string filename; + if (explicitFilename) + { + filename = prefix; + } + else + { + filename = pcapHelper.GetFilenameFromDevice (prefix, device); + } + + Ptr file = pcapHelper.CreateFile (filename, std::ios::out, + PcapHelper::DLT_PPP); + pcapHelper.HookDefaultSink (device, "PromiscSniffer", file); +} + +void +MyPointToPointHelper::EnableAsciiInternal ( + Ptr stream, + std::string prefix, + Ptr nd, + bool explicitFilename) +{ + // + // All of the ascii enable functions vector through here including the ones + // that are wandering through all of devices on perhaps all of the nodes in + // the system. We can only deal with devices of type PointToPointNetDevice. + // + Ptr device = nd->GetObject (); + if (device == 0) + { + NS_LOG_INFO ("MyPointToPointHelper::EnableAsciiInternal(): Device " << device << + " not of type ns3::PointToPointNetDevice"); + return; + } + + // + // Our default trace sinks are going to use packet printing, so we have to + // make sure that is turned on. + // + Packet::EnablePrinting (); + + // + // If we are not provided an OutputStreamWrapper, we are expected to create + // one using the usual trace filename conventions and do a Hook*WithoutContext + // since there will be one file per context and therefore the context would + // be redundant. + // + if (stream == 0) + { + // + // Set up an output stream object to deal with private ofstream copy + // constructor and lifetime issues. Let the helper decide the actual + // name of the file given the prefix. + // + AsciiTraceHelper asciiTraceHelper; + + std::string filename; + if (explicitFilename) + { + filename = prefix; + } + else + { + filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device); + } + + Ptr theStream = asciiTraceHelper.CreateFileStream (filename); + + // + // The MacRx trace source provides our "r" event. + // + asciiTraceHelper.HookDefaultReceiveSinkWithoutContext (device, "MacRx", theStream); + + // + // The "+", '-', and 'd' events are driven by trace sources actually in the + // transmit queue. + // + Ptr queue = device->GetQueue (); + asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext (queue, "Enqueue", theStream); + asciiTraceHelper.HookDefaultDropSinkWithoutContext (queue, "Drop", theStream); + asciiTraceHelper.HookDefaultDequeueSinkWithoutContext (queue, "Dequeue", theStream); + + // PhyRxDrop trace source for "d" event + asciiTraceHelper.HookDefaultDropSinkWithoutContext (device, "PhyRxDrop", theStream); + + return; + } + + // + // If we are provided an OutputStreamWrapper, we are expected to use it, and + // to providd a context. We are free to come up with our own context if we + // want, and use the AsciiTraceHelper Hook*WithContext functions, but for + // compatibility and simplicity, we just use Config::Connect and let it deal + // with the context. + // + // Note that we are going to use the default trace sinks provided by the + // ascii trace helper. There is actually no AsciiTraceHelper in sight here, + // but the default trace sinks are actually publicly available static + // functions that are always there waiting for just such a case. + // + uint32_t nodeid = nd->GetNode ()->GetId (); + uint32_t deviceid = nd->GetIfIndex (); + std::ostringstream oss; + + oss << "/NodeList/" << nd->GetNode ()->GetId () << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/MacRx"; + Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultReceiveSinkWithContext, stream)); + + oss.str (""); + oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Enqueue"; + Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultEnqueueSinkWithContext, stream)); + + oss.str (""); + oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Dequeue"; + Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDequeueSinkWithContext, stream)); + + oss.str (""); + oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Drop"; + Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDropSinkWithContext, stream)); + + oss.str (""); + oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/PhyRxDrop"; + Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDropSinkWithContext, stream)); +} + +NetDeviceContainer +MyPointToPointHelper::Install (NodeContainer c) +{ + NS_ASSERT (c.GetN () == 2); + return Install (c.Get (0), c.Get (1)); +} + +NetDeviceContainer +MyPointToPointHelper::Install (Ptr a, e_ns3_network_element_type_t type_a, Ptr b, e_ns3_network_element_type_t type_b) +{ + NetDeviceContainer container; + Ptr queueA; + Ptr queueB; + + Ptr devA = m_deviceFactory.Create (); + devA->SetAddress (Mac48Address::Allocate ()); + a->AddDevice (devA); + + if(type_a == NS3_NETWORK_ELEMENT_ROUTER){ + queueA = m_queueFactory_red.Create (); + } + else + queueA = m_queueFactory.Create (); + devA->SetQueue (queueA); + + Ptr devB = m_deviceFactory.Create (); + devB->SetAddress (Mac48Address::Allocate ()); + b->AddDevice (devB); + + if(type_b == NS3_NETWORK_ELEMENT_ROUTER){ + queueB = m_queueFactory_red.Create (); + } + else + queueB = m_queueFactory.Create (); + devB->SetQueue (queueB); + + // If MPI is enabled, we need to see if both nodes have the same system id + // (rank), and the rank is the same as this instance. If both are true, + //use a normal p2p channel, otherwise use a remote channel + bool useNormalChannel = true; + Ptr channel = 0; + if (MpiInterface::IsEnabled ()) + { + uint32_t n1SystemId = a->GetSystemId (); + uint32_t n2SystemId = b->GetSystemId (); + uint32_t currSystemId = MpiInterface::GetSystemId (); + if (n1SystemId != currSystemId || n2SystemId != currSystemId) + { + useNormalChannel = false; + } + } + if (useNormalChannel) + { + channel = m_channelFactory.Create (); + } + else + { + channel = m_remoteChannelFactory.Create (); + Ptr mpiRecA = CreateObject (); + Ptr mpiRecB = CreateObject (); + mpiRecA->SetReceiveCallback (MakeCallback (&PointToPointNetDevice::Receive, devA)); + mpiRecB->SetReceiveCallback (MakeCallback (&PointToPointNetDevice::Receive, devB)); + devA->AggregateObject (mpiRecA); + devB->AggregateObject (mpiRecB); + } + + devA->Attach (channel); + devB->Attach (channel); + container.Add (devA); + container.Add (devB); + + return container; +} + +NetDeviceContainer +MyPointToPointHelper::Install (Ptr a, Ptr b) +{ + NetDeviceContainer container; + + Ptr devA = m_deviceFactory.Create (); + devA->SetAddress (Mac48Address::Allocate ()); + a->AddDevice (devA); + Ptr queueA = m_queueFactory.Create (); + devA->SetQueue (queueA); + Ptr devB = m_deviceFactory.Create (); + devB->SetAddress (Mac48Address::Allocate ()); + b->AddDevice (devB); + Ptr queueB = m_queueFactory.Create (); + devB->SetQueue (queueB); + // If MPI is enabled, we need to see if both nodes have the same system id + // (rank), and the rank is the same as this instance. If both are true, + //use a normal p2p channel, otherwise use a remote channel + bool useNormalChannel = true; + Ptr channel = 0; + if (MpiInterface::IsEnabled ()) + { + uint32_t n1SystemId = a->GetSystemId (); + uint32_t n2SystemId = b->GetSystemId (); + uint32_t currSystemId = MpiInterface::GetSystemId (); + if (n1SystemId != currSystemId || n2SystemId != currSystemId) + { + useNormalChannel = false; + } + } + if (useNormalChannel) + { + channel = m_channelFactory.Create (); + } + else + { + channel = m_remoteChannelFactory.Create (); + Ptr mpiRecA = CreateObject (); + Ptr mpiRecB = CreateObject (); + mpiRecA->SetReceiveCallback (MakeCallback (&PointToPointNetDevice::Receive, devA)); + mpiRecB->SetReceiveCallback (MakeCallback (&PointToPointNetDevice::Receive, devB)); + devA->AggregateObject (mpiRecA); + devB->AggregateObject (mpiRecB); + } + + devA->Attach (channel); + devB->Attach (channel); + container.Add (devA); + container.Add (devB); + + return container; +} + +NetDeviceContainer +MyPointToPointHelper::Install (Ptr a, std::string bName) +{ + Ptr b = Names::Find (bName); + return Install (a, b); +} + +NetDeviceContainer +MyPointToPointHelper::Install (std::string aName, Ptr b) +{ + Ptr a = Names::Find (aName); + return Install (a, b); +} + +NetDeviceContainer +MyPointToPointHelper::Install (std::string aName, std::string bName) +{ + Ptr a = Names::Find (aName); + Ptr b = Names::Find (bName); + return Install (a, b); +} + +} // namespace ns3 diff --git a/src/surf/ns3/my-point-to-point-helper.h b/src/surf/ns3/my-point-to-point-helper.h new file mode 100644 index 0000000000..7edd931dad --- /dev/null +++ b/src/surf/ns3/my-point-to-point-helper.h @@ -0,0 +1,205 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * + * 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 + * + * Author: Mathieu Lacage + */ +#ifndef POINT_TO_POINT_HELPER_H +#define POINT_TO_POINT_HELPER_H + +#include + +#include "ns3/object-factory.h" +#include "ns3/net-device-container.h" +#include "ns3/node-container.h" +#include "ns3/deprecated.h" + +#include "ns3/trace-helper.h" + +#include "ns3_interface.h" + +namespace ns3 { + +class Queue; +class NetDevice; +class Node; + +/** + * \brief Build a set of PointToPointNetDevice objects + * + * Normally we eschew multiple inheritance, however, the classes + * PcapUserHelperForDevice and AsciiTraceUserHelperForDevice are + * "mixins". + */ +class MyPointToPointHelper : public PcapHelperForDevice, public AsciiTraceHelperForDevice +{ +public: + /** + * Create a MyPointToPointHelper to make life easier when creating point to + * point networks. + */ + MyPointToPointHelper (); + virtual ~MyPointToPointHelper () {} + + /** + * Each point to point net device must have a queue to pass packets through. + * This method allows one to set the type of the queue that is automatically + * created when the device is created and attached to a node. + * + * \param type the type of queue + * \param n1 the name of the attribute to set on the queue + * \param v1 the value of the attribute to set on the queue + * \param n2 the name of the attribute to set on the queue + * \param v2 the value of the attribute to set on the queue + * \param n3 the name of the attribute to set on the queue + * \param v3 the value of the attribute to set on the queue + * \param n4 the name of the attribute to set on the queue + * \param v4 the value of the attribute to set on the queue + * + * Set the type of queue to create and associated to each + * PointToPointNetDevice created through MyPointToPointHelper::Install. + */ + void SetQueue (std::string type, + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), + std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), + std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), + std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), + std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (), + std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue ()); + + /** + * Set an attribute value to be propagated to each NetDevice created by the + * helper. + * + * \param name the name of the attribute to set + * \param value the value of the attribute to set + * + * Set these attributes on each ns3::PointToPointNetDevice created + * by MyPointToPointHelper::Install + */ + void SetDeviceAttribute (std::string name, const AttributeValue &value); + + /** + * Set an attribute value to be propagated to each Channel created by the + * helper. + * + * \param name the name of the attribute to set + * \param value the value of the attribute to set + * + * Set these attribute on each ns3::PointToPointChannel created + * by MyPointToPointHelper::Install + */ + void SetChannelAttribute (std::string name, const AttributeValue &value); + + /** + * \param c a set of nodes + * + * This method creates a ns3::PointToPointChannel with the + * attributes configured by MyPointToPointHelper::SetChannelAttribute, + * then, for each node in the input container, we create a + * ns3::PointToPointNetDevice with the requested attributes, + * a queue for this ns3::NetDevice, and associate the resulting + * ns3::NetDevice with the ns3::Node and ns3::PointToPointChannel. + */ + NetDeviceContainer Install (NodeContainer c); + + /** + * \param a first node + * \param b second node + * + * Saves you from having to construct a temporary NodeContainer. + * Also, if MPI is enabled, for distributed simulations, + * appropriate remote point-to-point channels are created. + */ + NetDeviceContainer Install (Ptr a, Ptr b); + + /** + * \param a first node + * \param b second node + * + * Saves you from having to construct a temporary NodeContainer. + * Also, if MPI is enabled, for distributed simulations, + * appropriate remote point-to-point channels are created. + */ + NetDeviceContainer Install (Ptr a, e_ns3_network_element_type_t type_a, Ptr b, e_ns3_network_element_type_t type_b); + + /** + * \param a first node + * \param bName name of second node + * + * Saves you from having to construct a temporary NodeContainer. + */ + NetDeviceContainer Install (Ptr a, std::string bName); + + /** + * \param aName Name of first node + * \param b second node + * + * Saves you from having to construct a temporary NodeContainer. + */ + NetDeviceContainer Install (std::string aName, Ptr b); + + /** + * \param aNode Name of first node + * \param bNode Name of second node + * + * Saves you from having to construct a temporary NodeContainer. + */ + NetDeviceContainer Install (std::string aNode, std::string bNode); + +private: + /** + * \brief Enable pcap output the indicated net device. + * + * NetDevice-specific implementation mechanism for hooking the trace and + * writing to the trace file. + * + * \param prefix Filename prefix to use for pcap files. + * \param nd Net device for which you want to enable tracing. + * \param promiscuous If true capture all possible packets available at the device. + * \param explicitFilename Treat the prefix as an explicit filename if true + */ + virtual void EnablePcapInternal (std::string prefix, Ptr nd, bool promiscuous, bool explicitFilename); + + /** + * \brief Enable ascii trace output on the indicated net device. + * \internal + * + * NetDevice-specific implementation mechanism for hooking the trace and + * writing to the trace file. + * + * \param stream The output stream object to use when logging ascii traces. + * \param prefix Filename prefix to use for ascii trace files. + * \param nd Net device for which you want to enable tracing. + */ + virtual void EnableAsciiInternal ( + Ptr stream, + std::string prefix, + Ptr nd, + bool explicitFilename); + + ObjectFactory m_queueFactory; + ObjectFactory m_queueFactory_red; + ObjectFactory m_channelFactory; + ObjectFactory m_remoteChannelFactory; + ObjectFactory m_deviceFactory; +}; + +} // namespace ns3 + +#endif /* POINT_TO_POINT_HELPER_H */ diff --git a/src/surf/ns3/ns3_interface.cc b/src/surf/ns3/ns3_interface.cc index a748ce32d9..eed590cb9a 100644 --- a/src/surf/ns3/ns3_interface.cc +++ b/src/surf/ns3/ns3_interface.cc @@ -10,6 +10,7 @@ #include "xbt/log.h" #include "xbt/dynar.h" + using namespace ns3; extern xbt_lib_t host_lib; @@ -24,8 +25,6 @@ NodeContainer nodes; NodeContainer Cluster_nodes; Ipv4InterfaceContainer interfaces; - - int number_of_nodes = 0; int number_of_clusters_nodes = 0; int number_of_links = 1; @@ -103,6 +102,9 @@ int ns3_initialize(const char* TcpProtocol){ Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (1024)); // 1024-byte packet for easier reading Config::SetDefault ("ns3::TcpSocket::DelAckCount", UintegerValue (1)); +#ifdef _HAVE_NS3_RED + XBT_INFO("Using RED version of ns3"); +#endif if(!strcmp(TcpProtocol,"default")){ return 0; } @@ -227,14 +229,20 @@ static char* transformIpv4Address (Ipv4Address from){ return IPaddr; } -void * ns3_add_link(int src,int dst,char * bw,char * lat) +void * ns3_add_link(int src, e_ns3_network_element_type_t type_src, + int dst, e_ns3_network_element_type_t type_dst, + char * bw,char * lat) { if(number_of_links == 1 ) { LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); } +#ifdef _HAVE_NS3_RED + MyPointToPointHelper pointToPoint; +#else PointToPointHelper pointToPoint; +#endif NetDeviceContainer netA; Ipv4AddressHelper address; @@ -246,7 +254,11 @@ void * ns3_add_link(int src,int dst,char * bw,char * lat) pointToPoint.SetChannelAttribute ("Delay", StringValue (lat)); //pointToPoint.EnablePcapAll("test_ns3_trace"); //DEBUG +#ifdef _HAVE_NS3_RED + netA.Add(pointToPoint.Install (a, type_src, b, type_dst)); +#else netA.Add(pointToPoint.Install (a, b)); +#endif char * adr = bprintf("%d.%d.0.0",number_of_networks,number_of_links); address.SetBase (adr, "255.255.0.0"); diff --git a/src/surf/ns3/ns3_interface.h b/src/surf/ns3/ns3_interface.h index 1eb29ea2e7..15f847db8f 100644 --- a/src/surf/ns3/ns3_interface.h +++ b/src/surf/ns3/ns3_interface.h @@ -42,7 +42,9 @@ XBT_PUBLIC(void *) ns3_add_host(char * id); XBT_PUBLIC(void *) ns3_add_host_cluster(char * id); XBT_PUBLIC(void *) ns3_add_router(char * id); XBT_PUBLIC(void *) ns3_add_AS(char * id); -XBT_PUBLIC(void *) ns3_add_link(int src,int dst,char * bw,char * lat); +XBT_PUBLIC(void *) ns3_add_link(int src, e_ns3_network_element_type_t type_src, + int dst, e_ns3_network_element_type_t type_dst, + char * bw,char * lat); XBT_PUBLIC(void *) ns3_end_platform(void); XBT_PUBLIC(void *) ns3_add_cluster(char * bw,char * lat,char *id); #ifdef __cplusplus diff --git a/src/surf/ns3/ns3_simulator.h b/src/surf/ns3/ns3_simulator.h index 4f91f1aca5..503a7d593f 100644 --- a/src/surf/ns3/ns3_simulator.h +++ b/src/surf/ns3/ns3_simulator.h @@ -10,6 +10,9 @@ #ifdef __cplusplus #include "ns3/core-module.h" +#ifdef _HAVE_NS3_RED +#include "my-point-to-point-helper.h" +#endif #ifdef _NS3_3_10 /*NS3 3.10*/ @@ -29,6 +32,7 @@ #include "ns3/point-to-point-helper.h" #include "ns3/packet-sink-helper.h" #include "ns3/inet-socket-address.h" + #include "ns3/tcp-socket-factory.h" #endif using namespace ns3; -- 2.20.1