From 235ac2801f1ba22f0eb6736209567f261a334a74 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 29 Aug 2008 23:10:00 +0200 Subject: [PATCH] nsc: enable network simulation cradle This adds the hooks to allow the nsc code to be compiled into ns-3 if the --nsc flag is specified during 'waf configure'. --- src/helper/internet-stack-helper.cc | 18 ++++- src/helper/internet-stack-helper.h | 10 +++ src/internet-stack/internet-stack.cc | 111 +++++++++++++++++++++------ src/internet-stack/internet-stack.h | 1 + src/internet-stack/wscript | 63 +++++++++++++++ src/wscript | 1 + wscript | 32 ++++++++ 7 files changed, 211 insertions(+), 25 deletions(-) diff --git a/src/helper/internet-stack-helper.cc b/src/helper/internet-stack-helper.cc index 792f6e528..ac4523848 100644 --- a/src/helper/internet-stack-helper.cc +++ b/src/helper/internet-stack-helper.cc @@ -33,6 +33,10 @@ namespace ns3 { std::vector InternetStackHelper::m_traces; std::string InternetStackHelper::m_pcapBaseFilename; +InternetStackHelper::InternetStackHelper() : m_nscLibrary("") +{ +} + void InternetStackHelper::Cleanup (void) { @@ -48,6 +52,12 @@ InternetStackHelper::Cleanup (void) m_traces.clear (); } +void +InternetStackHelper::SetNscStack(const std::string soname) +{ + m_nscLibrary = soname; +} + void InternetStackHelper::Install (NodeContainer c) { @@ -59,8 +69,12 @@ InternetStackHelper::Install (NodeContainer c) NS_FATAL_ERROR ("InternetStackHelper::Install(): Aggregating " "an InternetStack to a node with an existing Ipv4 object"); return; - } - AddInternetStack (node); + } + if (m_nscLibrary != "") + AddNscInternetStack (node, m_nscLibrary); + else + AddInternetStack (node); + Ptr factory = CreateObject (); node->AggregateObject (factory); } diff --git a/src/helper/internet-stack-helper.h b/src/helper/internet-stack-helper.h index 74f1054e0..59b397a34 100644 --- a/src/helper/internet-stack-helper.h +++ b/src/helper/internet-stack-helper.h @@ -33,6 +33,8 @@ namespace ns3 { class InternetStackHelper { public: + InternetStackHelper(void); + /** * \param c the set of nodes * @@ -44,6 +46,13 @@ public: */ void Install (NodeContainer c); + /** + * \param soname name of the shared library with the nsc tcp stack + * to use, e.g. 'liblinux2.6.26.so'. The empty string resets + * the InternetStackHelper to use the ns-3 models again. + */ + void SetNscStack(std::string soname); + /** * \param filename filename prefix to use for pcap files. * @@ -60,6 +69,7 @@ public: static void EnablePcapAll (std::string filename); private: + std::string m_nscLibrary; static void Cleanup (void); static void LogRxIp (std::string context, Ptr packet, uint32_t deviceId); static void LogTxIp (std::string context, Ptr packet, uint32_t deviceId); diff --git a/src/internet-stack/internet-stack.cc b/src/internet-stack/internet-stack.cc index 6070daab9..56d287ebf 100644 --- a/src/internet-stack/internet-stack.cc +++ b/src/internet-stack/internet-stack.cc @@ -21,6 +21,7 @@ #include "ns3/net-device.h" #include "ns3/callback.h" #include "ns3/node.h" +#include "ns3/core-config.h" #include "ipv4-l4-demux.h" #include "udp-l4-protocol.h" @@ -31,41 +32,105 @@ #include "tcp-socket-factory-impl.h" #include "ipv4-impl.h" +#ifdef NETWORK_SIMULATION_CRADLE +#include "nsc-tcp-socket-factory-impl.h" +#include "nsc-tcp-l4-protocol.h" +#endif + namespace ns3 { -void +static void +AddArpStack (Ptr node) +{ + Ptr arp = CreateObject (); + arp->SetNode (node); + node->AggregateObject (arp); +} + +static void +AddUdpStack(Ptr node, Ptr ipv4L4Demux) +{ + Ptr udp = CreateObject (); + udp->SetNode (node); + ipv4L4Demux->Insert (udp); + Ptr udpFactory = CreateObject (); + udpFactory->SetUdp (udp); + node->AggregateObject (udpFactory); +} + +static void +AddTcpStack(Ptr node, Ptr ipv4L4Demux) +{ + Ptr tcp = CreateObject (); + tcp->SetNode (node); + ipv4L4Demux->Insert (tcp); + Ptr tcpFactory = CreateObject (); + tcpFactory->SetTcp (tcp); + node->AggregateObject (tcpFactory); +} + +static void +AddIpv4Impl(Ptr node, Ptr ipv4) +{ + Ptr ipv4Impl = CreateObject (); + ipv4Impl->SetIpv4 (ipv4); + node->AggregateObject (ipv4); + node->AggregateObject (ipv4Impl); +} + +void AddInternetStack (Ptr node) { + AddArpStack(node); Ptr ipv4 = CreateObject (); - Ptr arp = CreateObject (); ipv4->SetNode (node); - arp->SetNode (node); Ptr ipv4L4Demux = CreateObject (); - Ptr udp = CreateObject (); - Ptr tcp = CreateObject (); - ipv4L4Demux->SetNode (node); - udp->SetNode (node); - tcp->SetNode (node); - ipv4L4Demux->Insert (udp); - ipv4L4Demux->Insert (tcp); + AddUdpStack (node, ipv4L4Demux); + AddTcpStack (node, ipv4L4Demux); - Ptr udpFactory = CreateObject (); - Ptr tcpFactory = CreateObject (); - Ptr ipv4Impl = CreateObject (); - - udpFactory->SetUdp (udp); - tcpFactory->SetTcp (tcp); - ipv4Impl->SetIpv4 (ipv4); - - node->AggregateObject (ipv4); - node->AggregateObject (arp); - node->AggregateObject (ipv4Impl); - node->AggregateObject (udpFactory); - node->AggregateObject (tcpFactory); + AddIpv4Impl (node, ipv4); node->AggregateObject (ipv4L4Demux); } + +#ifdef NETWORK_SIMULATION_CRADLE +static void +AddNscStack(Ptr node, Ptr ipv4L4Demux, const std::string &soname) +{ + Ptr tcp = CreateObject (); + tcp->SetNscLibrary(soname); + tcp->SetNode (node); + ipv4L4Demux->Insert (tcp); + Ptr tcpFactory = CreateObject (); + tcpFactory->SetTcp (tcp); + node->AggregateObject (tcpFactory); +} + + +void +AddNscInternetStack (Ptr node, const std::string &soname) +{ + AddArpStack(node); + Ptr ipv4 = CreateObject (); + ipv4->SetNode (node); + + Ptr ipv4L4Demux = CreateObject (); + ipv4L4Demux->SetNode (node); + + AddUdpStack (node, ipv4L4Demux); + AddNscStack (node, ipv4L4Demux, soname); + + AddIpv4Impl (node, ipv4); + node->AggregateObject (ipv4L4Demux); +} +#else +void +AddNscInternetStack (Ptr node, const std::string &soname) +{ + NS_ASSERT_MSG(false, "ERROR: ns-3 was compiled without Network Simulation Cradle support"); +} +#endif }//namespace ns3 diff --git a/src/internet-stack/internet-stack.h b/src/internet-stack/internet-stack.h index 9997d862f..41ff375ad 100644 --- a/src/internet-stack/internet-stack.h +++ b/src/internet-stack/internet-stack.h @@ -27,6 +27,7 @@ namespace ns3 { class Node; void AddInternetStack (Ptr node); +void AddNscInternetStack (Ptr node, const std::string &soname); }//namespace ns3 diff --git a/src/internet-stack/wscript b/src/internet-stack/wscript index 6f1b7bbd7..1a4c615b0 100644 --- a/src/internet-stack/wscript +++ b/src/internet-stack/wscript @@ -1,4 +1,61 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- +import Params +import os + +# Mercurial repository of the network simulation cradle +NETWORK_SIMULATION_CRADLE_REPO = "https://secure.wand.net.nz/mercurial/nsc" +def nsc_fetch(): + def nsc_clone(): + print "Retrieving nsc from " + NETWORK_SIMULATION_CRADLE_REPO + if os.system("hg version > /dev/null 2>&1") != 0: + Params.fatal("Mercurial not installed, http fallback not yet implemented") + if os.system("hg -q clone " + NETWORK_SIMULATION_CRADLE_REPO) != 0: + Params.fatal("hg -q clone %s failed" % NETWORK_SIMULATION_CRADLE_REPO) + + def nsc_update(): + if os.system("hg version > /dev/null 2>&1") != 0: + Params.warning("Mercurial not installed, not updating nsc source") + + print "Pulling nsc updates from " + NETWORK_SIMULATION_CRADLE_REPO + if os.system("cd nsc && hg -q pull %s && hg -q update" % NETWORK_SIMULATION_CRADLE_REPO) != 0: + Params.warning("Updating nsc using mercurial failed") + + if not os.path.exists("nsc"): + nsc_clone() + else: + nsc_update() + +def configure(conf): + # checks for flex and bison, which is needed to build NSCs globaliser + def check_nsc_buildutils(): + import flex + import bison + conf.check_tool('flex bison') + e = conf.create_library_configurator() + e.mandatory = True + e.name = 'fl' + e.run() + + if not Params.g_options.nsc: + return + + check_nsc_buildutils() + + arch = os.uname()[4] + ok = False + if arch == 'x86_64' or arch == 'i686' or arch == 'i586' or arch == 'i486' or arch == 'i386': + conf.env['NSC_ENABLED'] = 'yes' + conf.define('NETWORK_SIMULATION_CRADLE', 1) + conf.write_config_header('ns3/core-config.h') + e = conf.create_library_configurator() + e.mandatory = True + e.name = 'dl' + e.define = 'HAVE_DL' + e.uselib = 'DL' + e.run() + ok = True + conf.check_message('NSC supported architecture', arch, ok) + nsc_fetch() def build(bld): @@ -43,3 +100,9 @@ def build(bld): 'ipv4-l3-protocol.h', 'ipv4-static-routing.h', ] + + if bld.env()['NSC_ENABLED']: + obj.source.append ('nsc-tcp-socket-impl.cc') + obj.source.append ('nsc-tcp-l4-protocol.cc') + obj.source.append ('nsc-tcp-socket-factory-impl.cc') + obj.source.append ('nsc-sysctl.cc') diff --git a/src/wscript b/src/wscript index e8e2938ec..dd50dbe58 100644 --- a/src/wscript +++ b/src/wscript @@ -49,6 +49,7 @@ def configure(conf): conf.sub_config('core') conf.sub_config('simulator') conf.sub_config('contrib') + conf.sub_config('internet-stack') blddir = os.path.abspath(os.path.join(conf.m_blddir, conf.env.variant())) conf.env.append_value('NS3_MODULE_PATH', blddir) diff --git a/wscript b/wscript index 68e942b18..5f6c0657c 100644 --- a/wscript +++ b/wscript @@ -55,6 +55,8 @@ REGRESSION_SUFFIX = "-ref-traces" # TRACEBALL_SUFFIX = ".tar.bz2" +# directory that contains network simulation cradle source +NSC_DIR = "nsc" def dist_hook(): import tarfile @@ -165,6 +167,10 @@ def set_options(opt): help=('For regression testing, only run/generate the indicated regression tests, ' 'specified as a comma separated list of test names'), dest='regression_tests', type="string") + opt.add_option('--nsc', + help=('Enable Network Simulation Cradle to allow the use real-world network stacks'), + action="store_true", default=False, + dest='nsc') # options provided in a script in a subdirectory named "src" opt.sub_options('src') @@ -193,6 +199,7 @@ def check_compilation_flag(conf, flag): def configure(conf): + conf.env['NS3_BUILDDIR'] = conf.m_blddir conf.check_tool('compiler_cxx') # create the second environment, set the variant and set its name @@ -304,6 +311,28 @@ def _exec_command_interact_win32(s): return stat >> 8 +def nsc_build(bld): + # XXX: Detect gcc major version(s) available to build supported stacks + kernels = [['linux-2.6.18', 'linux2.6.18'], + ['linux-2.6.26', 'linux2.6.26']] + for dir,name in kernels: + soname = 'lib' + name + '.so' + tmp = NSC_DIR + '/' + dir +'/' + soname + if not os.path.exists(tmp): + if os.system('cd ' + NSC_DIR + ' && python scons.py ' + dir) != 0: + Params.fatal("Building NSC stack failed") + builddir = os.path.abspath(os.path.join(bld.env()['NS3_BUILDDIR'], bld.env ().variant())) + if not os.path.exists(builddir + '/nsc'): + try: + os.symlink('../../' + NSC_DIR, builddir + '/nsc') + except: + Params.fatal("Error linkink " + builddir + '/nsc') + if not os.path.exists(builddir + '/' + soname): + try: + os.symlink('../../' + NSC_DIR + '/' + dir + '/' + soname, builddir + '/' + soname) + except: + Params.fatal("Error linking " + builddir + '/' + soname) + def build(bld): if Params.g_options.no_task_lines: import Runner @@ -393,6 +422,9 @@ def build(bld): bld.add_subdirs('bindings/python') + if env['NSC_ENABLED'] == 'yes': + nsc_build(bld) + def get_command_template(): if Params.g_options.valgrind: if Params.g_options.command_template: