Unexplained packet losses in NS-3: Where is my packet?

The NS-3 simulator tries to mimic as close as possible the journey of a packet through the IP-stack’s layers. Passing the packet from one layer to the next one is done through Callbacks or functions which access the packet. In this way, NS-3’s callbacks are taking successively control over the packet, which remains static.

 In NS-3 a packet can “travel” in two ways within :

  • From the upper layer (application layer) down to the lower layers (NetDevice)

  • From the lower layers up to the top layers

Depending on the situation, the packet can traverse the stack either by calling the specific function from a class or by using callbacks.

 This post describes some possible reasons behind unexpected packet “loss” in the stack without the user noticing. If not tackled and/or accounted for, these losses might leave your simulations results biased and you can hardly make any reasonable supported conclusions from your experiments.

In what follows, I present three possible ways your packets can get lost on their way to the network. I came across the three cases below as I was scratching my head over mysteriously disappearing packets in NS-3. Here what you should check if you think you are losing more packets than you should in your simulation.

1)   WifiMacQueue class

When a packet is received by the MAC layer and before being sent to the PHY layer, it is queued in the interface’s internal queue.  The length of this queue is set through the m_maxSize parameter (by default set to 400).

So, before the packet gets en-queued in the queue,  NS-3 first check whether there is enough space in the MAC queue:

1. if (m_size == m_maxSize)
2. {
4.     return;
5. }
6. Time now = Simulator::Now ();
7. m_queue.push_back (Item (packet, hdr, now));

As it can be observed in the code above, if there is space left, the packet is pushed in the queue.If not, the function returns with no message. This means the packet will not be processed by any other callback or function, hence will be considered “lost”.

What is happening here is that the application is sending more packets than the MAC layer can process – could be due to a congested medium.

If you want to track packets lost due to insufficient MAC queue you could use the NS_LOG_INFO with an adequate message. An example of such message is listed below and can be incorporated at line 3.:

 NS_LOG_INFO (“Packet dropped due to Wifi Mac queue full”);

Additional, you must use

LogComponentEnable (“WifiMacQueue”,LOG_LEVEL_INFO);

in the main simulation script.

2)   ARP Protocol

Before sending a packet to the next node, the current node needs to know the MAC address of the next hop. Hence, it sends an ARP request for every packet it receives and doesn’t have a MAC address for its next hop.

The problem is that until an ARP reply is received, the packets are saved into an ARP pending queue. This queue can keep only 2 packets. Hence, any other packet, which arrives between the ARP request and the ARP reply message, will be dropped.

You can always increase the size of this queue to allow for more time for the ARP discovery process.


1. NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", wait reply for " << destination << " valid -- drop previous");
2. if (!entry->UpdateWaitReply (packet))
3. {
4.     m_dropTrace (packet);
5. }

In order to observe packets lost due to the ARP pending queue, ArpL3Protocol component must be enabled through LogComponentEnable  in the main simulation script:

LogComponentEnable (“ArpL3Protocol”,LOG_LEVEL_LOGIC);


3)   Self-originated packets

Another place (less likely) where packets can get dropped without notification is inside the RoutingProtocol class.

When a packet arrives from the NetDevice layer, to be forwarded or delivered, the function RouteInput()  is called from the RoutingProtocol class. This function passes the ownership of the packet to the routing protocol object. Four possible callback can happen: to deliver the packet locally (through lcb callback), to unicast it (through ucb callback), to multicast it or to return an error.

But before any of the four callbacks, the following  condition is checked:

1. if (IsMyOwnAddress (origin) == true)
2. {
3.     return true;
4. }

Any packet, which matches the if-clause, is not processed any further. Hence, in the unlikely event that a packet in the re-routing process has to go on a path traversing the originating node, it will not be processed, and more important, the ns-3 user is not notified about this silent packet drop.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s