Difference between revisions of "Network Simulation Cradle Integration"

From Nsnam
Jump to: navigation, search
(update project status.)
(Plan and current status updated, document some aspects of ns-3-nsc plumbing)
Line 56: Line 56:
  
 
* Integrate nsc into ns-3 without circumventing ns-3s tcp/ip infrastructure
 
* Integrate nsc into ns-3 without circumventing ns-3s tcp/ip infrastructure
 +
 +
Done as of June 1st, although there is room for improvement (e.g. removing redundant code, cleanups, etc).
 +
 
* allow nsc to use layer2 code directly without having to piggyback data inside ns3-tcp
 
* allow nsc to use layer2 code directly without having to piggyback data inside ns3-tcp
 +
 +
Done, with a twist. Nsc uses layer 3 directly. For this to work, nsc-tcp-l4 does no longer include
 +
the nsc ipv4 header in the packet. Instead, the ns-3 ip header
 +
is used. The required ipv4 header checksum support was added to the ns-3 ipv4 header class.
 +
 
* extend ns-3 API so users can create "Linux-Nodes", "FreeBSD-Nodes", etc.
 
* extend ns-3 API so users can create "Linux-Nodes", "FreeBSD-Nodes", etc.
 +
 +
Partially done. One can call 'internet.SetTcpType("Linux");' before internet.Install().
 +
Also, a second version of Install() that takes a node argument was added, thus allowing
 +
mixed setups.
 +
 
* allow different nodes to use all kinds of nsc stacks in the same simulation.
 
* allow different nodes to use all kinds of nsc stacks in the same simulation.
 +
 +
Done. All stacks that ship with nsc-0.3.0 work, with the following known problems:
 +
The nsc glue code for the lwip stack causes problems when more than 0xFFFF bytes
 +
are passed into the Send() routine. Simple fix has been sent to Sam Jansen.
 +
Running the tcp-large-transfer example with Linux 2.6.18 triggers a segfault after simulation completion. A fix has
 +
been sent to Sam (All generated trace files are fine, though).
 +
 +
* Think about the ns-3-nsc API. It is desirable to allow a simulation to use nsc-setsockopts and tune the nsc stack via available sysctl tunables (e.g. for disabling SACK support on Linux at run time).
 +
 +
 +
  
 
Depending on whats required/requested this project will also extend nsc to support a more
 
Depending on whats required/requested this project will also extend nsc to support a more
 
recent linux kernel release, but this will happen only after the main intergration into ns-3 is complete.
 
recent linux kernel release, but this will happen only after the main intergration into ns-3 is complete.
 +
 +
 +
 +
== ns-3-nsc ==
 +
 +
This is here to document some parts of the actual ns-3/nsc plumbing.
 +
 +
The two main parts are:
 +
 +
* nsc-tcp-l4-protocol, a subclass of TcpL4Protocol (and two nsc classes: ISendCallback and IInterruptCallback)
 +
* nsc-tcp-socket-impl, a subclass of TcpSocket
 +
 +
 +
=== nsc-tcp-l4-protocol ===
 +
 +
This is the main class. Upon Initialization, it loads an nsc network stack to use (via dlopen()).
 +
Each instance of this class may use a different stack. The stack (=shared library) to use
 +
is set using the SetNscLibrary() method (at this time its called indirectly via the internet stack helper).
 +
The nsc stack is then set up accordingly (timers etc).
 +
The NscTcpL4Protocol::Receive() function hands the packet it receives (must be a complete tcp/ip packet)
 +
to the nsc stack for further processing.
 +
TO be able to send packets, this class implements the nsc send_callback method. This method
 +
is called by nsc whenever the nsc stack wishes to send a packet out to the network.
 +
Its arguments are a raw buffer, containing a complete Tcp/ip packet, and a length value.
 +
This method therefore has to convert the raw data to a Ptr<Packet> usable by ns-3.
 +
In order to avoid various ipv4 header issues, the nsc ip header is not included.
 +
Instead, the tcp header and the actual payload are put into the Ptr<Packet>, after
 +
this the Packet is passed down to layer 3 for sending the packet out (no further
 +
special treatment is needed in the send code path).
 +
 +
This class calls nsc-tcp-socket-impl both from the nsc wakeup() callback
 +
and from the Receive path (to ensure that possibly queued data is scheduled
 +
for sending).
 +
 +
 +
=== nsc-tcp-socket-impl ===
 +
 +
This implements the nsc socket interface. Each instance has its own nscTcpSocket.
 +
Data that is Send() will be handed to the nsc stack via m_nscTcpSocket->send_data().
 +
(and not to nsc-tcp-l4, this is the major difference compared to ns-3).
 +
The class also queues up data that is Send() before the underlying descriptor
 +
has entered an ESTABLISHED state.
 +
This class is called from the nsc-tcp-l4 class, when the nsc-tcp-l4 wakeup() callback
 +
is invoked by nsc. nsc-tcp-socket-impl then checks the current
 +
connection state (SYN_SENT, ESTABLISHED, LISTEN...) and schedules appropriate callbacks
 +
as needed, e.g. a LISTEN socket will schedule Accept to see if a new connection must
 +
be accepted, an ESTABLISHED socket schedules any pending data for writing, schedule
 +
a read callback, etc.
 +
  
 
== Current Status ==
 
== Current Status ==
 
The [http://hg.strlen.de/cgi-bin/hgwebdir.cgi/ns-3-nsc/ ns-3-nsc integration repository]
 
The [http://hg.strlen.de/cgi-bin/hgwebdir.cgi/ns-3-nsc/ ns-3-nsc integration repository]
 
contains the current status. This port uses the latest nsc release (0.3.0).
 
contains the current status. This port uses the latest nsc release (0.3.0).
To ease debugging, PcapWriter::WritePacket was changed to unconditionally skip the
+
The nsc glue code has been moved off to its own files in src/internet-node:
ns-3 TCP/IP header. This allows to load trace files into e.g. wireshark to see
+
the 'real' packets sent/received by NSC.
+
Work on this is ongoing, the current focus is to move all ns-3 glue code off to its own
+
files within src/internet-node (mostly completed):
+
  
 
* src/internet-node/nsc-tcp-socket-impl.cc contains ns-3s tcp-socket code, with nsc modifications.
 
* src/internet-node/nsc-tcp-socket-impl.cc contains ns-3s tcp-socket code, with nsc modifications.
 
* src/internet-node/nsc-tcp-l4-protocol.cc contains the ns3 tcp-l4 code, with nsc modifications.
 
* src/internet-node/nsc-tcp-l4-protocol.cc contains the ns3 tcp-l4 code, with nsc modifications.
 +
* src/internet-node/nsc-ipv4-l3-protocol.cc is identical with ipv4-l3-protocol.cc, except
 +
that it does not remove the ip header before forwarding the packet to nsc-tcp-l4-protocol.cc .
 +
This can probably be solved differently, for example by re-assembling the ip header in nsc-tcp-l4.
 +
 +
 +
At this time, both nsc-tcp-socket-impl and nsc-tcp-l4-protocol still contain lots of duplicate
 +
code from their ns-3 counterparts; work is in progress to gradually remove those.
  
At this time, both are essentially copies of their ns-3 counterpart; this makes it easier to
+
AddInternetStack() has been extended to allow setting a TcpStack to use, this allows
see the actual nsc modifications in diff output; the redundant (and unused) parts will be removed later.
+
a simulation to switch to a particular stack supported by NSC.
AddInternetStack() has been changed to create a NscTcpL4Protocol() object unconditionally, this is
+
currently the only major modification to ns-3 code (in fact, removing this modification disables
+
nsc support).
+

Revision as of 14:48, 2 June 2008

Network Simulation Cradle Integration

Network Simulation Crade (nsc) is a project to allow real-world network stacks to be used in simulated networks. A porting effort to bring nsc to version 3 of the network simulator was started by Tom Henderson. This Project continues this work and also will update at least the Linux network stack to current git (2.6.26).

Limitations

The existing porting effort is still in an early stage. ns3-nsc is able to run the tcp-large-transfer example that is included in ns-3. However, at this time the socket that accepts the connection leaks the listen socket and nsc-tcp is piggybacked within a ns-3 tcp connection (increasing all packets by 40 bytes).

NSC API

NSC provides its API in the form of a number of classes which are defined in sim/sim_interface.h in the nsc directory.

These are:

INetStack

INetStack contains the 'low level' operations for the operating system network stack, e.g. in and output functions from and to the network stack (think of this as the 'network driver interface'. There are also functions to create new TCP or UDP sockets.

ISendCallback

This is called by NSC when a packet should be sent out to the network. This simulator should use this callback to re-inject the packet into the simulator so the actual data can be delivered/routed to its destination, where it will eventually be handed into Receive() (and eventually back to the receivers NSC instance via INetStack->if_receive() ).

INetStreamSocket

This is the structure defining a particular connection endpoint (file descriptor). It contains methods to operate on this endpoint, e.g. connect, disconnect, accept, listen, send_data/read_data, ...

IInterruptCallback

This contains the wakeup callback, which is called by NSC whenever something of interest happens. Think of wakeup() as a replacement of the operating systems wakeup function: Whenever the operating system would wake up a process that has been waiting for an operation to complete (for example the TCP handshake during connect()), NSC invokes the wakeup() callback to allow the simulator to check for state changes in its connection endpoints.


Plan

  • Integrate nsc into ns-3 without circumventing ns-3s tcp/ip infrastructure

Done as of June 1st, although there is room for improvement (e.g. removing redundant code, cleanups, etc).

  • allow nsc to use layer2 code directly without having to piggyback data inside ns3-tcp

Done, with a twist. Nsc uses layer 3 directly. For this to work, nsc-tcp-l4 does no longer include the nsc ipv4 header in the packet. Instead, the ns-3 ip header is used. The required ipv4 header checksum support was added to the ns-3 ipv4 header class.

  • extend ns-3 API so users can create "Linux-Nodes", "FreeBSD-Nodes", etc.

Partially done. One can call 'internet.SetTcpType("Linux");' before internet.Install(). Also, a second version of Install() that takes a node argument was added, thus allowing mixed setups.

  • allow different nodes to use all kinds of nsc stacks in the same simulation.

Done. All stacks that ship with nsc-0.3.0 work, with the following known problems: The nsc glue code for the lwip stack causes problems when more than 0xFFFF bytes are passed into the Send() routine. Simple fix has been sent to Sam Jansen. Running the tcp-large-transfer example with Linux 2.6.18 triggers a segfault after simulation completion. A fix has been sent to Sam (All generated trace files are fine, though).

  • Think about the ns-3-nsc API. It is desirable to allow a simulation to use nsc-setsockopts and tune the nsc stack via available sysctl tunables (e.g. for disabling SACK support on Linux at run time).



Depending on whats required/requested this project will also extend nsc to support a more recent linux kernel release, but this will happen only after the main intergration into ns-3 is complete.


ns-3-nsc

This is here to document some parts of the actual ns-3/nsc plumbing.

The two main parts are:

  • nsc-tcp-l4-protocol, a subclass of TcpL4Protocol (and two nsc classes: ISendCallback and IInterruptCallback)
  • nsc-tcp-socket-impl, a subclass of TcpSocket


nsc-tcp-l4-protocol

This is the main class. Upon Initialization, it loads an nsc network stack to use (via dlopen()). Each instance of this class may use a different stack. The stack (=shared library) to use is set using the SetNscLibrary() method (at this time its called indirectly via the internet stack helper). The nsc stack is then set up accordingly (timers etc). The NscTcpL4Protocol::Receive() function hands the packet it receives (must be a complete tcp/ip packet) to the nsc stack for further processing. TO be able to send packets, this class implements the nsc send_callback method. This method is called by nsc whenever the nsc stack wishes to send a packet out to the network. Its arguments are a raw buffer, containing a complete Tcp/ip packet, and a length value. This method therefore has to convert the raw data to a Ptr<Packet> usable by ns-3. In order to avoid various ipv4 header issues, the nsc ip header is not included. Instead, the tcp header and the actual payload are put into the Ptr<Packet>, after this the Packet is passed down to layer 3 for sending the packet out (no further special treatment is needed in the send code path).

This class calls nsc-tcp-socket-impl both from the nsc wakeup() callback and from the Receive path (to ensure that possibly queued data is scheduled for sending).


nsc-tcp-socket-impl

This implements the nsc socket interface. Each instance has its own nscTcpSocket. Data that is Send() will be handed to the nsc stack via m_nscTcpSocket->send_data(). (and not to nsc-tcp-l4, this is the major difference compared to ns-3). The class also queues up data that is Send() before the underlying descriptor has entered an ESTABLISHED state. This class is called from the nsc-tcp-l4 class, when the nsc-tcp-l4 wakeup() callback is invoked by nsc. nsc-tcp-socket-impl then checks the current connection state (SYN_SENT, ESTABLISHED, LISTEN...) and schedules appropriate callbacks as needed, e.g. a LISTEN socket will schedule Accept to see if a new connection must be accepted, an ESTABLISHED socket schedules any pending data for writing, schedule a read callback, etc.


Current Status

The ns-3-nsc integration repository contains the current status. This port uses the latest nsc release (0.3.0). The nsc glue code has been moved off to its own files in src/internet-node:

  • src/internet-node/nsc-tcp-socket-impl.cc contains ns-3s tcp-socket code, with nsc modifications.
  • src/internet-node/nsc-tcp-l4-protocol.cc contains the ns3 tcp-l4 code, with nsc modifications.
  • src/internet-node/nsc-ipv4-l3-protocol.cc is identical with ipv4-l3-protocol.cc, except

that it does not remove the ip header before forwarding the packet to nsc-tcp-l4-protocol.cc . This can probably be solved differently, for example by re-assembling the ip header in nsc-tcp-l4.


At this time, both nsc-tcp-socket-impl and nsc-tcp-l4-protocol still contain lots of duplicate code from their ns-3 counterparts; work is in progress to gradually remove those.

AddInternetStack() has been extended to allow setting a TcpStack to use, this allows a simulation to switch to a particular stack supported by NSC.