Merge pull request #2500 from fnack/nhdp_optimize_rx

sys/nhdp: Remove temp address lists to optimize hello processing
This commit is contained in:
Oleg Hahm 2015-04-09 18:43:18 +02:00
commit 087b51e10b
8 changed files with 176 additions and 292 deletions

View File

@ -40,23 +40,17 @@ static iib_base_entry_t *iib_base_entry_head = NULL;
/* Internal function prototypes */
static void rem_link_set_entry(iib_base_entry_t *base_entry, iib_link_set_entry_t *ls_entry);
static void cleanup_link_sets(nhdp_addr_entry_t *rem_list);
static void cleanup_link_sets(void);
static iib_link_set_entry_t *add_default_link_set_entry(iib_base_entry_t *base_entry, timex_t *now,
uint64_t val_time);
static void reset_link_set_entry(iib_link_set_entry_t *ls_entry, timex_t *now, uint64_t val_time);
static iib_link_set_entry_t *update_link_set(iib_base_entry_t *base_entry, nib_entry_t *nb_elt,
nhdp_addr_entry_t *send_list, timex_t *now,
uint64_t val_time, uint8_t sym, uint8_t lost);
timex_t *now, uint64_t val_time,
uint8_t sym, uint8_t lost);
static void release_link_tuple_addresses(iib_link_set_entry_t *ls_entry);
static int update_two_hop_set(iib_base_entry_t *base_entry, iib_link_set_entry_t *ls_entry,
nhdp_addr_entry_t *th_sym_list, nhdp_addr_entry_t *th_rem_list,
timex_t *now, uint64_t val_time);
static uint8_t rem_exst_th_entries(iib_base_entry_t *base_entry, iib_two_hop_set_entry_t *ts_elt,
nhdp_addr_entry_t *th_sym_list);
static uint8_t rem_non_sym_th_entries(iib_base_entry_t *base_entry,
iib_two_hop_set_entry_t *ts_elt,
nhdp_addr_entry_t *th_rem_list);
static int add_two_hop_entry(iib_base_entry_t *base_entry, iib_link_set_entry_t *ls_entry,
nhdp_addr_t *th_addr, timex_t *now, uint64_t val_time);
static void rem_two_hop_entry(iib_base_entry_t *base_entry, iib_two_hop_set_entry_t *th_entry);
@ -92,10 +86,8 @@ int iib_register_if(kernel_pid_t pid)
return 0;
}
int iib_process_hello(kernel_pid_t if_pid, nib_entry_t *nb_elt, nhdp_addr_entry_t *send_list,
nhdp_addr_entry_t *th_sym_list, nhdp_addr_entry_t *th_rem_list,
nhdp_addr_entry_t *rem_list, uint64_t validity_time, uint8_t is_sym_nb,
uint8_t is_lost)
int iib_process_hello(kernel_pid_t if_pid, nib_entry_t *nb_elt,
uint64_t validity_time, uint8_t is_sym_nb, uint8_t is_lost)
{
iib_base_entry_t *base_elt;
timex_t now;
@ -103,7 +95,7 @@ int iib_process_hello(kernel_pid_t if_pid, nib_entry_t *nb_elt, nhdp_addr_entry_
mutex_lock(&mtx_iib_access);
/* Remove link tuple addresses that are included in the Removed Addr List */
cleanup_link_sets(rem_list);
cleanup_link_sets();
LL_FOREACH(iib_base_entry_head, base_elt) {
/* Find the link set and two hop set for the interface */
@ -116,12 +108,12 @@ int iib_process_hello(kernel_pid_t if_pid, nib_entry_t *nb_elt, nhdp_addr_entry_
vtimer_now(&now);
/* Create a new link tuple for the neighbor that originated the hello */
iib_link_set_entry_t *ls_entry = update_link_set(base_elt, nb_elt, send_list,
&now, validity_time, is_sym_nb, is_lost);
iib_link_set_entry_t *ls_entry = update_link_set(base_elt, nb_elt, &now,
validity_time, is_sym_nb, is_lost);
/* Create new two hop tuples for signaled symmetric neighbors */
if (ls_entry) {
update_two_hop_set(base_elt, ls_entry, th_sym_list, th_rem_list, &now, validity_time);
update_two_hop_set(base_elt, ls_entry, &now, validity_time);
}
}
@ -232,32 +224,22 @@ void iib_propagate_nb_entry_change(nib_entry_t *old_entry, nib_entry_t *new_entr
/**
* Remove addresses included in the Removed Address List from all existing Link Tuples
*/
static void cleanup_link_sets(nhdp_addr_entry_t *rem_list)
static void cleanup_link_sets(void)
{
/* Check whether the Removed Address List is not empty */
if (!rem_list) {
return;
}
iib_base_entry_t *base_elt;
/* Loop through all link sets */
iib_base_entry_t *base_elt;
LL_FOREACH(iib_base_entry_head, base_elt) {
/* Loop through all link tuples of the link set */
iib_link_set_entry_t *ls_elt, *ls_tmp;
LL_FOREACH_SAFE(base_elt->link_set_head, ls_elt, ls_tmp) {
/* Loop through all addresses of the link tuples */
nhdp_addr_entry_t *lt_elt;
LL_FOREACH(ls_elt->address_list_head, lt_elt) {
/* Loop through all addresses of the Removed Addr List */
nhdp_addr_entry_t *rem_elt;
LL_FOREACH(rem_list, rem_elt) {
nhdp_addr_entry_t *lt_elt, *lt_tmp;
LL_FOREACH_SAFE(ls_elt->address_list_head, lt_elt, lt_tmp) {
if (NHDP_ADDR_TMP_IN_REM_LIST(lt_elt->address)) {
/* Remove link tuple address if included in the Removed Addr List */
if (lt_elt->address == rem_elt->address) {
/* Addresses are equal (same NHDP address db entry) */
LL_DELETE(ls_elt->address_list_head, lt_elt);
nhdp_free_addr_entry(lt_elt);
break;
}
}
}
@ -283,12 +265,12 @@ static void cleanup_link_sets(nhdp_addr_entry_t *rem_list)
* Update the Link Set for the receiving interface during HELLO message processing
*/
static iib_link_set_entry_t *update_link_set(iib_base_entry_t *base_entry, nib_entry_t *nb_elt,
nhdp_addr_entry_t *send_list, timex_t *now,
uint64_t val_time, uint8_t sym, uint8_t lost)
timex_t *now, uint64_t val_time,
uint8_t sym, uint8_t lost)
{
iib_link_set_entry_t *ls_elt, *ls_tmp;
iib_link_set_entry_t *matching_lt = NULL;
nhdp_addr_entry_t *lt_elt, *send_elt;
nhdp_addr_entry_t *lt_elt;
timex_t v_time, l_hold;
uint8_t matches = 0;
@ -296,11 +278,8 @@ static iib_link_set_entry_t *update_link_set(iib_base_entry_t *base_entry, nib_e
LL_FOREACH_SAFE(base_entry->link_set_head, ls_elt, ls_tmp) {
/* Loop through all addresses of the link tuple */
LL_FOREACH(ls_elt->address_list_head, lt_elt) {
/* Loop through all addresses of the Sending Addr List */
LL_FOREACH(send_list, send_elt) {
if (NHDP_ADDR_TMP_IN_SEND_LIST(lt_elt->address)) {
/* If link tuple address matches a sending addr we found a fitting tuple */
if (lt_elt->address == send_elt->address) {
/* Addresses are equal (same NHDP address db entry) */
matches++;
if (matches > 1) {
@ -315,12 +294,6 @@ static iib_link_set_entry_t *update_link_set(iib_base_entry_t *base_entry, nib_e
matching_lt = ls_elt;
break;
}
if (matching_lt == ls_elt) {
/* This link tuple is already detected as matching */
break;
}
}
}
}
@ -350,7 +323,7 @@ static iib_link_set_entry_t *update_link_set(iib_base_entry_t *base_entry, nib_e
l_hold = timex_from_uint64(((uint64_t)NHDP_L_HOLD_TIME_MS) * MS_IN_USEC);
/* Set Sending Address List as this tuples address list */
matching_lt->address_list_head = nhdp_generate_new_addr_list(send_list);
matching_lt->address_list_head = nhdp_generate_addr_list_from_tmp(NHDP_ADDR_TMP_SEND_LIST);
if (!matching_lt->address_list_head) {
/* Insufficient memory */
@ -520,7 +493,6 @@ static void release_link_tuple_addresses(iib_link_set_entry_t *ls_entry)
* Update the 2-Hop Set during HELLO message processing
*/
static int update_two_hop_set(iib_base_entry_t *base_entry, iib_link_set_entry_t *ls_entry,
nhdp_addr_entry_t *th_sym_list, nhdp_addr_entry_t *th_rem_list,
timex_t *now, uint64_t val_time)
{
/* Check whether a corresponding link tuple was created */
@ -531,7 +503,7 @@ static int update_two_hop_set(iib_base_entry_t *base_entry, iib_link_set_entry_t
/* If the link to the neighbor is still symmetric */
if (get_tuple_status(ls_entry, now) == IIB_LT_STATUS_SYM) {
iib_two_hop_set_entry_t *ths_elt, *ths_tmp;
nhdp_addr_entry_t *sym_elt;
nhdp_addr_t *addr_elt;
/* Loop through all the two hop tuples of the two hop set */
LL_FOREACH_SAFE(base_entry->two_hop_set_head, ths_elt, ths_tmp) {
@ -540,61 +512,24 @@ static int update_two_hop_set(iib_base_entry_t *base_entry, iib_link_set_entry_t
rem_two_hop_entry(base_entry, ths_elt);
}
else if (ths_elt->ls_elt == ls_entry) {
if (!rem_non_sym_th_entries(base_entry, ths_elt, th_rem_list)) {
rem_exst_th_entries(base_entry, ths_elt, th_sym_list);
if (ths_elt->th_nb_addr->in_tmp_table &
(NHDP_ADDR_TMP_TH_REM_LIST | NHDP_ADDR_TMP_TH_SYM_LIST)) {
rem_two_hop_entry(base_entry, ths_elt);
}
}
}
/* Add a new entry for every signaled symmetric neighbor address */
LL_FOREACH(th_sym_list, sym_elt) {
if (add_two_hop_entry(base_entry, ls_entry, sym_elt->address, now, val_time)) {
LL_FOREACH(nhdp_get_addr_db_head(), addr_elt) {
if (NHDP_ADDR_TMP_IN_TH_SYM_LIST(addr_elt)) {
if (add_two_hop_entry(base_entry, ls_entry, addr_elt, now, val_time)) {
/* No more memory available, return error */
return -1;
}
}
}
return 0;
}
/**
* Remove an existing 2-Hop Tuple if its address was signalled as lost in the received HELLO
*/
static uint8_t rem_non_sym_th_entries(iib_base_entry_t *base_entry,
iib_two_hop_set_entry_t *ts_elt,
nhdp_addr_entry_t *th_rem_list)
{
nhdp_addr_entry_t *rem_elt;
/* Remove the given two hop entry if it was signaled as lost */
LL_FOREACH(th_rem_list, rem_elt) {
if (ts_elt->th_nb_addr == rem_elt->address) {
/* Addresses are equal (same NHDP address db entry) */
rem_two_hop_entry(base_entry, ts_elt);
return 1;
}
}
return 0;
}
/**
* Remove an existing 2-Hop Tuple if it is present in the 2-Hop symmetric address
* list of the received HELLO
*/
static uint8_t rem_exst_th_entries(iib_base_entry_t *base_entry,
iib_two_hop_set_entry_t *ts_elt, nhdp_addr_entry_t *th_sym_list)
{
nhdp_addr_entry_t *sym_elt;
/* Remove the given two hop entry if it was signaled as symmetric (new one is added) */
LL_FOREACH(th_sym_list, sym_elt) {
if (ts_elt->th_nb_addr == sym_elt->address) {
/* Addresses are equal (same NHDP address db entry) */
rem_two_hop_entry(base_entry, ts_elt);
return 1;
}
}
return 0;
}

View File

@ -96,20 +96,14 @@ int iib_register_if(kernel_pid_t pid);
*
* @param[in] if_pid PID of the interface the message was received on
* @param[in] nb_elt Pointer to the Neighbor Tuple for the message originator
* @param[in] send_list Pointer to the Sending Address List from the received HELLO
* @param[in] th_sym_list Pointer to the Addr List of the originator's symmetric 2-Hop neighbors
* @param[in] th_rem_list Pointer to the Addr List of the originator's lost 2-Hop neighbors
* @param[in] rem_list Pointer to the Removed Address List
* @param[in] validity_time Validity time in milliseconds for the originator's information
* @param[in] is_sym_nb Flag whether the link to the originator is symmetric
* @param[in] is_lost Flag whether the originator marked this link as lost
*
* @return 0 on success
*/
int iib_process_hello(kernel_pid_t if_pid, nib_entry_t *nb_elt, nhdp_addr_entry_t *send_list,
nhdp_addr_entry_t *th_sym_list, nhdp_addr_entry_t *th_rem_list,
nhdp_addr_entry_t *rem_list, uint64_t validity_time, uint8_t is_sym_nb,
uint8_t is_lost);
int iib_process_hello(kernel_pid_t if_pid, nib_entry_t *nb_elt,
uint64_t validity_time, uint8_t is_sym_nb, uint8_t is_lost);
/**
* @brief Add addresses to the currently constructed HELLO message

View File

@ -115,12 +115,14 @@ void nhdp_free_addr_entry(nhdp_addr_entry_t *addr_entry)
free(addr_entry);
}
nhdp_addr_entry_t *nhdp_generate_new_addr_list(nhdp_addr_entry_t *orig_list)
nhdp_addr_entry_t *nhdp_generate_addr_list_from_tmp(uint8_t tmp_type)
{
nhdp_addr_entry_t *new_list_head, *addr_elt;
nhdp_addr_entry_t *new_list_head;
nhdp_addr_t *addr_elt;
new_list_head = NULL;
LL_FOREACH(orig_list, addr_elt) {
LL_FOREACH(nhdp_addr_db_head, addr_elt) {
if (addr_elt->in_tmp_table & tmp_type) {
nhdp_addr_entry_t *new_entry = (nhdp_addr_entry_t *) malloc(sizeof(nhdp_addr_entry_t));
if (!new_entry) {
@ -129,20 +131,31 @@ nhdp_addr_entry_t *nhdp_generate_new_addr_list(nhdp_addr_entry_t *orig_list)
return NULL;
}
new_entry->address = addr_elt->address;
new_entry->address = addr_elt;
/* Increment usage counter of address in central NHDP address storage */
addr_elt->address->usg_count++;
addr_elt->usg_count++;
LL_PREPEND(new_list_head, new_entry);
}
}
return new_list_head;
}
void nhdp_reset_addresses_tmp_usg(void)
void nhdp_reset_addresses_tmp_usg(uint8_t decr_usg)
{
nhdp_addr_t *addr_elt;
nhdp_addr_t *addr_elt, *addr_tmp;
LL_FOREACH(nhdp_addr_db_head, addr_elt) {
LL_FOREACH_SAFE(nhdp_addr_db_head, addr_elt, addr_tmp) {
if (addr_elt->in_tmp_table) {
addr_elt->in_tmp_table = NHDP_ADDR_TMP_NONE;
if (decr_usg) {
nhdp_decrement_addr_usage(addr_elt);
}
}
}
}
nhdp_addr_t *nhdp_get_addr_db_head(void)
{
return nhdp_addr_db_head;
}

View File

@ -51,9 +51,19 @@ typedef struct nhdp_addr_entry_t {
#define NHDP_ADDR_TMP_NONE (0x00)
#define NHDP_ADDR_TMP_ANY (0x01)
#define NHDP_ADDR_TMP_SYM (0x03)
#define NHDP_ADDR_TMP_REM_LIST (0x04)
#define NHDP_ADDR_TMP_TH_REM_LIST (0x08)
#define NHDP_ADDR_TMP_TH_SYM_LIST (0x10)
#define NHDP_ADDR_TMP_NB_LIST (0x20)
#define NHDP_ADDR_TMP_SEND_LIST (0x60)
#define NHDP_ADDR_TMP_IN_SYM(addr) ((addr->in_tmp_table & 0x02) >> 1)
#define NHDP_ADDR_TMP_IN_ANY(addr) ((addr->in_tmp_table & 0x01))
#define NHDP_ADDR_TMP_IN_SYM(addr) ((addr->in_tmp_table & 0x02) >> 1)
#define NHDP_ADDR_TMP_IN_REM_LIST(addr) ((addr->in_tmp_table & 0x04) >> 2)
#define NHDP_ADDR_TMP_IN_TH_REM_LIST(addr) ((addr->in_tmp_table & 0x08) >> 3)
#define NHDP_ADDR_TMP_IN_TH_SYM_LIST(addr) ((addr->in_tmp_table & 0x10) >> 4)
#define NHDP_ADDR_TMP_IN_NB_LIST(addr) ((addr->in_tmp_table & 0x20) >> 5)
#define NHDP_ADDR_TMP_IN_SEND_LIST(addr) ((addr->in_tmp_table & 0x40) >> 6)
/** @} */
/**
@ -97,22 +107,31 @@ void nhdp_free_addr_list(nhdp_addr_entry_t *list_head);
void nhdp_free_addr_entry(nhdp_addr_entry_t *addr_entry);
/**
* @brief Construct an address list containing the addresses of the given list
*
* @param[in] orig_list Pointer to the head of the address list to 'clone'
* @brief Construct an addr list containing all addresses with
* the given tmp_type
*
* @return Pointer to the head of the newly created address list
* @return NULL on error
*/
nhdp_addr_entry_t *nhdp_generate_new_addr_list(nhdp_addr_entry_t *orig_list);
nhdp_addr_entry_t *nhdp_generate_addr_list_from_tmp(uint8_t tmp_type);
/**
* @brief Reset in_tmp_table flag of all NHDP addresses
*
* @note
* Must not be called from outside the NHDP writer's message creation process.
* Must not be called from outside the NHDP writer's or reader's message creation process.
*
* @param[in] decr_usg Flag whether the usage counter of a resetted addr has to be decremented
*/
void nhdp_reset_addresses_tmp_usg(void);
void nhdp_reset_addresses_tmp_usg(uint8_t decr_usg);
/**
* @brief Get a pointer to the head of the address storage list
*
* @return Pointer to the head of the central storage address list
* @return NULL if no addresses are registered
*/
nhdp_addr_t *nhdp_get_addr_db_head(void);
#ifdef __cplusplus
}

View File

@ -36,12 +36,6 @@
struct rfc5444_reader reader;
static mutex_t mtx_packet_handler = MUTEX_INIT;
static nhdp_addr_entry_t *send_addr_list_head;
static nhdp_addr_entry_t *nb_addr_list_head;
static nhdp_addr_entry_t *th_sym_addr_list_head;
static nhdp_addr_entry_t *th_rem_addr_list_head;
static nhdp_addr_entry_t *rem_addr_list_head;
static kernel_pid_t if_pid;
static uint64_t val_time;
static uint64_t int_time;
@ -57,7 +51,6 @@ static enum rfc5444_result check_msg_validity(struct rfc5444_reader_tlvblock_con
static enum rfc5444_result check_addr_validity(nhdp_addr_t *addr);
static nhdp_addr_t *get_nhdp_db_addr(uint8_t *addr, uint8_t prefix);
static void process_temp_tables(void);
static void cleanup_temp_addr_lists(void);
/* Array containing the processable message TLVs for HELLO messages */
static struct rfc5444_reader_tlvblock_consumer_entry _nhdp_msg_tlvs[] = {
@ -93,13 +86,6 @@ static struct rfc5444_reader_tlvblock_consumer _nhdp_address_consumer = {
void nhdp_reader_init(void)
{
/* Reset locally created address lists */
send_addr_list_head = NULL;
nb_addr_list_head = NULL;
th_sym_addr_list_head = NULL;
th_rem_addr_list_head = NULL;
rem_addr_list_head = NULL;
/* Initialize reader */
rfc5444_reader_init(&reader);
@ -128,7 +114,6 @@ int nhdp_reader_handle_packet(kernel_pid_t rcvg_if_pid, void *buffer, size_t len
void nhdp_reader_cleanup(void)
{
cleanup_temp_addr_lists();
rfc5444_reader_cleanup(&reader);
}
@ -145,26 +130,18 @@ static enum rfc5444_result
_nhdp_blocktlv_address_cb(struct rfc5444_reader_tlvblock_context *cont)
{
uint8_t tmp_result;
/* Create address list entry to add it later to one of the temp address lists */
nhdp_addr_entry_t *current_addr = (nhdp_addr_entry_t *) malloc(sizeof(nhdp_addr_entry_t));
/* Get NHDP address for the current netaddr */
nhdp_addr_t *current_addr = get_nhdp_db_addr(&cont->addr._addr[0], cont->addr._prefix_len);
if (!current_addr) {
/* Insufficient memory */
return RFC5444_DROP_MESSAGE;
}
/* Get NHDP address for the current netaddr */
current_addr->address = get_nhdp_db_addr(&cont->addr._addr[0], cont->addr._prefix_len);
if (!current_addr->address) {
/* Insufficient memory */
free(current_addr);
return RFC5444_DROP_MESSAGE;
}
/* Check validity of address tlvs */
if (check_addr_validity(current_addr->address) != RFC5444_OKAY) {
nhdp_free_addr_entry(current_addr);
if (check_addr_validity(current_addr) != RFC5444_OKAY) {
nhdp_decrement_addr_usage(current_addr);
return RFC5444_DROP_MESSAGE;
}
@ -172,32 +149,20 @@ _nhdp_blocktlv_address_cb(struct rfc5444_reader_tlvblock_context *cont)
if (_nhdp_addr_tlvs[RFC5444_ADDRTLV_LOCAL_IF].tlv) {
switch (*_nhdp_addr_tlvs[RFC5444_ADDRTLV_LOCAL_IF].tlv->single_value) {
case RFC5444_LOCALIF_THIS_IF:
LL_PREPEND(send_addr_list_head, current_addr);
/* Local IF marked addresses have to be added to two temp lists */
nhdp_addr_entry_t *sec_container =
(nhdp_addr_entry_t *) malloc(sizeof(nhdp_addr_entry_t));
if (!sec_container) {
return RFC5444_DROP_MESSAGE;
}
/* Increment usage counter of address in central NHDP address storage */
current_addr->address->usg_count++;
sec_container->address = current_addr->address;
LL_PREPEND(nb_addr_list_head, sec_container);
current_addr->in_tmp_table = NHDP_ADDR_TMP_SEND_LIST;
break;
case RFC5444_LOCALIF_OTHER_IF:
LL_PREPEND(nb_addr_list_head, current_addr);
current_addr->in_tmp_table = NHDP_ADDR_TMP_NB_LIST;
break;
default:
/* Wrong value, drop message */
nhdp_free_addr_entry(current_addr);
nhdp_decrement_addr_usage(current_addr);
return RFC5444_DROP_MESSAGE;
}
}
else if ((tmp_result = lib_is_reg_addr(if_pid, current_addr->address))) {
else if ((tmp_result = lib_is_reg_addr(if_pid, current_addr))) {
/* The address is one of our local addresses (do not add it for processing) */
if ((!sym) && (tmp_result == 1) && _nhdp_addr_tlvs[RFC5444_ADDRTLV_LINK_STATUS].tlv) {
/* If address is a local address of the receiving interface, check */
@ -216,18 +181,18 @@ _nhdp_blocktlv_address_cb(struct rfc5444_reader_tlvblock_context *cont)
default:
/* Wrong value, drop message */
nhdp_free_addr_entry(current_addr);
nhdp_decrement_addr_usage(current_addr);
return RFC5444_DROP_MESSAGE;
}
}
/* Address is one of our own addresses, ignore it */
nhdp_free_addr_entry(current_addr);
nhdp_decrement_addr_usage(current_addr);
}
else if (_nhdp_addr_tlvs[RFC5444_ADDRTLV_LINK_STATUS].tlv) {
switch (*_nhdp_addr_tlvs[RFC5444_ADDRTLV_LINK_STATUS].tlv->single_value) {
case RFC5444_LINKSTATUS_SYMMETRIC:
LL_PREPEND(th_sym_addr_list_head, current_addr);
current_addr->in_tmp_table = NHDP_ADDR_TMP_TH_SYM_LIST;
break;
case RFC5444_LINKSTATUS_HEARD:
@ -238,39 +203,39 @@ _nhdp_blocktlv_address_cb(struct rfc5444_reader_tlvblock_context *cont)
&& *_nhdp_addr_tlvs[RFC5444_ADDRTLV_OTHER_NEIGHB].tlv->single_value
== RFC5444_OTHERNEIGHB_SYMMETRIC) {
/* Symmetric has higher priority */
LL_PREPEND(th_sym_addr_list_head, current_addr);
current_addr->in_tmp_table = NHDP_ADDR_TMP_TH_SYM_LIST;
}
else {
LL_PREPEND(th_rem_addr_list_head, current_addr);
current_addr->in_tmp_table = NHDP_ADDR_TMP_TH_REM_LIST;
}
break;
default:
/* Wrong value, drop message */
nhdp_free_addr_entry(current_addr);
nhdp_decrement_addr_usage(current_addr);
return RFC5444_DROP_MESSAGE;
}
}
else if (_nhdp_addr_tlvs[RFC5444_ADDRTLV_OTHER_NEIGHB].tlv) {
switch (*_nhdp_addr_tlvs[RFC5444_ADDRTLV_OTHER_NEIGHB].tlv->single_value) {
case RFC5444_OTHERNEIGHB_SYMMETRIC:
LL_PREPEND(th_sym_addr_list_head, current_addr);
current_addr->in_tmp_table = NHDP_ADDR_TMP_TH_SYM_LIST;
break;
case RFC5444_OTHERNEIGHB_LOST:
LL_PREPEND(th_rem_addr_list_head, current_addr);
current_addr->in_tmp_table = NHDP_ADDR_TMP_TH_REM_LIST;
break;
default:
/* Wrong value, drop message */
nhdp_free_addr_entry(current_addr);
nhdp_decrement_addr_usage(current_addr);
return RFC5444_DROP_MESSAGE;
}
}
else {
/* Addresses without expected TLV are ignored */
nhdp_free_addr_entry(current_addr);
nhdp_decrement_addr_usage(current_addr);
return RFC5444_DROP_ADDRESS;
}
@ -320,7 +285,7 @@ _nhdp_msg_end_cb(struct rfc5444_reader_tlvblock_context *cont __attribute__((unu
int_time = 0ULL;
sym = 0;
lost = 0;
cleanup_temp_addr_lists();
nhdp_reset_addresses_tmp_usg(1);
if (dropped) {
return RFC5444_DROP_MESSAGE;
@ -430,27 +395,9 @@ static void process_temp_tables(void)
vtimer_now(&now);
iib_update_lt_status(&now);
nib_elt = nib_process_hello(nb_addr_list_head, &rem_addr_list_head);
nib_elt = nib_process_hello();
if (nib_elt) {
iib_process_hello(if_pid, nib_elt, send_addr_list_head, th_sym_addr_list_head,
th_rem_addr_list_head, rem_addr_list_head, val_time, sym, lost);
iib_process_hello(if_pid, nib_elt, val_time, sym, lost);
}
}
/**
* Free all allocated space for the temporary address lists
*/
static void cleanup_temp_addr_lists(void)
{
nhdp_free_addr_list(send_addr_list_head);
nhdp_free_addr_list(nb_addr_list_head);
nhdp_free_addr_list(th_sym_addr_list_head);
nhdp_free_addr_list(th_rem_addr_list_head);
nhdp_free_addr_list(rem_addr_list_head);
send_addr_list_head = NULL;
nb_addr_list_head = NULL;
th_sym_addr_list_head = NULL;
th_rem_addr_list_head = NULL;
rem_addr_list_head = NULL;
}

View File

@ -213,7 +213,7 @@ static void _nhdp_add_addresses_cb(struct rfc5444_writer *wr)
lib_fill_wr_addresses(nhdp_wr_curr_if_entry->if_pid, wr);
iib_fill_wr_addresses(nhdp_wr_curr_if_entry->if_pid, wr);
nib_fill_wr_addresses(wr);
nhdp_reset_addresses_tmp_usg();
nhdp_reset_addresses_tmp_usg(0);
}
/**

View File

@ -37,11 +37,9 @@ static nib_entry_t *nib_entry_head = NULL;
static nib_lost_address_entry_t *nib_lost_address_entry_head = NULL;
/* Internal function prototypes */
static nib_entry_t *add_nib_entry(nhdp_addr_entry_t *nb_list);
static void rem_nib_entry(nib_entry_t *nib_entry, nhdp_addr_entry_t *nb_list,
nhdp_addr_entry_t **out_list, timex_t *now);
static void clear_nb_addresses(nib_entry_t *nib_entry, nhdp_addr_entry_t *nb_list,
nhdp_addr_entry_t **out_list, timex_t *now);
static nib_entry_t *add_nib_entry_for_nb_addr_list(void);
static void rem_nib_entry(nib_entry_t *nib_entry, timex_t *now);
static void clear_nb_addresses(nib_entry_t *nib_entry, timex_t *now);
static int add_lost_neighbor_address(nhdp_addr_t *lost_addr, timex_t *now);
static void rem_ln_entry(nib_lost_address_entry_t *ln_entry);
@ -50,56 +48,46 @@ static void rem_ln_entry(nib_lost_address_entry_t *ln_entry);
* Neighbor Information Base API *
*---------------------------------------------------------------------------*/
nib_entry_t *nib_process_hello(nhdp_addr_entry_t *nb_list, nhdp_addr_entry_t **out_list)
nib_entry_t *nib_process_hello(void)
{
nib_entry_t *nb_match = NULL;
nib_entry_t *nib_elt, *nib_tmp;
timex_t now;
uint8_t matches = 0;
mutex_lock(&mtx_nib_access);
if (nb_list) {
nib_entry_t *nib_elt, *nib_tmp;
uint8_t matches = 0;
vtimer_now(&now);
LL_FOREACH_SAFE(nib_entry_head, nib_elt, nib_tmp) {
nhdp_addr_entry_t *list_elt;
LL_FOREACH(nib_elt->address_list_head, list_elt) {
nhdp_addr_entry_t *list_elt2;
LL_FOREACH(nb_list, list_elt2) {
if (list_elt->address == list_elt2->address) {
/* Addresses are equal (same NHDP address db entry) */
if (NHDP_ADDR_TMP_IN_NB_LIST(list_elt->address)) {
/* Matching neighbor tuple */
matches++;
if (matches > 1) {
/* Multiple matching nb tuples, delete the previous one */
iib_propagate_nb_entry_change(nb_match, nib_elt);
rem_nib_entry(nb_match, nb_list, out_list, &now);
rem_nib_entry(nb_match, &now);
}
nb_match = nib_elt;
break;
}
}
if (nb_match == nib_elt) {
/* This nb tuple is already detected as matching */
break;
}
}
}
/* Add or update nb tuple */
if (matches > 0) {
/* We found matching nb tuples, reuse the last one */
clear_nb_addresses(nb_match, nb_list, out_list, &now);
clear_nb_addresses(nb_match, &now);
if (matches > 1) {
nb_match->symmetric = 0;
}
nb_match->address_list_head = nhdp_generate_new_addr_list(nb_list);
nb_match->address_list_head = nhdp_generate_addr_list_from_tmp(NHDP_ADDR_TMP_NB_LIST);
if (!nb_match->address_list_head) {
/* Insufficient memory */
@ -109,8 +97,7 @@ nib_entry_t *nib_process_hello(nhdp_addr_entry_t *nb_list, nhdp_addr_entry_t **o
}
}
else {
nb_match = add_nib_entry(nb_list);
}
nb_match = add_nib_entry_for_nb_addr_list();
}
mutex_unlock(&mtx_nib_access);
@ -205,9 +192,9 @@ void nib_reset_nb_entry_sym(nib_entry_t *nib_entry, timex_t *now)
/*------------------------------------------------------------------------------------*/
/**
* Add a Neighbor Tuple with the given address list
* Add a Neighbor Tuple for the neighbor address list
*/
static nib_entry_t *add_nib_entry(nhdp_addr_entry_t *nb_list)
static nib_entry_t *add_nib_entry_for_nb_addr_list(void)
{
nib_entry_t *new_elem;
@ -218,8 +205,8 @@ static nib_entry_t *add_nib_entry(nhdp_addr_entry_t *nb_list)
return NULL;
}
/* Copy address list to new neighbor tuple */
new_elem->address_list_head = nhdp_generate_new_addr_list(nb_list);
/* Copy neighbor address list to new neighbor tuple */
new_elem->address_list_head = nhdp_generate_addr_list_from_tmp(NHDP_ADDR_TMP_NB_LIST);
if (!new_elem->address_list_head) {
/* Insufficient memory */
@ -236,10 +223,9 @@ static nib_entry_t *add_nib_entry(nhdp_addr_entry_t *nb_list)
/**
* Remove a given Neighbor Tuple
*/
static void rem_nib_entry(nib_entry_t *nib_entry, nhdp_addr_entry_t *nb_list,
nhdp_addr_entry_t **out_list, timex_t *now)
static void rem_nib_entry(nib_entry_t *nib_entry, timex_t *now)
{
clear_nb_addresses(nib_entry, nb_list, out_list, now);
clear_nb_addresses(nib_entry, now);
LL_DELETE(nib_entry_head, nib_entry);
free(nib_entry);
}
@ -248,34 +234,27 @@ static void rem_nib_entry(nib_entry_t *nib_entry, nhdp_addr_entry_t *nb_list,
* Clear address list of a Neighbor Tuple and add Lost Neighbor Tuple for addresses
* no longer used by this neighbor
*/
static void clear_nb_addresses(nib_entry_t *nib_entry, nhdp_addr_entry_t *nb_list,
nhdp_addr_entry_t **out_list, timex_t *now)
static void clear_nb_addresses(nib_entry_t *nib_entry, timex_t *now)
{
nhdp_addr_entry_t *elt, *nib_elt, *nib_tmp;
nhdp_addr_entry_t *nib_elt, *nib_tmp;
LL_FOREACH_SAFE(nib_entry->address_list_head, nib_elt, nib_tmp) {
uint8_t found = 0;
LL_FOREACH(nb_list, elt) {
/* Check whether address is still present in the new neighbor address list */
if (nib_elt->address == elt->address) {
/* Simply free the address entry */
nhdp_free_addr_entry(nib_elt);
found = 1;
break;
}
}
if (!found) {
if (!NHDP_ADDR_TMP_IN_NB_LIST(nib_elt->address)) {
/* Address is not in the newly received address list of the neighbor */
/* Add it to the Removed Address List (out_list) */
LL_PREPEND(*out_list, nib_elt);
/* Add it to the Removed Address List */
nib_elt->address->in_tmp_table |= NHDP_ADDR_TMP_REM_LIST;
/* Increment usage counter of address in central NHDP address storage */
nib_elt->address->usg_count++;
if (nib_entry->symmetric) {
/* Additionally create a Lost Neighbor Tuple for symmetric neighbors */
add_lost_neighbor_address(nib_elt->address, now);
}
}
/* Free the address entry */
nhdp_free_addr_entry(nib_elt);
}
nib_entry->address_list_head = NULL;
}

View File

@ -53,13 +53,10 @@ typedef struct nib_lost_address_entry_t {
* @note
* Must not be called from outside the NHDP reader's message processing.
*
* @param[in] nb_list Pointer to the Neighbor Address List from the received HELLO
* @param[out] out_list Pointer to the created Removed Address List
*
* @return Pointer to the new Neighbor Tuple
* @return NULL on error
*/
nib_entry_t *nib_process_hello(nhdp_addr_entry_t *nb_list, nhdp_addr_entry_t **out_list);
nib_entry_t *nib_process_hello(void);
/**
* @brief Add addresses to the currently constructed HELLO message