From Nsnam
Jump to: navigation, search


The NS-3 Click Integration code is publicly available here.


Why ns-3-click?

One of the main motivations behind the Click Modular Router was to provide a flexible platform for easy protocol development and testing. The idea behind integrating ns-2 with Click was to bridge simulation and deployment, and thus bring the flexibility of Click to ns-2. The current implementation of nsclick has several flaws that make it cumbersome to use, thus acting against the advantages of using Click. Some of these drawbacks are as follows:

  • nsclick works only with ns-2 raw packets because the ns-2 simulator does not deal with real world packet formats.
  • As a consequence of the above, nsclick does not work with all kinds of traffic generator and transport. This can be overcome in ns-3-click.
  • Nsclick needed extensions to account for different kinds of interfaces. This lead to the implementation of the madwifi driver for nsclick.

ns-3's design is well suited for an integration with Click due to the following reasons:

  • Packets in ns-3 are serialised/deserialised as they move up/down the stack. This allows ns-3 packets to be passed to and from Click as they are.
  • This also means that any kind of ns-3 traffic generator and transport should work easily on top of Click.
  • By striving to implement click as an Ipv4RoutingProtocol instance, we can avoid significant changes to the LL and MAC layer of the ns-3 code.

The design goal would be to make the ns-3-click public API simple enough such that the user needs to merely add an Ipv4ClickRouting instance to the node, and inform each Click node of the Click configuration file (.click file) that it is to use.

Project Components

The ns-3-click project comprises of the following components:

  • Developing a Simulator API which will allow ns-3 to talk with Click and vice versa.
  • Timer synchronisation between ns-3 and Click.
  • Setting up packet hand off points between ns-3 and Click.
  • Test Cases.
  • Helper API for the end user.

Component Specifics

Developing a Simulator API which will allow ns-3 to talk with Click and vice versa:

Much of the API is already well defined, which allows Click to probe for information from the simulator (like a Node's ID, an Interface ID and so forth). By retaining most of the methods, it should be possible to write new implementations specific to ns-3 for the same functionality.

Since we are trying to implement Click as a subclass of the Ipv4RoutingProtocol method, our aim is to have enough methods in the Simulator API which will allow us to provide the functionality provided by the following methods easily:

  • RouteOutput (), used for locally originated packets, and
  • RouteInput (), used for forwarding and or/delivering received packets.

Hence, for the Click integration with ns-3, I propose to make a subclass of Ipv4RoutingProtocol named Ipv4ClickRouting. Ipv4ClickRouting will handle most of the interaction with Click.

Timer synchronisation between ns-3 and Click:

The current nsclick implementation already has a method named simclick_gettimeofday() which acts as a gettimeofday() substitute for Click. In the ns-3 specific implementation of this method, we can simply make a call to Simulator::Now() to achieve this. Note that this work will be done as part of component 1 (Simulator API).

Furthermore, nsclick presently uses a special Click Queue and a special Link Layer implementation to talk between a simulated Click interface and the simulator's MAC layer. This has been done because Click works in real time unlike the ns-2 simulator. But the current version of Click provides a –simtime option, which turns Click into an event driven simulator. Using this, we can synchronise the ns-3 and Click timers with the added benefit of not having to implement a special Link Layer and avoiding the use of a special Click Queue to control packet transfer rates between ns-3 and Click.

Packet hand off between ns-3 and Click.

There are four kinds of packet hand-offs that can occur between ns-3 and Click.

Packet coming down the stack from layer 4 to layer 3:

Sending a packet down the stack at this point involves two steps. The first step is where RouteOutput() is called by the socket (in UdpSocketImpl/TcpSocketImpl) to obtain the correct routing table entry from the Ipv4RoutingProtocol instance. This information is used to set the source and destination addresses as required for the packet's IP headers. This then leads to a Send() call by the UdpSocketImpl/TcpSocketImpl instance and finally a Send() call by the UdpL4Protocol/TcpL4Protocol instance. This sequence of calls ultimately passes the packet onto the Ipv4L3Protocol component of the node.

For ns-3-click, the following is proposed:

  • We skip the call to Ipv4RoutingProtocol::RouteOutput(), and pass a packet without an IPv4 header onto Click. Click can then proceed to add the required headers as per the Click graph.
  • Modify the UdpL4Protocol/TcpL4Protocol Send() implementations such that for Click based nodes, the packets are passed on to Click using the simulator API.
  • The [TcpL4Protocol/UdpL4Protocol]::Send() implementations in this case would make a call to Ipv4ClickRouting::SendToExtRouter() in order to execute the handoff.

Packet coming up the stack from layer 3 to layer 4:

When the Ipv4L3Protocol receives a packet from the node's protocol handlers, it forwards the packet to the Ipv4RoutingProtocol instance using RouteInput(). The Ipv4RoutingProtocol then decides whether to forward the packet or to perform a local delivery. In case of a Local Delivery, the Ipv4RoutingProtocol makes a call to Ipv4L3Protocol::LocalDelivery(), which calls the Receive() method of UdpL4Protocol/TcpL4Protocol as is appropriate.

For ns-3-click, the following is proposed:

  • 1. Avoid passing the packet from NetDevice to Ipv4L3Protocol. This means that there won't be an explicit call to RouteInput(). Instead, the packet is delivered directly to Click from the NetDevice (as will be explained below). Click then decides whether the packet is to be locally delivered or forwarded.
  • In case of local delivery, Click will use the ToSimDevice() element and in turn, Ipv4ClickRouting's ReceiveFromExtRouter() function to transfer the packet to Ipv4ClickRouting. ReceiveFromExtRouter(), as shown in section, will make a call to Ipv4ClickRouting::Send() which will make a call to Ipv4L3Protocol::LocalDeliver(). This will avoid making changes to the Receive() methods of UdpL4Protocol/TcpL4Protocol.

Packet coming down the stack from layer 3 to layer 2:

A packet coming down the stack, after being processed by Click, can be sent out from Click using ToSimDevice(). ReceiveFromExtRouter() will then handle the packet accordingly and call Ipv4ClickRouting::Send() which will pass the packet to the Ipv4Interface instance of the node. If this node supports ARP, it will make use of the node's ArpL3Protocol instance. Hence, we leave ARP handling to ns-3 which implies that the user needn't make use of the ARPQuery element in the Click graph(s).

Packet coming up the stack from layer 2 to layer 3.

Presently, Ipv4L3Protocol::AddInterface() contains code which registers callbacks that cause Ipv4L3Protocol::Receive() to be called when the appropriate protocol number is matched by the corresponding protocol handler.

For ns-3-click, the following is proposed:

  • If the node is a Click Node, we register a callback which will pass the packet to Click rather than to the Ipv4L3Protocol instance. We then let Click handle the packet and decide if it is to be forwarded or to be locally delivered.
  • The implementation within Ipv4L3Protocol::AddInterface() can look something like:
if (node->IsClickNode())
   node->RegisterProtocolHandler (MakeCallback (pass_packet_to_click),
  				 Ipv4L3Protocol::PROT_NUMBER, device);
   node->RegisterProtocolHandler (MakeCallback
       (&Ipv4L3Protocol::Receive, this),
       Ipv4L3Protocol::PROT_NUMBER, device);

Test Cases:

In conformance with the ns-3 development model, test cases will be written as required to test the working of the Ipv4ClickRouting module. This will contain tests for verifying the functionality of the Simulator API, the time synchronisation between ns-3 and Click and the packet exchange between ns-3 and Click.

Click Helper and Public API:

The exposed public API and a helper class named ClickHelper will be developed to allow the user to bind a node with a specific Click configuration file and to also use any other options necessary.


  • An ns-3 simulator API for Click.
  • An Ipv4ClickRouting class that can be instantiated to have a node use Click for routing.
  • Test cases for the above implementations.
  • A ClickHelper class and the necessary public methods to allow users easily use ns-3-click.
  • Example scripts on how to use ns-3-click.
  • Documentation describing ns-3-click, its design and how to use it.

Each of the above will be implemented in the same order as has been described in section 2.4.3.


I propose to divide the project over the GSoC coding period as follows:

  • May 24th to May 31st : Identify key requirements for the Simulator API.
  • June 1st to June 7th : Code the Simulator API.
  • June 7th to June 9th : Prepare Test Cases to test the Simulator API.
  • June 9th to June 19th : Code the time synchronisation component.
  • June 19th to June 20th : Prepare Test Cases to test time synchronisation component.
  • June 20th to June 27th : Code Layer 4 to Layer 3 packet hand off.
  • June 28th to July 5th : Code Layer 3 to Layer 4 packet hand off.
  • July 6th to July 13th : Code Layer 3 to Layer 2 packet hand off.
  • July 14th to July 21st : Code Layer 2 to Layer 3 packet hand off.
  • July 21st to 24th : Prepare Test Cases to test packet hand off.
  • July 24th to July 31st : Code Helper API.
  • August 1st to August 10th : Write ns-3-click documentation and prepare example scripts.


The following milestones have been recorded with the project:

  • June 1st, 2010: Simulator API completed.
  • June 3rd, 2010: Test Cases for Simulator API completed.
  • June 3rd, 2010: Click nodes can now send UDP packets to a normal ns-3 node.
  • June 5th, 2010: Click nodes are now ready to establish TCP connections.
  • June 11th, 2010: Ipv4L3ClickProtocol implemented specifically for Click.
  • June 12th, 2010: Proof of concept for running Click with wifi done.
  • June 29th, 2010: Wifi and CSMA now work with a common interface.
  • July 3rd, 2010: IP Router Click graph tested successfully. (examples/click/
  • July 6th, 2010: Helper classes implemented.
  • July 20th, 2010: Added an example test for Click in the framework

Using ns-3-click

Build Instructions

The first step is to build Click. At the top of your Click source directory:

$: ./configure --enable-userlevel --disable-linuxmodule --enable-nsclick --enable-wifi
$: make

The --enable-wifi flag may be skipped if you don't intend on using Click with Wifi.

  • Note: You don't need to do a 'make install'.

Once Click has been built successfully, change into the ns-3 directory and configure ns-3 with Click Integration support:

$: ./waf configure --with-nsclick=/path/to/click/source

If it says 'enabled' beside 'NS-3 Click Integration Support', then you're good to go.

Next, try running one of the examples:

$: ./waf --run nsclick-simple-lan

You will find a lot of output being generated. This is because of the IPPrint and Print elements present in the configuration file that the example script uses.

Click Graph Instructions

The following should be kept in mind when making your Click graph:

  • Only userlevel elements can be used.
  • You will need to replace FromDevice and ToDevice elements with FromSimDevice and ToSimDevice elements.
  • Packets to the kernel are sent up using ToSimDevice(tap0,IP).
  • For any node, the 0th device will be tap0. The remaining devices should be eth0, eth1 and so forth (even if you're using wifi). Please note that the device numbering should begin from 0.
  • A routing table element is a mandatory. The OUTports of the routing table element should correspond to the interface number of the device through which the packet will ultimately be sent out. Violating this rule will lead to really weird packet traces. This routing table element's name should then be passed to the Ipv4ClickRouting protocol object as a simulation parameter. See the Click examples for details.
  • When using Wifi with ns-3-click, do not use wifi specific elements like WifiEncap, ExtraEncap, MadWifiRate etc. for outgoing packets. Incoming packets should have their Wifi headers removed using WifiDecap + ExtraDecap or Strip elements. See the file for an idea of the same.
  • When using Point to Point devices with Click, you needn't strip off any bytes when a packet is received from a device. Normally, this will leave you with an IP encapsulated packet.
  • The current implementation leaves Click with mainly L3 functionality, with ns-3 handling L2. We will soon begin working to support the use of MAC protocols on Click as well.

Setting up a Click based node

To have a node run Click, the easiest way would be to use the ClickInternetStackHelper class in your simulation script. For instance:

ClickInternetStackHelper click;
click.SetClickFile (myNodeContainer, "");
click.SetRoutingTableElement (myNodeContainer, "u/rt");
click.Install (myNodeContainer);

The example scripts inside examples/click/ demonstrate the use of Click based nodes in different scenarios.