This walkthrough is for implementing Ingress Queuing for OLSR in ns-2. The OLSR version is as implemented by the University of Murcia. Ingress Queuing is presented by Lars Landmark, Knut Øvsthus and Øivind Kure in “Alternative packet forwarding for otherwise discarded packets”, FGCN2007, and the walkthrough is based on ns-2.34.

In principle, Ingress Queuing is the possibility to route packets immediately before handing them to the network card, meaning AFTER the packets have been queued in the interface queue. All that is required is for the MAC-layer code to request a routing operation from the routing protocol as the packet is fetched from the interface queue to be transmitted. The benefit of such a mechanism is that possible route changes that are discovered by the routing protocol after a packet has been committed to the interface queue with a routed link layer next hop address can be used to increase the probability of transmission success.

Changes are required to:
– the script file, where the routing protocol handle must be sent to the mac protocol.
– the routing protocol’s main file and header file, to deliver the handle to the mac protocol.
– the mac protocol’s main file and header file, to receive the handle from the routing protocol and to do the extra routing operation.

Changes to the script file:
The initialization of all nodes in the network must be appended with the passing of a routing protocol handle to the mac protocol.

for {set i 0} {$i < $opt(nn) } {incr i} {
set node_($i) [$ns_ node]
$node_($i) random-motion 0 ;# disable random motion
puts "Routing access from mac for node $i: "
set nmac_($i) [$node_($i) set mac_(0)]
set nolsr_($i) [$node_($i) agent 255]
$nmac_($i) register-olsr $nolsr_($i)

Changes to the OLSR code in to enable the mac layer to check up the newest next hop:

nsaddr_t OLSR::lookup(nsaddr_t a)
OLSR_rt_entry* entry = rtable_.lookup(a);

if (entry == NULL) {
return -1;
else {
entry = rtable_.find_send_entry(entry);
assert(entry != NULL);
return entry->next_addr();
return -1;

Changes to OLSR.h:

nsaddr_t lookup(nsaddr_t);

Changes to mac-802_11.h:
#include "olsr/OLSR.h"
And under private variables:
OLSR* olsr_;
int ingress_;

Changes to
At the top, right after the includes:

#define IP_MULTICAST 0xE000000

Inside the construct, at the end:
bind_bool("ingress", &ingress_);
Inside the int Mac802_11::command(int argc, const char*const* argv) function right before the end of the if (argc == 3):

else if(strcmp(argv[1], "register-olsr") == 0 ){
olsr_ = (OLSR*)TclObject::lookup(argv[2]);
printf("Registering olsr: %s\n",argv[2]);
return TCL_OK;

In addition in function void Mac802_11::recv(Packet *p, Handler *h) right after the line if(hdr->direction() == hdr_cmn::DOWN) {:

if (hdr->ptype() != PT_OLSR && hdr->addr_type() == NS_AF_INET)
if (ingress_ == true){
struct hdr_ip *ih = HDR_IP(p);
nsaddr_t nexthop = olsr_->lookup(ih->daddr());
nsaddr_t oldhop = hdr->next_hop();
if (nexthop != -1){
if (hdr->next_hop() != nexthop){
if (ih->daddr() == nexthop)
//printf("(%f) %d from %d to %d, next hop now %d, not %d.\n",now,hdr->uid(),index_,ih->daddr(),nexthop,hdr->next_hop() );

hdr->next_hop_ = olsr_->lookup(ih->daddr());
struct hdr_mac* dh = HDR_MAC(p);
char *mh = (char*)HDR_MAC(p);
dh->macDA() = nexthop;
hdr_dst(mh, nexthop);
//printf("changed from %d to %d\n",oldhop,hdr->next_hop());
else if (ih->daddr() handle((Event*) 0);