From c4a121bf1804964f802a83efc205dce826ae4cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Dawans?= Date: Thu, 25 Jul 2013 10:39:39 +0200 Subject: [PATCH 1/3] No-Path DAO Propagation --- core/net/rpl/rpl-icmp6.c | 28 ++++++++++++++++++---------- core/net/rpl/rpl-private.h | 1 + core/net/rpl/rpl.c | 14 ++++++++++++++ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 11c414222..92cb319ae 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -709,20 +709,28 @@ dao_input(void) void dao_output(rpl_parent_t *n, uint8_t lifetime) { - rpl_dag_t *dag; - rpl_instance_t *instance; - unsigned char *buffer; - uint8_t prefixlen; - uip_ipaddr_t prefix; - int pos; - /* Destination Advertisement Object */ + uip_ipaddr_t prefix; if(get_global_addr(&prefix) == 0) { PRINTF("RPL: No global address set for this node - suppressing DAO\n"); return; } + dao_output_target(n, &prefix, lifetime); +} +/*---------------------------------------------------------------------------*/ +void +dao_output_target(rpl_parent_t *n, uip_ipaddr_t *prefix, uint8_t lifetime) +{ + rpl_dag_t *dag; + rpl_instance_t *instance; + unsigned char *buffer; + uint8_t prefixlen; + int pos; + + /* Destination Advertisement Object */ + dag = n->dag; instance = dag->instance; @@ -752,12 +760,12 @@ dao_output(rpl_parent_t *n, uint8_t lifetime) #endif /* RPL_DAO_SPECIFY_DAG */ /* create target subopt */ - prefixlen = sizeof(prefix) * CHAR_BIT; + prefixlen = sizeof(*prefix) * CHAR_BIT; buffer[pos++] = RPL_OPTION_TARGET; buffer[pos++] = 2 + ((prefixlen + 7) / CHAR_BIT); buffer[pos++] = 0; /* reserved */ buffer[pos++] = prefixlen; - memcpy(buffer + pos, &prefix, (prefixlen + 7) / CHAR_BIT); + memcpy(buffer + pos, prefix, (prefixlen + 7) / CHAR_BIT); pos += ((prefixlen + 7) / CHAR_BIT); /* Create a transit information sub-option. */ @@ -769,7 +777,7 @@ dao_output(rpl_parent_t *n, uint8_t lifetime) buffer[pos++] = lifetime; PRINTF("RPL: Sending DAO with prefix "); - PRINT6ADDR(&prefix); + PRINT6ADDR(prefix); PRINTF(" to "); PRINT6ADDR(&n->addr); PRINTF("\n"); diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index a8f884ee1..b4c3deca8 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -270,6 +270,7 @@ extern rpl_instance_t *default_instance; void dis_output(uip_ipaddr_t *addr); void dio_output(rpl_instance_t *, uip_ipaddr_t *uc_addr); 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); /* RPL logic functions. */ diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index f7b8bb722..2e9a10e5a 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -63,6 +63,8 @@ void rpl_purge_routes(void) { uip_ds6_route_t *r; + uip_ipaddr_t prefix; + rpl_dag_t *dag; /* First pass, decrement lifetime */ r = uip_ds6_route_list_head(); @@ -86,8 +88,20 @@ rpl_purge_routes(void) if(r->state.lifetime < 1) { /* Routes with lifetime == 1 have only just been decremented from 2 to 1, * thus we want to keep them. Hence < and not <= */ + uip_ipaddr_copy(&prefix, &r->ipaddr); uip_ds6_route_rm(r); r = uip_ds6_route_list_head(); + PRINTF("No more routes to "); + PRINT6ADDR(&prefix); + dag = default_instance->current_dag; + /* Propagate this information with a No-Path DAO to preferred parent if we are not a RPL Root */ + if(dag->rank != ROOT_RANK(default_instance)) { + PRINTF(" -> generate No-Path DAO\n"); + dao_output_target(dag->preferred_parent, &prefix, RPL_ZERO_LIFETIME); + /* Don't schedule more than 1 No-Path DAO, let next iteration handle that */ + return; + } + PRINTF("\n"); } else { r = list_item_next(r); } From 0bd26d83c8ad9a47474faf55d7453d8f3309affc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Dawans?= Date: Thu, 25 Jul 2013 11:21:04 +0200 Subject: [PATCH 2/3] Ignore No-Path DAO if target is already reachable through a different route than the DAO sender --- core/net/rpl/rpl-icmp6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 92cb319ae..4f3f6c4c9 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -655,7 +655,7 @@ dao_input(void) if(lifetime == RPL_ZERO_LIFETIME) { /* No-Path DAO received; invoke the route purging routine. */ - if(rep != NULL && rep->state.saved_lifetime == 0 && rep->length == prefixlen) { + if(rep != NULL && rep->state.saved_lifetime == 0 && rep->length == prefixlen && uip_ipaddr_cmp(&rep->nexthop, &dao_sender_addr)) { PRINTF("RPL: Setting expiration timer for prefix "); PRINT6ADDR(&prefix); PRINTF("\n"); From a05d635512b460f426013fad2696b26eeef1246f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Dawans?= Date: Thu, 25 Jul 2013 11:22:38 +0200 Subject: [PATCH 3/3] Improve readability of DAO output variables --- core/net/rpl/rpl-icmp6.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 4f3f6c4c9..6c2f9d737 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -707,7 +707,7 @@ dao_input(void) } /*---------------------------------------------------------------------------*/ void -dao_output(rpl_parent_t *n, uint8_t lifetime) +dao_output(rpl_parent_t *parent, uint8_t lifetime) { /* Destination Advertisement Object */ uip_ipaddr_t prefix; @@ -717,11 +717,12 @@ dao_output(rpl_parent_t *n, uint8_t lifetime) return; } - dao_output_target(n, &prefix, lifetime); + /* Sending a DAO with own prefix as target */ + dao_output_target(parent, &prefix, lifetime); } /*---------------------------------------------------------------------------*/ void -dao_output_target(rpl_parent_t *n, uip_ipaddr_t *prefix, uint8_t lifetime) +dao_output_target(rpl_parent_t *parent, uip_ipaddr_t *prefix, uint8_t lifetime) { rpl_dag_t *dag; rpl_instance_t *instance; @@ -731,11 +732,11 @@ dao_output_target(rpl_parent_t *n, uip_ipaddr_t *prefix, uint8_t lifetime) /* Destination Advertisement Object */ - dag = n->dag; + dag = parent->dag; instance = dag->instance; #ifdef RPL_DEBUG_DAO_OUTPUT - RPL_DEBUG_DAO_OUTPUT(n); + RPL_DEBUG_DAO_OUTPUT(parent); #endif buffer = UIP_ICMP_PAYLOAD; @@ -779,10 +780,10 @@ dao_output_target(rpl_parent_t *n, uip_ipaddr_t *prefix, uint8_t lifetime) PRINTF("RPL: Sending DAO with prefix "); PRINT6ADDR(prefix); PRINTF(" to "); - PRINT6ADDR(&n->addr); + PRINT6ADDR(&parent->addr); PRINTF("\n"); - uip_icmp6_send(&n->addr, ICMP6_RPL, RPL_CODE_DAO, pos); + uip_icmp6_send(&parent->addr, ICMP6_RPL, RPL_CODE_DAO, pos); } /*---------------------------------------------------------------------------*/ static void