mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-11-12 18:06:40 +00:00
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
|
||||
#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
|
||||
node will be able to handle. */
|
||||
#ifndef UIP_CONF_MAX_ROUTES
|
||||
|
@ -79,9 +79,11 @@ uip_ds6_neighbors_init(void)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_nbr_t *
|
||||
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) {
|
||||
uip_ipaddr_copy(&nbr->ipaddr, ipaddr);
|
||||
#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);
|
||||
|
||||
/** \brief Neighbor Cache basic routines */
|
||||
uip_ds6_nbr_t *uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
|
||||
uint8_t isrouter, uint8_t state);
|
||||
uip_ds6_nbr_t *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, void *data);
|
||||
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_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
|
||||
are attached to this neighbor. */
|
||||
routes = nbr_table_add_lladdr(nbr_routes,
|
||||
(linkaddr_t *)nexthop_lladdr);
|
||||
(linkaddr_t *)nexthop_lladdr,
|
||||
NBR_TABLE_REASON_ROUTE, NULL);
|
||||
if(routes == NULL) {
|
||||
/* This should not happen, as we explicitly deallocated one
|
||||
route table entry above. */
|
||||
|
@ -188,7 +188,7 @@ parse(void)
|
||||
|
||||
info = nbr_table_get_from_lladdr(anti_replay_table, sender);
|
||||
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) {
|
||||
PRINTF("noncoresec: could not get nbr_table_item\n");
|
||||
return FRAMER_FAILED;
|
||||
|
@ -122,7 +122,7 @@ phase_update(const linkaddr_t *neighbor, rtimer_clock_t time,
|
||||
} else {
|
||||
/* No matching phase was found, so we allocate a new one. */
|
||||
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) {
|
||||
e->time = time;
|
||||
#if PHASE_DRIFT_CORRECT
|
||||
|
@ -47,11 +47,20 @@
|
||||
static void handle_periodic_timer(void *ptr);
|
||||
static struct ctimer periodic_timer;
|
||||
static uint8_t initialized = 0;
|
||||
static void print_table();
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#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 */
|
||||
typedef struct nbr_table_key {
|
||||
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 *
|
||||
nbr_table_allocate(void)
|
||||
nbr_table_allocate(nbr_table_reason_t reason, void *data)
|
||||
{
|
||||
nbr_table_key_t *key;
|
||||
int least_used_count = 0;
|
||||
@ -179,39 +188,66 @@ nbr_table_allocate(void)
|
||||
key = memb_alloc(&neighbor_addr_mem);
|
||||
if(key != NULL) {
|
||||
return key;
|
||||
} else { /* 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;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef NBR_TABLE_FIND_REMOVABLE
|
||||
const linkaddr_t *lladdr;
|
||||
lladdr = NBR_TABLE_FIND_REMOVABLE(reason, data);
|
||||
if(lladdr == NULL) {
|
||||
/* Nothing found that can be deleted - return NULL to indicate failure */
|
||||
PRINTF("*** Not removing entry to allocate new\n");
|
||||
return NULL;
|
||||
} else {
|
||||
/* used least_used_key to indicate what is the least useful entry */
|
||||
int index;
|
||||
int locked;
|
||||
if((index = index_from_lladdr(lladdr)) != -1) {
|
||||
least_used_key = key_from_index(index);
|
||||
locked = locked_map[index];
|
||||
}
|
||||
/* Allow delete of locked item? */
|
||||
if(least_used_key != NULL && locked) {
|
||||
PRINTF("Deleting locked item!\n");
|
||||
locked_map[index] = 0;
|
||||
}
|
||||
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) {
|
||||
/* We haven't found any unlocked item, allocation fails */
|
||||
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 */
|
||||
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;
|
||||
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) {
|
||||
/* 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 */
|
||||
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);
|
||||
nbr_set_bit(used_map, table, item, 1);
|
||||
|
||||
#if DEBUG
|
||||
print_table();
|
||||
#endif
|
||||
return item;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -379,7 +418,7 @@ nbr_table_get_lladdr(nbr_table_t *table, const void *item)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if DEBUG
|
||||
static void
|
||||
handle_periodic_timer(void *ptr)
|
||||
print_table()
|
||||
{
|
||||
int i, j;
|
||||
/* Printout all neighbors and which tables they are used in */
|
||||
@ -394,6 +433,12 @@ handle_periodic_timer(void *ptr)
|
||||
PRINTF("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
handle_periodic_timer(void *ptr)
|
||||
{
|
||||
print_table();
|
||||
ctimer_reset(&periodic_timer);
|
||||
}
|
||||
#endif
|
||||
|
@ -75,6 +75,17 @@ typedef struct nbr_table {
|
||||
/** \brief Declaration of non-static neighbor tables */
|
||||
#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 */
|
||||
/** @{ */
|
||||
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 */
|
||||
/** @{ */
|
||||
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);
|
||||
/** @} */
|
||||
|
||||
|
@ -634,8 +634,9 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
|
||||
PRINT6ADDR(addr);
|
||||
PRINTF("\n");
|
||||
if(lladdr != NULL) {
|
||||
/* Add parent in rpl_parents */
|
||||
p = nbr_table_add_lladdr(rpl_parents, (linkaddr_t *)lladdr);
|
||||
/* Add parent in rpl_parents - again this is due to DIO */
|
||||
p = nbr_table_add_lladdr(rpl_parents, (linkaddr_t *)lladdr,
|
||||
NBR_TABLE_REASON_RPL_DIO, dio);
|
||||
if(p == NULL) {
|
||||
PRINTF("RPL: rpl_add_parent p NULL\n");
|
||||
} else {
|
||||
@ -1028,7 +1029,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||
rpl_set_default_route(instance, from);
|
||||
|
||||
if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
|
||||
rpl_schedule_dao_immediately(instance);
|
||||
rpl_schedule_dao(instance);
|
||||
} else {
|
||||
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
|
||||
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 */
|
||||
if(RPL_NBR_POLICY.check_add_from_dio(from, dio)) {
|
||||
/* add this to the neighbor cache if not already there */
|
||||
if(rpl_icmp6_update_nbr_table(from) == NULL) {
|
||||
PRINTF("RPL: Out of memory, dropping DIO from ");
|
||||
PRINT6ADDR(from);
|
||||
PRINTF("\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
/* add this to the neighbor cache if not already there */
|
||||
if(rpl_icmp6_update_nbr_table(from, NBR_TABLE_REASON_RPL_DIO, dio) == NULL) {
|
||||
PRINTF("RPL: Out of memory, dropping DIO from ");
|
||||
PRINT6ADDR(from);
|
||||
PRINTF("\n");
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -182,14 +182,14 @@ set16(uint8_t *buffer, int pos, uint16_t value)
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
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;
|
||||
|
||||
if((nbr = uip_ds6_nbr_lookup(from)) == NULL) {
|
||||
if((nbr = uip_ds6_nbr_add(from, (uip_lladdr_t *)
|
||||
packetbuf_addr(PACKETBUF_ADDR_SENDER),
|
||||
0, NBR_REACHABLE)) != NULL) {
|
||||
0, NBR_REACHABLE, reason, data)) != NULL) {
|
||||
PRINTF("RPL: Neighbor added to neighbor cache ");
|
||||
PRINT6ADDR(from);
|
||||
PRINTF(", ");
|
||||
@ -231,19 +231,18 @@ dis_input(void)
|
||||
} else {
|
||||
#endif /* !RPL_LEAF_ONLY */
|
||||
/* Check if this neighbor should be added according to the policy. */
|
||||
if(RPL_NBR_POLICY.check_add_from_dis(&UIP_IP_BUF->srcipaddr)) {
|
||||
/* Add this to the neighbor cache if not already there */
|
||||
if(rpl_icmp6_update_nbr_table(&UIP_IP_BUF->srcipaddr) == NULL) {
|
||||
PRINTF("RPL: Out of Memory, not sending unicast DIO, DIS from ");
|
||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||
PRINTF(", ");
|
||||
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
PRINTF("\n");
|
||||
return;
|
||||
}
|
||||
PRINTF("RPL: Unicast DIS, reply to sender\n");
|
||||
dio_output(instance, &UIP_IP_BUF->srcipaddr);
|
||||
}
|
||||
if(rpl_icmp6_update_nbr_table(&UIP_IP_BUF->srcipaddr,
|
||||
NBR_TABLE_REASON_RPL_DIS, NULL) == NULL) {
|
||||
PRINTF("RPL: Out of Memory, not sending unicast DIO, DIS from ");
|
||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||
PRINTF(", ");
|
||||
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
PRINTF("\n");
|
||||
} else {
|
||||
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");
|
||||
|
||||
/* 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. */
|
||||
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 ");
|
||||
PRINT6ADDR(&dao_sender_addr);
|
||||
PRINTF(", ");
|
||||
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
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;
|
||||
}
|
||||
|
||||
@ -931,7 +930,9 @@ handle_dao_retransmission(void *ptr)
|
||||
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);
|
||||
|
||||
instance->my_dao_transmissions++;
|
||||
@ -1079,6 +1080,7 @@ dao_ack_input(void)
|
||||
|
||||
buffer = UIP_ICMP_PAYLOAD;
|
||||
|
||||
instance_id = buffer[0];
|
||||
sequence = buffer[2];
|
||||
status = buffer[3];
|
||||
|
||||
@ -1131,7 +1133,9 @@ dao_ack_input(void)
|
||||
if(nexthop == NULL) {
|
||||
PRINTF("No next hop to fwd DAO ACK to\n");
|
||||
} else {
|
||||
PRINTF("Fwd DAO ACK\n");
|
||||
PRINTF("Fwd DAO ACK to:");
|
||||
PRINT6ADDR(nexthop);
|
||||
PRINTF("\n");
|
||||
buffer[2] = re->state.dao_seqno_in;
|
||||
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-route.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#define DEBUG DEBUG_FULL
|
||||
#include "net/ip/uip-debug.h"
|
||||
|
||||
/*
|
||||
@ -58,14 +58,18 @@
|
||||
* - max X children (nexthops)
|
||||
* - max Y "best parents"
|
||||
* => 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 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_children; /* all children that we have as nexthop */
|
||||
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;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if DEBUG == DEBUG_FULL
|
||||
@ -124,8 +128,12 @@ update_nbr(void)
|
||||
parent->dag->instance != NULL &&
|
||||
(rank = parent->dag->instance->of->calculate_rank(parent, 0)) > worst_rank) {
|
||||
/* This is the worst-rank neighbor - this is a good candidate for removal */
|
||||
worst_rank = rank;
|
||||
worst_rank_nbr = nbr;
|
||||
if(uip_ds6_route_is_nexthop((uip_lladdr_t *)lladdr) == 0) {
|
||||
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) {
|
||||
/* This neighbor is neither parent or child and can be safely removed */
|
||||
worst_rank_nbr = nbr;
|
||||
worst_rank_nbr = lladdr;
|
||||
worst_rank = INFINITE_RANK;
|
||||
} else if(is_used > 1) {
|
||||
/* Both parent and child - this should never happen! */
|
||||
PRINTF("NBR-POLICY: *** Neighbor is both child and candidate parent: ");
|
||||
PRINTLLADDR((uip_lladdr_t *)lladdr);
|
||||
PRINTF("\n");
|
||||
@ -157,67 +164,36 @@ update_nbr(void)
|
||||
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
|
||||
have this node in its table - since it is a unicast */
|
||||
static int
|
||||
check_add_from_dis(uip_ipaddr_t *from)
|
||||
const linkaddr_t *
|
||||
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();
|
||||
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) {
|
||||
return remove_worst_nbr();
|
||||
return worst_rank_nbr;
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
check_add_from_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||
const linkaddr_t *
|
||||
find_removable_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||
{
|
||||
rpl_instance_t *instance;
|
||||
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();
|
||||
|
||||
/* If there is room for this neighbor just add it. */
|
||||
if(num_free > 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
instance = rpl_get_instance(dio->instance_id);
|
||||
if(instance == NULL || instance->current_dag == NULL) {
|
||||
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. */
|
||||
@ -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",
|
||||
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",
|
||||
rank, worst_rank);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
check_add_from_dao(uip_ipaddr_t *from)
|
||||
const linkaddr_t *
|
||||
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();
|
||||
|
||||
/* Check if this DAO sender is not yet neighbor and there is already too
|
||||
many children. */
|
||||
if(num_children >= MAX_CHILDREN) {
|
||||
PRINTF("Can not add another child - already at max.\n");
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return 1;
|
||||
/* remove the worst ranked nbr */
|
||||
return worst_rank_nbr;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct nbr_policy rpl_nbr_policy = {
|
||||
check_add_from_dis,
|
||||
check_add_from_dio,
|
||||
check_add_from_dao
|
||||
};
|
||||
const linkaddr_t *
|
||||
rpl_nbr_policy_find_removable(nbr_table_reason_t reason,void * data) {
|
||||
/* When we get the DIO/DAO/DIS we know that UIP contains the
|
||||
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;
|
||||
#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. */
|
||||
@ -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_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t, uint8_t);
|
||||
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. */
|
||||
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 *
|
||||
(clock_time_t)instance->lifetime_unit *
|
||||
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",
|
||||
(unsigned)expiration_time);
|
||||
ctimer_set(&instance->dao_lifetime_timer, expiration_time,
|
||||
|
Loading…
Reference in New Issue
Block a user