Merge pull request #652 from cetic/pr-rpl-rank-and-fw-errors
RPL rank and forward errors
This commit is contained in:
commit
63563ed8df
5 changed files with 61 additions and 24 deletions
|
@ -227,10 +227,32 @@ uip_ds6_neighbor_periodic(void)
|
||||||
switch(nbr->state) {
|
switch(nbr->state) {
|
||||||
case NBR_REACHABLE:
|
case NBR_REACHABLE:
|
||||||
if(stimer_expired(&nbr->reachable)) {
|
if(stimer_expired(&nbr->reachable)) {
|
||||||
|
#if UIP_CONF_IPV6_RPL
|
||||||
|
/* when a neighbor leave it's REACHABLE state and is a default router,
|
||||||
|
instead of going to STALE state it enters DELAY state in order to
|
||||||
|
force a NUD on it. Otherwise, if there is no upward traffic, the
|
||||||
|
node never knows if the default router is still reachable. This
|
||||||
|
mimics the 6LoWPAN-ND behavior.
|
||||||
|
*/
|
||||||
|
if(uip_ds6_defrt_lookup(&nbr->ipaddr) != NULL) {
|
||||||
|
PRINTF("REACHABLE: defrt moving to DELAY (");
|
||||||
|
PRINT6ADDR(&nbr->ipaddr);
|
||||||
|
PRINTF(")\n");
|
||||||
|
nbr->state = NBR_DELAY;
|
||||||
|
stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
|
||||||
|
nbr->nscount = 0;
|
||||||
|
} else {
|
||||||
|
PRINTF("REACHABLE: moving to STALE (");
|
||||||
|
PRINT6ADDR(&nbr->ipaddr);
|
||||||
|
PRINTF(")\n");
|
||||||
|
nbr->state = NBR_STALE;
|
||||||
|
}
|
||||||
|
#else /* UIP_CONF_IPV6_RPL */
|
||||||
PRINTF("REACHABLE: moving to STALE (");
|
PRINTF("REACHABLE: moving to STALE (");
|
||||||
PRINT6ADDR(&nbr->ipaddr);
|
PRINT6ADDR(&nbr->ipaddr);
|
||||||
PRINTF(")\n");
|
PRINTF(")\n");
|
||||||
nbr->state = NBR_STALE;
|
nbr->state = NBR_STALE;
|
||||||
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#if UIP_ND6_SEND_NA
|
#if UIP_ND6_SEND_NA
|
||||||
|
|
|
@ -1207,7 +1207,11 @@ uip_process(uint8_t flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UIP_CONF_IPV6_RPL
|
#if UIP_CONF_IPV6_RPL
|
||||||
rpl_update_header_empty();
|
if(rpl_update_header_empty()) {
|
||||||
|
/* Packet can not be forwarded */
|
||||||
|
PRINTF("RPL Forward Option Error\n");
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
|
|
||||||
UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
|
UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
|
||||||
|
|
|
@ -93,6 +93,13 @@ rpl_dag_init(void)
|
||||||
nbr_table_register(rpl_parents, (nbr_table_callback *)nbr_callback);
|
nbr_table_register(rpl_parents, (nbr_table_callback *)nbr_callback);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
rpl_parent_t *
|
||||||
|
rpl_get_parent(uip_lladdr_t *addr)
|
||||||
|
{
|
||||||
|
rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (linkaddr_t *)addr);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_rank_t
|
rpl_rank_t
|
||||||
rpl_get_parent_rank(uip_lladdr_t *addr)
|
rpl_get_parent_rank(uip_lladdr_t *addr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "net/ip/tcpip.h"
|
#include "net/ip/tcpip.h"
|
||||||
#include "net/ipv6/uip-ds6.h"
|
#include "net/ipv6/uip-ds6.h"
|
||||||
#include "net/rpl/rpl-private.h"
|
#include "net/rpl/rpl-private.h"
|
||||||
|
#include "net/packetbuf.h"
|
||||||
|
|
||||||
#define DEBUG DEBUG_NONE
|
#define DEBUG DEBUG_NONE
|
||||||
#include "net/ip/uip-debug.h"
|
#include "net/ip/uip-debug.h"
|
||||||
|
@ -105,19 +106,12 @@ rpl_verify_header(int uip_ext_opt_offset)
|
||||||
route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
|
route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
|
||||||
if(route != NULL) {
|
if(route != NULL) {
|
||||||
uip_ds6_route_rm(route);
|
uip_ds6_route_rm(route);
|
||||||
|
|
||||||
/* If we are the root and just needed to remove a DAO route,
|
|
||||||
chances are that the network needs to be repaired. The
|
|
||||||
rpl_repair_root() function will cause a global repair if we
|
|
||||||
happen to be the root node of the dag. */
|
|
||||||
PRINTF("RPL: initiate global repair\n");
|
|
||||||
rpl_repair_root(instance->instance_id);
|
|
||||||
}
|
}
|
||||||
|
RPL_STAT(rpl_stats.forward_errors++);
|
||||||
/* Remove the forwarding error flag and return 0 to let the packet
|
/* Trigger DAO retransmission */
|
||||||
be forwarded again. */
|
rpl_reset_dio_timer(instance);
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_FWD_ERR;
|
/* drop the packet as it is not routable */
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!instance->current_dag->joined) {
|
if(!instance->current_dag->joined) {
|
||||||
|
@ -145,10 +139,9 @@ rpl_verify_header(int uip_ext_opt_offset)
|
||||||
sender_closer);
|
sender_closer);
|
||||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR) {
|
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR) {
|
||||||
PRINTF("RPL: Rank error signalled in RPL option!\n");
|
PRINTF("RPL: Rank error signalled in RPL option!\n");
|
||||||
/* We should try to repair it, not implemented for the moment */
|
/* Packet must be dropped and dio trickle timer reset, see RFC6550 - 11.2.2.2 */
|
||||||
rpl_reset_dio_timer(instance);
|
rpl_reset_dio_timer(instance);
|
||||||
/* Forward the packet anyway. */
|
return 1;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
PRINTF("RPL: Single error tolerated\n");
|
PRINTF("RPL: Single error tolerated\n");
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
|
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
|
||||||
|
@ -183,12 +176,13 @@ set_rpl_opt(unsigned uip_ext_opt_offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
int
|
||||||
rpl_update_header_empty(void)
|
rpl_update_header_empty(void)
|
||||||
{
|
{
|
||||||
rpl_instance_t *instance;
|
rpl_instance_t *instance;
|
||||||
int uip_ext_opt_offset;
|
int uip_ext_opt_offset;
|
||||||
int last_uip_ext_len;
|
int last_uip_ext_len;
|
||||||
|
rpl_parent_t *parent;
|
||||||
|
|
||||||
last_uip_ext_len = uip_ext_len;
|
last_uip_ext_len = uip_ext_len;
|
||||||
uip_ext_len = 0;
|
uip_ext_len = 0;
|
||||||
|
@ -211,12 +205,12 @@ rpl_update_header_empty(void)
|
||||||
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||||
PRINTF("RPL: RPL Hop-by-hop option has wrong length\n");
|
PRINTF("RPL: RPL Hop-by-hop option has wrong length\n");
|
||||||
uip_ext_len = last_uip_ext_len;
|
uip_ext_len = last_uip_ext_len;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||||
if(instance == NULL || !instance->used || !instance->current_dag->joined) {
|
if(instance == NULL || !instance->used || !instance->current_dag->joined) {
|
||||||
PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect instance\n");
|
PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect instance\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -224,11 +218,11 @@ rpl_update_header_empty(void)
|
||||||
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) {
|
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) {
|
||||||
PRINTF("RPL: Packet too long: impossible to add hop-by-hop option\n");
|
PRINTF("RPL: Packet too long: impossible to add hop-by-hop option\n");
|
||||||
uip_ext_len = last_uip_ext_len;
|
uip_ext_len = last_uip_ext_len;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
set_rpl_opt(uip_ext_opt_offset);
|
set_rpl_opt(uip_ext_opt_offset);
|
||||||
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
|
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(UIP_EXT_HDR_OPT_BUF->type) {
|
switch(UIP_EXT_HDR_OPT_BUF->type) {
|
||||||
|
@ -244,6 +238,15 @@ rpl_update_header_empty(void)
|
||||||
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR;
|
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR;
|
||||||
PRINTF("RPL forwarding error\n");
|
PRINTF("RPL forwarding error\n");
|
||||||
|
/* We should send back the packet to the originating parent,
|
||||||
|
but it is not feasible yet, so we send a No-Path DAO instead */
|
||||||
|
PRINTF("RPL generate No-Path DAO\n");
|
||||||
|
parent = rpl_get_parent((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
|
if(parent != NULL) {
|
||||||
|
dao_output_target(parent, &UIP_IP_BUF->destipaddr, RPL_ZERO_LIFETIME);
|
||||||
|
}
|
||||||
|
/* Drop packet */
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Set the down extension flag correctly as described in Section
|
/* Set the down extension flag correctly as described in Section
|
||||||
|
@ -262,11 +265,11 @@ rpl_update_header_empty(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
uip_ext_len = last_uip_ext_len;
|
uip_ext_len = last_uip_ext_len;
|
||||||
return;
|
return 0;
|
||||||
default:
|
default:
|
||||||
PRINTF("RPL: Multi Hop-by-hop options not implemented\n");
|
PRINTF("RPL: Multi Hop-by-hop options not implemented\n");
|
||||||
uip_ext_len = last_uip_ext_len;
|
uip_ext_len = last_uip_ext_len;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -240,13 +240,14 @@ int rpl_repair_root(uint8_t instance_id);
|
||||||
int rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from);
|
int rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from);
|
||||||
rpl_dag_t *rpl_get_any_dag(void);
|
rpl_dag_t *rpl_get_any_dag(void);
|
||||||
rpl_instance_t *rpl_get_instance(uint8_t instance_id);
|
rpl_instance_t *rpl_get_instance(uint8_t instance_id);
|
||||||
void rpl_update_header_empty(void);
|
int rpl_update_header_empty(void);
|
||||||
int rpl_update_header_final(uip_ipaddr_t *addr);
|
int rpl_update_header_final(uip_ipaddr_t *addr);
|
||||||
int rpl_verify_header(int);
|
int rpl_verify_header(int);
|
||||||
void rpl_insert_header(void);
|
void rpl_insert_header(void);
|
||||||
void rpl_remove_header(void);
|
void rpl_remove_header(void);
|
||||||
uint8_t rpl_invert_header(void);
|
uint8_t rpl_invert_header(void);
|
||||||
uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr);
|
uip_ipaddr_t *rpl_get_parent_ipaddr(rpl_parent_t *nbr);
|
||||||
|
rpl_parent_t *rpl_get_parent(uip_lladdr_t *addr);
|
||||||
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
|
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
|
||||||
uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr);
|
uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr);
|
||||||
void rpl_dag_init(void);
|
void rpl_dag_init(void);
|
||||||
|
|
Loading…
Reference in a new issue