fd-net-device: (merges !811) Remove PlanetLab helper

This commit is contained in:
Tom Henderson
2021-12-10 10:15:39 -08:00
parent fcc095b05c
commit 12dee93f70
14 changed files with 4 additions and 1055 deletions

View File

@@ -60,6 +60,7 @@ us a note on ns-developers mailing list.</p>
<h2>Changes to existing API:</h2>
<ul>
<li>internet: Support for Network Simulation Cradle (NSC) TCP has been removed.</li>
<li>fd-net-device: Support for PlanetLabFdNetDeviceHelper has been removed.</li>
</ul>
<h2>Changes to build system:</h2>
<ul>

View File

@@ -39,7 +39,6 @@ option(NS3_TESTS "Enable tests to be built" OFF)
# fd-net-device options
option(NS3_EMU "Build with emulation support" ON)
option(NS3_PLANETLAB "Build with Planetlab support" OFF)
option(NS3_TAP "Build with Tap support" ON)
# maintenance and documentation

View File

@@ -18,7 +18,6 @@
# NS-3 Click Integration : not enabled (nsclick not enabled (see option --with-nsclick))
# NS-3 OpenFlow Integration : not enabled (OpenFlow not enabled (see option --with-openflow))
# Netmap emulation FdNetDevice : not enabled (needs net/netmap_user.h)
# PlanetLab FdNetDevice : not enabled (PlanetLab operating system not detected (see option --force-planetlab))
# PyViz visualizer : not enabled (Missing python modules: pygraphviz, gi.repository.GooCanvas)
# Python API Scanning Support : not enabled (castxml too old)
# Python Bindings : enabled
@@ -146,11 +145,6 @@ macro(write_fakewaf_config)
string(APPEND out "Netmap emulation FdNetDevice : ")
check_on_or_off("${ENABLE_EMU}" "${ENABLE_NETMAP_EMU}")
string(
APPEND
out
"PlanetLab FdNetDevice : flag is set to ${NS3_PLANETLAB}, but currently not supported\n"
)
string(APPEND out "PyViz visualizer : ")
check_on_or_off("${NS3_VISUALIZER}" "${ENABLE_VISUALIZER}")

View File

@@ -624,7 +624,6 @@ output that looks similar to the following::
MPI Support : not enabled (option --enable-mpi not selected)
NS-3 Click Integration : not enabled (nsclick not enabled (see option --with-nsclick))
NS-3 OpenFlow Integration : not enabled (Required boost libraries not found)
PlanetLab FdNetDevice : not enabled (PlanetLab operating system not detected (see option --force-planetlab))
PyViz visualizer : enabled
Python API Scanning Support : not enabled (Missing 'pygccxml' Python module)
Python Bindings : enabled

View File

@@ -95,26 +95,6 @@ if(${ENABLE_FDNETDEV})
list(APPEND fd-net-device_creators tap-device-creator)
endif()
if(${ENABLE_TAPNETDEV} AND ${NS3_PLANETLAB}) # todo: find planetlab libraries
set(planetlab_sources helper/planetlab-fd-net-device-helper.cc)
set(planetlab_headers helper/planetlab-fd-net-device-helper.h)
add_executable(
planetlab-tap-creator helper/creator-utils.cc helper/encode-decode.cc
helper/planetlab-tap-creator.cc
)
add_definitions(
-DPLANETLAB_TAP_CREATOR="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/src/fd-net-device/ns${NS3_VER}-device_planetlab-tap-creator${build_profile_suffix}"
)
target_link_libraries(planetlab-tap-creator ${PLANETLAB_LIBRARIES})
set_runtime_outputdirectory(
planetlab-tap-creator
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/src/fd-net-device/ ""
)
list(APPEND fd-net-device_creators planetlab-tap-creator)
endif()
if(${ENABLE_NETMAP_EMU})
set(netmap_sources helper/netmap-net-device-helper.cc
model/netmap-net-device.cc
@@ -147,7 +127,6 @@ if(${ENABLE_FDNETDEV})
set(source_files
${tap_sources}
${emu_sources}
${planetlab_sources}
${netmap_sources}
${dpdk_sources}
helper/creator-utils.cc
@@ -157,7 +136,7 @@ if(${ENABLE_FDNETDEV})
)
set(header_files
${tap_headers} ${emu_headers} ${planetlab_headers} ${dpdk_headers}
${tap_headers} ${emu_headers} ${dpdk_headers}
model/fd-net-device.h helper/fd-net-device-helper.h
)

View File

@@ -11,10 +11,6 @@ def post_register_types(root_module):
if 'ns3::TapFdNetDeviceHelper'in root_module:
root_module.classes.remove(root_module['ns3::TapFdNetDeviceHelper'])
if 'PlanetLabFdNetDevice' not in enabled_features:
if 'ns3::PlanetLabFdNetDeviceHelper'in root_module:
root_module.classes.remove(root_module['ns3::PlanetLabFdNetDeviceHelper'])
if 'FdNetDevice' not in enabled_features:
for clsname in ['FdNetDevice', 'FdNetDeviceHelper', 'FdNetDeviceFdReader']:
if 'ns3::%s' % clsname in root_module:

View File

@@ -18,15 +18,12 @@ The user has full freedom to define how external traffic is generated
and |ns3| traffic is consumed.
Different mechanisms to associate a simulation to external traffic can
be provided through helper classes. Three specific helpers are provided:
be provided through helper classes. Two specific helpers are provided:
* EmuFdNetDeviceHelper (to associate the |ns3| device with a physical device
in the host machine)
* TapFdNetDeviceHelper (to associate the ns-3 device with the file descriptor
from a tap device in the host machine)
* PlanteLabFdNetDeviceHelper (to automate the creation of tap devices in
PlanetLab nodes, enabling |ns3| simulations that can send and receive
traffic though the Internet using PlanetLab resource.
Model Description
*****************
@@ -377,80 +374,6 @@ on the device, and the PI header if needed. For example:
helper.Install (node);
PlanetLabFdNetDeviceHelper
##########################
PlanetLab is a world wide distributed network testbed composed of
nodes connected to the Internet.
Running ns-3 simulations in PlanetLab nodes using the
PlanetLabFdNetDeviceHelper allows to send simulated traffic generated by
ns-3 directly to the Internet. This setup can be useful to validate
ns-3 Internet protocols or other future protocols implemented in ns-3.
To run experiments using PlanetLab nodes it is required to have a
PlanetLab account.
Only members of PlanetLab partner institutions can obtain such accounts
( for more information visit http://www.planet-lab.org/ or
http://www.planet-lab.eu ).
Once the account is obtained, a PlanetLab `slice` must be requested in
order to conduct experiments.
A slice represents an experiment unit related to a group of PlanetLab users,
and can be associated to virtual machines in different PlanetLab nodes.
Slices can also be customized by adding configuration tags to it
(this is done by PlanetLab administrators).
The PlanetLabFdNetDeviceHelper creates TAP devices on PlanetLab nodes
using specific PlanetLab mechanisms (i.e. the vsys system), and
associates the TAP device to a FdNetDevice in ns-3.
The functionality provided by this helper is similar to that provided
by the FdTapNetDeviceHelper, except that the underlying mechanisms
to create the TAP device are different.
.. sourcecode:: text
+-------------------------------------+
| PlanetLab host |
+-------------------------------------+
| ns-3 simulation | |
+----------------------+ |
| ns-3 Node | |
| +----------------+ | |
| | ns-3 TCP | | |
| +----------------+ | |
| | ns-3 IP | | |
| +----------------+ | |
| | FdNetDevice | | |
|--+----------------+--+ +------+ |
| | TAP | | eth0 | |
| +------+ +------+ |
| 192.168.0.1 | |
+-------------------------------|-----+
|
|
------------ (Internet) -----
In order to be able to assign private IPv4 addresses to the TAP devices,
account holders must request the `vsys_vnet` tag to be added to their slice
by PlanetLab administrators.
The vsys_vnet tag is associated to private network segment and only addresses
from this segment can be used in experiments.
The syntax used to create a TAP device with this helper is similar to that
used for the previously described helpers:
::
PlanetLabFdNetDeviceHelper helper;
helper.SetTapIpAddress (tapIp);
helper.SetTapMask (tapMask);
...
helper.Install (node);
PlanetLab nodes have a Fedora based distribution, so ns-3 can be installed
following the instructions for ns-3 Linux installation.
Attributes
==========
@@ -518,8 +441,6 @@ Several examples are provided:
traffic over a real channel.
* ``fd-emu-udp-echo.cc``: This example uses the EmuFdNetDeviceHelper to send UDP
traffic over a real channel.
* ``fd-planetlab-ping.cc``: This example shows how to set up an experiment to send
ICMP traffic from a PlanetLab node to the Internet.
* ``fd-tap-ping.cc``: This example uses the TapFdNetDeviceHelper to send ICMP
traffic over a real channel.

View File

@@ -99,13 +99,3 @@ if(${ENABLE_TAP})
"${name}" "${source_files}" "${header_files}" "${libraries_to_link}"
)
endif()
if(${NS3_PLANETLAB})
set(name fd-planetlab-ping)
set(source_files ${name}.cc)
set(header_files)
set(libraries_to_link ${libfd-net-device} ${libinternet} ${libinternet-apps})
build_lib_example(
"${name}" "${source_files}" "${header_files}" "${libraries_to_link}"
)
endif()

View File

@@ -1,209 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 University of Washington, 2012 INRIA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// Allow ns-3 to ping a real host somewhere, using emulation mode and ping
// the simulated node from the host.
//
//
// +-------------------------------------+
// | PlanetLab host |
// +-------------------------------------+
// | ns-3 simulation | |
// +----------------------+ |
// | ns-3 Node | |
// | +----------------+ | |
// | | ns-3 TCP | | |
// | +----------------+ | |
// | | ns-3 IPv4 | | |
// | +----------------+ | |
// | | FdNetDevice | | |
// |--+----------------+--+ +------+ |
// | | TAP | | eth0 | |
// | +------+ +------+ |
// | 1.2.3.4 | |
// +-------------------------------|-----+
// |
// |
// ------------ (Internet) -----
//
// To use this example:
// 1) A ns-3 creator binary will create the TAP device for you in the host machine.
// For this you need to provide the network address to allocate IP addresses
// for the TAP/TU device and the ns-3 FdNetDevice.
// 2) Once the experiment is running you can ping the FdNetDevice IP address from
// the host machine.
// 3) For more information on the required configuration to create TAP devices
// on PlanetLab refer to:
// http://minerva.netgroup.uniroma2.it/fairvpn/wiki/TapDevice
//
#include "ns3/abort.h"
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/network-module.h"
#include "ns3/fd-net-device-module.h"
#include "ns3/internet-apps-module.h"
#include "ns3/ipv4-static-routing-helper.h"
#include "ns3/ipv4-list-routing-helper.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("PlanetLabTAPPingExample");
static void
PingRtt (std::string context, Time rtt)
{
NS_LOG_UNCOND ("Received Response with RTT = " << rtt);
}
int
main (int argc, char *argv[])
{
NS_LOG_INFO ("Ping Emulation Example with TAP on PlanetLab host");
std::string remote ("173.194.34.51"); // example.com
//
// Make sure network and mask correspond to those assigned to your PlanetLab
// slice, through the tag vsys_vnet x.x.x.x/yy .
// In this case The network should be x.x.x.x and the mask should correspond to
// the prefix yy.
//
std::string network ("1.2.3.4");
std::string mask ("255.255.255.0");
//
// Allow the user to override any of the defaults at run-time, via
// command-line arguments
//
CommandLine cmd (__FILE__);
cmd.AddValue ("remote", "Remote IP address (dotted decimal only please)", remote);
cmd.AddValue ("tapNetwork", "Network address to assign the TAP device IP address (dotted decimal only please). Note that the network address must be that from the vsys_vnet tag which must exist in your PlanetLab slice.", network);
cmd.AddValue ("tapMask", "Network mask for configure the TAP device (dotted decimal only please)", mask);
cmd.Parse (argc, argv);
NS_ABORT_MSG_IF (network == "1.2.3.4", "You must change the local IP address before running this example");
Ipv4Address remoteIp (remote.c_str ());
Ipv4Address tapNetwork (network.c_str ());
Ipv4Mask tapMask (mask.c_str ());
//
// Since we are using a real piece of hardware we need to use the realtime
// simulator.
//
GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
//
// Since we are going to be talking to real-world machines, we need to enable
// calculation of checksums in our protocols.
//
GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
//
// In such a simple topology, the use of the helper API can be a hindrance
// so we drop down into the low level API and do it manually.
//
// First we need a single node.
//
NS_LOG_INFO ("Create Node");
Ptr<Node> node = CreateObject<Node> ();
// Create an fd device, set a MAC address and point the device to the
// Linux device name. The device needs a transmit queueing discipline so
// create a droptail queue and give it to the device. Finally, "install"
// the device into the node.
//
Ipv4AddressHelper addresses;
addresses.SetBase (tapNetwork, tapMask);
Ipv4Address tapIp = addresses.NewAddress ();
NS_LOG_INFO ("Create Device");
PlanetLabFdNetDeviceHelper helper;
helper.SetTapIpAddress (tapIp);
helper.SetTapMask (tapMask);
NetDeviceContainer devices = helper.Install (node);
Ptr<NetDevice> device = devices.Get (0);
//
// Add a default internet stack to the node (ARP, IPv4, ICMP, UDP and TCP).
//
NS_LOG_INFO ("Add Internet Stack");
InternetStackHelper internetStackHelper;
internetStackHelper.Install (node);
//
// Add an address to the ns-3 device in the same network than one
// assigned to the TAP.
//
NS_LOG_INFO ("Create IPv4 Interface");
Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
uint32_t interface = ipv4->AddInterface (device);
Ipv4Address devIp = addresses.NewAddress ();
Ipv4InterfaceAddress address = Ipv4InterfaceAddress (devIp, tapMask);
ipv4->AddAddress (interface, address);
ipv4->SetMetric (interface, 1);
ipv4->SetUp (interface);
//
// Add a route to the ns-3 device so it can reach the outside world though the
// TAP.
//
Ipv4StaticRoutingHelper ipv4RoutingHelper;
Ptr<Ipv4StaticRouting> staticRouting = ipv4RoutingHelper.GetStaticRouting (ipv4);
staticRouting->SetDefaultRoute (tapIp, interface);
//
// Create the ping application. This application knows how to send
// ICMP echo requests. Setting up the packet sink manually is a bit
// of a hassle and since there is no law that says we cannot mix the
// helper API with the low level API, let's just use the helper.
//
NS_LOG_INFO ("Create V4Ping Appliation");
Ptr<V4Ping> app = CreateObject<V4Ping> ();
app->SetAttribute ("Remote", Ipv4AddressValue (remoteIp));
app->SetAttribute ("Verbose", BooleanValue (true) );
node->AddApplication (app);
app->SetStartTime (Seconds (1.0));
app->SetStopTime (Seconds (21.0));
//
// Give the application a name. This makes life much easier when constructing
// config paths.
//
Names::Add ("app", app);
//
// Hook a trace to print something when the response comes back.
//
Config::Connect ("/Names/app/Rtt", MakeCallback (&PingRtt));
//
// Enable a promiscuous pcap trace to see what is coming and going on our device.
//
helper.EnablePcap ("fd-planete-ping", device, true);
//
// Now, do the actual emulation.
//
NS_LOG_INFO ("Run Emulation.");
Simulator::Stop (Seconds (22.0));
Simulator::Run ();
Simulator::Destroy ();
NS_LOG_INFO ("Done.");
}

View File

@@ -35,7 +35,3 @@ def build(bld):
obj.source = 'fd-tap-ping.cc'
obj = bld.create_ns3_program('fd-tap-ping6', ['fd-net-device', 'internet', 'internet-apps', 'csma'])
obj.source = 'fd-tap-ping6.cc'
if bld.env['ENABLE_PLANETLAB']:
obj = bld.create_ns3_program('fd-planetlab-ping', ['fd-net-device', 'internet', 'internet-apps'])
obj.source = 'fd-planetlab-ping.cc'

View File

@@ -1,335 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 INRIA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Alina Quereilhac <alina.quereilhac@inria.fr>
* Claudio Freire <klaussfreire@sourceforge.net>
*
*/
#include "planetlab-fd-net-device-helper.h"
#include "encode-decode.h"
#include "ns3/abort.h"
#include "ns3/config.h"
#include "ns3/fd-net-device.h"
#include "ns3/log.h"
#include "ns3/names.h"
#include "ns3/object-factory.h"
#include "ns3/packet.h"
#include "ns3/simulator.h"
#include "ns3/trace-helper.h"
#include "ns3/internet-module.h"
#include <arpa/inet.h>
#include <errno.h>
#include <iostream>
#include <iomanip>
#include <limits>
#include <linux/if_tun.h>
#include <memory>
#include <net/ethernet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netpacket/packet.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/ioctl.h>
#include <time.h>
#include <unistd.h>
#include <string>
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("PlanetLabFdNetDeviceHelper");
#define PLANETLAB_MAGIC 75867
PlanetLabFdNetDeviceHelper::PlanetLabFdNetDeviceHelper ()
{
m_tapIp = Ipv4Address ("255.255.255.255");
m_tapMask = Ipv4Mask ("255.255.255.255");
}
void
PlanetLabFdNetDeviceHelper::SetTapIpAddress (Ipv4Address address)
{
m_tapIp = address;
}
void
PlanetLabFdNetDeviceHelper::SetTapMask (Ipv4Mask mask)
{
m_tapMask = mask;
}
Ptr<NetDevice>
PlanetLabFdNetDeviceHelper::InstallPriv (Ptr<Node> node) const
{
Ptr<NetDevice> d = FdNetDeviceHelper::InstallPriv (node);
Ptr<FdNetDevice> device = d->GetObject<FdNetDevice> ();
//
// The PlanetLab mechanism to create a TAP device doesn't allow
// for the moment to set the IFF_NOPI flag. In consequence, a PI
// header will be present in the traffic.
// We need to explicitly set the encapsulation mode to DIXPI,
// so the FdNetDevice is able to treat correctly the traffic
// traversing TAP device.
//
Ptr<FdNetDevice> fdnd = device->GetObject<FdNetDevice> ();
fdnd->SetEncapsulationMode (FdNetDevice::DIXPI);
SetFileDescriptor (device);
return device;
}
void
PlanetLabFdNetDeviceHelper::SetFileDescriptor (Ptr<FdNetDevice> device) const
{
NS_LOG_LOGIC ("Creating TAP device");
//
// Call out to a separate process running as suid root in order to create a
// TAP device. We do this to avoid having the entire simulation running as root.
//
int fd = CreateFileDescriptor ();
device->SetFileDescriptor (fd);
}
int
PlanetLabFdNetDeviceHelper::CreateFileDescriptor (void) const
{
NS_LOG_FUNCTION (this);
//
// We're going to fork and exec that program soon, but first we need to have
// a socket to talk to it with. So we create a local interprocess (Unix)
// socket for that purpose.
//
int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
NS_ABORT_MSG_IF (sock == -1, "PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): Unix socket creation error, errno = " << strerror (errno));
//
// Bind to that socket and let the kernel allocate an endpoint
//
struct sockaddr_un un;
memset (&un, 0, sizeof (un));
un.sun_family = AF_UNIX;
int status = bind (sock, (struct sockaddr*)&un, sizeof (sa_family_t));
NS_ABORT_MSG_IF (status == -1, "PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): Could not bind(): errno = " << strerror (errno));
NS_LOG_INFO ("Created Unix socket");
NS_LOG_INFO ("sun_family = " << un.sun_family);
NS_LOG_INFO ("sun_path = " << un.sun_path);
//
// We have a socket here, but we want to get it there -- to the program we're
// going to exec. What we'll do is to do a getsockname and then encode the
// resulting address information as a string, and then send the string to the
// program as an argument. So we need to get the sock name.
//
socklen_t len = sizeof (un);
status = getsockname (sock, (struct sockaddr*)&un, &len);
NS_ABORT_MSG_IF (status == -1, "PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): Could not getsockname(): errno = " << strerror (errno));
//
// Now encode that socket name (family and path) as a string of hex digits
//
std::string path = BufferToString ((uint8_t *)&un, len);
NS_LOG_INFO ("Encoded Unix socket as \"" << path << "\"");
//
// Fork and exec the process to create our socket. If we're us (the parent)
// we wait for the child (the creator) to complete and read the socket it
// created and passed back using the ancillary data mechanism.
//
pid_t pid = ::fork ();
if (pid == 0)
{
NS_LOG_DEBUG ("Child process");
//
// build a command line argument from the encoded endpoint string that
// the socket creation process will use to figure out how to respond to
// the (now) parent process. We're going to have to give this program
// quite a bit of information.
//
// -i<IP-address> The IP address to assign to the new tap device;
// -n<network-prefix> The network prefix to assign to the new tap device;
// -t Set the IFF_TAP flag
// -p<path> the path to the unix socket described above.
//
// Example tap-creator -i1.2.3.1 -n24 -t -pblah
//
std::ostringstream ossIp;
ossIp << "-i" << m_tapIp;
std::ostringstream ossPrefix;
ossPrefix << "-n" << m_tapMask.GetPrefixLength ();
std::ostringstream ossMode;
ossMode << "-t";
std::ostringstream ossPath;
ossPath << "-p" << path;
//
// Execute the socket creation process image.
//
status = ::execlp (PLANETLAB_TAP_CREATOR,
PLANETLAB_TAP_CREATOR, // argv[0] (filename)
ossIp.str ().c_str (), // argv[1] (-i<IP address>)
ossPrefix.str ().c_str (), // argv[2] (-n<prefix>)
ossMode.str ().c_str (), // argv[3] (-t <tap>)
ossPath.str ().c_str (), // argv[4] (-p<path>)
(char *)NULL);
//
// If the execlp successfully completes, it never returns. If it returns it failed or the OS is
// broken. In either case, we bail.
//
NS_FATAL_ERROR ("PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): Back from execlp(), errno = " << ::strerror (errno));
}
else
{
NS_LOG_DEBUG ("Parent process");
//
// We're the process running the emu net device. We need to wait for the
// socket creator process to finish its job.
//
int st;
pid_t waited = waitpid (pid, &st, 0);
NS_ABORT_MSG_IF (waited == -1, "PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): waitpid() fails, errno = " << strerror (errno));
NS_ASSERT_MSG (pid == waited, "PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): pid mismatch");
//
// Check to see if the socket creator exited normally and then take a
// look at the exit code. If it bailed, so should we. If it didn't
// even exit normally, we bail too.
//
if (WIFEXITED (st))
{
int exitStatus = WEXITSTATUS (st);
NS_ABORT_MSG_IF (exitStatus != 0,
"PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): socket creator exited normally with status " << exitStatus);
}
else
{
NS_FATAL_ERROR ("PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): socket creator exited abnormally");
}
//
// At this point, the socket creator has run successfully and should
// have created our tap device, initialized it with the information we
// passed and sent it back to the socket address we provided. A socket
// (fd) we can use to talk to this tap device should be waiting on the
// Unix socket we set up to receive information back from the creator
// program. We've got to do a bunch of grunt work to get at it, though.
//
// The struct iovec below is part of a scatter-gather list. It describes a
// buffer. In this case, it describes a buffer (an integer) that will
// get the data that comes back from the socket creator process. It will
// be a magic number that we use as a consistency/sanity check.
//
struct iovec iov;
uint32_t magic;
iov.iov_base = &magic;
iov.iov_len = sizeof(magic);
//
// The CMSG macros you'll see below are used to create and access control
// messages (which is another name for ancillary data). The ancillary
// data is made up of pairs of struct cmsghdr structures and associated
// data arrays.
//
// First, we're going to allocate a buffer on the stack to receive our
// data array (that contains the socket). Sometimes you'll see this called
// an "ancillary element" but the msghdr uses the control message termimology
// so we call it "control."
//
size_t msg_size = sizeof(int);
char control[CMSG_SPACE (msg_size)];
//
// There is a msghdr that is used to minimize the number of parameters
// passed to recvmsg (which we will use to receive our ancillary data).
// This structure uses terminology corresponding to control messages, so
// you'll see msg_control, which is the pointer to the ancillary data and
// controllen which is the size of the ancillary data array.
//
// So, initialize the message header that describes the ancillary/control
// data we expect to receive and point it to buffer.
//
struct msghdr msg;
msg.msg_name = 0;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = control;
msg.msg_controllen = sizeof (control);
msg.msg_flags = 0;
//
// Now we can actually receive the interesting bits from the tap
// creator process. Lots of pain to get four bytes.
//
ssize_t bytesRead = recvmsg (sock, &msg, 0);
NS_ABORT_MSG_IF (bytesRead != sizeof(int), "PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): Wrong byte count from socket creator");
//
// There may be a number of message headers/ancillary data arrays coming in.
// Let's look for the one with a type SCM_RIGHTS which indicates it's the
// one we're interested in.
//
struct cmsghdr *cmsg;
for (cmsg = CMSG_FIRSTHDR (&msg); cmsg != NULL; cmsg = CMSG_NXTHDR (&msg, cmsg))
{
if (cmsg->cmsg_level == SOL_SOCKET
&& cmsg->cmsg_type == SCM_RIGHTS)
{
//
// This is the type of message we want. Check to see if the magic
// number is correct and then pull out the socket we care about if
// it matches
//
if (magic == PLANETLAB_MAGIC)
{
NS_LOG_INFO ("Got SCM_RIGHTS with correct magic " << magic);
int *rawSocket = (int*)CMSG_DATA (cmsg);
NS_LOG_INFO ("Got the socket from the socket creator = " << *rawSocket);
return *rawSocket;
}
else
{
NS_LOG_INFO ("Got SCM_RIGHTS, but with bad magic " << magic);
}
}
}
NS_FATAL_ERROR ("Did not get the raw socket from the socket creator");
}
}
} // namespace ns3

View File

@@ -1,107 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 INRIA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Alina Quereilhac <alina.quereilhac@inria.fr>
* Claudio Freire <klaussfreire@sourceforge.net>
*/
#ifndef PLANETLAB_FD_NET_DEVICE_HELPER_H
#define PLANETLAB_FD_NET_DEVICE_HELPER_H
#include <string>
#include "ns3/attribute.h"
#include "ns3/fd-net-device.h"
#include "ns3/object-factory.h"
#include "ns3/mac48-address.h"
#include "ns3/net-device-container.h"
#include "ns3/node-container.h"
#include "emu-fd-net-device-helper.h"
namespace ns3 {
/**
* \ingroup fd-net-device
* \brief build a set of FdNetDevice objects attached to a virtual TAP network
* interface
*
*/
class PlanetLabFdNetDeviceHelper : public EmuFdNetDeviceHelper
{
public:
/**
* Construct a PlanetLabFdNetDeviceHelper.
*/
PlanetLabFdNetDeviceHelper ();
virtual ~PlanetLabFdNetDeviceHelper ()
{
}
/**
* Set the device IPv4 address.
*
* \param address The IPv4 address for the TAP device.
*/
void SetTapIpAddress (Ipv4Address address);
/**
* Set the network mask for the TAP device.
*
* \param mask The network mask for the TAP device.
*/
void SetTapMask (Ipv4Mask mask);
protected:
/**
* This method creates an ns3::FdNetDevice attached to a virtual TAP network
* interface
*
* \param node The node to install the device in
* \returns A container holding the added net device.
*/
Ptr<NetDevice> InstallPriv (Ptr<Node> node) const;
/**
* Sets a file descriptor on the FileDescriptorNetDevice.
* \param device the device to install the file descriptor in
*/
virtual void SetFileDescriptor (Ptr<FdNetDevice> device) const;
/**
* Call out to a separate process running as suid root in order to create a
* TAP device and obtain the file descriptor associated to it.
* \returns The file descriptor associated with the TAP device.
*/
virtual int CreateFileDescriptor (void) const;
/**
* The IP address for the TAP device.
*/
Ipv4Address m_tapIp;
/**
* The network mask for the TAP device.
*/
Ipv4Mask m_tapMask;
};
} // namespace ns3
#endif /* PLANETLAB_FD_NET_DEVICE_HELPER_H */

View File

@@ -1,234 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 INRIA
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Alina Quereilhac <alina.quereilhac@inria.fr>
* Claudio Freire <klaussfreire@sourceforge.net>
*
*/
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <string.h> // for strerror
#include <iostream>
#include <iomanip>
#include <sstream>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <net/if.h>
#include <linux/if_tun.h>
#include <net/route.h>
#include <netinet/in.h>
#include "creator-utils.h"
#define PLANETLAB_MAGIC 75867
#define VSYS_TUNTAP "/vsys/fd_tuntap.control"
#define VSYS_VIFUP_IN "/vsys/vif_up.in"
#define VSYS_VIFUP_OUT "/vsys/vif_up.out"
using namespace ns3;
/**
*
* Reads vif FD from "fd", writes interface name to vif_name, and returns vif FD.
* vif_name should be IFNAMSIZ chars long.
*
*/
int
ReceiveVifFd (int fd, char *vif_name)
{
struct msghdr msg;
struct iovec iov;
int rv;
size_t ccmsg[CMSG_SPACE (sizeof(int)) / sizeof(size_t)];
struct cmsghdr *cmsg;
/* Use IOV to read interface name */
iov.iov_base = vif_name;
iov.iov_len = IFNAMSIZ;
msg.msg_name = 0;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
/* old BSD implementations should use msg_accrights instead of
* msg_control; the interface is different. */
msg.msg_control = ccmsg;
msg.msg_controllen = sizeof(ccmsg);
while (((rv = recvmsg (fd, &msg, 0)) == -1) && errno == EINTR)
{
}
ABORT_IF (rv == -1, "Could not receive fd from Vsys", 0);
ABORT_IF (!rv, "Could not receive fd from Vsys (EOF)", 0);
cmsg = CMSG_FIRSTHDR (&msg);
ABORT_IF (!cmsg->cmsg_type == SCM_RIGHTS, "got control message of unknown type" << cmsg->cmsg_type, 0);
int* retfd = (int*)CMSG_DATA (cmsg);
return *retfd;
}
/**
*
* Creates a TUN/TAP device on a PlanetLab virtual machine (sliver).
* PlanetLab provides the Vsys API to enable privileged operating system calls
* in an environment with restricted privileges.
* To create a TUN/TAP device the it is necessary to connect to the
* /vsys/fd_tuntap.control socket, and send the device initialization parameters.
*
*/
int
TunAlloc (int iftype, char *if_name)
{
int control_fd;
struct sockaddr_un addr;
int ret;
control_fd = socket (AF_UNIX, SOCK_STREAM, 0);
ABORT_IF (control_fd == -1, "Could not create UNIX socket", 0);
memset (&addr, 0, sizeof(struct sockaddr_un));
/* Clear structure */
addr.sun_family = AF_UNIX;
strncpy (addr.sun_path, VSYS_TUNTAP, sizeof(addr.sun_path) - 1);
ret = connect (control_fd, (struct sockaddr *) &addr,
sizeof(struct sockaddr_un));
ABORT_IF (ret == -1, "Could not connect to Vsys control socket", 0);
/* passing type param */
ret = send (control_fd, &iftype, sizeof(iftype), 0);
ABORT_IF (ret != sizeof(iftype), "Could not send parameter to Vsys control socket", 0);
return ReceiveVifFd (control_fd, if_name);
}
/**
*
* Sets the TAP/TUN interface up.
* When a TAP/TUN device is created on PlanetLab it must be set up
* writing some configuration information to the vsys fifo at /vsys/vif_up.in
*
*/
void
SetTunUp (const char *ip, const char *prefix, const char *if_name)
{
FILE *in;
FILE *out;
char errbuff[4096];
memset(errbuff, 0, 4096);
in = fopen (VSYS_VIFUP_IN, "a");
if (in == NULL)
{
ABORT_IF (in == NULL, "Failed to open " << VSYS_VIFUP_IN, 0);
}
out = fopen (VSYS_VIFUP_OUT, "r");
if (out == NULL)
{
ABORT_IF (out == NULL, "Failed to open " << VSYS_VIFUP_OUT, 0);
}
// send input to process
fprintf (in, "%s\n%s\n%s\nsnat=1\n", if_name, ip, prefix);
// close pipe to indicate end parameter passing and flush the fifo
fclose (in);
fread((void*)errbuff, 4096, 1, out);
// the error buffer will not be empty if we read an error
ABORT_IF (strcmp(errbuff, "") != 0, errbuff, 0);
fclose (out);
}
int
main (int argc, char *argv[])
{
int c;
char *ip = NULL;
char *prefix = NULL;
char *path = NULL;
int iftype = IFF_TUN;
char if_name[4096];
memset(if_name, 0, 4096);
opterr = 0;
while ((c = getopt (argc, argv, "vi:n:tp:")) != -1)
{
switch (c)
{
case 'i':
ip = optarg; // ip address of the new device
break;
case 'n':
prefix = optarg; // prefix for the new device
break;
case 't':
iftype = IFF_TAP; // mode for the device (TAP or TUN)
break;
case 'p':
path = optarg; // path back to the tap bridge
break;
case 'v':
gVerbose = true;
break;
}
}
ABORT_IF (ip == NULL, "IP Address is a required argument", 0);
LOG ("Provided IP Address is \"" << ip << "\"");
ABORT_IF (prefix == NULL, "Prefix is a required argument", 0);
LOG ("Provided prefix \"" << prefix << "\"");
ABORT_IF (path == NULL, "path is a required argument", 0);
LOG ("Provided path is \"" << path << "\"");
LOG ("Creating Tap");
// allocate a TAP device in planetLab
int fd = TunAlloc (iftype, if_name);
ABORT_IF (fd == -1, "main(): Unable to create tap device", 1);
// set the TAP interface up
SetTunUp (ip, prefix, (const char*)if_name);
//
// Send the socket back to the tap net device so it can go about its business
//
SendSocket (path, fd, PLANETLAB_MAGIC);
return 0;
}

View File

@@ -4,11 +4,6 @@ import os.path
from waflib import Options
def options(opt):
opt.add_option('--force-planetlab',
help=('Forces compilation of PlanetLab even if not supported by the local system'),
dest='force_planetlab', default=False, action="store_true")
def configure(conf):
conf.env['ENABLE_FDNETDEV'] = False
@@ -99,7 +94,7 @@ def configure(conf):
conf.env['MODULES_NOT_BUILT'].append('fd-net-device')
# Next, check for whether specialized FdNetDevice features are enabled
# such as tap device support, raw socket support, netmap support, and planetlab
# such as tap device support, raw socket support, and netmap support
if conf.env['ENABLE_FDNETDEV']:
conf.env['ENABLE_TAP'] = conf.check_nonfatal(
@@ -149,23 +144,6 @@ def configure(conf):
False,
"needs net/netmap_user.h")
# Enable use of PlanetLab TAP helper
# TODO: How to validate
(sysname, nodename, release, version, machine) = os.uname()
if release.find('onelab') != -1 or Options.options.force_planetlab:
conf.env['ENABLE_PLANETLAB'] = True
if conf.env['ENABLE_PLANETLAB']:
conf.report_optional_feature("PlanetLabFdNetDevice",
"PlanetLab FdNetDevice",
True,
"Planetlab support enabled")
else:
conf.report_optional_feature("PlanetLabFdNetDevice",
"PlanetLab FdNetDevice",
False,
"PlanetLab operating system not detected (see option --force-planetlab)")
def build(bld):
# Don't do anything for this module if emu's not enabled.
if not bld.env['ENABLE_FDNETDEV']:
@@ -269,25 +247,6 @@ def build(bld):
module.env.append_value("DEFINES",
"NETMAP_DEV_CREATOR=\"%s\"" % (creator.target,))
if bld.env['ENABLE_PLANETLAB']:
module.source.extend([
'helper/planetlab-fd-net-device-helper.cc',
])
headers.source.extend([
'helper/planetlab-fd-net-device-helper.h',
])
creator = bld.create_suid_program('planetlab-tap-creator')
creator.source = [
'helper/planetlab-tap-creator.cc',
'helper/encode-decode.cc',
'helper/creator-utils.cc',
]
module.env.append_value("DEFINES",
"PLANETLAB_TAP_CREATOR=\"%s\"" % (creator.target,))
if bld.env['ENABLE_EXAMPLES']:
bld.recurse('examples')