uip-ds6-nbr: introduce UIP_DS6_NBR_MULTI_IPV6_ADDRS
This feature, which is disabled by default, extends the neighbor cache management in order to have multiple IPv6 address associated with a single link-layer address as neighbor caches. To use this feature, set 1 to UIP_DS6_NBR_CONF_MAX_NEIGHBOR_CACHES.
This commit is contained in:
parent
8ef5c8b8c6
commit
ee452b5287
@ -55,19 +55,40 @@
|
|||||||
#include "net/ipv6/uip-nd6.h"
|
#include "net/ipv6/uip-nd6.h"
|
||||||
#include "net/routing/routing.h"
|
#include "net/routing/routing.h"
|
||||||
|
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
#include "lib/memb.h"
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
|
|
||||||
/* Log configuration */
|
/* Log configuration */
|
||||||
#include "sys/log.h"
|
#include "sys/log.h"
|
||||||
#define LOG_MODULE "IPv6 Nbr"
|
#define LOG_MODULE "IPv6 Nbr"
|
||||||
#define LOG_LEVEL LOG_LEVEL_IPV6
|
#define LOG_LEVEL LOG_LEVEL_IPV6
|
||||||
|
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
static void add_uip_ds6_nbr_to_nbr_entry(uip_ds6_nbr_t *nbr,
|
||||||
|
uip_ds6_nbr_entry_t *nbr_entry);
|
||||||
|
static void remove_uip_ds6_nbr_from_nbr_entry(uip_ds6_nbr_t *nbr);
|
||||||
|
static void remove_nbr_entry(uip_ds6_nbr_entry_t *nbr_entry);
|
||||||
|
static void free_uip_ds6_nbr(uip_ds6_nbr_t *nbr);
|
||||||
|
static void callback_nbr_entry_removal(uip_ds6_nbr_entry_t *nbr_entry);
|
||||||
|
NBR_TABLE(uip_ds6_nbr_entry_t, uip_ds6_nbr_entries);
|
||||||
|
MEMB(uip_ds6_nbr_memb, uip_ds6_nbr_t, UIP_DS6_NBR_MAX_NEIGHBOR_CACHES);
|
||||||
|
#else
|
||||||
NBR_TABLE(uip_ds6_nbr_t, ds6_neighbors);
|
NBR_TABLE(uip_ds6_nbr_t, ds6_neighbors);
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_ds6_neighbors_init(void)
|
uip_ds6_neighbors_init(void)
|
||||||
{
|
{
|
||||||
link_stats_init();
|
link_stats_init();
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
memb_init(&uip_ds6_nbr_memb);
|
||||||
|
nbr_table_register(uip_ds6_nbr_entries,
|
||||||
|
(nbr_table_callback *)callback_nbr_entry_removal);
|
||||||
|
#else
|
||||||
nbr_table_register(ds6_neighbors, (nbr_table_callback *)uip_ds6_nbr_rm);
|
nbr_table_register(ds6_neighbors, (nbr_table_callback *)uip_ds6_nbr_rm);
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_nbr_t *
|
uip_ds6_nbr_t *
|
||||||
@ -75,8 +96,44 @@ uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
|
|||||||
uint8_t isrouter, uint8_t state, nbr_table_reason_t reason,
|
uint8_t isrouter, uint8_t state, nbr_table_reason_t reason,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr
|
uip_ds6_nbr_t *nbr;
|
||||||
, reason, data);
|
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
uip_ds6_nbr_entry_t *nbr_entry;
|
||||||
|
|
||||||
|
assert(uip_ds6_nbr_lookup(ipaddr) == NULL);
|
||||||
|
if(uip_ds6_nbr_lookup(ipaddr)) {
|
||||||
|
LOG_ERR("%s: uip_ds6_nbr for ", __func__);
|
||||||
|
LOG_ERR_6ADDR(ipaddr);
|
||||||
|
LOG_ERR_("has already existed\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbr_entry = nbr_table_get_from_lladdr(uip_ds6_nbr_entries,
|
||||||
|
(const linkaddr_t *)lladdr);
|
||||||
|
if(nbr_entry == NULL) {
|
||||||
|
if((nbr_entry =
|
||||||
|
nbr_table_add_lladdr(uip_ds6_nbr_entries,
|
||||||
|
(linkaddr_t*)lladdr, reason, data)) == NULL) {
|
||||||
|
LOG_ERR("%s: cannot allocate a new uip_ds6_nbr_entry\n", __func__);
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
LIST_STRUCT_INIT(nbr_entry, uip_ds6_nbrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((nbr = (uip_ds6_nbr_t *)memb_alloc(&uip_ds6_nbr_memb)) == NULL) {
|
||||||
|
LOG_ERR("%s: cannot allocate a new uip_ds6_nbr\n", __func__);
|
||||||
|
if(list_length(nbr_entry->uip_ds6_nbrs) == 0) {
|
||||||
|
nbr_table_remove(uip_ds6_nbr_entries, nbr_entry);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
add_uip_ds6_nbr_to_nbr_entry(nbr, nbr_entry);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr, reason, data);
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
|
|
||||||
if(nbr) {
|
if(nbr) {
|
||||||
uip_ipaddr_copy(&nbr->ipaddr, ipaddr);
|
uip_ipaddr_copy(&nbr->ipaddr, ipaddr);
|
||||||
#if UIP_ND6_SEND_RA || !UIP_CONF_ROUTER
|
#if UIP_ND6_SEND_RA || !UIP_CONF_ROUTER
|
||||||
@ -113,10 +170,91 @@ uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
add_uip_ds6_nbr_to_nbr_entry(uip_ds6_nbr_t *nbr,
|
||||||
|
uip_ds6_nbr_entry_t *nbr_entry)
|
||||||
|
{
|
||||||
|
LOG_DBG("%s: add nbr(%p) to nbr_entry (%p)\n",
|
||||||
|
__func__, nbr, nbr_entry);
|
||||||
|
nbr->nbr_entry = nbr_entry;
|
||||||
|
list_add(nbr_entry->uip_ds6_nbrs, nbr);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
remove_uip_ds6_nbr_from_nbr_entry(uip_ds6_nbr_t *nbr)
|
||||||
|
{
|
||||||
|
if(nbr == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LOG_DBG("%s: remove nbr(%p) from nbr_entry (%p)\n",
|
||||||
|
__func__, nbr, nbr->nbr_entry);
|
||||||
|
list_remove(nbr->nbr_entry->uip_ds6_nbrs, nbr);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
remove_nbr_entry(uip_ds6_nbr_entry_t *nbr_entry)
|
||||||
|
{
|
||||||
|
if(nbr_entry == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LOG_DBG("%s: remove nbr_entry (%p) from nbr_table\n",
|
||||||
|
__func__, nbr_entry);
|
||||||
|
(void)nbr_table_remove(uip_ds6_nbr_entries, nbr_entry);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
free_uip_ds6_nbr(uip_ds6_nbr_t *nbr)
|
||||||
|
{
|
||||||
|
if(nbr == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||||
|
uip_packetqueue_free(&nbr->packethandle);
|
||||||
|
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
||||||
|
NETSTACK_ROUTING.neighbor_state_changed(nbr);
|
||||||
|
assert(nbr->nbr_entry != NULL);
|
||||||
|
if(nbr->nbr_entry == NULL) {
|
||||||
|
LOG_ERR("%s: unexpected error nbr->nbr_entry is NULL\n", __func__);
|
||||||
|
} else {
|
||||||
|
remove_uip_ds6_nbr_from_nbr_entry(nbr);
|
||||||
|
if(list_length(nbr->nbr_entry->uip_ds6_nbrs) == 0) {
|
||||||
|
remove_nbr_entry(nbr->nbr_entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_DBG("%s: free memory for nbr(%p)\n", __func__, nbr);
|
||||||
|
memb_free(&uip_ds6_nbr_memb, nbr);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
callback_nbr_entry_removal(uip_ds6_nbr_entry_t *nbr_entry)
|
||||||
|
{
|
||||||
|
uip_ds6_nbr_t *nbr;
|
||||||
|
uip_ds6_nbr_t *next_nbr;
|
||||||
|
if(nbr_entry == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(nbr = (uip_ds6_nbr_t *)list_head(nbr_entry->uip_ds6_nbrs);
|
||||||
|
nbr != NULL;
|
||||||
|
nbr = next_nbr) {
|
||||||
|
next_nbr = (uip_ds6_nbr_t *)list_item_next(nbr);
|
||||||
|
free_uip_ds6_nbr(nbr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
|
uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
|
||||||
{
|
{
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
if(nbr == NULL) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
free_uip_ds6_nbr(nbr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
if(nbr != NULL) {
|
if(nbr != NULL) {
|
||||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||||
uip_packetqueue_free(&nbr->packethandle);
|
uip_packetqueue_free(&nbr->packethandle);
|
||||||
@ -125,19 +263,52 @@ uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
|
|||||||
return nbr_table_remove(ds6_neighbors, nbr);
|
return nbr_table_remove(ds6_neighbors, nbr);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
uip_ds6_nbr_update_ll(uip_ds6_nbr_t **nbr_pp, const uip_lladdr_t *new_ll_addr)
|
uip_ds6_nbr_update_ll(uip_ds6_nbr_t **nbr_pp, const uip_lladdr_t *new_ll_addr)
|
||||||
{
|
{
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
uip_ds6_nbr_entry_t *nbr_entry;
|
||||||
|
uip_ds6_nbr_t *nbr;
|
||||||
|
#else
|
||||||
uip_ds6_nbr_t nbr_backup;
|
uip_ds6_nbr_t nbr_backup;
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
|
|
||||||
if(nbr_pp == NULL || new_ll_addr == NULL) {
|
if(nbr_pp == NULL || new_ll_addr == NULL) {
|
||||||
LOG_ERR("%s: invalid argument\n", __func__);
|
LOG_ERR("%s: invalid argument\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
|
||||||
|
if((nbr_entry =
|
||||||
|
nbr_table_get_from_lladdr(uip_ds6_nbr_entries,
|
||||||
|
(const linkaddr_t *)new_ll_addr)) == NULL) {
|
||||||
|
if((nbr_entry =
|
||||||
|
nbr_table_add_lladdr(uip_ds6_nbr_entries,
|
||||||
|
(const linkaddr_t*)new_ll_addr,
|
||||||
|
NBR_TABLE_REASON_IPV6_ND, NULL)) == NULL) {
|
||||||
|
LOG_ERR("%s: cannot allocate a nbr_entry for", __func__);
|
||||||
|
LOG_ERR_LLADDR((const linkaddr_t *)new_ll_addr);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
LIST_STRUCT_INIT(nbr_entry, uip_ds6_nbrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nbr = *nbr_pp;
|
||||||
|
|
||||||
|
remove_uip_ds6_nbr_from_nbr_entry(nbr);
|
||||||
|
if(list_length(nbr->nbr_entry->uip_ds6_nbrs) == 0) {
|
||||||
|
remove_nbr_entry(nbr->nbr_entry);
|
||||||
|
}
|
||||||
|
add_uip_ds6_nbr_to_nbr_entry(nbr, nbr_entry);
|
||||||
|
|
||||||
|
#else /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
|
|
||||||
/* make sure new_ll_addr is not used in some other nbr */
|
/* make sure new_ll_addr is not used in some other nbr */
|
||||||
if(uip_ds6_nbr_ll_lookup(new_ll_addr) != NULL) {
|
if(uip_ds6_nbr_ll_lookup(new_ll_addr) != NULL) {
|
||||||
LOG_ERR("%s: new_ll_addr, ", __func__);
|
LOG_ERR("%s: new_ll_addr, ", __func__);
|
||||||
@ -159,6 +330,7 @@ uip_ds6_nbr_update_ll(uip_ds6_nbr_t **nbr_pp, const uip_lladdr_t *new_ll_addr)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(*nbr_pp, &nbr_backup, sizeof(uip_ds6_nbr_t));
|
memcpy(*nbr_pp, &nbr_backup, sizeof(uip_ds6_nbr_t));
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -173,47 +345,89 @@ uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr)
|
|||||||
const uip_lladdr_t *
|
const uip_lladdr_t *
|
||||||
uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr)
|
uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr)
|
||||||
{
|
{
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
if(nbr == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (const uip_lladdr_t *)nbr_table_get_lladdr(uip_ds6_nbr_entries,
|
||||||
|
nbr->nbr_entry);
|
||||||
|
#else
|
||||||
return (const uip_lladdr_t *)nbr_table_get_lladdr(ds6_neighbors, nbr);
|
return (const uip_lladdr_t *)nbr_table_get_lladdr(ds6_neighbors, nbr);
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
uip_ds6_nbr_num(void)
|
uip_ds6_nbr_num(void)
|
||||||
{
|
{
|
||||||
uip_ds6_nbr_t *nbr;
|
int num = 0;
|
||||||
int num;
|
|
||||||
|
|
||||||
num = 0;
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
uip_ds6_nbr_entry_t *nbr_entry;
|
||||||
|
for(nbr_entry = nbr_table_head(uip_ds6_nbr_entries);
|
||||||
|
nbr_entry != NULL;
|
||||||
|
nbr_entry = nbr_table_next(uip_ds6_nbr_entries, nbr_entry)) {
|
||||||
|
num += list_length(nbr_entry->uip_ds6_nbrs);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
uip_ds6_nbr_t *nbr;
|
||||||
for(nbr = nbr_table_head(ds6_neighbors);
|
for(nbr = nbr_table_head(ds6_neighbors);
|
||||||
nbr != NULL;
|
nbr != NULL;
|
||||||
nbr = nbr_table_next(ds6_neighbors, nbr)) {
|
nbr = nbr_table_next(ds6_neighbors, nbr)) {
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_nbr_t *
|
uip_ds6_nbr_t *
|
||||||
uip_ds6_nbr_head(void)
|
uip_ds6_nbr_head(void)
|
||||||
{
|
{
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
uip_ds6_nbr_entry_t *nbr_entry;
|
||||||
|
if((nbr_entry = nbr_table_head(uip_ds6_nbr_entries)) == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
assert(list_head(nbr_entry->uip_ds6_nbrs) != NULL);
|
||||||
|
return (uip_ds6_nbr_t *)list_head(nbr_entry->uip_ds6_nbrs);
|
||||||
|
#else
|
||||||
return nbr_table_head(ds6_neighbors);
|
return nbr_table_head(ds6_neighbors);
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_nbr_t *
|
uip_ds6_nbr_t *
|
||||||
uip_ds6_nbr_next(uip_ds6_nbr_t *nbr)
|
uip_ds6_nbr_next(uip_ds6_nbr_t *nbr)
|
||||||
{
|
{
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
uip_ds6_nbr_entry_t *nbr_entry;
|
||||||
|
if(nbr == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(list_item_next(nbr) != NULL) {
|
||||||
|
return list_item_next(nbr);
|
||||||
|
}
|
||||||
|
nbr_entry = nbr_table_next(uip_ds6_nbr_entries, nbr->nbr_entry);
|
||||||
|
if(nbr_entry == NULL) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
assert(list_head(nbr_entry->uip_ds6_nbrs) != NULL);
|
||||||
|
return (uip_ds6_nbr_t *)list_head(nbr_entry->uip_ds6_nbrs);
|
||||||
|
}
|
||||||
|
#else
|
||||||
return nbr_table_next(ds6_neighbors, nbr);
|
return nbr_table_next(ds6_neighbors, nbr);
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_nbr_t *
|
uip_ds6_nbr_t *
|
||||||
uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr)
|
uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr)
|
||||||
{
|
{
|
||||||
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
|
uip_ds6_nbr_t *nbr;
|
||||||
if(ipaddr != NULL) {
|
if(ipaddr == NULL) {
|
||||||
while(nbr != NULL) {
|
return NULL;
|
||||||
|
}
|
||||||
|
for(nbr = uip_ds6_nbr_head(); nbr != NULL; nbr = uip_ds6_nbr_next(nbr)) {
|
||||||
if(uip_ipaddr_cmp(&nbr->ipaddr, ipaddr)) {
|
if(uip_ipaddr_cmp(&nbr->ipaddr, ipaddr)) {
|
||||||
return nbr;
|
return nbr;
|
||||||
}
|
}
|
||||||
nbr = nbr_table_next(ds6_neighbors, nbr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -221,7 +435,23 @@ uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr)
|
|||||||
uip_ds6_nbr_t *
|
uip_ds6_nbr_t *
|
||||||
uip_ds6_nbr_ll_lookup(const uip_lladdr_t *lladdr)
|
uip_ds6_nbr_ll_lookup(const uip_lladdr_t *lladdr)
|
||||||
{
|
{
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
uip_ds6_nbr_entry_t *nbr_entry;
|
||||||
|
/*
|
||||||
|
* we cannot determine which entry should return by lladdr alone;
|
||||||
|
* return the first entry associated with lladdr.
|
||||||
|
*/
|
||||||
|
nbr_entry =
|
||||||
|
(uip_ds6_nbr_entry_t *)nbr_table_get_from_lladdr(uip_ds6_nbr_entries,
|
||||||
|
(linkaddr_t*)lladdr);
|
||||||
|
if(nbr_entry == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
assert(list_head(nbr_entry->uip_ds6_nbrs) != NULL);
|
||||||
|
return (uip_ds6_nbr_t *)list_head(nbr_entry->uip_ds6_nbrs);
|
||||||
|
#else
|
||||||
return nbr_table_get_from_lladdr(ds6_neighbors, (linkaddr_t*)lladdr);
|
return nbr_table_get_from_lladdr(ds6_neighbors, (linkaddr_t*)lladdr);
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
@ -239,6 +469,20 @@ uip_ds6_nbr_lladdr_from_ipaddr(const uip_ipaddr_t *ipaddr)
|
|||||||
uip_ds6_nbr_t *nbr = uip_ds6_nbr_lookup(ipaddr);
|
uip_ds6_nbr_t *nbr = uip_ds6_nbr_lookup(ipaddr);
|
||||||
return nbr ? uip_ds6_nbr_get_ll(nbr) : NULL;
|
return nbr ? uip_ds6_nbr_get_ll(nbr) : NULL;
|
||||||
}
|
}
|
||||||
|
#if UIP_DS6_LL_NUD
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
update_nbr_reachable_state_by_ack(uip_ds6_nbr_t *nbr, const linkaddr_t *lladdr)
|
||||||
|
{
|
||||||
|
if(nbr != NULL && nbr->state != NBR_INCOMPLETE) {
|
||||||
|
nbr->state = NBR_REACHABLE;
|
||||||
|
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
|
||||||
|
LOG_INFO("received a link layer ACK : ");
|
||||||
|
LOG_INFO_LLADDR(lladdr);
|
||||||
|
LOG_INFO_(" is reachable.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* UIP_DS6_LL_NUD */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_ds6_link_callback(int status, int numtx)
|
uip_ds6_link_callback(int status, int numtx)
|
||||||
@ -266,14 +510,22 @@ uip_ds6_link_callback(int status, int numtx)
|
|||||||
* acknowledges link packets. */
|
* acknowledges link packets. */
|
||||||
if(status == MAC_TX_OK) {
|
if(status == MAC_TX_OK) {
|
||||||
uip_ds6_nbr_t *nbr;
|
uip_ds6_nbr_t *nbr;
|
||||||
nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
if(nbr != NULL && nbr->state != NBR_INCOMPLETE) {
|
uip_ds6_nbr_entry_t *nbr_entry;
|
||||||
nbr->state = NBR_REACHABLE;
|
if((nbr_entry =
|
||||||
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
|
(uip_ds6_nbr_entry_t *)nbr_table_get_from_lladdr(uip_ds6_nbr_entries,
|
||||||
LOG_INFO("received a link layer ACK : ");
|
dest)) == NULL) {
|
||||||
LOG_INFO_LLADDR((uip_lladdr_t *)dest);
|
return;
|
||||||
LOG_INFO_(" is reachable.\n");
|
|
||||||
}
|
}
|
||||||
|
for(nbr = (uip_ds6_nbr_t *)list_head(nbr_entry->uip_ds6_nbrs);
|
||||||
|
nbr != NULL;
|
||||||
|
nbr = (uip_ds6_nbr_t *)list_item_next(nbr)) {
|
||||||
|
update_nbr_reachable_state_by_ack(nbr, dest);
|
||||||
|
}
|
||||||
|
#else /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
|
nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
|
||||||
|
update_nbr_reachable_state_by_ack(nbr, dest);
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
}
|
}
|
||||||
#endif /* UIP_DS6_LL_NUD */
|
#endif /* UIP_DS6_LL_NUD */
|
||||||
}
|
}
|
||||||
@ -283,7 +535,7 @@ uip_ds6_link_callback(int status, int numtx)
|
|||||||
void
|
void
|
||||||
uip_ds6_neighbor_periodic(void)
|
uip_ds6_neighbor_periodic(void)
|
||||||
{
|
{
|
||||||
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
|
uip_ds6_nbr_t *nbr = uip_ds6_nbr_head();
|
||||||
while(nbr != NULL) {
|
while(nbr != NULL) {
|
||||||
switch(nbr->state) {
|
switch(nbr->state) {
|
||||||
case NBR_REACHABLE:
|
case NBR_REACHABLE:
|
||||||
@ -354,7 +606,7 @@ uip_ds6_neighbor_periodic(void)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nbr = nbr_table_next(ds6_neighbors, nbr);
|
nbr = uip_ds6_nbr_next(nbr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
@ -373,7 +625,7 @@ uip_ds6_nbr_refresh_reachable_state(const uip_ipaddr_t *ipaddr)
|
|||||||
uip_ds6_nbr_t *
|
uip_ds6_nbr_t *
|
||||||
uip_ds6_get_least_lifetime_neighbor(void)
|
uip_ds6_get_least_lifetime_neighbor(void)
|
||||||
{
|
{
|
||||||
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
|
uip_ds6_nbr_t *nbr = uip_ds6_nbr_head();
|
||||||
uip_ds6_nbr_t *nbr_expiring = NULL;
|
uip_ds6_nbr_t *nbr_expiring = NULL;
|
||||||
while(nbr != NULL) {
|
while(nbr != NULL) {
|
||||||
if(nbr_expiring != NULL) {
|
if(nbr_expiring != NULL) {
|
||||||
@ -384,7 +636,7 @@ uip_ds6_get_least_lifetime_neighbor(void)
|
|||||||
} else {
|
} else {
|
||||||
nbr_expiring = nbr;
|
nbr_expiring = nbr;
|
||||||
}
|
}
|
||||||
nbr = nbr_table_next(ds6_neighbors, nbr);
|
nbr = uip_ds6_nbr_next(nbr);
|
||||||
}
|
}
|
||||||
return nbr_expiring;
|
return nbr_expiring;
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,10 @@
|
|||||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||||
#include "net/ipv6/uip-packetqueue.h"
|
#include "net/ipv6/uip-packetqueue.h"
|
||||||
#endif /*UIP_CONF_QUEUE_PKT */
|
#endif /*UIP_CONF_QUEUE_PKT */
|
||||||
|
#if UIP_DS6_NBR_CONF_MULTI_IPV6_ADDRS
|
||||||
|
#include "lib/assert.h"
|
||||||
|
#include "lib/list.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*--------------------------------------------------*/
|
/*--------------------------------------------------*/
|
||||||
/** \brief Possible states for the nbr cache entries */
|
/** \brief Possible states for the nbr cache entries */
|
||||||
@ -63,8 +67,32 @@
|
|||||||
#define NBR_DELAY 3
|
#define NBR_DELAY 3
|
||||||
#define NBR_PROBE 4
|
#define NBR_PROBE 4
|
||||||
|
|
||||||
|
#ifdef UIP_DS6_NBR_CONF_MULTI_IPV6_ADDRS
|
||||||
|
#define UIP_DS6_NBR_MULTI_IPV6_ADDRS UIP_DS6_NBR_CONF_MULTI_IPV6_ADDRS
|
||||||
|
#else
|
||||||
|
#define UIP_DS6_NBR_MULTI_IPV6_ADDRS 0
|
||||||
|
#endif /* UIP_DS6_NBR_CONF_MULTI_IPV6_ADDRS */
|
||||||
|
|
||||||
|
#ifdef UIP_DS6_NBR_CONF_MAX_NEIGHBOR_CACHES
|
||||||
|
#define UIP_DS6_NBR_MAX_NEIGHBOR_CACHES UIP_DS6_NBR_CONF_MAX_NEIGHBOR_CACHES
|
||||||
|
#else
|
||||||
|
#define UIP_DS6_NBR_MAX_NEIGHBOR_CACHES NBR_TABLE_MAX_NEIGHBORS
|
||||||
|
#endif /* UIP_DS6_NBR_CONF_MAX_NEIGHBOR_CACHES */
|
||||||
|
|
||||||
|
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
/** \brief An nbr_table entry for neighbor caches */
|
||||||
|
typedef struct {
|
||||||
|
LIST_STRUCT(uip_ds6_nbrs);
|
||||||
|
} uip_ds6_nbr_entry_t;
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
|
|
||||||
/** \brief An entry in the nbr cache */
|
/** \brief An entry in the nbr cache */
|
||||||
typedef struct uip_ds6_nbr {
|
typedef struct uip_ds6_nbr {
|
||||||
|
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||||
|
struct uip_ds6_nbr *next;
|
||||||
|
uip_ds6_nbr_entry_t *nbr_entry;
|
||||||
|
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||||
uip_ipaddr_t ipaddr;
|
uip_ipaddr_t ipaddr;
|
||||||
uint8_t isrouter;
|
uint8_t isrouter;
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
|
Loading…
Reference in New Issue
Block a user