No-Path DAO Propagation

This commit is contained in:
Sébastien Dawans 2013-07-25 10:39:39 +02:00
parent 4108066f0a
commit c4a121bf18
3 changed files with 33 additions and 10 deletions

View File

@ -709,20 +709,28 @@ dao_input(void)
void void
dao_output(rpl_parent_t *n, uint8_t lifetime) 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 */ /* Destination Advertisement Object */
uip_ipaddr_t prefix;
if(get_global_addr(&prefix) == 0) { if(get_global_addr(&prefix) == 0) {
PRINTF("RPL: No global address set for this node - suppressing DAO\n"); PRINTF("RPL: No global address set for this node - suppressing DAO\n");
return; 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; dag = n->dag;
instance = dag->instance; instance = dag->instance;
@ -752,12 +760,12 @@ dao_output(rpl_parent_t *n, uint8_t lifetime)
#endif /* RPL_DAO_SPECIFY_DAG */ #endif /* RPL_DAO_SPECIFY_DAG */
/* create target subopt */ /* create target subopt */
prefixlen = sizeof(prefix) * CHAR_BIT; prefixlen = sizeof(*prefix) * CHAR_BIT;
buffer[pos++] = RPL_OPTION_TARGET; buffer[pos++] = RPL_OPTION_TARGET;
buffer[pos++] = 2 + ((prefixlen + 7) / CHAR_BIT); buffer[pos++] = 2 + ((prefixlen + 7) / CHAR_BIT);
buffer[pos++] = 0; /* reserved */ buffer[pos++] = 0; /* reserved */
buffer[pos++] = prefixlen; buffer[pos++] = prefixlen;
memcpy(buffer + pos, &prefix, (prefixlen + 7) / CHAR_BIT); memcpy(buffer + pos, prefix, (prefixlen + 7) / CHAR_BIT);
pos += ((prefixlen + 7) / CHAR_BIT); pos += ((prefixlen + 7) / CHAR_BIT);
/* Create a transit information sub-option. */ /* Create a transit information sub-option. */
@ -769,7 +777,7 @@ dao_output(rpl_parent_t *n, uint8_t lifetime)
buffer[pos++] = lifetime; buffer[pos++] = lifetime;
PRINTF("RPL: Sending DAO with prefix "); PRINTF("RPL: Sending DAO with prefix ");
PRINT6ADDR(&prefix); PRINT6ADDR(prefix);
PRINTF(" to "); PRINTF(" to ");
PRINT6ADDR(&n->addr); PRINT6ADDR(&n->addr);
PRINTF("\n"); PRINTF("\n");

View File

@ -270,6 +270,7 @@ extern rpl_instance_t *default_instance;
void dis_output(uip_ipaddr_t *addr); void dis_output(uip_ipaddr_t *addr);
void dio_output(rpl_instance_t *, uip_ipaddr_t *uc_addr); void dio_output(rpl_instance_t *, uip_ipaddr_t *uc_addr);
void dao_output(rpl_parent_t *, uint8_t lifetime); 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); void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t);
/* RPL logic functions. */ /* RPL logic functions. */

View File

@ -63,6 +63,8 @@ void
rpl_purge_routes(void) rpl_purge_routes(void)
{ {
uip_ds6_route_t *r; uip_ds6_route_t *r;
uip_ipaddr_t prefix;
rpl_dag_t *dag;
/* First pass, decrement lifetime */ /* First pass, decrement lifetime */
r = uip_ds6_route_list_head(); r = uip_ds6_route_list_head();
@ -86,8 +88,20 @@ rpl_purge_routes(void)
if(r->state.lifetime < 1) { if(r->state.lifetime < 1) {
/* Routes with lifetime == 1 have only just been decremented from 2 to 1, /* Routes with lifetime == 1 have only just been decremented from 2 to 1,
* thus we want to keep them. Hence < and not <= */ * thus we want to keep them. Hence < and not <= */
uip_ipaddr_copy(&prefix, &r->ipaddr);
uip_ds6_route_rm(r); uip_ds6_route_rm(r);
r = uip_ds6_route_list_head(); 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 { } else {
r = list_item_next(r); r = list_item_next(r);
} }