Drop forwarding error packet and send back DAO to originating parent

This commit is contained in:
Laurent Deru 2014-01-31 09:38:42 +01:00
parent a964380155
commit 29f894c07e
4 changed files with 32 additions and 9 deletions

View file

@ -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;

View file

@ -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)
{ {

View file

@ -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"
@ -175,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;
@ -203,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:
@ -216,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) {
@ -236,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
@ -254,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;
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -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);