diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 5970cbede..dfd9c997c 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -45,6 +45,7 @@ #include "net/rpl/rpl-private.h" #include "net/uip.h" #include "net/uip-nd6.h" +#include "net/neighbor-table.h" #include "lib/list.h" #include "lib/memb.h" #include "sys/ctimer.h" @@ -62,13 +63,6 @@ extern rpl_of_t RPL_OF; static rpl_of_t * const objective_functions[] = {&RPL_OF}; -/*---------------------------------------------------------------------------*/ -#ifndef RPL_CONF_MAX_PARENTS_PER_DAG -#define RPL_MAX_PARENTS_PER_DAG 8 -#else -#define RPL_MAX_PARENTS_PER_DAG RPL_CONF_MAX_PARENTS_PER_DAG -#endif /* !RPL_CONF_MAX_PARENTS_PER_DAG */ - /*---------------------------------------------------------------------------*/ /* RPL definitions. */ @@ -79,14 +73,49 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF}; #endif /* !RPL_CONF_GROUNDED */ /*---------------------------------------------------------------------------*/ -/* Allocate parents from the same static MEMB chunk to reduce memory waste. */ -MEMB(parent_memb, struct rpl_parent, - RPL_MAX_PARENTS_PER_DAG * RPL_MAX_INSTANCES * RPL_MAX_DAG_PER_INSTANCE); +/* Per-parent RPL information */ +NEIGHBOR_TABLE(rpl_parent_t, rpl_parents); /*---------------------------------------------------------------------------*/ /* Allocate instance table. */ rpl_instance_t instance_table[RPL_MAX_INSTANCES]; rpl_instance_t *default_instance; /*---------------------------------------------------------------------------*/ +void +rpl_dag_init() +{ + nbr_table_register(rpl_parents, (remove_callback_func *)rpl_remove_parent); +} +/*---------------------------------------------------------------------------*/ +rpl_rank_t +rpl_get_parent_rank(uip_lladdr_t *addr) +{ + rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (rimeaddr_t *)addr); + if(p != NULL) { + return p->rank; + } else { + return 0; + } +} +/*---------------------------------------------------------------------------*/ +uip_ipaddr_t * +rpl_get_parent_ipaddr(rpl_parent_t *p) +{ + rimeaddr_t *lladdr = nbr_table_get_lladdr(rpl_parents, p); + return uip_ds6_nbr_ipaddr_from_lladdr((uip_lladdr_t *)lladdr); +} +/*---------------------------------------------------------------------------*/ +static void +rpl_set_preferred_parent(rpl_dag_t *dag, rpl_parent_t *p) +{ + if(dag != NULL && dag->preferred_parent != p) { + /* Always keep the preferred parent locked, so it remains in the + * neighbor table. */ + nbr_table_unlock(rpl_parents, dag->preferred_parent); + nbr_table_lock(rpl_parents, p); + } + dag->preferred_parent = p; +} +/*---------------------------------------------------------------------------*/ /* Greater-than function for the lollipop counter. */ /*---------------------------------------------------------------------------*/ static int @@ -107,53 +136,34 @@ lollipop_greater_than(int a, int b) static void remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank) { - rpl_parent_t *p, *p2; + rpl_parent_t *p; PRINTF("RPL: Removing parents (minimum rank %u)\n", minimum_rank); - for(p = list_head(dag->parents); p != NULL; p = p2) { - p2 = p->next; - if(p->rank >= minimum_rank) { - rpl_remove_parent(dag, p); + p = nbr_table_head(rpl_parents); + while(p != NULL) { + if(dag == p->dag && p->rank >= minimum_rank) { + rpl_remove_parent(p); } + p = nbr_table_next(rpl_parents, p); } } /*---------------------------------------------------------------------------*/ static void nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank) { - rpl_parent_t *p, *p2; + rpl_parent_t *p; PRINTF("RPL: Removing parents (minimum rank %u)\n", minimum_rank); - for(p = list_head(dag->parents); p != NULL; p = p2) { - p2 = p->next; - if(p->rank >= minimum_rank) { - rpl_nullify_parent(dag, p); + p = nbr_table_head(rpl_parents); + while(p != NULL) { + if(dag == p->dag && p->rank >= minimum_rank) { + rpl_nullify_parent(p); } - } -} -/*---------------------------------------------------------------------------*/ -static void -remove_worst_parent(rpl_dag_t *dag, rpl_rank_t min_worst_rank) -{ - rpl_parent_t *p, *worst; - - PRINTF("RPL: Removing the worst parent\n"); - - /* Find the parent with the highest rank. */ - worst = NULL; - for(p = list_head(dag->parents); p != NULL; p = list_item_next(p)) { - if(p != dag->preferred_parent && - (worst == NULL || p->rank > worst->rank)) { - worst = p; - } - } - /* Remove the neighbor if its rank is worse than the minimum worst rank. */ - if(worst != NULL && worst->rank > min_worst_rank) { - rpl_remove_parent(dag, worst); + p = nbr_table_next(rpl_parents, p); } } /*---------------------------------------------------------------------------*/ @@ -231,7 +241,7 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) dag->grounded = RPL_GROUNDED; instance->mop = RPL_MOP_DEFAULT; instance->of = &RPL_OF; - dag->preferred_parent = NULL; + rpl_set_preferred_parent(dag, NULL); memcpy(&dag->dag_id, dag_id, sizeof(dag->dag_id)); @@ -378,8 +388,8 @@ rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from) PRINT6ADDR(from); PRINTF("\n"); instance->def_route = uip_ds6_defrt_add(from, - RPL_LIFETIME(instance, - instance->default_lifetime)); + RPL_LIFETIME(instance, + instance->default_lifetime)); if(instance->def_route == NULL) { return 0; } @@ -430,7 +440,6 @@ rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id) for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { if(!dag->used) { memset(dag, 0, sizeof(*dag)); - LIST_STRUCT_INIT(dag, parents); dag->used = 1; dag->rank = INFINITE_RANK; dag->min_rank = INFINITE_RANK; @@ -502,77 +511,65 @@ rpl_free_dag(rpl_dag_t *dag) rpl_parent_t * rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr) { - rpl_parent_t *p; + rpl_parent_t *p = NULL; + /* Is the parent known by ds6? Drop this request if not. + * Typically, the parent is added upon receiving a DIO. */ + uip_lladdr_t *lladdr = uip_ds6_nbr_lladdr_from_ipaddr(addr); - if(RPL_PARENT_COUNT(dag) == RPL_MAX_PARENTS_PER_DAG) { - return NULL; - } - - p = memb_alloc(&parent_memb); - if(p == NULL) { - RPL_STAT(rpl_stats.mem_overflows++); - return NULL; - } - memcpy(&p->addr, addr, sizeof(p->addr)); - p->dag = dag; - p->rank = dio->rank; - p->dtsn = dio->dtsn; - p->link_metric = RPL_INIT_LINK_METRIC; + if(lladdr != NULL) { + /* Add parent in rpl_parents */ + p = nbr_table_add_lladdr(rpl_parents, (rimeaddr_t *)lladdr); + p->dag = dag; + p->rank = dio->rank; + p->dtsn = dio->dtsn; + p->link_metric = RPL_INIT_LINK_METRIC; #if RPL_DAG_MC != RPL_DAG_MC_NONE - memcpy(&p->mc, &dio->mc, sizeof(p->mc)); + memcpy(&p->mc, &dio->mc, sizeof(p->mc)); #endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ - list_add(dag->parents, p); + } + return p; } /*---------------------------------------------------------------------------*/ +static rpl_parent_t * +find_parent_any_dag_any_instance(uip_ipaddr_t *addr) +{ + uip_ds6_nbr_t *ds6_nbr = uip_ds6_nbr_lookup(addr); + uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(ds6_nbr); + return nbr_table_get_from_lladdr(rpl_parents, (rimeaddr_t *)lladdr); +} +/*---------------------------------------------------------------------------*/ rpl_parent_t * rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr) { - rpl_parent_t *p; - - for(p = list_head(dag->parents); p != NULL; p = p->next) { - if(uip_ipaddr_cmp(&p->addr, addr)) { - return p; - } + rpl_parent_t *p = find_parent_any_dag_any_instance(addr); + if(p != NULL && p->dag == dag) { + return p; + } else { + return NULL; } - return NULL; } - /*---------------------------------------------------------------------------*/ static rpl_dag_t * find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr) { - rpl_parent_t *p; - rpl_dag_t *dag, *end; - - for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { - if(dag->used) { - for(p = list_head(dag->parents); p != NULL; p = p->next) { - if(uip_ipaddr_cmp(&p->addr, addr)) { - return dag; - } - } - } + rpl_parent_t *p = find_parent_any_dag_any_instance(addr); + if(p != NULL) { + return p->dag; + } else { + return NULL; } - return NULL; } /*---------------------------------------------------------------------------*/ rpl_parent_t * rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr) { - rpl_parent_t *p; - rpl_dag_t *dag, *end; - - for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { - if(dag->used) { - for(p = list_head(dag->parents); p != NULL; p = p->next) { - if(uip_ipaddr_cmp(&p->addr, addr)) { - return p; - } - } - } + rpl_parent_t *p = find_parent_any_dag_any_instance(addr); + if(p && p->dag && p->dag->instance == instance) { + return p; + } else { + return NULL; } - return NULL; } /*---------------------------------------------------------------------------*/ rpl_dag_t * @@ -636,7 +633,7 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p) best_dag->min_rank = best_dag->rank; } else if(!acceptable_rank(best_dag, best_dag->rank)) { PRINTF("RPL: New rank unacceptable!\n"); - instance->current_dag->preferred_parent = NULL; + rpl_set_preferred_parent(instance->current_dag, NULL); if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES && last_parent != NULL) { /* Send a No-Path DAO to the removed preferred parent. */ dao_output(last_parent, RPL_ZERO_LIFETIME); @@ -645,7 +642,7 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p) } if(best_dag->preferred_parent != last_parent) { - rpl_set_default_route(instance, &best_dag->preferred_parent->addr); + rpl_set_default_route(instance, rpl_get_parent_ipaddr(best_dag->preferred_parent)); PRINTF("RPL: Changed preferred parent, rank changed from %u to %u\n", (unsigned)old_rank, best_dag->rank); RPL_STAT(rpl_stats.parent_switch++); @@ -672,7 +669,9 @@ rpl_select_parent(rpl_dag_t *dag) rpl_parent_t *p, *best; best = NULL; - for(p = list_head(dag->parents); p != NULL; p = p->next) { + + p = nbr_table_head(rpl_parents); + while(p != NULL) { if(p->rank == INFINITE_RANK) { /* ignore this neighbor */ } else if(best == NULL) { @@ -680,42 +679,43 @@ rpl_select_parent(rpl_dag_t *dag) } else { best = dag->instance->of->best_parent(best, p); } + p = nbr_table_next(rpl_parents, p); } if(best != NULL) { - dag->preferred_parent = best; + rpl_set_preferred_parent(dag, best); } return best; } /*---------------------------------------------------------------------------*/ void -rpl_remove_parent(rpl_dag_t *dag, rpl_parent_t *parent) +rpl_remove_parent(rpl_parent_t *parent) { - rpl_nullify_parent(dag, parent); - PRINTF("RPL: Removing parent "); - PRINT6ADDR(&parent->addr); + PRINT6ADDR(rpl_get_parent_ipaddr(parent)); PRINTF("\n"); - list_remove(dag->parents, parent); - memb_free(&parent_memb, parent); + rpl_nullify_parent(parent); + + nbr_table_remove(rpl_parents, parent); } /*---------------------------------------------------------------------------*/ void -rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent) +rpl_nullify_parent(rpl_parent_t *parent) { + rpl_dag_t *dag = parent->dag; /* This function can be called when the preferred parent is NULL, so we need to handle this condition in order to trigger uip_ds6_defrt_rm. */ if(parent == dag->preferred_parent || dag->preferred_parent == NULL) { - dag->preferred_parent = NULL; + rpl_set_preferred_parent(dag, NULL); dag->rank = INFINITE_RANK; if(dag->joined) { if(dag->instance->def_route != NULL) { - PRINTF("RPL: Removing default route "); - PRINT6ADDR(&parent->addr); - PRINTF("\n"); - uip_ds6_defrt_rm(dag->instance->def_route); + PRINTF("RPL: Removing default route "); + PRINT6ADDR(rpl_get_parent_ipaddr(parent)); + PRINTF("\n"); + uip_ds6_defrt_rm(dag->instance->def_route); dag->instance->def_route = NULL; } dao_output(parent, RPL_ZERO_LIFETIME); @@ -723,7 +723,7 @@ rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent) } PRINTF("RPL: Nullifying parent "); - PRINT6ADDR(&parent->addr); + PRINT6ADDR(rpl_get_parent_ipaddr(parent)); PRINTF("\n"); } /*---------------------------------------------------------------------------*/ @@ -731,11 +731,11 @@ void rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent) { if(parent == dag_src->preferred_parent) { - dag_src->preferred_parent = NULL; + rpl_set_preferred_parent(dag_src, NULL); dag_src->rank = INFINITE_RANK; if(dag_src->joined && dag_src->instance->def_route != NULL) { PRINTF("RPL: Removing default route "); - PRINT6ADDR(&parent->addr); + PRINT6ADDR(rpl_get_parent_ipaddr(parent)); PRINTF("\n"); PRINTF("rpl_move_parent\n"); uip_ds6_defrt_rm(dag_src->instance->def_route); @@ -743,11 +743,11 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent) } } else if(dag_src->joined) { /* Remove uIPv6 routes that have this parent as the next hop. */ - rpl_remove_routes_by_nexthop(&parent->addr, dag_src); + rpl_remove_routes_by_nexthop(rpl_get_parent_ipaddr(parent), dag_src); } PRINTF("RPL: Moving parent "); - PRINT6ADDR(&parent->addr); + PRINT6ADDR(rpl_get_parent_ipaddr(parent)); PRINTF("\n"); list_remove(dag_src->parents, parent); @@ -831,7 +831,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) if(of == NULL) { PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n", dio->instance_id); - rpl_remove_parent(dag, p); + rpl_remove_parent(p); instance->used = 0; return; } @@ -866,7 +866,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio) /* Copy prefix information from the DIO into the DAG object. */ memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t)); - dag->preferred_parent = p; + rpl_set_preferred_parent(dag, p); instance->of->update_metric_container(instance); dag->rank = instance->of->calculate_rank(p, 0); /* So far this is the lowest rank we are aware of. */ @@ -943,7 +943,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio) instance->lifetime_unit != dio->lifetime_unit) { PRINTF("RPL: DIO for DAG instance %u uncompatible with previos DIO\n", dio->instance_id); - rpl_remove_parent(dag, p); + rpl_remove_parent(p); dag->used = 0; return; } @@ -958,7 +958,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio) /* copy prefix information into the dag */ memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t)); - dag->preferred_parent = p; + rpl_set_preferred_parent(dag, p); dag->rank = instance->of->calculate_rank(p, 0); dag->min_rank = dag->rank; /* So far this is the lowest rank we know of. */ @@ -1022,38 +1022,22 @@ rpl_local_repair(rpl_instance_t *instance) void rpl_recalculate_ranks(void) { - rpl_instance_t *instance, *end; rpl_parent_t *p; - int i; /* * We recalculate ranks when we receive feedback from the system rather * than RPL protocol messages. This periodical recalculation is called * from a timer in order to keep the stack depth reasonably low. */ - for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; - instance < end; ++instance) { - if(instance->used) { - for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) { - if(instance->dag_table[i].used) { - for(p = list_head(instance->dag_table[i].parents); - p != NULL; p = p->next) { - if(p->updated) { - p->updated = 0; - if(!rpl_process_parent_event(instance, p)) { - PRINTF("RPL: A parent was dropped\n"); - } - /* - * Stop calculating here because the parent list may have changed. - * If more ranks need to be recalculated, it will be taken care of - * in subsequent calls to this functions. - */ - break; - } - } - } + p = nbr_table_head(rpl_parents); + while(p != NULL) { + if(p->dag != NULL && p->dag->instance && p->updated) { + p->updated = 0; + if(!rpl_process_parent_event(p->dag->instance, p)) { + PRINTF("RPL: A parent was dropped\n"); } } + p = nbr_table_next(rpl_parents, p); } } /*---------------------------------------------------------------------------*/ @@ -1070,11 +1054,10 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p) /* The candidate parent is no longer valid: the rank increase resulting from the choice of it as a parent would be too high. */ PRINTF("RPL: Unacceptable rank %u\n", (unsigned)p->rank); + rpl_nullify_parent(p); if(p != instance->current_dag->preferred_parent) { - rpl_nullify_parent(p->dag, p); return 0; } else { - rpl_nullify_parent(p->dag, p); return_value = 0; } } @@ -1092,7 +1075,7 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p) DAG_RANK(old_rank, instance), DAG_RANK(instance->current_dag->rank, instance)); if(instance->current_dag->rank != INFINITE_RANK) { PRINTF("RPL: The preferred parent is "); - PRINT6ADDR(&instance->current_dag->preferred_parent->addr); + PRINT6ADDR(rpl_get_parent_ipaddr(instance->current_dag->preferred_parent)); PRINTF(" (rank %u)\n", (unsigned)DAG_RANK(instance->current_dag->preferred_parent->rank, instance)); } else { @@ -1143,8 +1126,8 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) /* The DIO sender is on an older version of the DAG. */ PRINTF("RPL: old version received => inconsistency detected\n"); if(dag->joined) { - rpl_reset_dio_timer(instance); - return; + rpl_reset_dio_timer(instance); + return; } } } @@ -1196,10 +1179,6 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) if(p == NULL) { previous_dag = find_parent_dag(instance, from); if(previous_dag == NULL) { - if(RPL_PARENT_COUNT(dag) == RPL_MAX_PARENTS_PER_DAG) { - /* Make room for a new parent. */ - remove_worst_parent(dag, dio->rank); - } /* Add the DIO sender as a candidate parent. */ p = rpl_add_parent(dag, dio, from); if(p == NULL) { diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 711617ae0..dee62fcff 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -664,7 +664,7 @@ dao_input(void) if(lifetime == RPL_ZERO_LIFETIME) { /* No-Path DAO received; invoke the route purging routine. */ - if(rep != NULL && rep->state.nopath_received == 0 && rep->length == prefixlen && uip_ipaddr_cmp(&rep->nexthop, &dao_sender_addr)) { + if(rep != NULL && rep->state.nopath_received == 0 && rep->length == prefixlen && uip_ipaddr_cmp(uip_ds6_route_nexthop(rep), &dao_sender_addr)) { PRINTF("RPL: Setting expiration timer for prefix "); PRINT6ADDR(&prefix); PRINTF("\n"); @@ -706,7 +706,7 @@ dao_input(void) PRINTF("RPL: Forwarding DAO to parent "); PRINT6ADDR(&dag->preferred_parent->addr); PRINTF("\n"); - uip_icmp6_send(&dag->preferred_parent->addr, + uip_icmp6_send(rpl_get_parent_ipaddr(dag->preferred_parent), ICMP6_RPL, RPL_CODE_DAO, buffer_length); } if(flags & RPL_DAO_K_FLAG) { @@ -792,7 +792,7 @@ dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime) PRINT6ADDR(&parent->addr); PRINTF("\n"); - uip_icmp6_send(&parent->addr, ICMP6_RPL, RPL_CODE_DAO, pos); + uip_icmp6_send(rpl_get_parent_ipaddr(parent), ICMP6_RPL, RPL_CODE_DAO, pos); } /*---------------------------------------------------------------------------*/ static void diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index b4c3deca8..bc307e459 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -290,8 +290,8 @@ void rpl_free_instance(rpl_instance_t *); rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *); rpl_parent_t *rpl_find_parent(rpl_dag_t *, uip_ipaddr_t *); rpl_parent_t *rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr); -void rpl_nullify_parent(rpl_dag_t *, rpl_parent_t *); -void rpl_remove_parent(rpl_dag_t *, rpl_parent_t *); +void rpl_nullify_parent(rpl_parent_t *); +void rpl_remove_parent(rpl_parent_t *); void rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent); rpl_parent_t *rpl_select_parent(rpl_dag_t *dag); rpl_dag_t *rpl_select_dag(rpl_instance_t *instance,rpl_parent_t *parent); diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index b12c869be..c57d4105d 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -240,6 +240,7 @@ rpl_init(void) PRINTF("RPL started\n"); default_instance = NULL; + rpl_dag_init(); rpl_reset_periodic_timer(); neighbor_info_subscribe(rpl_link_neighbor_callback); diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index 8e770ddd8..db89f38cd 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -113,9 +113,8 @@ struct rpl_parent { #if RPL_DAG_MC != RPL_DAG_MC_NONE rpl_metric_container_t mc; #endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ - uip_ipaddr_t addr; rpl_rank_t rank; - uint8_t link_metric; + uint16_t link_metric; uint8_t dtsn; uint8_t updated; }; @@ -243,5 +242,8 @@ int rpl_update_header_final(uip_ipaddr_t *addr); int rpl_verify_header(int); void rpl_remove_header(void); uint8_t rpl_invert_header(void); +uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr); +rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr); +void rpl_dag_init(); /*---------------------------------------------------------------------------*/ #endif /* RPL_H */