115 lines
4.5 KiB
Plaintext
115 lines
4.5 KiB
Plaintext
@node Node and NetDevices
|
|
@chapter Node and NetDevices
|
|
@anchor{chap:Node}
|
|
|
|
This chapter describes how ns-3 nodes are put together, and provides
|
|
a walk-through of how packets traverse an internet-based Node.
|
|
|
|
@float Figure,fig:node
|
|
@caption{High-level node architecture.}
|
|
@image{figures/node,5in}
|
|
@end float
|
|
|
|
In ns-3, nodes are instances of @code{class Node}. This class
|
|
may be subclassed, but instead, the conceptual model is that
|
|
we @emph{aggregate} or insert objects to it rather than define
|
|
subclasses.
|
|
|
|
One might think of a bare ns-3 node as a shell of a computer,
|
|
to which one may add NetDevices (cards) and other innards including
|
|
the protocols and applications. @ref{fig:node} illustrates
|
|
that Node objects contain a list of Applications (initially,
|
|
the list is empty), a list of NetDevices (initially, the list
|
|
is empty), a list of ProtocolHandlers, a unique integer ID, and
|
|
a system ID (for distributed simulation).
|
|
|
|
The design tries to avoid putting too many dependencies on the
|
|
base class Node, Application, or NetDevice for the following:
|
|
@itemize @bullet
|
|
@item IP version, or whether IP is at all even used in the Node.
|
|
@item implementation details of the IP stack
|
|
@end itemize
|
|
|
|
From a software perspective, the lower interface of applications
|
|
corresponds to the C-based sockets API. The upper interface
|
|
of NetDevice objects corresponds to the device independent
|
|
sublayer of the Linux stack. Everything in between can be
|
|
aggregated and plumbed together as needed.
|
|
|
|
Let's look more closely at the protocol demultiplexer. We want
|
|
incoming frames at layer-2 to be delivered to the right layer-3
|
|
protocol such as Ipv4. The
|
|
function of this demultiplexer is to register callbacks for
|
|
receiving packets. The callbacks are indexed based on the
|
|
@uref{http://en.wikipedia.org/wiki/EtherType,,EtherType}
|
|
in the layer-2 frame.
|
|
|
|
Many different types of higher-layer protocols may be
|
|
connected to the NetDevice, such as IPv4, IPv6, ARP,
|
|
MPLS, IEEE 802.1x, and packet sockets. Therefore, the
|
|
use of a callback-based demultiplexer avoids the need to
|
|
use a common base class for all of these protocols, which
|
|
is problematic because of the different types of objects
|
|
(including packet sockets) expected to be registered there.
|
|
|
|
Each NetDevice delivers packets to a callback with the following
|
|
signature:
|
|
@verbatim
|
|
/**
|
|
* \param device a pointer to the net device which is calling this callback
|
|
* \param packet the packet received
|
|
* \param protocol the 16 bit protocol number associated with this packet.
|
|
* This protocol number is expected to be the same protocol number
|
|
* given to the Send method by the user on the sender side.
|
|
* \param address the address of the sender
|
|
* \returns true if the callback could handle the packet successfully,
|
|
* false otherwise.
|
|
*/
|
|
typedef Callback<bool, Ptr<NetDevice>, Ptr<Packet>, uint16_t,
|
|
const Address &> ReceiveCallback;
|
|
@end verbatim
|
|
|
|
There is a function in class Node that matches that signature:
|
|
@verbatim
|
|
private:
|
|
bool ReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet>,
|
|
uint16_t protocol, const Address &from);
|
|
@end verbatim
|
|
|
|
However, users do not need to access this function directly. Instead,
|
|
when users call @code{uint32_t AddDevice (Ptr<NetDevice> device)},
|
|
the implementation of this function sets the callback (and the
|
|
function returns the ifIndex of the NetDevice on that Node).
|
|
|
|
But what does the ReceiveFromDevice function do? Here, it looks
|
|
up another callback, in its list of callbacks, corresponding to the
|
|
matching EtherType. This callback is called a ProtocolHandler, and
|
|
is specified as follows:
|
|
@verbatim
|
|
typedef Callback<void, Ptr<NetDevice>, Ptr<Packet>, uint16_t,
|
|
const Address &> ProtocolHandler;
|
|
@end verbatim
|
|
|
|
Upper-layer protocols or objects are expected to provide such a function.
|
|
and register it with the list of ProtocolHandlers by calling
|
|
@code{Node::RegisterProtocolHandler ();}
|
|
For instance, if Ipv4 is aggregated to a Node, then the Ipv4 receive
|
|
function can be registered with the protocol handler by calling:
|
|
@verbatim
|
|
RegisterProtocolHandler (
|
|
MakeCallback (&Ipv4L3Protocol::Receive, ipv4),
|
|
Ipv4L3Protocol::PROT_NUMBER, 0);
|
|
@end verbatim
|
|
and likewise for Ipv6, ARP, etc.
|
|
|
|
@section NodeList
|
|
|
|
Every Node created is automatically added to the ns-3 @code{NodeList}.
|
|
The NodeList class provides an @code{Add()} method and C++ iterators
|
|
to allow one to walk the node list or fetch a Node pointer by
|
|
its integer identifier.
|
|
|
|
The following chapters provide reference information on the available
|
|
NetDevices in ns-3.
|
|
|