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
============================
.. 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"
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;
{
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());
}
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++;
+ }
}
}