Wifi Infrastructure Mode Failure - nps-ros2/ns3_testbed GitHub Wiki

Problem

Ping fails when running ns-3 to simulate Wifi Infrastructure mode with real nodes and simulated networks via ns-3 Tap. Specifically, ping Station from AP results in ping hang and ping AP from Station results in Destination Host Unreachable. Ping works fine in Ad hoc and CSMA modes.

Problem Enviornment

Ubuntu 18.4 with ns-3.29.

Network Namespace and Network Device Configuration

Set up network namespaces nns1 and nns2 and network devices for each using root privilege. This provides address 10.0.0.1 for AP at nns1 and 10.0.0.4 for Sta at nns2:

Setup for nns1:

ip link add wifi_veth1 type veth peer name wifi_vethb1
ip address add 10.0.0.2/9 dev wifi_vethb1
ip link set wifi_veth1 netns nns1
ip netns exec nns1 ip addr add 10.0.0.1/9  dev wifi_veth1
ip link add name wifi_br1 type bridge
ip link set wifi_br1 up
ip link set wifi_vethb1 up
ip netns exec nns1 ip link set wifi_veth1 up
ip link set wifi_vethb1 master wifi_br1
ip tuntap add wifi_tap1 mode tap
ip addr flush dev wifi_tap1
ip address add 10.0.0.3/9 dev wifi_tap1
ip link set wifi_tap1 up
ip link set wifi_tap1 master wifi_br1

Setup for nns2:

ip link add wifi_veth2 type veth peer name wifi_vethb2
ip address add 10.0.0.5/9 dev wifi_vethb2
ip link set wifi_veth2 netns nns2
ip netns exec nns2 ip addr add 10.0.0.4/9  dev wifi_veth2
ip link add name wifi_br2 type bridge
ip link set wifi_br2 up
ip link set wifi_vethb2 up
ip netns exec nns2 ip link set wifi_veth2 up
ip link set wifi_vethb2 master wifi_br2
ip tuntap add wifi_tap2 mode tap
ip addr flush dev wifi_tap2
ip address add 10.0.0.6/9 dev wifi_tap2
ip link set wifi_tap2 up
ip link set wifi_tap2 master wifi_br2

Here is the diagram for this setup:

nns detail

ns-3 Program

Compile the ns-3 test program to connect nns1 and nns2 with a mode: adhoc, infrastructure, or csma:

Here is the source code for ns3_wifi_tap_test.cpp:

#include <getopt.h>
#include <cstdio>
#include <iostream> // std::cout
#include <iomanip> // std::setprecision

#include "ns3/core-module.h"
#include "ns3/node-container.h"
#include "ns3/network-module.h"
#include "ns3/mobility-module.h"
#include "ns3/wifi-module.h"
#include "ns3/tap-bridge-module.h"
#include "ns3/random-variable-stream.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/wifi-mac-helper.h"
#include "ns3/csma-module.h" // for csma

std::string mode = "infrastructure";

// parse user input
int get_options(int argc, char *argv[]) {

  // parse options
  int option_index; // not used
  while (1) {

    const struct option long_options[] = {
      // options
      {"help",                          no_argument, 0, 'h'},
      {"Help",                          no_argument, 0, 'H'},
      {"mode",                    required_argument, 0, 'm'},

      // end
      {0,0,0,0}
    };

    int ch = getopt_long(argc, argv, "hHm:", long_options, &option_index);

    if (ch == -1) {
      // no more arguments
      break;
    }
    if (ch == 0) {
      // command options set flags and use ch==0
      continue;
    }
    switch (ch) {
      case 'h': {	// help
        std::cout << "Usage: -h|-H|-m <infrastructure|adhoc|csma>\n"
                  << "default infrastructure";
        exit(0);
      }
      case 'H': {	// Help
        std::cout << "Usage: -h|-H|-m <infrastructure|adhoc|csma>\n"
                  << "default infrastructure";
        exit(0);
      }
      case 'm': {	// count
        mode = std::string(optarg);
        break;
      }
      default:
        exit(1);
    }
  }
}

// set fixt position for two nodes
void set_mobility(ns3::NodeContainer& nodes) {

  // all antenna locations start deterministically at 0, 0, 0
  ns3::Ptr<ns3::ListPositionAllocator>positionAlloc =
                         ns3::CreateObject<ns3::ListPositionAllocator>();
  positionAlloc->Add(ns3::Vector(0.0, 0.0, 0.0));
  positionAlloc->Add(ns3::Vector(1.0, 0.0, 0.0));

  ns3::MobilityHelper gs_mobility;
  gs_mobility.SetPositionAllocator(positionAlloc);
  gs_mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
  gs_mobility.Install(nodes.Get(0));
  gs_mobility.Install(nodes.Get(1));
}

int main(int argc, char *argv[]) {

  // maybe change mode from infrastructure to adhoc or csma
  get_options(argc, argv);

  // run ns3 real-time with checksums
  ns3::GlobalValue::Bind("SimulatorImplementationType",
                          ns3::StringValue("ns3::RealtimeSimulatorImpl"));
  ns3::GlobalValue::Bind("ChecksumEnabled", ns3::BooleanValue(true));

  // ns3 nodes
  ns3::NodeContainer nodes;
  nodes.Create(2);

  // ns3 Net devices
  ns3::NetDeviceContainer devices;

  // Wifi settings
  ns3::WifiHelper wifi;
  wifi.SetStandard(ns3::WIFI_PHY_STANDARD_80211b);
  wifi.SetRemoteStationManager ("ns3::AarfWifiManager");

  // wifi MAC
  ns3::WifiMacHelper wifiMac;


  // physical layer
  ns3::YansWifiChannelHelper wifiChannel(
                                 ns3::YansWifiChannelHelper::Default());
  ns3::YansWifiPhyHelper wifiPhy(ns3::YansWifiPhyHelper::Default());
  wifiPhy.SetChannel(wifiChannel.Create());

  // ssid for Infrastructure mode
  ns3::Ssid ssid = ns3::Ssid ("wifi-default");

  if(mode == "csma") {
    // CSMA works
    ns3::CsmaHelper csma;
    devices = csma.Install(nodes);

  } else if (mode == "adhoc") {
    // Ad hoc works
    set_mobility(nodes);
    wifiMac.SetType("ns3::AdhocWifiMac");
    devices = wifi.Install(wifiPhy, wifiMac, nodes);

  } else if (mode == "infrastructure") {

    set_mobility(nodes);

    // AP
    wifiMac.SetType ("ns3::ApWifiMac",
                     "Ssid", ns3::SsidValue (ssid));
    devices = wifi.Install (wifiPhy, wifiMac, nodes.Get(0));

    // Sta
    wifiMac.SetType ("ns3::StaWifiMac",
                     "Ssid", ns3::SsidValue (ssid),
                     "ActiveProbing", ns3::BooleanValue (false));
    ns3::NetDeviceContainer staDevices = wifi.Install (
                                      wifiPhy, wifiMac, nodes.Get(1));
    devices.Add (staDevices);


  } else {
    std::cerr << "Invalid mode: " << mode << "\n";
  }

  // bind nodes to devices
  ns3::TapBridgeHelper tapBridge;
  tapBridge.SetAttribute("DeviceName", ns3::StringValue("wifi_tap1"));
  tapBridge.Install(nodes.Get(0), devices.Get(0));
  tapBridge.SetAttribute("DeviceName", ns3::StringValue("wifi_tap2"));
  tapBridge.Install(nodes.Get(1), devices.Get(1));

  // set to run for a while
  ns3::Simulator::Stop(ns3::Seconds(60*60*24*365.)); // 1 year

  // run
  std::cout << "Starting ns-3 Wifi " << mode << " mode test.\n";
  ns3::Simulator::Run();
  ns3::Simulator::Destroy();
  std::cout << "Ending ns-3 Wifi mode test.\n";
  return 0;
}

Run the Test

  • Start nns1 in a window: open a window and type:

    sudo /bin/bash
    ip netns exec nns1 /bin/bash
    
  • Start nns2 in a window: open a window and type:

    sudo /bin/bash
    ip netns exec nns2 /bin/bash
    
  • Start the ns-3 test program in a window: open a window and type:

    cd <your path>
    ./ns3_wifi_tap_test
    
  • Now check to see if ping works:

    From nns1 AP window type:

    ping 10.0.0.4
    

    From nns2 Sta window type:

    ping 10.0.0.1
    
  • Try other ns3 modes: Type Ctrl-C, restart with ./ns3_wifi_tap_test -m adhoc or ./ns3_wifi_tap_test -m csma and see if ping works. You do not need to restart the windows running nns1 and nns2.

References

⚠️ **GitHub.com Fallback** ⚠️