Skip to content
Snippets Groups Projects
Commit a967fabd authored by Oleg Hahm's avatar Oleg Hahm
Browse files

Merge pull request #3624 from authmillenon/gnrc_ndp/fix/i3597

gnrc: Fix #3597 (multi-hop ping)
parents 99adcbe2 9f3cef5f
No related branches found
No related tags found
No related merge requests found
...@@ -689,6 +689,7 @@ static void _receive(ng_pktsnip_t *pkt) ...@@ -689,6 +689,7 @@ static void _receive(ng_pktsnip_t *pkt)
ipv6->next = pkt; /* reorder for sending */ ipv6->next = pkt; /* reorder for sending */
pkt->next = NULL; pkt->next = NULL;
_send(ipv6, false); _send(ipv6, false);
return;
} }
else { else {
DEBUG("ipv6: hop limit reached 0: drop packet\n"); DEBUG("ipv6: hop limit reached 0: drop packet\n");
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <string.h> #include <string.h>
#include "byteorder.h" #include "byteorder.h"
#include "net/fib.h"
#include "net/ng_icmpv6.h" #include "net/ng_icmpv6.h"
#include "net/ng_ipv6.h" #include "net/ng_ipv6.h"
#include "net/ng_ipv6/ext/rh.h" #include "net/ng_ipv6/ext/rh.h"
...@@ -312,9 +311,6 @@ void ng_ndp_retrans_nbr_sol(ng_ipv6_nc_t *nc_entry) ...@@ -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)), ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)),
nc_entry->iface); 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); 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, ...@@ -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, kernel_pid_t iface, ipv6_addr_t *dst,
ng_pktsnip_t *pkt) ng_pktsnip_t *pkt)
{ {
ng_ipv6_nc_t *nc_entry;
ipv6_addr_t *next_hop_ip = NULL, *prefix = NULL; ipv6_addr_t *next_hop_ip = NULL, *prefix = NULL;
#ifdef MODULE_NG_IPV6_EXT_RH #ifdef MODULE_NG_IPV6_EXT_RH
next_hop_ip = ng_ipv6_ext_rh_next_hop(hdr); next_hop_ip = ng_ipv6_ext_rh_next_hop(hdr);
#endif #endif
#ifdef MODULE_FIB #ifdef MODULE_FIB
size_t next_hop_size = sizeof(ipv6_addr_t); /* don't look-up link local addresses in FIB */
uint32_t next_hop_flags = 0; if (!ipv6_addr_is_link_local(dst)) {
ipv6_addr_t next_hop_actual; /* FIB copies address into this variable */ size_t next_hop_size = sizeof(ipv6_addr_t);
uint32_t next_hop_flags = 0;
if ((next_hop_ip == NULL) && ipv6_addr_t next_hop_actual; /* FIB copies address into this variable */
(fib_get_next_hop(&iface, next_hop_actual.u8, &next_hop_size,
&next_hop_flags, (uint8_t *)dst, if ((next_hop_ip == NULL) &&
sizeof(ipv6_addr_t), 0) >= 0) && (fib_get_next_hop(&iface, next_hop_actual.u8, &next_hop_size,
(next_hop_size == sizeof(ipv6_addr_t))) { &next_hop_flags, (uint8_t *)dst,
next_hop_ip = &next_hop_actual; sizeof(ipv6_addr_t), 0) >= 0) &&
(next_hop_size == sizeof(ipv6_addr_t))) {
next_hop_ip = &next_hop_actual;
}
} }
#endif #endif
if ((next_hop_ip == NULL)) { /* no route to host */ 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, ...@@ -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_get(prefix)->flags &
NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK)) { NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK)) {
next_hop_ip = dst; 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) { if (next_hop_ip == NULL) {
next_hop_ip = ng_ndp_internal_default_router(); 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)) { if (next_hop_ip == NULL) {
DEBUG("ndp node: found reachable neighbor (%s => ", next_hop_ip = dst; /* Just look if it's in the neighbor cache
ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str))); * (aka on-link but not registered in prefix list as such) */
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) { /* start address resolution */
ng_ndp_internal_set_state(nc_entry, NG_IPV6_NC_STATE_DELAY); nc_entry = ng_ipv6_nc_get(iface, next_hop_ip);
}
memcpy(l2addr, nc_entry->l2_addr, nc_entry->l2_addr_len); if ((nc_entry != NULL) && ng_ipv6_nc_is_reachable(nc_entry)) {
*l2addr_len = nc_entry->l2_addr_len; DEBUG("ndp node: found reachable neighbor (%s => ",
/* TODO: unreachability check */ ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)));
return nc_entry->iface; 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, memcpy(l2addr, nc_entry->l2_addr, nc_entry->l2_addr_len);
NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS); *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) { nc_entry = ng_ipv6_nc_add(iface, next_hop_ip, NULL, 0,
DEBUG("ndp node: could not create neighbor cache entry\n"); NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS);
return KERNEL_PID_UNDEF;
}
pkt_node = _alloc_pkt_node(pkt); if (nc_entry == NULL) {
DEBUG("ndp node: could not create neighbor cache entry\n");
return KERNEL_PID_UNDEF;
}
if (pkt_node == NULL) { pkt_node = _alloc_pkt_node(pkt);
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 */ if (pkt_node == NULL) {
ipv6_addr_set_solicited_nodes(&dst_sol, next_hop_ip); 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);
}
if (iface == KERNEL_PID_UNDEF) { /* address resolution */
timex_t t = { 0, NG_NDP_RETRANS_TIMER }; ipv6_addr_set_solicited_nodes(&dst_sol, next_hop_ip);
kernel_pid_t ifs[NG_NETIF_NUMOF];
size_t ifnum = ng_netif_get(ifs);
for (size_t i = 0; i < ifnum; i++) { if (iface == KERNEL_PID_UNDEF) {
ng_ndp_internal_send_nbr_sol(ifs[i], next_hop_ip, &dst_sol); timex_t t = { 0, NG_NDP_RETRANS_TIMER };
} kernel_pid_t ifs[NG_NETIF_NUMOF];
size_t ifnum = ng_netif_get(ifs);
vtimer_remove(&nc_entry->nbr_sol_timer); for (size_t i = 0; i < ifnum; i++) {
vtimer_set_msg(&nc_entry->nbr_sol_timer, t, ng_ipv6_pid, ng_ndp_internal_send_nbr_sol(ifs[i], next_hop_ip, &dst_sol);
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); 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);
mutex_lock(&ipv6_iface->mutex); ng_ndp_internal_send_nbr_sol(iface, next_hop_ip, &dst_sol);
vtimer_remove(&nc_entry->nbr_sol_timer);
vtimer_set_msg(&nc_entry->nbr_sol_timer, mutex_lock(&ipv6_iface->mutex);
ipv6_iface->retrans_timer, ng_ipv6_pid, vtimer_remove(&nc_entry->nbr_sol_timer);
NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry); vtimer_set_msg(&nc_entry->nbr_sol_timer,
mutex_unlock(&ipv6_iface->mutex); ipv6_iface->retrans_timer, ng_ipv6_pid,
} NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry);
mutex_unlock(&ipv6_iface->mutex);
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment