With a reservation, pending a more thorough investigation by Francisco Javier Ros Munoz, I want to make a note of what I percieve as a bug in the UM-OLSR v.0.8.8 code.

In case of link layer notification, the code works as specified in the RFC, deleting all MPR selector tuples with the neighbor causing the link break. However, this is done using a function in the OLSR_state.cc “erase_mprsel_tuples(..)“, while other additions and deletions of MPR selector tuples are performed using the functions in OLSR.cc “add_mprsel_tuple(..)” and “rm_mprsel_tuple(..)

The difference between the function in OLSR_state.cc and the functions in OLSR.cc is that there is no incrementation of the sequence number ansn_ in the OLSR_state.cc function. This breaks with the RFC and has the effect that nodes outside the 2hop neighbor range can receive a TC from the node discovering the link break with the same ansn_ as a former TC. Although the new TC does not report the broken link neighbor as an MPR selector, the nodes receiving the TC will not remove this tuple, since the ansn_ is not higher than the former TC message. This may then cause unnecessary loops.

A solution to this bug can be implemented through changing OLSR.cc, OLSR_state.h and OLSR_state.cc as follows:

OLSR.cc:
Change the function nb_loss(OLSR_link_tuple* tuple) to the following:

void OLSR::nb_loss(OLSR_link_tuple* tuple) {
debug("%f: Node %d detects neighbor %d loss\n",
CURRENT_TIME,
OLSR::node_id(ra_addr()),
OLSR::node_id(tuple->nb_iface_addr()));
updated_link_tuple(tuple);
state_.erase_nb2hop_tuples(get_main_addr(tuple->nb_iface_addr()));
if (state_.erase_mprsel_tuples(get_main_addr(tuple->nb_iface_addr())) == true){
// Erl - here was a bug before, not incrementing the ANSN value.
ansn_ = (ansn_ + 1)%(OLSR_MAX_SEQ_NUM + 1);
}
mpr_computation();
rtable_computation();
}

OLSR_state.h:
Change the return parameter of OLSR_state::erase_mprsel_tuples(nsaddr_t main_addr) from void to bool.

OLSR_state.cc:
Change the function erase_mprsel_tuples(nsaddr_t main_addr) to the following:

bool OLSR_state::erase_mprsel_tuples(nsaddr_t main_addr) {
bool r = false;
for (mprselset_t::iterator it = mprselset_.begin(); it != mprselset_.end(); it++) {
OLSR_mprsel_tuple* tuple = *it;
if (tuple->main_addr() == main_addr) {
it = mprselset_.erase(it);
it--;
r = true;
}
}
return r;
}

Any comments are welcome!

Advertisements