Implement forwarding error handling: if a packet changes direction, we set the FWD_ERR flag. If we see the FWD_ERR flag, we drop the route that we sent it to. If we are the root node, we also initiate a global repair.

This commit is contained in:
Adam Dunkels 2013-08-12 00:06:12 +02:00 committed by Simon Duquennoy
parent abb3ef9b3b
commit d830e9df3f

View File

@ -75,12 +75,6 @@ rpl_verify_header(int uip_ext_opt_offset)
return 1; return 1;
} }
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
PRINTF("RPL: Forward error!\n");
/* We should try to repair it, not implemented for the moment */
return 2;
}
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) { if(instance == NULL) {
PRINTF("RPL: Unknown instance: %u\n", PRINTF("RPL: Unknown instance: %u\n",
@ -88,6 +82,31 @@ rpl_verify_header(int uip_ext_opt_offset)
return 1; return 1;
} }
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
PRINTF("RPL: Forward error!\n");
/* We should try to repair it by removing the neighbor that caused
the packet to be forwareded in the first place. We drop any
routes that go through the neighbor that sent the packet to
us. */
uip_ds6_route_t *route;
route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
if(route != NULL) {
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);
}
/* Remove the forwarding error flag and return 0 to let the packet
be forwarded again. */
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_FWD_ERR;
return 0;
}
if(!instance->current_dag->joined) { if(!instance->current_dag->joined) {
PRINTF("RPL: No DAG in the instance\n"); PRINTF("RPL: No DAG in the instance\n");
return 1; return 1;
@ -191,18 +210,29 @@ rpl_update_header_empty(void)
PRINTF("RPL: Updating RPL option\n"); PRINTF("RPL: Updating RPL option\n");
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = instance->current_dag->rank; UIP_EXT_HDR_OPT_RPL_BUF->senderrank = instance->current_dag->rank;
/* Check the direction of the down flag, as per Section 11.2.2.3,
/* Set the down extension flag correctly as described in Section which states that if a packet is going down it should in
11.2 of RFC6550. If the packet progresses along a DAO route, general not go back up again. If this happens, a
the down flag should be set. */ RPL_HDR_OPT_FWD_ERR should be flagged. */
if((UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN)) {
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) { if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
/* No route was found, so this packet will go towards the RPL UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR;
root. If so, we should not set the down flag. */ PRINTF("RPL forwarding error\n");
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN; }
} else { } else {
/* A DAO route was found so we set the down flag. */ /* Set the down extension flag correctly as described in Section
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN; 11.2 of RFC6550. If the packet progresses along a DAO route,
the down flag should be set. */
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
/* No route was found, so this packet will go towards the RPL
root. If so, we should not set the down flag. */
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN;
PRINTF("RPL option going up\n");
} else {
/* A DAO route was found so we set the down flag. */
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN;
PRINTF("RPL option going down\n");
}
} }
uip_ext_len = last_uip_ext_len; uip_ext_len = last_uip_ext_len;