Check if the nexthop neighbor for a given route has disappeared. If so, we drop the route too. If we happen to be the RPL root, we also initiate a global repair as the neighbor may moved.
This commit is contained in:
parent
d0a939afb0
commit
8dc4e46968
1 changed files with 56 additions and 13 deletions
|
@ -561,14 +561,22 @@ tcpip_ipv6_output(void)
|
||||||
if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
||||||
/* Next hop determination */
|
/* Next hop determination */
|
||||||
nbr = NULL;
|
nbr = NULL;
|
||||||
|
|
||||||
|
/* We first check if the destination address is on our immediate
|
||||||
|
link. If so, we simply use the destination address as our
|
||||||
|
nexthop address. */
|
||||||
if(uip_ds6_is_addr_onlink(&UIP_IP_BUF->destipaddr)){
|
if(uip_ds6_is_addr_onlink(&UIP_IP_BUF->destipaddr)){
|
||||||
nexthop = &UIP_IP_BUF->destipaddr;
|
nexthop = &UIP_IP_BUF->destipaddr;
|
||||||
} else {
|
} else {
|
||||||
uip_ds6_route_t* locrt;
|
uip_ds6_route_t *route;
|
||||||
locrt = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
|
/* Check if we have a route to the destination address. */
|
||||||
if(locrt == NULL) {
|
route = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
|
||||||
|
|
||||||
|
/* No route was found - we send to the default route instead. */
|
||||||
|
if(route == NULL) {
|
||||||
PRINTF("tcpip_ipv6_output: no route found, using default route\n");
|
PRINTF("tcpip_ipv6_output: no route found, using default route\n");
|
||||||
if((nexthop = uip_ds6_defrt_choose()) == NULL) {
|
nexthop = uip_ds6_defrt_choose();
|
||||||
|
if(nexthop == NULL) {
|
||||||
#ifdef UIP_FALLBACK_INTERFACE
|
#ifdef UIP_FALLBACK_INTERFACE
|
||||||
PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n",
|
PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n",
|
||||||
uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40));
|
uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40));
|
||||||
|
@ -586,26 +594,61 @@ tcpip_ipv6_output(void)
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
nexthop = uip_ds6_route_nexthop(locrt);
|
/* A route was found, so we look up the nexthop neighbor for
|
||||||
|
the route. */
|
||||||
|
nexthop = uip_ds6_route_nexthop(route);
|
||||||
|
|
||||||
|
/* If the nexthop is dead, for example because the neighbor
|
||||||
|
never responded to link-layer acks, we drop its route. */
|
||||||
|
if(nexthop == NULL) {
|
||||||
|
#if UIP_CONF_IPV6_RPL
|
||||||
|
/* If we are running RPL, and if we are the root of the
|
||||||
|
network, we'll trigger a global repair berfore we remove
|
||||||
|
the route. */
|
||||||
|
rpl_dag_t *dag;
|
||||||
|
rpl_instance_t *instance;
|
||||||
|
|
||||||
|
dag = (rpl_dag_t *)route->state.dag;
|
||||||
|
if(dag != NULL) {
|
||||||
|
instance = dag->instance;
|
||||||
|
|
||||||
|
rpl_repair_root(instance->instance_id);
|
||||||
|
}
|
||||||
|
#endif /* UIP_CONF_RPL */
|
||||||
|
uip_ds6_route_rm(route);
|
||||||
|
|
||||||
|
/* We don't have a nexthop to send the packet to, so we drop
|
||||||
|
it. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(nexthop != NULL) {
|
|
||||||
PRINTF("tcpip_ipv6_output: next hop ");
|
|
||||||
PRINT6ADDR(nexthop);
|
|
||||||
PRINTF("\n");
|
|
||||||
#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
|
#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
|
||||||
|
if(nexthop != NULL) {
|
||||||
|
static uint8_t annotate_last;
|
||||||
|
static uint8_t annotate_has_last = 0;
|
||||||
|
|
||||||
|
if(annotate_has_last) {
|
||||||
|
printf("#L %u 0; red\n", annotate_last);
|
||||||
|
}
|
||||||
printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
||||||
|
annotate_last = nexthop->u8[sizeof(uip_ipaddr_t) - 1];
|
||||||
|
annotate_has_last = 1;
|
||||||
|
}
|
||||||
#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */
|
#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* End of next hop determination */
|
/* End of next hop determination */
|
||||||
|
|
||||||
#if UIP_CONF_IPV6_RPL
|
#if UIP_CONF_IPV6_RPL
|
||||||
if(rpl_update_header_final(nexthop)) {
|
if(rpl_update_header_final(nexthop)) {
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
if((nbr = uip_ds6_nbr_lookup(nexthop)) == NULL) {
|
nbr = uip_ds6_nbr_lookup(nexthop);
|
||||||
|
if(nbr == NULL) {
|
||||||
#if UIP_ND6_SEND_NA
|
#if UIP_ND6_SEND_NA
|
||||||
if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) {
|
if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) {
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
|
@ -679,8 +722,8 @@ tcpip_ipv6_output(void)
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Multicast IP destination address. */
|
/* Multicast IP destination address. */
|
||||||
tcpip_output(NULL);
|
tcpip_output(NULL);
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
|
|
Loading…
Reference in a new issue