diff --git a/core/net/tcpip.c b/core/net/tcpip.c index cf22a0556..5a94a1688 100644 --- a/core/net/tcpip.c +++ b/core/net/tcpip.c @@ -561,14 +561,22 @@ tcpip_ipv6_output(void) if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { /* Next hop determination */ 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)){ nexthop = &UIP_IP_BUF->destipaddr; } else { - uip_ds6_route_t* locrt; - locrt = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr); - if(locrt == NULL) { + uip_ds6_route_t *route; + /* Check if we have a route to the destination address. */ + 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"); - if((nexthop = uip_ds6_defrt_choose()) == NULL) { + nexthop = uip_ds6_defrt_choose(); + if(nexthop == NULL) { #ifdef UIP_FALLBACK_INTERFACE PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n", uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40)); @@ -586,26 +594,61 @@ tcpip_ipv6_output(void) uip_len = 0; return; } + } 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 - printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); -#endif /* 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]); + annotate_last = nexthop->u8[sizeof(uip_ipaddr_t) - 1]; + annotate_has_last = 1; } +#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */ } + /* End of next hop determination */ + #if UIP_CONF_IPV6_RPL if(rpl_update_header_final(nexthop)) { uip_len = 0; return; } #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((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) { uip_len = 0; @@ -679,8 +722,8 @@ tcpip_ipv6_output(void) uip_len = 0; return; } + return; } - /* Multicast IP destination address. */ tcpip_output(NULL); uip_len = 0;