example/dce-umip-cmip6.cc
author Hajime Tazaki <tazaki@nict.go.jp>
Tue, 12 Mar 2013 12:56:54 +0900
changeset 38 b5447406cb67
parent 33 cfdbca608f37
child 48 598771b433ac
permissions -rw-r--r--
update bake.py path in document

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

//
// MIPv6 (Mobile IPv6) simulation with umip (mip6d) and net-next-2.6.
//
// UMIP: http://www.umip.org/git/umip.git
// patchset: 0daa3924177f326e26ed8bbb9dc9f0cdf8a51618
// build:  CFLAGS="-fPIC -g" CXXFLAGS="-fPIC -g" LDFLAGS="-pie -g" ./configure --enable-vt --with-cflags="-DRT_DEBUG_LEVEL=1" --with-builtin-crypto
//
// Simulation Topology:
// Scenario: MN moves from under AR1 to AR2 with Care-of-Address
//           alternation. during movement, MN keeps ping6 to CN.
//
//                                    +-----------+
//                                    |    HA     |
//                                    +-----------+
//                                         |sim0
//                              +----------+------------+
//                              |sim0                   |sim0
//      +--------+     sim2+----+---+              +----+---+
//      |   CN   |  - - - -|   AR1  |              |   AR2  |
//      +--------+         +---+----+              +----+---+
//                             |sim1                    |sim1
//                             |                        |
//                           :::::
//                             |sim0                    |sim0
//                        +---------+   (Movement)  +--------+
//                        |    MN   |     <=====>   |   MN   |
//                        +---------+               +--------+

#include "ns3/network-module.h"
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/dce-module.h"
#include "ns3/mip6d-helper.h"
#include "ns3/csma-helper.h"
#include "ns3/wifi-helper.h"
#include "ns3/yans-wifi-helper.h"
#include "ns3/nqos-wifi-mac-helper.h"
#include "ns3/mobility-module.h"
#include "ns3/ping6-helper.h"
#include "ns3/quagga-helper.h"


using namespace ns3;

static void RunIp (Ptr<Node> node, Time at, std::string str)
{
  DceApplicationHelper process;
  ApplicationContainer apps;
  process.SetBinary ("ip");
  process.SetStackSize (1 << 16);
  process.ResetArguments ();
  process.ParseArguments (str.c_str ());
  apps = process.Install (node);
  apps.Start (at);
}

static void AddAddress (Ptr<Node> node, Time at, const char *name, const char *address)
{
  std::ostringstream oss;
  oss << "-f inet6 addr add " << address << " dev " << name;
  RunIp (node, at, oss.str ());
}

bool usePing = true;
int main (int argc, char *argv[])
{
  CommandLine cmd;
  cmd.AddValue ("usePing", "Using Ping6 or not", usePing);
  cmd.Parse (argc, argv);

  NodeContainer mn, ha, ar;
  ha.Create (1);
  ar.Create (2);
  mn.Create (1);
  NodeContainer cn;
  cn.Create (1);

  NetDeviceContainer devices;
  MobilityHelper mobility;
  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
  positionAlloc->Add (Vector (75.0, -50.0, 0.0)); // HA
  positionAlloc->Add (Vector (0.0, 10.0, 0.0)); // AR1
  positionAlloc->Add (Vector (300.0, 10.0, 0.0)); // AR2
  positionAlloc->Add (Vector (-50.0, 10.0, 0.0)); // CN
  mobility.SetPositionAllocator (positionAlloc);
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (ha);
  mobility.Install (ar);
  mobility.Install (cn);

  Ptr<ns3::RandomDiscPositionAllocator> r_position =
    CreateObject<RandomDiscPositionAllocator> ();
  Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();                                x->SetAttribute ("Min", DoubleValue (0.0));
  x->SetAttribute ("Max", DoubleValue (200.0));
  r_position->SetX (100);
  r_position->SetY (50);
  r_position->SetRho (x);
  mobility.SetPositionAllocator (r_position);
  mobility.SetMobilityModel ("ns3::RandomDirection2dMobilityModel",
                             "Bounds", RectangleValue (Rectangle (0, 200, 30, 60)),
                             "Speed", StringValue ("ns3::ConstantRandomVariable[Constant=10.0]"),
                             "Pause", StringValue ("ns3::ConstantRandomVariable[Constant=0.2]"));
  //  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
  mobility.Install (mn);


  WifiHelper wifi = WifiHelper::Default ();
  YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
  YansWifiChannelHelper phyChannel = YansWifiChannelHelper::Default ();
  NqosWifiMacHelper mac;
  CsmaHelper csma;
  phy.SetChannel (phyChannel.Create ());
  mac.SetType ("ns3::AdhocWifiMac");
  wifi.SetStandard (WIFI_PHY_STANDARD_80211a);

  devices = csma.Install (NodeContainer (ar.Get (0), ha.Get (0), ar.Get (1)));

  phy.SetChannel (phyChannel.Create ());
  devices = wifi.Install (phy, mac, NodeContainer (ar.Get (0), mn, ar.Get (1)));

  NetDeviceContainer cn_devices = csma.Install (NodeContainer (ar.Get (0), cn.Get (0)));

  DceManagerHelper dceMng;
  DceApplicationHelper dce;
  // dceMng.SetLoader ("ns3::DlmLoaderFactory");
  dceMng.SetTaskManagerAttribute ("FiberManagerType",
                                          EnumValue (0));
  dceMng.SetNetworkStack ("ns3::LinuxSocketFdFactory",
                       "Library", StringValue ("liblinux.so"));
  dceMng.Install (mn);
  dceMng.Install (ha);
  dceMng.Install (ar);

  // Prefix configuration
  std::string ha_sim0 ("2001:1:2:3::1/64");

  // For HA
  AddAddress (ha.Get (0), Seconds (0.1), "sim0", ha_sim0.c_str ());
  RunIp (ha.Get (0), Seconds (0.11), "link set lo up");
  RunIp (ha.Get (0), Seconds (0.11), "link set sim0 up");
  RunIp (ha.Get (0), Seconds (3.0), "link set ip6tnl0 up");
  RunIp (ha.Get (0), Seconds (3.1), "addr list");
  //  RunIp (ha.Get (0), Seconds (3.2), "-6 route add default via 2001:1:2:3::2 dev sim0");
  RunIp (ha.Get (0), Seconds (3.15), "-6 route add 2001:1:2:4::/64 via 2001:1:2:3::2 dev sim0");
  RunIp (ha.Get (0), Seconds (3.15), "-6 route add 2001:1:2:6::/64 via 2001:1:2:3::2 dev sim0");
  RunIp (ha.Get (0), Seconds (3.15), "-6 route add 2001:1:2:7::/64 via 2001:1:2:3::3 dev sim0");

  // For AR1 (the intermediate node)
  AddAddress (ar.Get (0), Seconds (0.1), "sim0", "2001:1:2:3::2/64");
  RunIp (ar.Get (0), Seconds (0.11), "link set lo up");
  RunIp (ar.Get (0), Seconds (0.11), "link set sim0 up");
  AddAddress (ar.Get (0), Seconds (0.12), "sim1", "2001:1:2:4::2/64");
  RunIp (ar.Get (0), Seconds (0.13), "link set sim1 up");
  AddAddress (ar.Get (0), Seconds (0.13), "sim2", "2001:1:2:6::2/64");
  RunIp (ar.Get (0), Seconds (0.14), "link set sim2 up");
  RunIp (ar.Get (0), Seconds (0.15), "-6 route add 2001:1:2::/48 via 2001:1:2:3::1 dev sim0");
  RunIp (ar.Get (0), Seconds (0.15), "route show table all");
  Ptr<LinuxSocketFdFactory> kern = ar.Get (0)->GetObject<LinuxSocketFdFactory>();
  Simulator::ScheduleWithContext (ar.Get (0)->GetId (), Seconds (0.1),
                                  MakeEvent (&LinuxSocketFdFactory::Set, kern,
                                             ".net.ipv6.conf.all.forwarding", "1"));

  // For AR2 (the intermediate node)
  AddAddress (ar.Get (1), Seconds (0.1), "sim0", "2001:1:2:3::3/64");
  RunIp (ar.Get (1), Seconds (0.11), "link set lo up");
  RunIp (ar.Get (1), Seconds (0.11), "link set sim0 up");
  AddAddress (ar.Get (1), Seconds (0.12), "sim1", "2001:1:2:7::2/64");
  RunIp (ar.Get (1), Seconds (0.13), "link set sim1 up");
  RunIp (ar.Get (1), Seconds (0.15), "route show table all");
  kern = ar.Get (1)->GetObject<LinuxSocketFdFactory>();
  Simulator::ScheduleWithContext (ar.Get (1)->GetId (), Seconds (0.1),
                                  MakeEvent (&LinuxSocketFdFactory::Set, kern,
                                             ".net.ipv6.conf.all.forwarding", "1"));

  // For MN
  RunIp (mn.Get (0), Seconds (0.11), "link set lo up");
  RunIp (mn.Get (0), Seconds (0.11), "link set sim0 up");
  RunIp (mn.Get (0), Seconds (3.0), "link set ip6tnl0 up");
  //      RunIp (mn.Get (0), Seconds (3.1), "addr list");

  RunIp (ha.Get (0), Seconds (4.0), "addr list");
  RunIp (ar.Get (0), Seconds (4.1), "addr list");
  RunIp (mn.Get (0), Seconds (40.2), "addr list");
  RunIp (ha.Get (0), Seconds (20.0), "route show table all");
  RunIp (mn.Get (0), Seconds (50.0), "route show table all");

  {
    ApplicationContainer apps;
    QuaggaHelper quagga;
    Mip6dHelper mip6d;

    // HA
    mip6d.EnableHA (ha);
    mip6d.Install (ha);

    // MN
    std::string ha_addr = ha_sim0;
    ha_addr.replace (ha_addr.find ("/"), 3, "\0  ");
    mip6d.AddHomeAgentAddress (mn.Get (0), Ipv6Address (ha_addr.c_str ()));
    mip6d.AddHomeAddress (mn.Get (0), Ipv6Address ("2001:1:2:3::1000"), Ipv6Prefix (64));
    mip6d.AddEgressInterface (mn.Get (0), "sim0");
    mip6d.Install (mn);

    // AR
    quagga.EnableRadvd (ar.Get (0), "sim0", "2001:1:2:3::/64");
    quagga.EnableHomeAgentFlag (ar.Get (0), "sim0");
    quagga.EnableRadvd (ar.Get (0), "sim1", "2001:1:2:4::/64");
    quagga.EnableRadvd (ar.Get (0), "sim2", "2001:1:2:6::/64");
    quagga.EnableRadvd (ar.Get (1), "sim1", "2001:1:2:7::/64");
    quagga.EnableZebraDebug (ar);
    quagga.Install (ar);
  }

  // MNN
  if (usePing)
    {
      LogComponentEnable ("Ping6Application", LOG_LEVEL_INFO);
      // Ping6
      /* Install IPv4/IPv6 stack */
      InternetStackHelper internetv6;
      internetv6.SetIpv4StackInstall (false);
      internetv6.Install (cn);

      Ipv6AddressHelper ipv6;
      ipv6.NewNetwork (Ipv6Address ("2001:1:2:6::"), 64);
      Ipv6InterfaceContainer i2 = ipv6.Assign (cn_devices.Get (1));

      Ptr<Ipv6StaticRouting> routing = 0;
      Ipv6StaticRoutingHelper routingHelper;
      routing = routingHelper.GetStaticRouting (cn.Get (0)->GetObject<Ipv6> ());
      routing->SetDefaultRoute (Ipv6Address ("2001:1:2:6::2"), 1, Ipv6Address ("::"), 0);

      uint32_t packetSize = 1024;
      uint32_t maxPacketCount = 50000000;
      Time interPacketInterval = Seconds (1.);
      Ping6Helper ping6;

      dce.SetBinary ("ping6");
      dce.SetStackSize (1 << 16);
      dce.ResetArguments ();
      dce.ResetEnvironment ();
      // dce.AddArgument ("-i");
      // dce.AddArgument (interPacketInterval.GetSeconds ());
      std::ostringstream oss;
      oss << i2.GetAddress (0, 1);
      dce.AddArgument (oss.str ());
      ApplicationContainer apps = dce.Install (mn.Get (0));
      apps.Start (Seconds (50.0));
    }

  phy.EnablePcapAll ("dce-umip-cmip6");
  csma.EnablePcapAll ("dce-umip-cmip6");

  Simulator::Stop (Seconds (300.0));
  Simulator::Run ();
  Simulator::Destroy ();

  return 0;
}