commit
500d9cc3e4
3 changed files with 40 additions and 16 deletions
|
@ -655,7 +655,7 @@ dao_input(void)
|
||||||
|
|
||||||
if(lifetime == RPL_ZERO_LIFETIME) {
|
if(lifetime == RPL_ZERO_LIFETIME) {
|
||||||
/* No-Path DAO received; invoke the route purging routine. */
|
/* 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 ");
|
PRINTF("RPL: Setting expiration timer for prefix ");
|
||||||
PRINT6ADDR(&prefix);
|
PRINT6ADDR(&prefix);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
|
@ -707,27 +707,36 @@ dao_input(void)
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
dao_output(rpl_parent_t *n, uint8_t lifetime)
|
dao_output(rpl_parent_t *parent, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
dag = n->dag;
|
/* Sending a DAO with own prefix as target */
|
||||||
|
dao_output_target(parent, &prefix, lifetime);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
dao_output_target(rpl_parent_t *parent, 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 = parent->dag;
|
||||||
instance = dag->instance;
|
instance = dag->instance;
|
||||||
|
|
||||||
#ifdef RPL_DEBUG_DAO_OUTPUT
|
#ifdef RPL_DEBUG_DAO_OUTPUT
|
||||||
RPL_DEBUG_DAO_OUTPUT(n);
|
RPL_DEBUG_DAO_OUTPUT(parent);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
buffer = UIP_ICMP_PAYLOAD;
|
buffer = UIP_ICMP_PAYLOAD;
|
||||||
|
@ -752,12 +761,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,12 +778,12 @@ 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(&parent->addr);
|
||||||
PRINTF("\n");
|
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
|
static void
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue