mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #3624 from authmillenon/gnrc_ndp/fix/i3597
gnrc: Fix #3597 (multi-hop ping)
This commit is contained in:
commit
a967fabde1
@ -689,6 +689,7 @@ static void _receive(ng_pktsnip_t *pkt)
|
||||
ipv6->next = pkt; /* reorder for sending */
|
||||
pkt->next = NULL;
|
||||
_send(ipv6, false);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
DEBUG("ipv6: hop limit reached 0: drop packet\n");
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "byteorder.h"
|
||||
#include "net/fib.h"
|
||||
#include "net/ng_icmpv6.h"
|
||||
#include "net/ng_ipv6.h"
|
||||
#include "net/ng_ipv6/ext/rh.h"
|
||||
@ -312,9 +311,6 @@ void ng_ndp_retrans_nbr_sol(ng_ipv6_nc_t *nc_entry)
|
||||
ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)),
|
||||
nc_entry->iface);
|
||||
|
||||
#ifdef MODULE_FIB
|
||||
fib_remove_entry((uint8_t *) & (nc_entry->ipv6_addr), sizeof(ipv6_addr_t));
|
||||
#endif
|
||||
ng_ipv6_nc_remove(nc_entry->iface, &nc_entry->ipv6_addr);
|
||||
}
|
||||
}
|
||||
|
@ -59,24 +59,27 @@ kernel_pid_t ng_ndp_node_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
|
||||
kernel_pid_t iface, ipv6_addr_t *dst,
|
||||
ng_pktsnip_t *pkt)
|
||||
{
|
||||
ng_ipv6_nc_t *nc_entry;
|
||||
ipv6_addr_t *next_hop_ip = NULL, *prefix = NULL;
|
||||
|
||||
#ifdef MODULE_NG_IPV6_EXT_RH
|
||||
next_hop_ip = ng_ipv6_ext_rh_next_hop(hdr);
|
||||
#endif
|
||||
#ifdef MODULE_FIB
|
||||
size_t next_hop_size = sizeof(ipv6_addr_t);
|
||||
uint32_t next_hop_flags = 0;
|
||||
ipv6_addr_t next_hop_actual; /* FIB copies address into this variable */
|
||||
/* don't look-up link local addresses in FIB */
|
||||
if (!ipv6_addr_is_link_local(dst)) {
|
||||
size_t next_hop_size = sizeof(ipv6_addr_t);
|
||||
uint32_t next_hop_flags = 0;
|
||||
ipv6_addr_t next_hop_actual; /* FIB copies address into this variable */
|
||||
|
||||
if ((next_hop_ip == NULL) &&
|
||||
(fib_get_next_hop(&iface, next_hop_actual.u8, &next_hop_size,
|
||||
&next_hop_flags, (uint8_t *)dst,
|
||||
sizeof(ipv6_addr_t), 0) >= 0) &&
|
||||
(next_hop_size == sizeof(ipv6_addr_t))) {
|
||||
next_hop_ip = &next_hop_actual;
|
||||
if ((next_hop_ip == NULL) &&
|
||||
(fib_get_next_hop(&iface, next_hop_actual.u8, &next_hop_size,
|
||||
&next_hop_flags, (uint8_t *)dst,
|
||||
sizeof(ipv6_addr_t), 0) >= 0) &&
|
||||
(next_hop_size == sizeof(ipv6_addr_t))) {
|
||||
next_hop_ip = &next_hop_actual;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if ((next_hop_ip == NULL)) { /* no route to host */
|
||||
@ -93,97 +96,89 @@ kernel_pid_t ng_ndp_node_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
|
||||
(ng_ipv6_netif_addr_get(prefix)->flags &
|
||||
NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK)) {
|
||||
next_hop_ip = dst;
|
||||
#ifdef MODULE_FIB
|
||||
/* We don't care if FIB is full, this is just for efficiency
|
||||
* for later sends */
|
||||
fib_add_entry(iface, (uint8_t *)dst, sizeof(ipv6_addr_t), 0,
|
||||
(uint8_t *)next_hop_ip, sizeof(ipv6_addr_t), 0,
|
||||
FIB_LIFETIME_NO_EXPIRE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* dst has not an on-link prefix */
|
||||
if (next_hop_ip == NULL) {
|
||||
next_hop_ip = ng_ndp_internal_default_router();
|
||||
#ifdef MODULE_FIB
|
||||
/* We don't care if FIB is full, this is just for efficiency for later
|
||||
* sends */
|
||||
fib_add_entry(iface, (uint8_t *)dst, sizeof(ipv6_addr_t), 0,
|
||||
(uint8_t *)next_hop_ip, sizeof(ipv6_addr_t), 0,
|
||||
FIB_LIFETIME_NO_EXPIRE);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (next_hop_ip != NULL) {
|
||||
ng_ipv6_nc_t *nc_entry = ng_ipv6_nc_get(iface, next_hop_ip);
|
||||
|
||||
if ((nc_entry != NULL) && ng_ipv6_nc_is_reachable(nc_entry)) {
|
||||
DEBUG("ndp node: found reachable neighbor (%s => ",
|
||||
ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)));
|
||||
DEBUG("%s)\n",
|
||||
ng_netif_addr_to_str(addr_str, sizeof(addr_str),
|
||||
nc_entry->l2_addr, nc_entry->l2_addr_len));
|
||||
if (next_hop_ip == NULL) {
|
||||
next_hop_ip = dst; /* Just look if it's in the neighbor cache
|
||||
* (aka on-link but not registered in prefix list as such) */
|
||||
}
|
||||
|
||||
if (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_STALE) {
|
||||
ng_ndp_internal_set_state(nc_entry, NG_IPV6_NC_STATE_DELAY);
|
||||
}
|
||||
/* start address resolution */
|
||||
nc_entry = ng_ipv6_nc_get(iface, next_hop_ip);
|
||||
|
||||
memcpy(l2addr, nc_entry->l2_addr, nc_entry->l2_addr_len);
|
||||
*l2addr_len = nc_entry->l2_addr_len;
|
||||
/* TODO: unreachability check */
|
||||
return nc_entry->iface;
|
||||
if ((nc_entry != NULL) && ng_ipv6_nc_is_reachable(nc_entry)) {
|
||||
DEBUG("ndp node: found reachable neighbor (%s => ",
|
||||
ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)));
|
||||
DEBUG("%s)\n",
|
||||
ng_netif_addr_to_str(addr_str, sizeof(addr_str),
|
||||
nc_entry->l2_addr, nc_entry->l2_addr_len));
|
||||
|
||||
if (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_STALE) {
|
||||
ng_ndp_internal_set_state(nc_entry, NG_IPV6_NC_STATE_DELAY);
|
||||
}
|
||||
else if (nc_entry == NULL) {
|
||||
ng_pktqueue_t *pkt_node;
|
||||
ipv6_addr_t dst_sol;
|
||||
|
||||
nc_entry = ng_ipv6_nc_add(iface, next_hop_ip, NULL, 0,
|
||||
NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS);
|
||||
memcpy(l2addr, nc_entry->l2_addr, nc_entry->l2_addr_len);
|
||||
*l2addr_len = nc_entry->l2_addr_len;
|
||||
/* TODO: unreachability check */
|
||||
return nc_entry->iface;
|
||||
}
|
||||
else if (nc_entry == NULL) {
|
||||
ng_pktqueue_t *pkt_node;
|
||||
ipv6_addr_t dst_sol;
|
||||
|
||||
if (nc_entry == NULL) {
|
||||
DEBUG("ndp node: could not create neighbor cache entry\n");
|
||||
return KERNEL_PID_UNDEF;
|
||||
nc_entry = ng_ipv6_nc_add(iface, next_hop_ip, NULL, 0,
|
||||
NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS);
|
||||
|
||||
if (nc_entry == NULL) {
|
||||
DEBUG("ndp node: could not create neighbor cache entry\n");
|
||||
return KERNEL_PID_UNDEF;
|
||||
}
|
||||
|
||||
pkt_node = _alloc_pkt_node(pkt);
|
||||
|
||||
if (pkt_node == NULL) {
|
||||
DEBUG("ndp node: could not add packet to packet queue\n");
|
||||
}
|
||||
else {
|
||||
/* prevent packet from being released by IPv6 */
|
||||
ng_pktbuf_hold(pkt_node->pkt, 1);
|
||||
ng_pktqueue_add(&nc_entry->pkts, pkt_node);
|
||||
}
|
||||
|
||||
/* address resolution */
|
||||
ipv6_addr_set_solicited_nodes(&dst_sol, next_hop_ip);
|
||||
|
||||
if (iface == KERNEL_PID_UNDEF) {
|
||||
timex_t t = { 0, NG_NDP_RETRANS_TIMER };
|
||||
kernel_pid_t ifs[NG_NETIF_NUMOF];
|
||||
size_t ifnum = ng_netif_get(ifs);
|
||||
|
||||
for (size_t i = 0; i < ifnum; i++) {
|
||||
ng_ndp_internal_send_nbr_sol(ifs[i], next_hop_ip, &dst_sol);
|
||||
}
|
||||
|
||||
pkt_node = _alloc_pkt_node(pkt);
|
||||
vtimer_remove(&nc_entry->nbr_sol_timer);
|
||||
vtimer_set_msg(&nc_entry->nbr_sol_timer, t, ng_ipv6_pid,
|
||||
NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry);
|
||||
}
|
||||
else {
|
||||
ng_ipv6_netif_t *ipv6_iface = ng_ipv6_netif_get(iface);
|
||||
|
||||
if (pkt_node == NULL) {
|
||||
DEBUG("ndp node: could not add packet to packet queue\n");
|
||||
}
|
||||
else {
|
||||
/* prevent packet from being released by IPv6 */
|
||||
ng_pktbuf_hold(pkt_node->pkt, 1);
|
||||
ng_pktqueue_add(&nc_entry->pkts, pkt_node);
|
||||
}
|
||||
ng_ndp_internal_send_nbr_sol(iface, next_hop_ip, &dst_sol);
|
||||
|
||||
/* address resolution */
|
||||
ipv6_addr_set_solicited_nodes(&dst_sol, next_hop_ip);
|
||||
|
||||
if (iface == KERNEL_PID_UNDEF) {
|
||||
timex_t t = { 0, NG_NDP_RETRANS_TIMER };
|
||||
kernel_pid_t ifs[NG_NETIF_NUMOF];
|
||||
size_t ifnum = ng_netif_get(ifs);
|
||||
|
||||
for (size_t i = 0; i < ifnum; i++) {
|
||||
ng_ndp_internal_send_nbr_sol(ifs[i], next_hop_ip, &dst_sol);
|
||||
}
|
||||
|
||||
vtimer_remove(&nc_entry->nbr_sol_timer);
|
||||
vtimer_set_msg(&nc_entry->nbr_sol_timer, t, ng_ipv6_pid,
|
||||
NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry);
|
||||
}
|
||||
else {
|
||||
ng_ipv6_netif_t *ipv6_iface = ng_ipv6_netif_get(iface);
|
||||
|
||||
ng_ndp_internal_send_nbr_sol(iface, next_hop_ip, &dst_sol);
|
||||
|
||||
mutex_lock(&ipv6_iface->mutex);
|
||||
vtimer_remove(&nc_entry->nbr_sol_timer);
|
||||
vtimer_set_msg(&nc_entry->nbr_sol_timer,
|
||||
ipv6_iface->retrans_timer, ng_ipv6_pid,
|
||||
NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry);
|
||||
mutex_unlock(&ipv6_iface->mutex);
|
||||
}
|
||||
mutex_lock(&ipv6_iface->mutex);
|
||||
vtimer_remove(&nc_entry->nbr_sol_timer);
|
||||
vtimer_set_msg(&nc_entry->nbr_sol_timer,
|
||||
ipv6_iface->retrans_timer, ng_ipv6_pid,
|
||||
NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry);
|
||||
mutex_unlock(&ipv6_iface->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user