refactored the rpl-nbr-policy to be called from nbr-table module
This commit is contained in:
parent
be81d1d2c6
commit
444015df67
|
@ -148,6 +148,13 @@
|
||||||
#define UIP_CONF_IPV6_RPL 1
|
#define UIP_CONF_IPV6_RPL 1
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
|
|
||||||
|
/* If RPL is enabled also enable the RPL NBR Policy */
|
||||||
|
#if UIP_CONF_IPV6_RPL
|
||||||
|
#ifndef NBR_TABLE_FIND_REMOVABLE
|
||||||
|
#define NBR_TABLE_FIND_REMOVABLE rpl_nbr_policy_find_removable
|
||||||
|
#endif /* NBR_TABLE_FIND_REMOVABLE */
|
||||||
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
|
|
||||||
/* UIP_CONF_MAX_ROUTES specifies the maximum number of routes that each
|
/* UIP_CONF_MAX_ROUTES specifies the maximum number of routes that each
|
||||||
node will be able to handle. */
|
node will be able to handle. */
|
||||||
#ifndef UIP_CONF_MAX_ROUTES
|
#ifndef UIP_CONF_MAX_ROUTES
|
||||||
|
|
|
@ -79,9 +79,11 @@ uip_ds6_neighbors_init(void)
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_nbr_t *
|
uip_ds6_nbr_t *
|
||||||
uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
|
uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
|
||||||
uint8_t isrouter, uint8_t state)
|
uint8_t isrouter, uint8_t state, nbr_table_reason_t reason,
|
||||||
|
void *data)
|
||||||
{
|
{
|
||||||
uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr);
|
uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr
|
||||||
|
,reason, data);
|
||||||
if(nbr) {
|
if(nbr) {
|
||||||
uip_ipaddr_copy(&nbr->ipaddr, ipaddr);
|
uip_ipaddr_copy(&nbr->ipaddr, ipaddr);
|
||||||
#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER
|
#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER
|
||||||
|
|
|
@ -86,8 +86,10 @@ typedef struct uip_ds6_nbr {
|
||||||
void uip_ds6_neighbors_init(void);
|
void uip_ds6_neighbors_init(void);
|
||||||
|
|
||||||
/** \brief Neighbor Cache basic routines */
|
/** \brief Neighbor Cache basic routines */
|
||||||
uip_ds6_nbr_t *uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
|
uip_ds6_nbr_t *uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr,
|
||||||
uint8_t isrouter, uint8_t state);
|
const uip_lladdr_t *lladdr,
|
||||||
|
uint8_t isrouter, uint8_t state,
|
||||||
|
nbr_table_reason_t reason, void *data);
|
||||||
int uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr);
|
int uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr);
|
||||||
const uip_lladdr_t *uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr);
|
const uip_lladdr_t *uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr);
|
||||||
const uip_ipaddr_t *uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr);
|
const uip_ipaddr_t *uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr);
|
||||||
|
|
|
@ -348,7 +348,8 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
|
||||||
initialize this pointer with the list of routing entries that
|
initialize this pointer with the list of routing entries that
|
||||||
are attached to this neighbor. */
|
are attached to this neighbor. */
|
||||||
routes = nbr_table_add_lladdr(nbr_routes,
|
routes = nbr_table_add_lladdr(nbr_routes,
|
||||||
(linkaddr_t *)nexthop_lladdr);
|
(linkaddr_t *)nexthop_lladdr,
|
||||||
|
NBR_TABLE_REASON_ROUTE, NULL);
|
||||||
if(routes == NULL) {
|
if(routes == NULL) {
|
||||||
/* This should not happen, as we explicitly deallocated one
|
/* This should not happen, as we explicitly deallocated one
|
||||||
route table entry above. */
|
route table entry above. */
|
||||||
|
|
|
@ -188,7 +188,7 @@ parse(void)
|
||||||
|
|
||||||
info = nbr_table_get_from_lladdr(anti_replay_table, sender);
|
info = nbr_table_get_from_lladdr(anti_replay_table, sender);
|
||||||
if(!info) {
|
if(!info) {
|
||||||
info = nbr_table_add_lladdr(anti_replay_table, sender);
|
info = nbr_table_add_lladdr(anti_replay_table, sender, NBR_TABLE_REASON_LLSEC, NULL);
|
||||||
if(!info) {
|
if(!info) {
|
||||||
PRINTF("noncoresec: could not get nbr_table_item\n");
|
PRINTF("noncoresec: could not get nbr_table_item\n");
|
||||||
return FRAMER_FAILED;
|
return FRAMER_FAILED;
|
||||||
|
|
|
@ -122,7 +122,7 @@ phase_update(const linkaddr_t *neighbor, rtimer_clock_t time,
|
||||||
} else {
|
} else {
|
||||||
/* No matching phase was found, so we allocate a new one. */
|
/* No matching phase was found, so we allocate a new one. */
|
||||||
if(mac_status == MAC_TX_OK && e == NULL) {
|
if(mac_status == MAC_TX_OK && e == NULL) {
|
||||||
e = nbr_table_add_lladdr(nbr_phase, neighbor);
|
e = nbr_table_add_lladdr(nbr_phase, neighbor, NBR_TABLE_REASON_MAC, NULL);
|
||||||
if(e) {
|
if(e) {
|
||||||
e->time = time;
|
e->time = time;
|
||||||
#if PHASE_DRIFT_CORRECT
|
#if PHASE_DRIFT_CORRECT
|
||||||
|
|
|
@ -47,11 +47,20 @@
|
||||||
static void handle_periodic_timer(void *ptr);
|
static void handle_periodic_timer(void *ptr);
|
||||||
static struct ctimer periodic_timer;
|
static struct ctimer periodic_timer;
|
||||||
static uint8_t initialized = 0;
|
static uint8_t initialized = 0;
|
||||||
|
static void print_table();
|
||||||
#define PRINTF(...) printf(__VA_ARGS__)
|
#define PRINTF(...) printf(__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define PRINTF(...)
|
#define PRINTF(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This is the callback function that will be called when there is a
|
||||||
|
* nbr-policy active
|
||||||
|
**/
|
||||||
|
#ifdef NBR_TABLE_FIND_REMOVABLE
|
||||||
|
const linkaddr_t *NBR_TABLE_FIND_REMOVABLE(nbr_table_reason_t reason, void *data);
|
||||||
|
#endif /* NBR_TABLE_FIND_REMOVABLE */
|
||||||
|
|
||||||
|
|
||||||
/* List of link-layer addresses of the neighbors, used as key in the tables */
|
/* List of link-layer addresses of the neighbors, used as key in the tables */
|
||||||
typedef struct nbr_table_key {
|
typedef struct nbr_table_key {
|
||||||
struct nbr_table_key *next;
|
struct nbr_table_key *next;
|
||||||
|
@ -170,7 +179,7 @@ nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item, int val
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static nbr_table_key_t *
|
static nbr_table_key_t *
|
||||||
nbr_table_allocate(void)
|
nbr_table_allocate(nbr_table_reason_t reason, void *data)
|
||||||
{
|
{
|
||||||
nbr_table_key_t *key;
|
nbr_table_key_t *key;
|
||||||
int least_used_count = 0;
|
int least_used_count = 0;
|
||||||
|
@ -179,39 +188,66 @@ nbr_table_allocate(void)
|
||||||
key = memb_alloc(&neighbor_addr_mem);
|
key = memb_alloc(&neighbor_addr_mem);
|
||||||
if(key != NULL) {
|
if(key != NULL) {
|
||||||
return key;
|
return key;
|
||||||
} else { /* No more space, try to free a neighbor.
|
} else {
|
||||||
* The replacement policy is the following: remove neighbor that is:
|
#ifdef NBR_TABLE_FIND_REMOVABLE
|
||||||
* (1) not locked
|
const linkaddr_t *lladdr;
|
||||||
* (2) used by fewest tables
|
lladdr = NBR_TABLE_FIND_REMOVABLE(reason, data);
|
||||||
* (3) oldest (the list is ordered by insertion time)
|
if(lladdr == NULL) {
|
||||||
* */
|
/* Nothing found that can be deleted - return NULL to indicate failure */
|
||||||
/* Get item from first key */
|
PRINTF("*** Not removing entry to allocate new\n");
|
||||||
key = list_head(nbr_table_keys);
|
return NULL;
|
||||||
while(key != NULL) {
|
} else {
|
||||||
int item_index = index_from_key(key);
|
/* used least_used_key to indicate what is the least useful entry */
|
||||||
int locked = locked_map[item_index];
|
int index;
|
||||||
/* Never delete a locked item */
|
int locked;
|
||||||
if(!locked) {
|
if((index = index_from_lladdr(lladdr)) != -1) {
|
||||||
int used = used_map[item_index];
|
least_used_key = key_from_index(index);
|
||||||
int used_count = 0;
|
locked = locked_map[index];
|
||||||
/* Count how many tables are using this item */
|
}
|
||||||
while(used != 0) {
|
/* Allow delete of locked item? */
|
||||||
if((used & 1) == 1) {
|
if(least_used_key != NULL && locked) {
|
||||||
used_count++;
|
PRINTF("Deleting locked item!\n");
|
||||||
}
|
locked_map[index] = 0;
|
||||||
used >>= 1;
|
|
||||||
}
|
|
||||||
/* Find least used item */
|
|
||||||
if(least_used_key == NULL || used_count < least_used_count) {
|
|
||||||
least_used_key = key;
|
|
||||||
least_used_count = used_count;
|
|
||||||
if(used_count == 0) { /* We won't find any least used item */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
key = list_item_next(key);
|
|
||||||
}
|
}
|
||||||
|
#endif /* NBR_TABLE_FIND_REMOVABLE */
|
||||||
|
|
||||||
|
if(least_used_key == NULL) {
|
||||||
|
/* No more space, try to free a neighbor.
|
||||||
|
* The replacement policy is the following: remove neighbor that is:
|
||||||
|
* (1) not locked
|
||||||
|
* (2) used by fewest tables
|
||||||
|
* (3) oldest (the list is ordered by insertion time)
|
||||||
|
* */
|
||||||
|
/* Get item from first key */
|
||||||
|
key = list_head(nbr_table_keys);
|
||||||
|
while(key != NULL) {
|
||||||
|
int item_index = index_from_key(key);
|
||||||
|
int locked = locked_map[item_index];
|
||||||
|
/* Never delete a locked item */
|
||||||
|
if(!locked) {
|
||||||
|
int used = used_map[item_index];
|
||||||
|
int used_count = 0;
|
||||||
|
/* Count how many tables are using this item */
|
||||||
|
while(used != 0) {
|
||||||
|
if((used & 1) == 1) {
|
||||||
|
used_count++;
|
||||||
|
}
|
||||||
|
used >>= 1;
|
||||||
|
}
|
||||||
|
/* Find least used item */
|
||||||
|
if(least_used_key == NULL || used_count < least_used_count) {
|
||||||
|
least_used_key = key;
|
||||||
|
least_used_count = used_count;
|
||||||
|
if(used_count == 0) { /* We won't find any least used item */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
key = list_item_next(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(least_used_key == NULL) {
|
if(least_used_key == NULL) {
|
||||||
/* We haven't found any unlocked item, allocation fails */
|
/* We haven't found any unlocked item, allocation fails */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -289,7 +325,7 @@ nbr_table_next(nbr_table_t *table, nbr_table_item_t *item)
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Add a neighbor indexed with its link-layer address */
|
/* Add a neighbor indexed with its link-layer address */
|
||||||
nbr_table_item_t *
|
nbr_table_item_t *
|
||||||
nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr)
|
nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr, nbr_table_reason_t reason, void *data)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
nbr_table_item_t *item;
|
nbr_table_item_t *item;
|
||||||
|
@ -303,7 +339,7 @@ nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr)
|
||||||
|
|
||||||
if((index = index_from_lladdr(lladdr)) == -1) {
|
if((index = index_from_lladdr(lladdr)) == -1) {
|
||||||
/* Neighbor not yet in table, let's try to allocate one */
|
/* Neighbor not yet in table, let's try to allocate one */
|
||||||
key = nbr_table_allocate();
|
key = nbr_table_allocate(reason, data);
|
||||||
|
|
||||||
/* No space available for new entry */
|
/* No space available for new entry */
|
||||||
if(key == NULL) {
|
if(key == NULL) {
|
||||||
|
@ -327,6 +363,9 @@ nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr)
|
||||||
memset(item, 0, table->item_size);
|
memset(item, 0, table->item_size);
|
||||||
nbr_set_bit(used_map, table, item, 1);
|
nbr_set_bit(used_map, table, item, 1);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
print_table();
|
||||||
|
#endif
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -379,7 +418,7 @@ nbr_table_get_lladdr(nbr_table_t *table, const void *item)
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
static void
|
static void
|
||||||
handle_periodic_timer(void *ptr)
|
print_table()
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
/* Printout all neighbors and which tables they are used in */
|
/* Printout all neighbors and which tables they are used in */
|
||||||
|
@ -394,6 +433,12 @@ handle_periodic_timer(void *ptr)
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
handle_periodic_timer(void *ptr)
|
||||||
|
{
|
||||||
|
print_table();
|
||||||
ctimer_reset(&periodic_timer);
|
ctimer_reset(&periodic_timer);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -75,6 +75,17 @@ typedef struct nbr_table {
|
||||||
/** \brief Declaration of non-static neighbor tables */
|
/** \brief Declaration of non-static neighbor tables */
|
||||||
#define NBR_TABLE_DECLARE(name) extern nbr_table_t *name
|
#define NBR_TABLE_DECLARE(name) extern nbr_table_t *name
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NBR_TABLE_REASON_UNDEFINED,
|
||||||
|
NBR_TABLE_REASON_RPL_DIO,
|
||||||
|
NBR_TABLE_REASON_RPL_DAO,
|
||||||
|
NBR_TABLE_REASON_RPL_DIS,
|
||||||
|
NBR_TABLE_REASON_ROUTE,
|
||||||
|
NBR_TABLE_REASON_IPV6_ND,
|
||||||
|
NBR_TABLE_REASON_MAC,
|
||||||
|
NBR_TABLE_REASON_LLSEC
|
||||||
|
} nbr_table_reason_t;
|
||||||
|
|
||||||
/** \name Neighbor tables: register and loop through table elements */
|
/** \name Neighbor tables: register and loop through table elements */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
int nbr_table_register(nbr_table_t *table, nbr_table_callback *callback);
|
int nbr_table_register(nbr_table_t *table, nbr_table_callback *callback);
|
||||||
|
@ -84,7 +95,7 @@ nbr_table_item_t *nbr_table_next(nbr_table_t *table, nbr_table_item_t *item);
|
||||||
|
|
||||||
/** \name Neighbor tables: add and get data */
|
/** \name Neighbor tables: add and get data */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
nbr_table_item_t *nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr);
|
nbr_table_item_t *nbr_table_add_lladdr(nbr_table_t *table, const linkaddr_t *lladdr, nbr_table_reason_t reason, void *data);
|
||||||
nbr_table_item_t *nbr_table_get_from_lladdr(nbr_table_t *table, const linkaddr_t *lladdr);
|
nbr_table_item_t *nbr_table_get_from_lladdr(nbr_table_t *table, const linkaddr_t *lladdr);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
|
@ -634,8 +634,9 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
|
||||||
PRINT6ADDR(addr);
|
PRINT6ADDR(addr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
if(lladdr != NULL) {
|
if(lladdr != NULL) {
|
||||||
/* Add parent in rpl_parents */
|
/* Add parent in rpl_parents - again this is due to DIO */
|
||||||
p = nbr_table_add_lladdr(rpl_parents, (linkaddr_t *)lladdr);
|
p = nbr_table_add_lladdr(rpl_parents, (linkaddr_t *)lladdr,
|
||||||
|
NBR_TABLE_REASON_RPL_DIO, dio);
|
||||||
if(p == NULL) {
|
if(p == NULL) {
|
||||||
PRINTF("RPL: rpl_add_parent p NULL\n");
|
PRINTF("RPL: rpl_add_parent p NULL\n");
|
||||||
} else {
|
} else {
|
||||||
|
@ -1028,7 +1029,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
rpl_set_default_route(instance, from);
|
rpl_set_default_route(instance, from);
|
||||||
|
|
||||||
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
|
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
|
||||||
rpl_schedule_dao_immediately(instance);
|
rpl_schedule_dao(instance);
|
||||||
} else {
|
} else {
|
||||||
PRINTF("RPL: The DIO does not meet the prerequisites for sending a DAO\n");
|
PRINTF("RPL: The DIO does not meet the prerequisites for sending a DAO\n");
|
||||||
}
|
}
|
||||||
|
@ -1255,18 +1256,14 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
|
||||||
static int
|
static int
|
||||||
add_nbr_from_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
add_nbr_from_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
{
|
{
|
||||||
/* check if it is ok to add this nbr based on this DIO */
|
/* add this to the neighbor cache if not already there */
|
||||||
if(RPL_NBR_POLICY.check_add_from_dio(from, dio)) {
|
if(rpl_icmp6_update_nbr_table(from, NBR_TABLE_REASON_RPL_DIO, dio) == NULL) {
|
||||||
/* add this to the neighbor cache if not already there */
|
PRINTF("RPL: Out of memory, dropping DIO from ");
|
||||||
if(rpl_icmp6_update_nbr_table(from) == NULL) {
|
PRINT6ADDR(from);
|
||||||
PRINTF("RPL: Out of memory, dropping DIO from ");
|
PRINTF("\n");
|
||||||
PRINT6ADDR(from);
|
return 0;
|
||||||
PRINTF("\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
|
|
@ -182,14 +182,14 @@ set16(uint8_t *buffer, int pos, uint16_t value)
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_nbr_t *
|
uip_ds6_nbr_t *
|
||||||
rpl_icmp6_update_nbr_table(uip_ipaddr_t *from)
|
rpl_icmp6_update_nbr_table(uip_ipaddr_t *from, nbr_table_reason_t reason, void *data)
|
||||||
{
|
{
|
||||||
uip_ds6_nbr_t *nbr;
|
uip_ds6_nbr_t *nbr;
|
||||||
|
|
||||||
if((nbr = uip_ds6_nbr_lookup(from)) == NULL) {
|
if((nbr = uip_ds6_nbr_lookup(from)) == NULL) {
|
||||||
if((nbr = uip_ds6_nbr_add(from, (uip_lladdr_t *)
|
if((nbr = uip_ds6_nbr_add(from, (uip_lladdr_t *)
|
||||||
packetbuf_addr(PACKETBUF_ADDR_SENDER),
|
packetbuf_addr(PACKETBUF_ADDR_SENDER),
|
||||||
0, NBR_REACHABLE)) != NULL) {
|
0, NBR_REACHABLE, reason, data)) != NULL) {
|
||||||
PRINTF("RPL: Neighbor added to neighbor cache ");
|
PRINTF("RPL: Neighbor added to neighbor cache ");
|
||||||
PRINT6ADDR(from);
|
PRINT6ADDR(from);
|
||||||
PRINTF(", ");
|
PRINTF(", ");
|
||||||
|
@ -231,19 +231,18 @@ dis_input(void)
|
||||||
} else {
|
} else {
|
||||||
#endif /* !RPL_LEAF_ONLY */
|
#endif /* !RPL_LEAF_ONLY */
|
||||||
/* Check if this neighbor should be added according to the policy. */
|
/* Check if this neighbor should be added according to the policy. */
|
||||||
if(RPL_NBR_POLICY.check_add_from_dis(&UIP_IP_BUF->srcipaddr)) {
|
if(rpl_icmp6_update_nbr_table(&UIP_IP_BUF->srcipaddr,
|
||||||
/* Add this to the neighbor cache if not already there */
|
NBR_TABLE_REASON_RPL_DIS, NULL) == NULL) {
|
||||||
if(rpl_icmp6_update_nbr_table(&UIP_IP_BUF->srcipaddr) == NULL) {
|
PRINTF("RPL: Out of Memory, not sending unicast DIO, DIS from ");
|
||||||
PRINTF("RPL: Out of Memory, not sending unicast DIO, DIS from ");
|
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
PRINTF(", ");
|
||||||
PRINTF(", ");
|
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
PRINTF("\n");
|
||||||
PRINTF("\n");
|
} else {
|
||||||
return;
|
PRINTF("RPL: Unicast DIS, reply to sender\n");
|
||||||
}
|
dio_output(instance, &UIP_IP_BUF->srcipaddr);
|
||||||
PRINTF("RPL: Unicast DIS, reply to sender\n");
|
}
|
||||||
dio_output(instance, &UIP_IP_BUF->srcipaddr);
|
/* } */
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -806,18 +805,18 @@ dao_input(void)
|
||||||
|
|
||||||
PRINTF("RPL: adding DAO route\n");
|
PRINTF("RPL: adding DAO route\n");
|
||||||
|
|
||||||
/* Check if we should add another neighbor based on DAO. */
|
|
||||||
if(!RPL_NBR_POLICY.check_add_from_dao(&dao_sender_addr)) {
|
|
||||||
/* Do not add the neighbor. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Update and add neighbor - if no room - fail. */
|
/* Update and add neighbor - if no room - fail. */
|
||||||
if((nbr = rpl_icmp6_update_nbr_table(&dao_sender_addr)) == NULL) {
|
if((nbr = rpl_icmp6_update_nbr_table(&dao_sender_addr, NBR_TABLE_REASON_RPL_DAO, NULL)) == NULL) {
|
||||||
PRINTF("RPL: Out of Memory, dropping DAO from ");
|
PRINTF("RPL: Out of Memory, dropping DAO from ");
|
||||||
PRINT6ADDR(&dao_sender_addr);
|
PRINT6ADDR(&dao_sender_addr);
|
||||||
PRINTF(", ");
|
PRINTF(", ");
|
||||||
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
|
if(flags & RPL_DAO_K_FLAG) {
|
||||||
|
/* signal the failure to add the node */
|
||||||
|
dao_ack_output(instance, &dao_sender_addr, sequence,
|
||||||
|
RPL_DAO_ACK_UNABLE_TO_ACCEPT);
|
||||||
|
}
|
||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,7 +930,9 @@ handle_dao_retransmission(void *ptr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctimer_set(&instance->dao_retransmit_timer, RPL_DAO_RETRANSMISSION_TIMEOUT,
|
ctimer_set(&instance->dao_retransmit_timer,
|
||||||
|
RPL_DAO_RETRANSMISSION_TIMEOUT / 2 +
|
||||||
|
(random_rand() % (RPL_DAO_RETRANSMISSION_TIMEOUT / 2)),
|
||||||
handle_dao_retransmission, parent);
|
handle_dao_retransmission, parent);
|
||||||
|
|
||||||
instance->my_dao_transmissions++;
|
instance->my_dao_transmissions++;
|
||||||
|
@ -1079,6 +1080,7 @@ dao_ack_input(void)
|
||||||
|
|
||||||
buffer = UIP_ICMP_PAYLOAD;
|
buffer = UIP_ICMP_PAYLOAD;
|
||||||
|
|
||||||
|
instance_id = buffer[0];
|
||||||
sequence = buffer[2];
|
sequence = buffer[2];
|
||||||
status = buffer[3];
|
status = buffer[3];
|
||||||
|
|
||||||
|
@ -1131,7 +1133,9 @@ dao_ack_input(void)
|
||||||
if(nexthop == NULL) {
|
if(nexthop == NULL) {
|
||||||
PRINTF("No next hop to fwd DAO ACK to\n");
|
PRINTF("No next hop to fwd DAO ACK to\n");
|
||||||
} else {
|
} else {
|
||||||
PRINTF("Fwd DAO ACK\n");
|
PRINTF("Fwd DAO ACK to:");
|
||||||
|
PRINT6ADDR(nexthop);
|
||||||
|
PRINTF("\n");
|
||||||
buffer[2] = re->state.dao_seqno_in;
|
buffer[2] = re->state.dao_seqno_in;
|
||||||
uip_icmp6_send(nexthop, ICMP6_RPL, RPL_CODE_DAO_ACK, 4);
|
uip_icmp6_send(nexthop, ICMP6_RPL, RPL_CODE_DAO_ACK, 4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
#include "net/ipv6/uip-ds6-nbr.h"
|
#include "net/ipv6/uip-ds6-nbr.h"
|
||||||
#include "net/ipv6/uip-ds6-route.h"
|
#include "net/ipv6/uip-ds6-route.h"
|
||||||
|
|
||||||
#define DEBUG DEBUG_NONE
|
#define DEBUG DEBUG_FULL
|
||||||
#include "net/ip/uip-debug.h"
|
#include "net/ip/uip-debug.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -58,14 +58,18 @@
|
||||||
* - max X children (nexthops)
|
* - max X children (nexthops)
|
||||||
* - max Y "best parents"
|
* - max Y "best parents"
|
||||||
* => at least MAX_NBRS - (Y + X + 1) free slots for other.
|
* => at least MAX_NBRS - (Y + X + 1) free slots for other.
|
||||||
|
*
|
||||||
|
* NOTE: this policy assumes that all neighbors end up being IPv6
|
||||||
|
* neighbors and are not only MAC neighbors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MAX_CHILDREN (NBR_TABLE_MAX_NEIGHBORS - 3)
|
#define MAX_CHILDREN (NBR_TABLE_MAX_NEIGHBORS - 3)
|
||||||
|
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||||
|
|
||||||
static int num_parents; /* any node that are possible parents */
|
static int num_parents; /* any node that are possible parents */
|
||||||
static int num_children; /* all children that we have as nexthop */
|
static int num_children; /* all children that we have as nexthop */
|
||||||
static int num_free;
|
static int num_free;
|
||||||
static uip_ds6_nbr_t *worst_rank_nbr; /* the parent that has the worst rank */
|
static linkaddr_t *worst_rank_nbr; /* the parent that has the worst rank */
|
||||||
static rpl_rank_t worst_rank;
|
static rpl_rank_t worst_rank;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if DEBUG == DEBUG_FULL
|
#if DEBUG == DEBUG_FULL
|
||||||
|
@ -124,8 +128,12 @@ update_nbr(void)
|
||||||
parent->dag->instance != NULL &&
|
parent->dag->instance != NULL &&
|
||||||
(rank = parent->dag->instance->of->calculate_rank(parent, 0)) > worst_rank) {
|
(rank = parent->dag->instance->of->calculate_rank(parent, 0)) > worst_rank) {
|
||||||
/* This is the worst-rank neighbor - this is a good candidate for removal */
|
/* This is the worst-rank neighbor - this is a good candidate for removal */
|
||||||
worst_rank = rank;
|
if(uip_ds6_route_is_nexthop((uip_lladdr_t *)lladdr) == 0) {
|
||||||
worst_rank_nbr = nbr;
|
worst_rank = rank;
|
||||||
|
worst_rank_nbr = lladdr;
|
||||||
|
} else {
|
||||||
|
printf("*** Can not use this as worst rank as it is a next hop\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,10 +146,9 @@ update_nbr(void)
|
||||||
|
|
||||||
if(is_used == 0) {
|
if(is_used == 0) {
|
||||||
/* This neighbor is neither parent or child and can be safely removed */
|
/* This neighbor is neither parent or child and can be safely removed */
|
||||||
worst_rank_nbr = nbr;
|
worst_rank_nbr = lladdr;
|
||||||
worst_rank = INFINITE_RANK;
|
worst_rank = INFINITE_RANK;
|
||||||
} else if(is_used > 1) {
|
} else if(is_used > 1) {
|
||||||
/* Both parent and child - this should never happen! */
|
|
||||||
PRINTF("NBR-POLICY: *** Neighbor is both child and candidate parent: ");
|
PRINTF("NBR-POLICY: *** Neighbor is both child and candidate parent: ");
|
||||||
PRINTLLADDR((uip_lladdr_t *)lladdr);
|
PRINTLLADDR((uip_lladdr_t *)lladdr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
|
@ -157,67 +164,36 @@ update_nbr(void)
|
||||||
num_free, num_children, num_parents, uip_ds6_route_num_routes());
|
num_free, num_children, num_parents, uip_ds6_route_num_routes());
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
|
||||||
remove_worst_nbr(void)
|
|
||||||
{
|
|
||||||
/* we assume that it is possible to remove the worst parent at the moment */
|
|
||||||
if(worst_rank_nbr != NULL) {
|
|
||||||
PRINTF("Removing worst ranked nbr ");
|
|
||||||
PRINTLLADDR((uip_lladdr_t*)nbr_table_get_lladdr(ds6_neighbors, worst_rank_nbr));
|
|
||||||
PRINTF(" with rank %d\n", worst_rank);
|
|
||||||
if(uip_ds6_nbr_rm(worst_rank_nbr)) {
|
|
||||||
worst_rank_nbr = NULL;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
PRINTF("FAILED to remove worst ranked nbr!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
PRINTF("FAILED to remove worst rank nbr - no found\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/* Called whenever we get a unicast DIS - e.g. someone that already
|
/* Called whenever we get a unicast DIS - e.g. someone that already
|
||||||
have this node in its table - since it is a unicast */
|
have this node in its table - since it is a unicast */
|
||||||
static int
|
const linkaddr_t *
|
||||||
check_add_from_dis(uip_ipaddr_t *from)
|
find_removable_dis(uip_ipaddr_t *from)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* do a lookup to see if it is alread there - then allow add/update */
|
|
||||||
if(uip_ds6_nbr_lookup(from)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
update_nbr();
|
update_nbr();
|
||||||
if(num_free > 0) {
|
if(num_free > 0) {
|
||||||
return 1;
|
printf("num-free > 0 = %d", num_free);
|
||||||
|
printf("**** Should remove unused elements but can not... \n");
|
||||||
|
/* return 1; */
|
||||||
}
|
}
|
||||||
if(num_children < MAX_CHILDREN) {
|
if(num_children < MAX_CHILDREN) {
|
||||||
return remove_worst_nbr();
|
return worst_rank_nbr;
|
||||||
}
|
}
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
const linkaddr_t *
|
||||||
check_add_from_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
find_removable_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
{
|
{
|
||||||
rpl_instance_t *instance;
|
rpl_instance_t *instance;
|
||||||
rpl_rank_t rank;
|
rpl_rank_t rank;
|
||||||
|
|
||||||
/* Do a lookup to see if it is already there - then allow add/update. */
|
|
||||||
if(uip_ds6_nbr_lookup(from)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
update_nbr();
|
update_nbr();
|
||||||
|
|
||||||
/* If there is room for this neighbor just add it. */
|
|
||||||
if(num_free > 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
instance = rpl_get_instance(dio->instance_id);
|
instance = rpl_get_instance(dio->instance_id);
|
||||||
if(instance == NULL || instance->current_dag == NULL) {
|
if(instance == NULL || instance->current_dag == NULL) {
|
||||||
PRINTF("Did not find instance id: %d\n", dio->instance_id);
|
PRINTF("Did not find instance id: %d\n", dio->instance_id);
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the new neighbor only if it is better than the preferred parent. */
|
/* Add the new neighbor only if it is better than the preferred parent. */
|
||||||
|
@ -227,38 +203,43 @@ check_add_from_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
PRINTF("Found better neighbor %d < %d - add to cache...\n",
|
PRINTF("Found better neighbor %d < %d - add to cache...\n",
|
||||||
rank, worst_rank);
|
rank, worst_rank);
|
||||||
|
|
||||||
return remove_worst_nbr();
|
return worst_rank_nbr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRINTF("Found worse neighbor with new %d and old %d - NOT add to cache.\n",
|
PRINTF("Found worse neighbor with new %d and old %d - NOT add to cache.\n",
|
||||||
rank, worst_rank);
|
rank, worst_rank);
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
const linkaddr_t *
|
||||||
check_add_from_dao(uip_ipaddr_t *from)
|
find_removable_dao(uip_ipaddr_t *from)
|
||||||
{
|
{
|
||||||
/* Do a lookup to see if it is alread there - then allow add/update. */
|
|
||||||
if(uip_ds6_nbr_lookup(from)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
update_nbr();
|
update_nbr();
|
||||||
|
|
||||||
/* Check if this DAO sender is not yet neighbor and there is already too
|
/* Check if this DAO sender is not yet neighbor and there is already too
|
||||||
many children. */
|
many children. */
|
||||||
if(num_children >= MAX_CHILDREN) {
|
if(num_children >= MAX_CHILDREN) {
|
||||||
PRINTF("Can not add another child - already at max.\n");
|
PRINTF("Can not add another child - already at max.\n");
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
/* remove the worst ranked nbr */
|
||||||
return 1;
|
return worst_rank_nbr;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
const struct nbr_policy rpl_nbr_policy = {
|
const linkaddr_t *
|
||||||
check_add_from_dis,
|
rpl_nbr_policy_find_removable(nbr_table_reason_t reason,void * data) {
|
||||||
check_add_from_dio,
|
/* When we get the DIO/DAO/DIS we know that UIP contains the
|
||||||
check_add_from_dao
|
incoming packet */
|
||||||
};
|
switch(reason) {
|
||||||
|
case NBR_TABLE_REASON_RPL_DIO:
|
||||||
|
return find_removable_dio(&UIP_IP_BUF->srcipaddr, data);
|
||||||
|
case NBR_TABLE_REASON_RPL_DAO:
|
||||||
|
return find_removable_dao(&UIP_IP_BUF->srcipaddr);
|
||||||
|
case NBR_TABLE_REASON_RPL_DIS:
|
||||||
|
return find_removable_dis(&UIP_IP_BUF->srcipaddr);
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @}*/
|
/** @}*/
|
||||||
|
|
|
@ -270,22 +270,6 @@ typedef struct rpl_stats rpl_stats_t;
|
||||||
extern rpl_stats_t rpl_stats;
|
extern rpl_stats_t rpl_stats;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct nbr_policy {
|
|
||||||
/** check if it is ok to add a nbr via UC DIS - positive => ok */
|
|
||||||
int (* check_add_from_dis)(uip_ipaddr_t *from);
|
|
||||||
int (* check_add_from_dio)(uip_ipaddr_t *from, rpl_dio_t *dio);
|
|
||||||
int (* check_add_from_dao)(uip_ipaddr_t *from);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef RPL_CONF_NBR_POLICY
|
|
||||||
#define RPL_NBR_POLICY RPL_CONF_NBR_POLICY
|
|
||||||
#else /* RPL_CONF_NBR_POLICY */
|
|
||||||
#define RPL_NBR_POLICY rpl_nbr_policy
|
|
||||||
#endif /* RPL_CONF_NBR_POLICY */
|
|
||||||
|
|
||||||
extern const struct nbr_policy RPL_NBR_POLICY;
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* RPL macros. */
|
/* RPL macros. */
|
||||||
|
@ -307,7 +291,8 @@ void dao_output(rpl_parent_t *, uint8_t lifetime);
|
||||||
void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime);
|
void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime);
|
||||||
void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t, uint8_t);
|
void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t, uint8_t);
|
||||||
void rpl_icmp6_register_handlers(void);
|
void rpl_icmp6_register_handlers(void);
|
||||||
uip_ds6_nbr_t *rpl_icmp6_update_nbr_table(uip_ipaddr_t *from);
|
uip_ds6_nbr_t *rpl_icmp6_update_nbr_table(uip_ipaddr_t *from,
|
||||||
|
nbr_table_reason_t r, void *data);
|
||||||
|
|
||||||
/* RPL logic functions. */
|
/* RPL logic functions. */
|
||||||
void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio);
|
void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio);
|
||||||
|
|
|
@ -224,6 +224,8 @@ set_dao_lifetime_timer(rpl_instance_t *instance)
|
||||||
expiration_time = (clock_time_t)instance->default_lifetime *
|
expiration_time = (clock_time_t)instance->default_lifetime *
|
||||||
(clock_time_t)instance->lifetime_unit *
|
(clock_time_t)instance->lifetime_unit *
|
||||||
CLOCK_SECOND / 2;
|
CLOCK_SECOND / 2;
|
||||||
|
/* make the time for the re registration be betwen 1/2 - 3/4 of lifetime */
|
||||||
|
expiration_time = expiration_time + (random_rand() % (expiration_time / 2));
|
||||||
PRINTF("RPL: Scheduling DAO lifetime timer %u ticks in the future\n",
|
PRINTF("RPL: Scheduling DAO lifetime timer %u ticks in the future\n",
|
||||||
(unsigned)expiration_time);
|
(unsigned)expiration_time);
|
||||||
ctimer_set(&instance->dao_lifetime_timer, expiration_time,
|
ctimer_set(&instance->dao_lifetime_timer, expiration_time,
|
||||||
|
|
Loading…
Reference in a new issue