From 29f894c07ec57d5be0f4a4024f798e894eb9882e Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Fri, 31 Jan 2014 09:38:42 +0100 Subject: [PATCH] Drop forwarding error packet and send back DAO to originating parent --- core/net/ipv6/uip6.c | 6 +++++- core/net/rpl/rpl-dag.c | 7 +++++++ core/net/rpl/rpl-ext-header.c | 25 ++++++++++++++++++------- core/net/rpl/rpl.h | 3 ++- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/core/net/ipv6/uip6.c b/core/net/ipv6/uip6.c index 0ee1d3102..638faf859 100644 --- a/core/net/ipv6/uip6.c +++ b/core/net/ipv6/uip6.c @@ -1207,7 +1207,11 @@ uip_process(uint8_t flag) } #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 */ UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1; diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 3869fdc7e..ed80dcfde 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -93,6 +93,13 @@ rpl_dag_init(void) 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_get_parent_rank(uip_lladdr_t *addr) { diff --git a/core/net/rpl/rpl-ext-header.c b/core/net/rpl/rpl-ext-header.c index 3319e6d29..b1d1d777a 100644 --- a/core/net/rpl/rpl-ext-header.c +++ b/core/net/rpl/rpl-ext-header.c @@ -48,6 +48,7 @@ #include "net/ip/tcpip.h" #include "net/ipv6/uip-ds6.h" #include "net/rpl/rpl-private.h" +#include "net/packetbuf.h" #define DEBUG DEBUG_NONE #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_instance_t *instance; int uip_ext_opt_offset; int last_uip_ext_len; + rpl_parent_t *parent; last_uip_ext_len = uip_ext_len; 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) { PRINTF("RPL: RPL Hop-by-hop option has wrong length\n"); uip_ext_len = last_uip_ext_len; - return; + return 0; } instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance); if(instance == NULL || !instance->used || !instance->current_dag->joined) { PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect instance\n"); - return; + return 0; } break; default: @@ -216,11 +218,11 @@ rpl_update_header_empty(void) if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) { PRINTF("RPL: Packet too long: impossible to add hop-by-hop option\n"); uip_ext_len = last_uip_ext_len; - return; + return 0; } set_rpl_opt(uip_ext_opt_offset); uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN; - return; + return 0; } 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) { UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR; 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 { /* 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; - return; + return 0; default: PRINTF("RPL: Multi Hop-by-hop options not implemented\n"); uip_ext_len = last_uip_ext_len; - return; + return 0; } } /*---------------------------------------------------------------------------*/ diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index c6f2b94fc..512c2f5f1 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -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); rpl_dag_t *rpl_get_any_dag(void); 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_verify_header(int); void rpl_insert_header(void); void rpl_remove_header(void); uint8_t rpl_invert_header(void); 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); uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr); void rpl_dag_init(void);