recent version of both SimGrid and ns-3. While the Debian package of SimGrid
don't have the ns-3 bindings activated, you can still use the packaged version
of ns-3 by grabbing the ``libns3-dev ns3`` packages. Alternatively, you can
-install ns-3 from scratch as follows:
-
-.. code-block:: shell
-
- # Download the source
- wget http://www.nsnam.org/release/ns-allinone-3.29.tar.bz2
- tar -xf ns-allinone-3.29.tar.bz2
- cd ns-allinone-3.29/ns-3.29/
- # Configure, build and install
- ./waf configure --prefix="/opt/ns3" # or give another path if you prefer
- ./waf
- ./waf install
-
-For more information, please refer to the ns-3 documentation
-(`official website <http://www.nsnam.org>`_).
+install ns-3 from scratch (see the `ns-3 documentation <http://www.nsnam.org>`_).
Enabling ns-3 in SimGrid
========================
SimGrid must be recompiled with the ``enable_ns3`` option activated in cmake.
-Optionally, use ``NS3_HINT`` to hint cmake about where to find ns-3.
+Optionally, use ``NS3_HINT`` to tell cmake where ns3 is installed on
+your disk.
.. code-block:: shell
Using ns-3 from SimGrid
***********************
--The SimGrid/ns-3 binding only contains features that are common to both
- systems: ns-3 wireless models are not available, while SimGrid routes
- cannot be longer than 1. Also, the platform built in ns-3 from the
-systems. Also, the platform built in ns-3 from the
--SimGrid description is very basic.
++The SimGrid/ns-3 binding only contains features that are common to
++both systems. Not all ns-3 models are available (only the TCP and wifi
++ones are), while not all SimGrid platform file can be used with ns-3
++(routes must be of length 1). Also, the platform built in ns-3 from
++the SimGrid description is very basic.
Platform files compatibility
============================
Any route longer than one will be ignored when using ns-3. They are
harmless, but you still need to connect your hosts using one-hop routes.
The best solution is to add routers to split your route. Here is an
-example of invalid platform:
+example of an invalid platform:
.. code-block:: shell
- <platform>
- <zone id="zone0" routing="Full">
- <?xml version='1.0'?><!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd">
- <platform version="4.1">
- <AS id="AS0" routing="Floyd">
-
- <host id="alice" speed="1Gf" />
- <host id="bob" speed="1Gf" />
-
- <link id="l1" bandwidth="1Mbps" latency="5ms" />
- <link id="l2" bandwidth="1Mbps" latency="5ms" />
-
- <route src="alice" dst="bob">
- <link_ctn id="l1"/> <!-- !!!! INVALID WITH ns-3 !!!! -->
- <link_ctn id="l2"/> <!-- !!!! length=2 IS TOO MUCH !!!! -->
- </route>
- </AS>
- </platform>
-
++ <?xml version='1.0'?>
++ <!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
++ <platform version="4.1">
++ <zone id="zone0" routing="Floyd">
+ <host id="alice" speed="1Gf" />
+ <host id="bob" speed="1Gf" />
+
- <link id="l1" bw="1Mbps" />
- <link id="l2" bw="1Mbps" />
++ <link id="l1" bandwidth="1Mbps" latency="5ms" />
++ <link id="l2" bandwidth="1Mbps" latency="5ms" />
+
+ <route src="alice" dst="bob">
+ <link_ctn id="l1"/> <!-- !!!! INVALID WITH ns-3 !!!! -->
+ <link_ctn id="l2"/> <!-- !!!! length=2 IS TOO MUCH !!!! -->
+ </route>
+ </zone>
+ </platform>
+
This can be reformulated as follows to make it usable with the ns-3 binding.
There is no direct connection from alice to bob, but that's OK because
ns-3 automatically routes from point to point.
.. code-block:: shell
- <platform>
- <?xml version='1.0'?><!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd">
- <platform version="4.1">
- <AS id="AS0" routing="Floyd">
++ <?xml version='1.0'?>
++ <!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
++ <platform version="4.1">
+ <zone id="zone0" routing="Full">
+ <host id="alice" speed="1Gf" />
+ <host id="bob" speed="1Gf" />
- <host id="alice" speed="1Gf"/>
- <host id="bob" speed="1Gf"/>
+ <router id="r1" /> <!-- routers are compute-less hosts -->
- <link id="l1" bw="1Mbps" />
- <link id="l2" bw="1Mbps" />
- <router id="r1"/> <!-- routers are compute-less hosts -->
++ <link id="l1" bandwidth="1Mbps" latency="5ms"/>
++ <link id="l2" bandwidth="1Mbps" latency="5ms"/>
- <link id="l1" bandwidth="1Mbps" latency="5ms"/>
- <link id="l2" bandwidth="1Mbps" latency="5ms"/>
-
- <route src="alice" dst="r1">
- <link_ctn id="l1"/>
- </route>
-
- <route src="r1" dst="bob">
- <link_ctn id="l2"/>
- </route>
- </AS>
- </platform>
+ <route src="alice" dst="r1">
+ <link_ctn id="l1"/>
+ </route>
+
+ <route src="r1" dst="bob">
+ <link_ctn id="l2"/>
+ </route>
+ </zone>
+ </platform>
Once your platform is OK, just change the :ref:`network/model
- <options_model_select>` configuration option to "ns-3" as follows. The rest
+ <options_model_select>`_ configuration option to "ns-3" as follows. The rest
is unchanged.
.. code-block:: shell
./network-ns3 --cfg=network/model:ns-3 (other parameters)
Many other files from the ``examples/platform directory`` are usable with the
-ns-3 model.
+ns-3 model, such as `examples/platforms/dogbone.xml <https://framagit.org/simgrid/simgrid/tree/master/examples/platforms/dogbone.xml>`_.
+Check the file `examples/s4u/network-ns3/network-ns3.tesh <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/network-ns3/network-ns3.tesh>`_
+to see which ones are used in our regression tests.
-between two simgrid hosts.
+ Build a wifi-compatible platform
+ ===================================
+
+ We describe here a simple platform allowing ns3 wifi communication
- <?xml version='1.0'?><!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd">
++between two SimGrid hosts.
+
+ First, here are the mandatory information necessary to create a
+ simgrid platform:
+
+ .. code-block:: shell
+
- <AS id="AS0" routing="Floyd">
++ <?xml version='1.0'?>
++ <!DOCTYPE platform SYSTEM "http://simgrid.org/simgrid.dtd">
+ <platform version="4.1">
-.. code-block:: shell``
++ <zone id="zone" routing="Floyd">
+
+ Then, we create our access point and station hosts:
+
+ .. code-block:: shell
+
+ <host id="alice" speed="1Gf"/>
+ <host id="bob" speed="1Gf"/>
+
+ We must specify that alice will be our access point. To do that we
+ simply add the property ``wifi_link`` to the host ``alice``:
+
+ .. code-block:: shell
+
+ <host id="alice" speed="1Gf">
+ <prop id="wifi_link" value="net0"/>
+ </host>
+
+ <host id="bob" speed="1Gf"/>
+
+ The value ``net0`` of this property defines the name of the wifi network
+ generated. To generate this wifi network we create a wifi link:
+
- </AS>
++.. code-block:: shell
+
+ <link id="net0" bandwidth="0" latency="0" sharing_policy="WIFI"/>
+
+ The important information here are:
+ * The id of the link, ``net0``, must match the network name defined by the property ``wifi_link`` of the access point node
+ * The sharing policy must be set to ``WIFI``
+
+ Note: bandwidth and latency are mandatory by simgrid to create a link but are NOT used to create a wifi network. Instead the
+ wifi network capabilities are defined by its MCS, NSS and distance from access point to station. Those properties are described in section :ref:`Optional access point node properties <optional_prop>`_
+
+ To connect the station node to the access point node, we
+ create a route between the hosts:
+
+ .. code-block:: shell
+
+ <route src="alice" dst="bob">
+ <link_ctn id="net0" />
+ </route>
+
+ Finally, we end the xml file with the missing closing tags:
+
+ .. code-block:: shell
+
++ </zone>
+ </platform>
+
+ .. _optional_prop:
+
+ Optional access point node properties
+ --------------------------------------
+
+ The MCS (`Modulation and Coding Scheme <https://en.wikipedia.org/wiki/Link_adaptation>`_) can be set with the property ``wifi_mcs``:
+
+ .. code-block:: shell
+
+ <host id="alice" speed="1Gf">
+ <prop id="wifi_link" value="net0"/>
+ <prop id="wifi_mcs" value="5"/>
+ </host>
+
+ Its default value is 3.
+
+ The NSS (Number of Spatial Streams, also known as the `number of antennas <https://en.wikipedia.org/wiki/IEEE_802.11n-2009#Number_of_antennas>`_) can be set with the property ``wifi_nss``:
+
+ .. code-block:: shell
+
+ <host id="alice" speed="1Gf">
+ <prop id="wifi_link" value="net0"/>
+ <prop id="wifi_nss" value="2"/>
+ </host>
+
+ Its default value is 1.
+
+ Note: not all value of MCS and NSS are valid nor compatible. Check `802.11n standard <https://en.wikipedia.org/wiki/IEEE_802.11n-2009#Data_rates>`_ for more information.
+
+ Optional station node properties
+ ---------------------------------
+
+ The distance in meter at which the station is placed from the access point can
+ be set with the property ``wifi_distance``.
+
+ .. code-block:: shell
+
+ <host id="alice" speed="100.0Mf,50.0Mf,20.0Mf" pstate="0">
+ <prop id="wifi_distance" value="30" />
+ </host>
+
+ Its default value is 10.
+
Limitations
===========
A ns-3 platform is automatically created from the provided SimGrid
platform. However, there are some known caveats:
- * The default values (e.g., TCP parameters) are the ns-3 default values.
- * ns-3 networks are routed using the shortest path algorithm, using
- ``ns3::Ipv4GlobalRoutingHelper::PopulateRoutingTables``.
- * End hosts cannot have more than one interface card. So, your
- SimGrid hosts should be connected to the platform through only
- one link. Otherwise, your SimGrid host will be considered as a
- router.
-
+ * The default values (e.g., TCP parameters) are the ns-3 default values.
+ * ns-3 networks are routed using the shortest path algorithm, using
+ ``ns3::Ipv4GlobalRoutingHelper::PopulateRoutingTables``.
-
++ * End hosts cannot have more than one interface card. So, your
++ SimGrid hosts should be connected to the platform through only
++ one link. Otherwise, your SimGrid host will be considered as a
++ router (FIXME: is it still true?).
++
Our goal is to keep the ns-3 plugin of SimGrid as easy (and hopefully readable)
as possible. If the current state does not fit your needs, you should modify
this plugin, and/or create your own plugin from the existing one. If you come up
#include <ns3/application-container.h>
#include <ns3/event-id.h>
-#include "ns3/wifi-module.h"
+ #include "ns3/mobility-module.h"
++#include "ns3/wifi-module.h"
+
#include "network_ns3.hpp"
#include "ns3/ns3_simulator.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ns3, surf, "Logging specific to the SURF network ns-3 module");
-std::vector<std::string> IPV4addr;
-static std::string transformIpv4Address(ns3::Ipv4Address from);
-
/*****************
* Crude globals *
*****************/
extern std::map<std::string, ns3::ApplicationContainer> sink_from_sock;
static ns3::InternetStackHelper stack;
-static ns3::NodeContainer nodes;
-static ns3::NodeContainer Cluster_nodes;
-static ns3::Ipv4InterfaceContainer interfaces;
-static int number_of_nodes = 0;
-static int number_of_clusters_nodes = 0;
static int number_of_links = 1;
static int number_of_networks = 1;
-static ns3::YansWifiPhyHelper wifiPhy = ns3::YansWifiPhyHelper::Default ();
-static ns3::YansWifiChannelHelper wifiChannel = ns3::YansWifiChannelHelper::Default ();
+ /* wifi globals */
+ static ns3::WifiHelper wifi;
++static ns3::YansWifiPhyHelper wifiPhy = ns3::YansWifiPhyHelper::Default();
++static ns3::YansWifiChannelHelper wifiChannel = ns3::YansWifiChannelHelper::Default();
+ static ns3::WifiMacHelper wifiMac;
+ static ns3::MobilityHelper mobility;
+
simgrid::xbt::Extension<simgrid::kernel::routing::NetPoint, NetPointNs3> NetPointNs3::EXTENSION_ID;
++static std::string transformIpv4Address(ns3::Ipv4Address from)
++{
++ std::stringstream sstream;
++ sstream << from;
++ return sstream.str();
++}
++
NetPointNs3::NetPointNs3() : ns3_node_(ns3::CreateObject<ns3::Node>(0))
{
stack.Install(ns3_node_);
- nodes.Add(ns3_node_);
- node_num = number_of_nodes++;
}
- ns3::Ptr<ns3::YansWifiChannel> channel_, int mcs_, int nss_, int network_, int link_) :
- name(name_), host(host_), ap_node(ap_node_), channel(channel_), mcs(mcs_), nss(nss_),
- network(network_), link(link_) {
- n_sta_nodes = 0;
- wifi_zones[name_] = this;
+ WifiZone::WifiZone(std::string name_, simgrid::s4u::Host* host_, ns3::Ptr<ns3::Node> ap_node_,
-bool WifiZone::is_ap(ns3::Ptr<ns3::Node> node){
- for (std::pair<std::string, WifiZone*> zone : wifi_zones)
- if (zone.second->get_ap_node() == node)
- return true;
- return false;
++ ns3::Ptr<ns3::YansWifiChannel> channel_, int mcs_, int nss_, int network_, int link_)
++ : name(name_)
++ , host(host_)
++ , ap_node(ap_node_)
++ , channel(channel_)
++ , mcs(mcs_)
++ , nss(nss_)
++ , network(network_)
++ , link(link_)
++{
++ n_sta_nodes = 0;
++ wifi_zones[name_] = this;
+ }
+
-WifiZone* WifiZone::by_name(std::string name) {
- WifiZone* zone;
- try {
- zone = wifi_zones.at(name);
- }
- catch (const std::out_of_range& oor) {
- return nullptr;
- }
- return zone;
++bool WifiZone::is_ap(ns3::Ptr<ns3::Node> node)
++{
++ for (std::pair<std::string, WifiZone*> zone : wifi_zones)
++ if (zone.second->get_ap_node() == node)
++ return true;
++ return false;
+ }
+
-static void initialize_ns3_wifi() {
- wifi.SetStandard (ns3::WIFI_PHY_STANDARD_80211n_5GHZ);
++WifiZone* WifiZone::by_name(std::string name)
++{
++ WifiZone* zone;
++ try {
++ zone = wifi_zones.at(name);
++ } catch (const std::out_of_range& oor) {
++ return nullptr;
++ }
++ return zone;
+ }
+
+ std::unordered_map<std::string, WifiZone*> WifiZone::wifi_zones;
+
- for (auto host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) {
- const char* wifi_link = host->get_property("wifi_link");
- const char* wifi_mcs = host->get_property("wifi_mcs");
- const char* wifi_nss = host->get_property("wifi_nss");
++static void initialize_ns3_wifi()
++{
++ wifi.SetStandard(ns3::WIFI_PHY_STANDARD_80211n_5GHZ);
+
- if (wifi_link)
- new WifiZone(wifi_link, host, host->get_netpoint()->extension<NetPointNs3>()->ns3_node_,
- wifiChannel.Create (), wifi_mcs ? atoi(wifi_mcs) : 3, wifi_nss ? atoi(wifi_nss) : 1, 0, 0);
- }
++ for (auto host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) {
++ const char* wifi_link = host->get_property("wifi_link");
++ const char* wifi_mcs = host->get_property("wifi_mcs");
++ const char* wifi_nss = host->get_property("wifi_nss");
+
++ if (wifi_link)
++ new WifiZone(wifi_link, host, host->get_netpoint()->extension<NetPointNs3>()->ns3_node_, wifiChannel.Create(),
++ wifi_mcs ? atoi(wifi_mcs) : 3, wifi_nss ? atoi(wifi_nss) : 1, 0, 0);
++ }
+ }
+
/*************
* Callbacks *
*************/
static void clusterCreation_cb(simgrid::kernel::routing::ClusterCreationArgs const& cluster)
{
- for (int const& i : *cluster.radicals) {
- // Routers don't create a router on the other end of the private link by themselves.
- // We just need this router to be given an ID so we create a temporary NetPointNS3 so that it gets one
- auto* host_dst = new NetPointNs3();
+ ns3::NodeContainer Nodes;
+ for (int const& i : *cluster.radicals) {
// Create private link
std::string host_id = cluster.prefix + std::to_string(i) + cluster.suffix;
- auto* host_src = simgrid::s4u::Host::by_name(host_id)->get_netpoint()->extension<NetPointNs3>();
- xbt_assert(host_src, "Cannot find a ns-3 host of name %s", host_id.c_str());
+ auto* src = simgrid::s4u::Host::by_name(host_id)->get_netpoint();
+ auto* dst = simgrid::s4u::Engine::get_instance()->netpoint_by_name_or_null(cluster.router_id);
+ xbt_assert(dst != nullptr, "No router named %s", cluster.router_id.c_str());
- ns3_add_direct_route(src, dst, cluster.bw, cluster.lat, cluster.sharing_policy); // Any ns-3 route is symmetrical
- // Any ns-3 route is symmetrical
- ns3_add_direct_route(host_src, host_dst, cluster.bw, cluster.lat, cluster.id, cluster.sharing_policy);
++ ns3_add_direct_route(src, dst, cluster.bw, cluster.lat, cluster.id,
++ cluster.sharing_policy); // Any ns-3 route is symmetrical
- delete host_dst;
+ // Also add the host to the list of hosts that will be connected to the backbone
+ Nodes.Add(src->extension<NetPointNs3>()->ns3_node_);
}
- //Create link backbone
- ns3_add_cluster(cluster.id.c_str(), cluster.bb_bw, cluster.bb_lat);
+ // Create link backbone
+
+ xbt_assert(Nodes.GetN() <= 65000, "Cluster with ns-3 is limited to 65000 nodes");
+ ns3::CsmaHelper csma;
+ csma.SetChannelAttribute("DataRate",
+ ns3::DataRateValue(ns3::DataRate(cluster.bb_bw * 8))); // ns-3 takes bps, but we provide Bps
+ csma.SetChannelAttribute("Delay", ns3::TimeValue(ns3::Seconds(cluster.bb_lat)));
+ ns3::NetDeviceContainer devices = csma.Install(Nodes);
+ XBT_DEBUG("Create CSMA");
+
+ std::string addr = simgrid::xbt::string_printf("%d.%d.0.0", number_of_networks, number_of_links);
+ XBT_DEBUG("Assign IP Addresses %s to CSMA.", addr.c_str());
+ ns3::Ipv4AddressHelper ipv4;
+ ipv4.SetBase(addr.c_str(), "255.255.0.0");
+ ipv4.Assign(devices);
+
+ if (number_of_links == 255) {
+ xbt_assert(number_of_networks < 255, "Number of links and networks exceed 255*255");
+ number_of_links = 1;
+ number_of_networks++;
+ } else {
+ number_of_links++;
+ }
}
static void routeCreation_cb(bool symmetrical, simgrid::kernel::routing::NetPoint* src,
// XBT_DEBUG("src (%s), dst (%s), src_id = %d, dst_id = %d",src,dst, src_id, dst_id);
XBT_DEBUG("\tLink (%s) bw:%fbps lat:%fs", link->get_cname(), link->get_bandwidth(), link->get_latency());
- ns3_add_direct_route(src, dst, link->get_bandwidth(), link->get_latency(), link->get_sharing_policy());
- // create link ns3
- auto* host_src = src->extension<NetPointNs3>();
- auto* host_dst = dst->extension<NetPointNs3>();
-
- host_src->set_name(src->get_name());
- host_dst->set_name(dst->get_name());
-
- xbt_assert(host_src != nullptr, "Network element %s does not seem to be ns-3-ready", src->get_cname());
- xbt_assert(host_dst != nullptr, "Network element %s does not seem to be ns-3-ready", dst->get_cname());
-
- ns3_add_direct_route(host_src, host_dst, link->get_bandwidth(), link->get_latency(), link->get_name(), link->get_sharing_policy());
++ ns3_add_direct_route(src, dst, link->get_bandwidth(), link->get_latency(), link->get_name(),
++ link->get_sharing_policy());
} else {
static bool warned_about_long_routes = false;
}
}
-/* Create the ns3 topology based on routing strategy */
-static void postparse_cb()
-{
- IPV4addr.shrink_to_fit();
- ns3::GlobalRouteManager::BuildGlobalRoutingDatabase();
- ns3::GlobalRouteManager::InitializeRoutes();
-}
-
/*********
* Model *
*********/
NetPointNs3::EXTENSION_ID = routing::NetPoint::extension_create<NetPointNs3>();
- ns3_initialize(ns3_tcp_model.get());
+ ns3::Config::SetDefault("ns3::TcpSocket::SegmentSize", ns3::UintegerValue(1000));
+ ns3::Config::SetDefault("ns3::TcpSocket::DelAckCount", ns3::UintegerValue(1));
+ ns3::Config::SetDefault("ns3::TcpSocketBase::Timestamp", ns3::BooleanValue(false));
+
+ auto TcpProtocol = ns3_tcp_model.get();
+ if (TcpProtocol == "default") {
+ /* nothing to do */
+
+ } else if (TcpProtocol == "Reno" || TcpProtocol == "NewReno" || TcpProtocol == "Tahoe") {
+ XBT_INFO("Switching Tcp protocol to '%s'", TcpProtocol.c_str());
+ ns3::Config::SetDefault("ns3::TcpL4Protocol::SocketType", ns3::StringValue("ns3::Tcp" + TcpProtocol));
+
+ } else {
+ xbt_die("The ns3/TcpModel must be: NewReno or Reno or Tahoe");
+ }
routing::NetPoint::on_creation.connect([](routing::NetPoint& pt) {
pt.extension_set<NetPointNs3>(new NetPointNs3());
- XBT_VERB("SimGrid's %s is known as node %d within ns-3", pt.get_cname(), pt.extension<NetPointNs3>()->node_num);
+ XBT_VERB("Declare SimGrid's %s within ns-3", pt.get_cname());
});
- routing::on_cluster_creation.connect(&clusterCreation_cb);
- s4u::Engine::on_platform_created.connect(&postparse_cb);
+ s4u::Engine::on_platform_created.connect([]() {
+ /* Create the ns3 topology based on routing strategy */
+ ns3::GlobalRouteManager::BuildGlobalRoutingDatabase();
+ ns3::GlobalRouteManager::InitializeRoutes();
+ });
+ routing::on_cluster_creation.connect(&clusterCreation_cb);
s4u::NetZone::on_route_creation.connect(&routeCreation_cb);
}
-NetworkNS3Model::~NetworkNS3Model() {
- IPV4addr.clear();
-}
-
LinkImpl* NetworkNS3Model::create_link(const std::string& name, const std::vector<double>& bandwidths, double latency,
s4u::Link::SharingPolicy policy)
{
return -1.0;
XBT_DEBUG("doing a ns3 simulation for a duration of %f", now);
- ns3_simulator(now);
+ ns3_simulator(now);
time_to_next_flow_completion = ns3::Simulator::Now().GetSeconds() - surf_get_clock();
// NS-3 stops as soon as a flow ends,
// but it does not process the other flows that may finish at the same (simulated) time.
// If another flow ends at the same time, time_to_next_flow_completion = 0
if(double_equals(time_to_next_flow_completion, 0, sg_surf_precision))
- time_to_next_flow_completion = 0.0;
-
+ time_to_next_flow_completion = 0.0;
+
XBT_DEBUG("min : %f", now);
XBT_DEBUG("ns3 time : %f", ns3::Simulator::Now().GetSeconds());
XBT_DEBUG("surf time : %f", surf_get_clock());
LinkNS3::LinkNS3(NetworkNS3Model* model, const std::string& name, double bandwidth, double latency,
s4u::Link::SharingPolicy policy)
- : LinkImpl(model, name, nullptr)
+ : LinkImpl(model, name, nullptr), sharing_policy_(policy)
{
bandwidth_.peak = bandwidth;
latency_.peak = latency;
- sharing_policy_ = policy;
+
+ /* If wifi, create the wifizone now. If not, don't do anything: the links will be created in routeCreate_cb */
- static bool wifi_init = false;
- if (!wifi_init) {
- initialize_ns3_wifi();
- wifi_init = true;
- }
-
- ns3::NetDeviceContainer netA;
- WifiZone* zone = WifiZone::by_name(name);
- xbt_assert(zone != 0, "Link name '%s' does not match the 'wifi_link' property of a host.", name.c_str());
- NetPointNs3* netpoint_ns3 = zone->get_host()->get_netpoint()->extension<NetPointNs3>();
-
- wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
- "ControlMode", ns3::StringValue ("HtMcs0"),
- "DataMode", ns3::StringValue ("HtMcs" + std::to_string(zone->get_mcs())));
-
- wifiPhy.SetChannel (zone->get_channel());
- wifiPhy.Set("Antennas", ns3::UintegerValue(zone->get_nss()));
- wifiPhy.Set("MaxSupportedTxSpatialStreams", ns3::UintegerValue(zone->get_nss()));
- wifiPhy.Set("MaxSupportedRxSpatialStreams", ns3::UintegerValue(zone->get_nss()));
-
- wifiMac.SetType("ns3::ApWifiMac");
-
- netA.Add(wifi.Install (wifiPhy, wifiMac, zone->get_ap_node()));
-
- ns3::Ptr<ns3::ListPositionAllocator> positionAllocS = ns3::CreateObject<ns3::ListPositionAllocator> ();
- positionAllocS->Add(ns3::Vector(0, 0, 0));
- mobility.SetPositionAllocator(positionAllocS);
- mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
- mobility.Install(zone->get_ap_node());
-
- ns3::Ipv4AddressHelper address;
- std::string addr = simgrid::xbt::string_printf("%d.%d.0.0", number_of_networks, number_of_links);
- address.SetBase(addr.c_str(), "255.255.0.0");
- XBT_DEBUG("\tInterface stack '%s'", addr.c_str());
- interfaces.Add(address.Assign (netA));
- zone->set_network(number_of_networks);
- zone->set_link(number_of_links);
-
- int nodeNum = netpoint_ns3->node_num;
- if (IPV4addr.size() <= (unsigned)nodeNum)
- IPV4addr.resize(nodeNum + 1);
- IPV4addr[nodeNum] = transformIpv4Address(interfaces.GetAddress(interfaces.GetN() - 1));
-
- if (number_of_links == 255){
- xbt_assert(number_of_networks < 255, "Number of links and networks exceed 255*255");
- number_of_links = 1;
- number_of_networks++;
- } else {
- number_of_links++;
- }
+ if (policy == simgrid::s4u::Link::SharingPolicy::WIFI) {
++ static bool wifi_init = false;
++ if (!wifi_init) {
++ initialize_ns3_wifi();
++ wifi_init = true;
++ }
++
++ ns3::NetDeviceContainer netA;
++ WifiZone* zone = WifiZone::by_name(name);
++ xbt_assert(zone != 0, "Link name '%s' does not match the 'wifi_link' property of a host.", name.c_str());
++ NetPointNs3* netpoint_ns3 = zone->get_host()->get_netpoint()->extension<NetPointNs3>();
++
++ wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "ControlMode", ns3::StringValue("HtMcs0"), "DataMode",
++ ns3::StringValue("HtMcs" + std::to_string(zone->get_mcs())));
++
++ wifiPhy.SetChannel(zone->get_channel());
++ wifiPhy.Set("Antennas", ns3::UintegerValue(zone->get_nss()));
++ wifiPhy.Set("MaxSupportedTxSpatialStreams", ns3::UintegerValue(zone->get_nss()));
++ wifiPhy.Set("MaxSupportedRxSpatialStreams", ns3::UintegerValue(zone->get_nss()));
++
++ wifiMac.SetType("ns3::ApWifiMac");
++
++ netA.Add(wifi.Install(wifiPhy, wifiMac, zone->get_ap_node()));
++
++ ns3::Ptr<ns3::ListPositionAllocator> positionAllocS = ns3::CreateObject<ns3::ListPositionAllocator>();
++ positionAllocS->Add(ns3::Vector(0, 0, 0));
++ mobility.SetPositionAllocator(positionAllocS);
++ mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
++ mobility.Install(zone->get_ap_node());
++
++ ns3::Ipv4AddressHelper address;
++ std::string addr = simgrid::xbt::string_printf("%d.%d.0.0", number_of_networks, number_of_links);
++ address.SetBase(addr.c_str(), "255.255.0.0");
++ XBT_DEBUG("\tInterface stack '%s'", addr.c_str());
++ auto addresses = address.Assign(netA);
++ zone->set_network(number_of_networks);
++ zone->set_link(number_of_links);
++
++ netpoint_ns3->ipv4_address_ = transformIpv4Address(addresses.GetAddress(addresses.GetN() - 1));
++
++ if (number_of_links == 255) {
++ xbt_assert(number_of_networks < 255, "Number of links and networks exceed 255*255");
++ number_of_links = 1;
++ number_of_networks++;
++ } else {
++ number_of_links++;
++ }
+ }
s4u::Link::on_creation(*this->get_iface());
}
static int port_number = 1025; // Port number is limited from 1025 to 65 000
- unsigned int node1 = src->get_netpoint()->extension<NetPointNs3>()->node_num;
- unsigned int node2 = dst->get_netpoint()->extension<NetPointNs3>()->node_num;
-
ns3::Ptr<ns3::Node> src_node = src->get_netpoint()->extension<NetPointNs3>()->ns3_node_;
ns3::Ptr<ns3::Node> dst_node = dst->get_netpoint()->extension<NetPointNs3>()->ns3_node_;
- xbt_assert(node2 < IPV4addr.size(), "Element %s is unknown to ns-3. Is it connected to any one-hop link?",
- dst->get_netpoint()->get_cname());
- std::string& addr = IPV4addr[node2];
+ std::string& addr = dst->get_netpoint()->extension<NetPointNs3>()->ipv4_address_;
xbt_assert(not addr.empty(), "Element %s is unknown to ns-3. Is it connected to any one-hop link?",
dst->get_netpoint()->get_cname());
- XBT_DEBUG("ns3: Create flow of %.0f Bytes from %u to %u with Interface %s", totalBytes, node1, node2, addr.c_str());
+ XBT_DEBUG("ns3: Create flow of %.0f Bytes from %s to %s with Interface %s", totalBytes, src->get_cname(),
+ dst->get_cname(), addr.c_str());
ns3::PacketSinkHelper sink("ns3::TcpSocketFactory", ns3::InetSocketAddress(ns3::Ipv4Address::GetAny(), port_number));
ns3::ApplicationContainer apps = sink.Install(dst_node);
port_number = 1025;
XBT_WARN("Too many connections! Port number is saturated. Trying to use the oldest ports.");
}
- xbt_assert(port_number <= 65000, "Too many connections! Port number is saturated.");
s4u::Link::on_communicate(*this);
}
void ns3_simulator(double maxSeconds)
{
- ns3::EventId id;
+ ns3::EventId id;
if (maxSeconds > 0.0) // If there is a maximum amount of time to run
id = ns3::Simulator::Schedule(ns3::Seconds(maxSeconds), &ns3::Simulator::Stop);
id.Cancel();
}
-// initialize the ns-3 interface and environment
-void ns3_initialize(std::string TcpProtocol)
-{
- // tcpModel are:
- // "ns3::TcpNewReno"
- // "ns3::TcpReno"
- // "ns3::TcpTahoe"
-
- ns3::Config::SetDefault ("ns3::TcpSocket::SegmentSize", ns3::UintegerValue (1000));
- ns3::Config::SetDefault ("ns3::TcpSocket::DelAckCount", ns3::UintegerValue (1));
- ns3::Config::SetDefault ("ns3::TcpSocketBase::Timestamp", ns3::BooleanValue (false));
-
- if (TcpProtocol == "default") {
- /* nothing to do */
-
- } else if (TcpProtocol == "Reno") {
- XBT_INFO("Switching Tcp protocol to '%s'", TcpProtocol.c_str());
- ns3::Config::SetDefault ("ns3::TcpL4Protocol::SocketType", ns3::StringValue("ns3::TcpReno"));
-
- } else if (TcpProtocol == "NewReno") {
- XBT_INFO("Switching Tcp protocol to '%s'", TcpProtocol.c_str());
- ns3::Config::SetDefault ("ns3::TcpL4Protocol::SocketType", ns3::StringValue("ns3::TcpNewReno"));
-
- } else if (TcpProtocol == "Tahoe") {
- XBT_INFO("Switching Tcp protocol to '%s'", TcpProtocol.c_str());
- ns3::Config::SetDefault ("ns3::TcpL4Protocol::SocketType", ns3::StringValue("ns3::TcpTahoe"));
-
- } else {
- xbt_die("The ns3/TcpModel must be: NewReno or Reno or Tahoe");
- }
-}
-
-void ns3_add_cluster(const char* /*id*/, double bw, double lat)
-{
- ns3::NodeContainer Nodes;
-
- for (unsigned int i = number_of_clusters_nodes; i < Cluster_nodes.GetN(); i++) {
- Nodes.Add(Cluster_nodes.Get(i));
- XBT_DEBUG("Add node %u to cluster", i);
- }
- number_of_clusters_nodes = Cluster_nodes.GetN();
-
- XBT_DEBUG("Add router %u to cluster", nodes.GetN() - Nodes.GetN() - 1);
- Nodes.Add(nodes.Get(nodes.GetN()-Nodes.GetN()-1));
-
- xbt_assert(Nodes.GetN() <= 65000, "Cluster with ns-3 is limited to 65000 nodes");
- ns3::CsmaHelper csma;
- csma.SetChannelAttribute("DataRate", ns3::DataRateValue(ns3::DataRate(bw * 8))); // ns-3 takes bps, but we provide Bps
- csma.SetChannelAttribute("Delay", ns3::TimeValue(ns3::Seconds(lat)));
- ns3::NetDeviceContainer devices = csma.Install(Nodes);
- XBT_DEBUG("Create CSMA");
-
- std::string addr = simgrid::xbt::string_printf("%d.%d.0.0", number_of_networks, number_of_links);
- XBT_DEBUG("Assign IP Addresses %s to CSMA.", addr.c_str());
- ns3::Ipv4AddressHelper ipv4;
- ipv4.SetBase(addr.c_str(), "255.255.0.0");
- interfaces.Add(ipv4.Assign (devices));
-
- if(number_of_links == 255){
- xbt_assert(number_of_networks < 255, "Number of links and networks exceed 255*255");
- number_of_links = 1;
- number_of_networks++;
- }else{
- number_of_links++;
- }
- XBT_DEBUG("Number of nodes in Cluster_nodes: %u", Cluster_nodes.GetN());
-}
-
--static std::string transformIpv4Address(ns3::Ipv4Address from)
--{
-- std::stringstream sstream;
-- sstream << from ;
-- return sstream.str();
--}
--
-void ns3_add_direct_route(NetPointNs3* src, NetPointNs3* dst, double bw, double lat, std::string link_name,
- simgrid::s4u::Link::SharingPolicy policy)
+void ns3_add_direct_route(simgrid::kernel::routing::NetPoint* src, simgrid::kernel::routing::NetPoint* dst, double bw,
- double lat, simgrid::s4u::Link::SharingPolicy policy)
++ double lat, std::string link_name, simgrid::s4u::Link::SharingPolicy policy)
{
ns3::Ipv4AddressHelper address;
ns3::NetDeviceContainer netA;
- int srcNum = src->node_num;
- int dstNum = dst->node_num;
+ // create link ns3
+ auto* host_src = src->extension<NetPointNs3>();
+ auto* host_dst = dst->extension<NetPointNs3>();
- ns3::Ptr<ns3::Node> a = src->ns3_node_;
- ns3::Ptr<ns3::Node> b = dst->ns3_node_;
+ xbt_assert(host_src != nullptr, "Network element %s does not seem to be ns-3-ready", src->get_cname());
+ xbt_assert(host_dst != nullptr, "Network element %s does not seem to be ns-3-ready", dst->get_cname());
if (policy == simgrid::s4u::Link::SharingPolicy::WIFI) {
- /* Install a ns3::WifiHelper */
- xbt_assert(WifiZone::is_ap(a) != WifiZone::is_ap(b), "A wifi route can only exist between an access point node and a station node.");
++ auto a = host_src->ns3_node_;
++ auto b = host_dst->ns3_node_;
++ xbt_assert(WifiZone::is_ap(a) != WifiZone::is_ap(b),
++ "A wifi route can only exist between an access point node and a station node.");
+
- ns3::Ptr<ns3::Node> apNode = WifiZone::is_ap(a) ? a : b;
- ns3::Ptr<ns3::Node> staNode = apNode == a ? b : a;
++ ns3::Ptr<ns3::Node> apNode = WifiZone::is_ap(a) ? a : b;
++ ns3::Ptr<ns3::Node> staNode = apNode == a ? b : a;
+
- WifiZone* zone = WifiZone::by_name(link_name);
++ WifiZone* zone = WifiZone::by_name(link_name);
+
- wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
- "ControlMode", ns3::StringValue ("HtMcs0"),
- "DataMode", ns3::StringValue ("HtMcs" + std::to_string(zone->get_mcs())));
++ wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "ControlMode", ns3::StringValue("HtMcs0"), "DataMode",
++ ns3::StringValue("HtMcs" + std::to_string(zone->get_mcs())));
+
- wifiPhy.SetChannel (zone->get_channel());
- wifiPhy.Set("Antennas", ns3::UintegerValue(zone->get_nss()));
- wifiPhy.Set("MaxSupportedTxSpatialStreams", ns3::UintegerValue(zone->get_nss()));
- wifiPhy.Set("MaxSupportedRxSpatialStreams", ns3::UintegerValue(zone->get_nss()));
++ wifiPhy.SetChannel(zone->get_channel());
++ wifiPhy.Set("Antennas", ns3::UintegerValue(zone->get_nss()));
++ wifiPhy.Set("MaxSupportedTxSpatialStreams", ns3::UintegerValue(zone->get_nss()));
++ wifiPhy.Set("MaxSupportedRxSpatialStreams", ns3::UintegerValue(zone->get_nss()));
+
- wifiMac.SetType ("ns3::StaWifiMac");
++ wifiMac.SetType("ns3::StaWifiMac");
+
- netA.Add(wifi.Install (wifiPhy, wifiMac, staNode));
++ netA.Add(wifi.Install(wifiPhy, wifiMac, staNode));
+
- ns3::Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", ns3::UintegerValue (40));
++ ns3::Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", ns3::UintegerValue(40));
+
- NetPointNs3* sta_netpointNs3 = WifiZone::is_ap(src->ns3_node_) ? dst : src;
- const char* wifi_distance = simgrid::s4u::Host::by_name(sta_netpointNs3->name_)->get_property("wifi_distance");
- ns3::Ptr<ns3::ListPositionAllocator> positionAllocS = ns3::CreateObject<ns3::ListPositionAllocator> ();
- positionAllocS->Add(ns3::Vector( wifi_distance ? atof(wifi_distance) : 10.0 , 0, 0));
- mobility.SetPositionAllocator(positionAllocS);
- mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
- mobility.Install(staNode);
++ NetPointNs3* sta_netpointNs3 = WifiZone::is_ap(host_src->ns3_node_) ? host_src : host_dst;
++ const char* wifi_distance = simgrid::s4u::Host::by_name(sta_netpointNs3->name_)->get_property("wifi_distance");
++ ns3::Ptr<ns3::ListPositionAllocator> positionAllocS = ns3::CreateObject<ns3::ListPositionAllocator>();
++ positionAllocS->Add(ns3::Vector(wifi_distance ? atof(wifi_distance) : 10.0, 0, 0));
++ mobility.SetPositionAllocator(positionAllocS);
++ mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
++ mobility.Install(staNode);
+
- std::string addr = simgrid::xbt::string_printf("%d.%d.0.0", zone->get_network(), zone->get_link());
- address.SetBase(addr.c_str(), "255.255.0.0", ("0.0.0." + std::to_string(zone->get_n_sta_nodes() + 2)).c_str());
- zone->add_sta_node();
- XBT_DEBUG("\tInterface stack '%s'", addr.c_str());
- interfaces.Add(address.Assign (netA));
- if (IPV4addr.size() <= (unsigned)dstNum)
- IPV4addr.resize(dstNum + 1);
- IPV4addr[dstNum] = transformIpv4Address(interfaces.GetAddress(interfaces.GetN() - 1));
++ std::string addr = simgrid::xbt::string_printf("%d.%d.0.0", zone->get_network(), zone->get_link());
++ address.SetBase(addr.c_str(), "255.255.0.0", ("0.0.0." + std::to_string(zone->get_n_sta_nodes() + 2)).c_str());
++ zone->add_sta_node();
++ XBT_DEBUG("\tInterface stack '%s'", addr.c_str());
++ auto addresses = address.Assign(netA);
++ host_dst->ipv4_address_ = transformIpv4Address(addresses.GetAddress(addresses.GetN() - 1));
} else {
ns3::PointToPointHelper pointToPoint;
- XBT_DEBUG("\tAdd PTP from %d to %d bw:'%f Bps' lat:'%fs'", srcNum, dstNum, bw, lat);
+
+ XBT_DEBUG("\tAdd PTP from %s to %s bw:'%f Bps' lat:'%fs'", src->get_cname(), dst->get_cname(), bw, lat);
pointToPoint.SetDeviceAttribute("DataRate",
ns3::DataRateValue(ns3::DataRate(bw * 8))); // ns-3 takes bps, but we provide Bps
pointToPoint.SetChannelAttribute("Delay", ns3::TimeValue(ns3::Seconds(lat)));
- netA.Add(pointToPoint.Install(a, b));
+ netA.Add(pointToPoint.Install(host_src->ns3_node_, host_dst->ns3_node_));
- }
- std::string addr = simgrid::xbt::string_printf("%d.%d.0.0", number_of_networks, number_of_links);
- address.SetBase(addr.c_str(), "255.255.0.0");
- XBT_DEBUG("\tInterface stack '%s'", addr.c_str());
- auto addresses = address.Assign(netA);
+ std::string addr = simgrid::xbt::string_printf("%d.%d.0.0", number_of_networks, number_of_links);
+ address.SetBase(addr.c_str(), "255.255.0.0");
+ XBT_DEBUG("\tInterface stack '%s'", addr.c_str());
- interfaces.Add(address.Assign (netA));
-
- if (IPV4addr.size() <= (unsigned)srcNum)
- IPV4addr.resize(srcNum + 1);
- IPV4addr[srcNum] = transformIpv4Address(interfaces.GetAddress(interfaces.GetN() - 2));
++ auto addresses = address.Assign(netA);
- host_src->ipv4_address_ = transformIpv4Address(addresses.GetAddress(0));
- host_dst->ipv4_address_ = transformIpv4Address(addresses.GetAddress(1));
- if (IPV4addr.size() <= (unsigned)dstNum)
- IPV4addr.resize(dstNum + 1);
- IPV4addr[dstNum] = transformIpv4Address(interfaces.GetAddress(interfaces.GetN() - 1));
++ host_src->ipv4_address_ = transformIpv4Address(addresses.GetAddress(0));
++ host_dst->ipv4_address_ = transformIpv4Address(addresses.GetAddress(1));
- if (number_of_links == 255){
- xbt_assert(number_of_networks < 255, "Number of links and networks exceed 255*255");
- number_of_links = 1;
- number_of_networks++;
- } else {
- number_of_links++;
- if (number_of_links == 255){
- xbt_assert(number_of_networks < 255, "Number of links and networks exceed 255*255");
- number_of_links = 1;
- number_of_networks++;
++ if (number_of_links == 255) {
++ xbt_assert(number_of_networks < 255, "Number of links and networks exceed 255*255");
++ number_of_links = 1;
++ number_of_networks++;
+ } else {
- number_of_links++;
++ number_of_links++;
+ }
}
}