From 797bead5e54fd07a87cd46d0b9afe0cd38f516e6 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 30 Nov 2015 19:17:17 +0100 Subject: [PATCH] RPL: if a neighbor is unreachable, remove routes via this neighbor --- core/net/rpl/rpl-dag.c | 24 ++++++++++++++++++++++++ core/net/rpl/rpl-mrhof.c | 9 +++++++++ core/net/rpl/rpl-of0.c | 7 +++++++ core/net/rpl/rpl.h | 6 ++++++ 4 files changed, 46 insertions(+) diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 89db83750..c4108fd5a 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -210,6 +210,23 @@ rpl_parent_is_fresh(rpl_parent_t *p) return link_stats_is_fresh(stats); } /*---------------------------------------------------------------------------*/ +int +rpl_parent_is_reachable(rpl_parent_t *p) { + if(p == NULL || p->dag == NULL || p->dag->instance == NULL || p->dag->instance->of == NULL) { + return 0; + } else { +#ifndef UIP_CONF_ND6_SEND_NA + uip_ds6_nbr_t *nbr = rpl_get_nbr(p); + /* Exclude links to a neighbor that is not reachable at a NUD level */ + if(nbr == NULL || nbr->state != NBR_REACHABLE) { + return 0; + } +#endif /* UIP_CONF_ND6_SEND_NA */ + /* If we don't have fresh link information, assume the parent is reachable. */ + return !rpl_parent_is_fresh(p) || p->dag->instance->of->parent_has_usable_link(p); + } +} +/*---------------------------------------------------------------------------*/ static void rpl_set_preferred_parent(rpl_dag_t *dag, rpl_parent_t *p) { @@ -1316,6 +1333,13 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p) return_value = 1; + if(uip_ds6_route_is_nexthop(rpl_get_parent_ipaddr(p)) && !rpl_parent_is_reachable(p)) { + PRINTF("RPL: Unacceptable link %u, removing routes via: ", rpl_get_parent_link_metric(p)); + PRINT6ADDR(rpl_get_parent_ipaddr(p)); + PRINTF("\n"); + rpl_remove_routes_by_nexthop(rpl_get_parent_ipaddr(p), p->dag); + } + if(!acceptable_rank(p->dag, p->rank)) { /* The candidate parent is no longer valid: the rank increase resulting from the choice of it as a parent would be too high. */ diff --git a/core/net/rpl/rpl-mrhof.c b/core/net/rpl/rpl-mrhof.c index a818d1c36..c51ac8694 100644 --- a/core/net/rpl/rpl-mrhof.c +++ b/core/net/rpl/rpl-mrhof.c @@ -185,6 +185,14 @@ parent_is_acceptable(rpl_parent_t *p) return link_metric <= MAX_LINK_METRIC && path_cost <= MAX_PATH_COST; } /*---------------------------------------------------------------------------*/ +static int +parent_has_usable_link(rpl_parent_t *p) +{ + uint16_t link_metric = parent_link_metric(p); + /* Exclude links with too high link metrics */ + return link_metric <= MAX_LINK_METRIC; +} +/*---------------------------------------------------------------------------*/ static rpl_parent_t * best_parent(rpl_parent_t *p1, rpl_parent_t *p2) { @@ -296,6 +304,7 @@ rpl_of_t rpl_mrhof = { dao_ack_callback, #endif parent_link_metric, + parent_has_usable_link, parent_path_cost, rank_via_parent, best_parent, diff --git a/core/net/rpl/rpl-of0.c b/core/net/rpl/rpl-of0.c index 16913d8c5..d0bfd1296 100644 --- a/core/net/rpl/rpl-of0.c +++ b/core/net/rpl/rpl-of0.c @@ -155,6 +155,12 @@ parent_is_acceptable(rpl_parent_t *p) && STEP_OF_RANK(p) <= MAX_STEP_OF_RANK; } /*---------------------------------------------------------------------------*/ +static int +parent_has_usable_link(rpl_parent_t *p) +{ + return parent_is_acceptable(p); +} +/*---------------------------------------------------------------------------*/ static rpl_parent_t * best_parent(rpl_parent_t *p1, rpl_parent_t *p2) { @@ -220,6 +226,7 @@ rpl_of_t rpl_of0 = { dao_ack_callback, #endif parent_link_metric, + parent_has_usable_link, parent_path_cost, rank_via_parent, best_parent, diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index f4efafd50..89bc70ae8 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -162,6 +162,10 @@ typedef struct rpl_instance rpl_instance_t; * * Returns the link metric of a parent * + * parent_has_usable_link(parent) + * + * Returns 1 iff we have a usable link to this parent + * * parent_path_cost(parent) * * Returns the path cost of a parent @@ -200,6 +204,7 @@ struct rpl_of { void (*dao_ack_callback)(rpl_parent_t *, int status); #endif uint16_t (*parent_link_metric)(rpl_parent_t *); + int (*parent_has_usable_link)(rpl_parent_t *); uint16_t (*parent_path_cost)(rpl_parent_t *); rpl_rank_t (*rank_via_parent)(rpl_parent_t *); rpl_parent_t *(*best_parent)(rpl_parent_t *, rpl_parent_t *); @@ -276,6 +281,7 @@ void rpl_remove_header(void); uint8_t rpl_invert_header(void); const struct link_stats *rpl_get_parent_link_stats(rpl_parent_t *p); int rpl_parent_is_fresh(rpl_parent_t *p); +int rpl_parent_is_reachable(rpl_parent_t *p); uint16_t rpl_get_parent_link_metric(rpl_parent_t *p); rpl_rank_t rpl_rank_via_parent(rpl_parent_t *p); const linkaddr_t *rpl_get_parent_lladdr(rpl_parent_t *p);