replaced add/remove ds6-nbr with an nbr-module controlled update of lladdress to avoid loss of other state information
This commit is contained in:
parent
2e852f758b
commit
e9e31e9fd1
3 changed files with 104 additions and 43 deletions
|
@ -136,7 +136,7 @@ static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
/* Copy link-layer address from LLAO option to a word-aligned uip_lladdr_t */
|
/* Copy link-layer address from LLAO option to a word-aligned uip_lladdr_t */
|
||||||
static void
|
static void
|
||||||
extract_lladdr_aligned(uip_lladdr_t *dest) {
|
extract_lladdr_from_llao_aligned(uip_lladdr_t *dest) {
|
||||||
if(dest != NULL && nd6_opt_llao != NULL) {
|
if(dest != NULL && nd6_opt_llao != NULL) {
|
||||||
memcpy(dest, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN);
|
memcpy(dest, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN);
|
||||||
}
|
}
|
||||||
|
@ -199,17 +199,29 @@ ns_input(void)
|
||||||
goto discard;
|
goto discard;
|
||||||
} else {
|
} else {
|
||||||
#endif /*UIP_CONF_IPV6_CHECKS */
|
#endif /*UIP_CONF_IPV6_CHECKS */
|
||||||
|
uip_lladdr_t lladdr_aligned;
|
||||||
|
extract_lladdr_from_llao_aligned(&lladdr_aligned);
|
||||||
nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr);
|
nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr);
|
||||||
if(nbr == NULL) {
|
if(nbr == NULL) {
|
||||||
|
<<<<<<< 2e852f758b3fbc18ad30ec75d8c62b5d5238e70a
|
||||||
uip_lladdr_t lladdr_aligned;
|
uip_lladdr_t lladdr_aligned;
|
||||||
extract_lladdr_aligned(&lladdr_aligned);
|
extract_lladdr_aligned(&lladdr_aligned);
|
||||||
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
|
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
|
||||||
0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
|
0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
|
||||||
|
=======
|
||||||
|
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE);
|
||||||
|
>>>>>>> replaced add/remove ds6-nbr with an nbr-module controlled update of lladdress to avoid loss of other state information
|
||||||
} else {
|
} else {
|
||||||
uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr);
|
const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr);
|
||||||
|
if(lladdr == NULL) {
|
||||||
|
goto discard;
|
||||||
|
}
|
||||||
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
||||||
lladdr, UIP_LLADDR_LEN) != 0) {
|
lladdr, UIP_LLADDR_LEN) != 0) {
|
||||||
memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN);
|
if(nbr_table_update_lladdr((const linkaddr_t *)lladdr, (const linkaddr_t *)&lladdr_aligned, 1) == 0) {
|
||||||
|
/* failed to update the lladdr */
|
||||||
|
goto discard;
|
||||||
|
}
|
||||||
nbr->state = NBR_STALE;
|
nbr->state = NBR_STALE;
|
||||||
} else {
|
} else {
|
||||||
if(nbr->state == NBR_INCOMPLETE) {
|
if(nbr->state == NBR_INCOMPLETE) {
|
||||||
|
@ -495,10 +507,12 @@ na_input(void)
|
||||||
if(nbr == NULL) {
|
if(nbr == NULL) {
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
lladdr = uip_ds6_nbr_get_ll(nbr);
|
lladdr = uip_ds6_nbr_get_ll(nbr);
|
||||||
|
if(lladdr == NULL) {
|
||||||
|
goto discard;
|
||||||
|
}
|
||||||
if(nd6_opt_llao != NULL) {
|
if(nd6_opt_llao != NULL) {
|
||||||
is_llchange = lladdr == NULL ||
|
is_llchange =
|
||||||
memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], lladdr,
|
memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], lladdr,
|
||||||
UIP_LLADDR_LEN);
|
UIP_LLADDR_LEN);
|
||||||
}
|
}
|
||||||
|
@ -507,17 +521,13 @@ na_input(void)
|
||||||
if(nd6_opt_llao == NULL) {
|
if(nd6_opt_llao == NULL) {
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
extract_lladdr_aligned(&lladdr_aligned);
|
|
||||||
|
|
||||||
/* Remove this neighbor - since it has a NULL MAC address */
|
extract_lladdr_from_llao_aligned(&lladdr_aligned);
|
||||||
uip_ds6_nbr_rm(nbr);
|
if(nbr_table_update_lladdr((const linkaddr_t *)lladdr, (const linkaddr_t *)&lladdr_aligned, 1) == 0) {
|
||||||
/* Re-add this neighbor - now with a correct MAC address */
|
/* failed to update the lladdr */
|
||||||
nbr = uip_ds6_nbr_add(&UIP_ND6_NA_BUF->tgtipaddr,
|
|
||||||
&lladdr_aligned,
|
|
||||||
is_router, NBR_STALE);
|
|
||||||
if(nbr == NULL) {
|
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_solicited) {
|
if(is_solicited) {
|
||||||
nbr->state = NBR_REACHABLE;
|
nbr->state = NBR_REACHABLE;
|
||||||
nbr->nscount = 0;
|
nbr->nscount = 0;
|
||||||
|
@ -529,7 +539,7 @@ na_input(void)
|
||||||
nbr->state = NBR_STALE;
|
nbr->state = NBR_STALE;
|
||||||
}
|
}
|
||||||
nbr->isrouter = is_router;
|
nbr->isrouter = is_router;
|
||||||
} else {
|
} else { /* NBR is not INCOMPLETE */
|
||||||
if(!is_override && is_llchange) {
|
if(!is_override && is_llchange) {
|
||||||
if(nbr->state == NBR_REACHABLE) {
|
if(nbr->state == NBR_REACHABLE) {
|
||||||
nbr->state = NBR_STALE;
|
nbr->state = NBR_STALE;
|
||||||
|
@ -543,15 +553,9 @@ na_input(void)
|
||||||
if(is_override || !is_llchange || nd6_opt_llao == NULL) {
|
if(is_override || !is_llchange || nd6_opt_llao == NULL) {
|
||||||
if(nd6_opt_llao != NULL && is_llchange) {
|
if(nd6_opt_llao != NULL && is_llchange) {
|
||||||
uip_lladdr_t lladdr_aligned;
|
uip_lladdr_t lladdr_aligned;
|
||||||
extract_lladdr_aligned(&lladdr_aligned);
|
extract_lladdr_from_llao_aligned(&lladdr_aligned);
|
||||||
|
if(nbr_table_update_lladdr((const linkaddr_t *) lladdr, (const linkaddr_t *) &lladdr_aligned, 1) == 0) {
|
||||||
/* Remove this neighbor - since it has updated its MAC address */
|
/* failed to update the lladdr */
|
||||||
uip_ds6_nbr_rm(nbr);
|
|
||||||
/* Re-add this neighbor - now with a correct (new) MAC address */
|
|
||||||
nbr = uip_ds6_nbr_add(&UIP_ND6_NA_BUF->tgtipaddr,
|
|
||||||
&lladdr_aligned,
|
|
||||||
is_router, NBR_STALE);
|
|
||||||
if(nbr == NULL) {
|
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -652,15 +656,19 @@ rs_input(void)
|
||||||
} else {
|
} else {
|
||||||
#endif /*UIP_CONF_IPV6_CHECKS */
|
#endif /*UIP_CONF_IPV6_CHECKS */
|
||||||
uip_lladdr_t lladdr_aligned;
|
uip_lladdr_t lladdr_aligned;
|
||||||
extract_lladdr_aligned(&lladdr_aligned);
|
extract_lladdr_from_llao_aligned(&lladdr_aligned);
|
||||||
if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) {
|
if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) {
|
||||||
/* we need to add the neighbor */
|
/* we need to add the neighbor */
|
||||||
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
|
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
|
||||||
0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
|
0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
|
||||||
} else {
|
} else {
|
||||||
/* If LL address changed, set neighbor state to stale */
|
/* If LL address changed, set neighbor state to stale */
|
||||||
|
const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr);
|
||||||
|
if(lladdr == NULL) {
|
||||||
|
goto discard;
|
||||||
|
}
|
||||||
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
||||||
uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) {
|
lladdr, UIP_LLADDR_LEN) != 0) {
|
||||||
uip_ds6_nbr_t nbr_data = *nbr;
|
uip_ds6_nbr_t nbr_data = *nbr;
|
||||||
uip_ds6_nbr_rm(nbr);
|
uip_ds6_nbr_rm(nbr);
|
||||||
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
|
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
|
||||||
|
@ -892,18 +900,31 @@ ra_input(void)
|
||||||
nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr);
|
nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr);
|
||||||
if(nbr == NULL) {
|
if(nbr == NULL) {
|
||||||
uip_lladdr_t lladdr_aligned;
|
uip_lladdr_t lladdr_aligned;
|
||||||
|
<<<<<<< 2e852f758b3fbc18ad30ec75d8c62b5d5238e70a
|
||||||
extract_lladdr_aligned(&lladdr_aligned);
|
extract_lladdr_aligned(&lladdr_aligned);
|
||||||
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
|
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
|
||||||
1, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
|
1, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
|
||||||
|
=======
|
||||||
|
extract_lladdr_from_llao_aligned(&lladdr_aligned);
|
||||||
|
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, NBR_STALE);
|
||||||
|
>>>>>>> replaced add/remove ds6-nbr with an nbr-module controlled update of lladdress to avoid loss of other state information
|
||||||
} else {
|
} else {
|
||||||
uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr);
|
uip_lladdr_t lladdr_aligned;
|
||||||
|
extract_lladdr_from_llao_aligned(&lladdr_aligned);
|
||||||
|
const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr);
|
||||||
|
if(lladdr == NULL) {
|
||||||
|
goto discard;
|
||||||
|
}
|
||||||
if(nbr->state == NBR_INCOMPLETE) {
|
if(nbr->state == NBR_INCOMPLETE) {
|
||||||
nbr->state = NBR_STALE;
|
nbr->state = NBR_STALE;
|
||||||
}
|
}
|
||||||
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
||||||
lladdr, UIP_LLADDR_LEN) != 0) {
|
lladdr, UIP_LLADDR_LEN) != 0) {
|
||||||
memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
|
/* change of link layer address */
|
||||||
UIP_LLADDR_LEN);
|
if(nbr_table_update_lladdr((const linkaddr_t *)lladdr, (const linkaddr_t *)&lladdr_aligned, 1) == 0) {
|
||||||
|
/* failed to update the lladdr */
|
||||||
|
goto discard;
|
||||||
|
}
|
||||||
nbr->state = NBR_STALE;
|
nbr->state = NBR_STALE;
|
||||||
}
|
}
|
||||||
nbr->isrouter = 1;
|
nbr->isrouter = 1;
|
||||||
|
|
|
@ -178,6 +178,26 @@ nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item, int val
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
remove_key(nbr_table_key_t *least_used_key)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < MAX_NUM_TABLES; i++) {
|
||||||
|
if(all_tables[i] != NULL && all_tables[i]->callback != NULL) {
|
||||||
|
/* Call table callback for each table that uses this item */
|
||||||
|
nbr_table_item_t *removed_item = item_from_key(all_tables[i], least_used_key);
|
||||||
|
if(nbr_get_bit(used_map, all_tables[i], removed_item) == 1) {
|
||||||
|
all_tables[i]->callback(removed_item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Empty used map */
|
||||||
|
used_map[index_from_key(least_used_key)] = 0;
|
||||||
|
/* Remove neighbor from list */
|
||||||
|
list_remove(nbr_table_keys, least_used_key);
|
||||||
|
/* Return associated key */
|
||||||
|
}
|
||||||
|
|
||||||
static nbr_table_key_t *
|
static nbr_table_key_t *
|
||||||
nbr_table_allocate(nbr_table_reason_t reason, void *data)
|
nbr_table_allocate(nbr_table_reason_t reason, void *data)
|
||||||
{
|
{
|
||||||
|
@ -253,21 +273,7 @@ nbr_table_allocate(nbr_table_reason_t reason, void *data)
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
/* Reuse least used item */
|
/* Reuse least used item */
|
||||||
int i;
|
remove_key(least_used_key);
|
||||||
for(i = 0; i<MAX_NUM_TABLES; i++) {
|
|
||||||
if(all_tables[i] != NULL && all_tables[i]->callback != NULL) {
|
|
||||||
/* Call table callback for each table that uses this item */
|
|
||||||
nbr_table_item_t *removed_item = item_from_key(all_tables[i], least_used_key);
|
|
||||||
if(nbr_get_bit(used_map, all_tables[i], removed_item) == 1) {
|
|
||||||
all_tables[i]->callback(removed_item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Empty used map */
|
|
||||||
used_map[index_from_key(least_used_key)] = 0;
|
|
||||||
/* Remove neighbor from list */
|
|
||||||
list_remove(nbr_table_keys, least_used_key);
|
|
||||||
/* Return associated key */
|
|
||||||
return least_used_key;
|
return least_used_key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,6 +422,39 @@ nbr_table_get_lladdr(nbr_table_t *table, const void *item)
|
||||||
return key != NULL ? &key->lladdr : NULL;
|
return key != NULL ? &key->lladdr : NULL;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Update link-layer address of an item */
|
||||||
|
int
|
||||||
|
nbr_table_update_lladdr(const linkaddr_t *old_addr, const linkaddr_t *new_addr,
|
||||||
|
int remove_if_duplicate)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
int new_index;
|
||||||
|
nbr_table_key_t *key;
|
||||||
|
index = index_from_lladdr(old_addr);
|
||||||
|
if(index == -1) {
|
||||||
|
/* Failure to change since there is nothing to change. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if((new_index = index_from_lladdr(new_addr)) != -1) {
|
||||||
|
/* check if it is a change or not - do not remove / fail if same */
|
||||||
|
if(new_index == index) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* This new entry already exists - failure! - remove if requested. */
|
||||||
|
if(remove_if_duplicate) {
|
||||||
|
remove_key(key_from_index(index));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
key = key_from_index(index);
|
||||||
|
/**
|
||||||
|
* Copy the new lladdr into the key - since we know that there is no
|
||||||
|
* conflicting entry.
|
||||||
|
*/
|
||||||
|
memcpy(&key->lladdr, new_addr, sizeof(linkaddr_t));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
static void
|
static void
|
||||||
print_table()
|
print_table()
|
||||||
|
|
|
@ -109,6 +109,7 @@ int nbr_table_unlock(nbr_table_t *table, nbr_table_item_t *item);
|
||||||
/** \name Neighbor tables: address manipulation */
|
/** \name Neighbor tables: address manipulation */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
linkaddr_t *nbr_table_get_lladdr(nbr_table_t *table, const nbr_table_item_t *item);
|
linkaddr_t *nbr_table_get_lladdr(nbr_table_t *table, const nbr_table_item_t *item);
|
||||||
|
int nbr_table_update_lladdr(const linkaddr_t *old_addr, const linkaddr_t *new_addr, int remove_if_duplicate);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#endif /* NBR_TABLE_H_ */
|
#endif /* NBR_TABLE_H_ */
|
||||||
|
|
Loading…
Add table
Reference in a new issue