Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of framagit.org:Adrien.Gougeon/simgrid into master
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Sat, 26 Sep 2020 19:56:02 +0000 (21:56 +0200)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Sat, 26 Sep 2020 19:56:02 +0000 (21:56 +0200)
CMakeLists.txt
NEWS
docs/source/ns3.rst
src/surf/network_ns3.cpp
src/surf/ns3/ns3_simulator.hpp

index 4fd4f24..bae099b 100644 (file)
@@ -230,7 +230,7 @@ if(enable_ns3)
   include(FindNS3)
   if (SIMGRID_HAVE_NS3)
     set(SIMGRID_HAVE_NS3 1)
-    foreach(lib core csma point-to-point internet network applications)
+    foreach(lib core csma point-to-point internet network applications wifi)
       set(SIMGRID_DEP "${SIMGRID_DEP} -lns${NS3_VERSION}-${lib}${NS3_SUFFIX}")
     endforeach()
   else()
diff --git a/NEWS b/NEWS
index 1e54108..8bfbd6e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ __   _____ _ __ ___(_) ___  _ __   |___ / |___ \ / /_
   \_/ \___|_|  |___/_|\___/|_| |_| |____(_)_____|\___/
                (unreleased)
 
+ * SMPI: improved support of the proxy apps (including those using petsc)
                     _               _____  ____  ____
 __   _____ _ __ ___(_) ___  _ __   |___ / |___ \| ___|
 \ \ / / _ \ '__/ __| |/ _ \| '_ \    |_ \   __) |___ \
index 969ca7d..3a20e28 100644 (file)
@@ -56,10 +56,11 @@ version of either SimGrid or ns-3, try upgrading everything.
 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
-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
 ============================
@@ -71,13 +72,15 @@ example of an invalid platform:
 
 .. code-block:: shell
 
-   <platform>
-     <zone id="zone0" routing="Full">
+   <?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    !!!! -->
@@ -92,15 +95,17 @@ ns-3 automatically routes from point to point.
 
 .. code-block:: shell
 
-   <platform>
+   <?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" />
 
        <router id="r1" /> <!-- routers are compute-less hosts -->
 
-       <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="r1">
          <link_ctn id="l1"/> 
@@ -113,7 +118,7 @@ ns-3 automatically routes from point to point.
    </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
@@ -125,20 +130,127 @@ ns-3 model, such as `examples/platforms/dogbone.xml <https://framagit.org/simgri
 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.
 
+Build a wifi-compatible platform
+===================================
+
+We describe here a simple platform allowing ns3 wifi communication
+between two SimGrid hosts.
+
+First, here are the mandatory information necessary to create a
+simgrid platform:
+
+.. code-block:: shell
+
+       <?xml version='1.0'?>
+       <!DOCTYPE platform SYSTEM "http://simgrid.org/simgrid.dtd">
+       <platform version="4.1">
+               <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:
+
+.. 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
index c9799cf..3587995 100644 (file)
@@ -20,6 +20,9 @@
 #include <ns3/application-container.h>
 #include <ns3/event-id.h>
 
+#include "ns3/mobility-module.h"
+#include "ns3/wifi-module.h"
+
 #include "network_ns3.hpp"
 #include "ns3/ns3_simulator.hpp"
 
@@ -46,13 +49,78 @@ static ns3::InternetStackHelper stack;
 static int number_of_links = 1;
 static int number_of_networks = 1;
 
+/* 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_);
 }
 
+WifiZone::WifiZone(std::string name_, simgrid::s4u::Host* host_, ns3::Ptr<ns3::Node> ap_node_,
+                   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;
+}
+
+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;
+}
+
+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;
+
+static void initialize_ns3_wifi()
+{
+  wifi.SetStandard(ns3::WIFI_PHY_STANDARD_80211n_5GHZ);
+
+  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 *
  *************/
@@ -68,7 +136,8 @@ static void clusterCreation_cb(simgrid::kernel::routing::ClusterCreationArgs con
     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
+    ns3_add_direct_route(src, dst, cluster.bw, cluster.lat, cluster.id,
+                         cluster.sharing_policy); // Any ns-3 route is symmetrical
 
     // Also add the host to the list of hosts that will be connected to the backbone
     Nodes.Add(src->extension<NetPointNs3>()->ns3_node_);
@@ -114,7 +183,8 @@ static void routeCreation_cb(bool symmetrical, simgrid::kernel::routing::NetPoin
     //   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());
+    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;
 
@@ -214,14 +284,14 @@ double NetworkNS3Model::next_occurring_event(double now)
     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());
@@ -298,6 +368,54 @@ LinkNS3::LinkNS3(NetworkNS3Model* model, const std::string& name, double bandwid
 
   /* If wifi, create the wifizone now. If not, don't do anything: the links will be created in routeCreate_cb */
 
+  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());
 }
 
@@ -388,7 +506,7 @@ void NetworkNS3Action::update_remains_lazy(double /*now*/)
 
 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);
 
@@ -400,15 +518,8 @@ void ns3_simulator(double maxSeconds)
     id.Cancel();
 }
 
-static std::string transformIpv4Address(ns3::Ipv4Address from)
-{
-  std::stringstream sstream;
-  sstream << from ;
-  return sstream.str();
-}
-
 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;
@@ -421,7 +532,44 @@ void ns3_add_direct_route(simgrid::kernel::routing::NetPoint* src, simgrid::kern
   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 */
+    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;
+
+    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())));
+
+    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");
+
+    netA.Add(wifi.Install(wifiPhy, wifiMac, staNode));
+
+    ns3::Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", ns3::UintegerValue(40));
+
+    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());
+    auto addresses          = address.Assign(netA);
+    host_dst->ipv4_address_ = transformIpv4Address(addresses.GetAddress(addresses.GetN() - 1));
   } else {
     ns3::PointToPointHelper pointToPoint;
 
@@ -431,21 +579,21 @@ void ns3_add_direct_route(simgrid::kernel::routing::NetPoint* src, simgrid::kern
     pointToPoint.SetChannelAttribute("Delay", ns3::TimeValue(ns3::Seconds(lat)));
 
     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());
+    auto addresses = address.Assign(netA);
 
-  host_src->ipv4_address_ = transformIpv4Address(addresses.GetAddress(0));
-  host_dst->ipv4_address_ = transformIpv4Address(addresses.GetAddress(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++;
+    } else {
+      number_of_links++;
+    }
   }
 }
index e22cb6d..3500c91 100644 (file)
@@ -9,6 +9,7 @@
 #include "simgrid/s4u/Host.hpp"
 #include "src/surf/network_ns3.hpp"
 
+#include "ns3/wifi-module.h"
 #include <ns3/node.h>
 #include <ns3/tcp-socket-factory.h>
 
@@ -18,7 +19,10 @@ class XBT_PRIVATE NetPointNs3 {
 public:
   static simgrid::xbt::Extension<simgrid::kernel::routing::NetPoint, NetPointNs3> EXTENSION_ID;
 
+  void set_name(std::string name) { name_ = name; }
+
   explicit NetPointNs3();
+  std::string name_;
   ns3::Ptr<ns3::Node> ns3_node_;
   std::string ipv4_address_;
 };
@@ -26,7 +30,8 @@ public:
 XBT_PRIVATE void ns3_initialize(std::string TcpProtocol);
 XBT_PRIVATE void ns3_simulator(double max_seconds);
 XBT_PRIVATE 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 bw, double lat, std::string link_name,
+                                      simgrid::s4u::Link::SharingPolicy policy);
 
 class XBT_PRIVATE SgFlow {
 public:
@@ -50,4 +55,39 @@ static inline std::string transform_socket_ptr(ns3::Ptr<ns3::Socket> local_socke
   return sstream.str();
 }
 
+class XBT_PRIVATE WifiZone {
+public:
+  WifiZone(std::string name_, simgrid::s4u::Host* host_, ns3::Ptr<ns3::Node> ap_node_,
+           ns3::Ptr<ns3::YansWifiChannel> channel_, int mcs_, int nss_, int network_, int link_);
+
+  const char* get_cname() { return name.c_str(); }
+  simgrid::s4u::Host* get_host() { return host; }
+  ns3::Ptr<ns3::Node> get_ap_node() { return ap_node; }
+  ns3::Ptr<ns3::YansWifiChannel> get_channel() { return channel; }
+  int get_mcs() { return mcs; }
+  int get_nss() { return nss; }
+  int get_network() { return network; }
+  int get_link() { return link; }
+  int get_n_sta_nodes() { return n_sta_nodes; }
+
+  void set_network(int network_) { network = network_; }
+  void set_link(int link_) { link = link_; }
+  void add_sta_node() { n_sta_nodes++; }
+
+  static bool is_ap(ns3::Ptr<ns3::Node> node);
+  static WifiZone* by_name(std::string name);
+
+private:
+  std::string name;
+  simgrid::s4u::Host* host;
+  ns3::Ptr<ns3::Node> ap_node;
+  ns3::Ptr<ns3::YansWifiChannel> channel;
+  int mcs;
+  int nss;
+  int network;
+  int link;
+  int n_sta_nodes = 0;
+  static std::unordered_map<std::string, WifiZone*> wifi_zones;
+};
+
 #endif