Skip to content

Commit

Permalink
ndp: separate & clean next hop & l2 determination
Browse files Browse the repository at this point in the history
Determining the next hop and the corresponding L2 address are split up
in two steps. No next hop look up is performed for link-local addresses
any more. Destination cache has been disabled.
  • Loading branch information
OlegHahm committed Aug 14, 2015
1 parent a967fab commit 8b15b9c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 59 deletions.
27 changes: 23 additions & 4 deletions sys/include/net/ng_ndp/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,33 @@ extern "C" {
#endif

/**
* @brief Get link-layer address and interface for next hop to destination
* IPv6 address.
* @brief Next hop determination for a destination address that is not on-link.
*
* @param[out] l2addr The link-layer for the next hop to @p dst.
* @see <a href="https://tools.ietf.org/html/rfc4861#section-3">
* RFC 4861, section 3
* </a>
*
* @param[out] next_hop_ip Will be filled with IPv6 address of the next hop
* or NULL if no next hop could be determined.
* @param[in,out] iface Will be filled with the interface id that has to be
* used for reaching the next hop.
* @param[in] dst The destination IPv6 address.
*
* @return true, if a next hop could be determined.
* @return false otherwise
*/
bool ng_ndp_node_next_hop_ipv6_addr(ipv6_addr_t *next_hop_ip,
kernel_pid_t *iface, ipv6_addr_t *dst);

/**
* @brief Get link-layer address a given IPv6 address.
*
* @param[out] l2addr The link-layer of @p dst.
* @param[out] l2addr_len Length of @p l2addr.
* @param[in] iface The interface to search the next hop on.
* May be @ref KERNEL_PID_UNDEF if not specified.
* @param[in] dst An IPv6 address to search the next hop for.
* @param[in] dst The IPv6 address to search the link-layer
* address hop for.
* @param[in] pkt Packet to send to @p dst. Leave NULL if you
* just want to get the addresses.
*
Expand Down
15 changes: 14 additions & 1 deletion sys/net/network_layer/ng_ipv6/ng_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,10 +550,23 @@ static void _send(ng_pktsnip_t *pkt, bool prep_hdr)
ng_netapi_receive(ng_ipv6_pid, rcv_pkt);
}
else {
/* forwarding packet */
ipv6_addr_t next_hop_ip;
/* determining next hop's IP address */
if (ipv6_addr_is_link_local(&(hdr->dst))) {
memcpy(&next_hop_ip, &(hdr->dst), sizeof(ipv6_addr_t));
}
else if (!ng_ndp_node_next_hop_ipv6_addr(&next_hop_ip, &iface,
&(hdr->dst))) {
DEBUG("ipv6: error determining next hop's IPv6 address\n");
return;
}

/* determining next hop's layer 2 address */
uint8_t l2addr_len = NG_IPV6_NC_L2_ADDR_MAX;
uint8_t l2addr[l2addr_len];

iface = _next_hop_l2addr(l2addr, &l2addr_len, iface, &hdr->dst, pkt);
iface = _next_hop_l2addr(l2addr, &l2addr_len, iface, &next_hop_ip, pkt);

if (iface == KERNEL_PID_UNDEF) {
DEBUG("ipv6: error determining next hop's link layer address\n");
Expand Down
2 changes: 1 addition & 1 deletion sys/net/network_layer/ng_ndp/ng_ndp.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

#include "net/ng_ndp.h"

#define ENABLE_DEBUG (0)
#define ENABLE_DEBUG (1)
#include "debug.h"

#if ENABLE_DEBUG
Expand Down
86 changes: 33 additions & 53 deletions sys/net/network_layer/ng_ndp/node/ng_ndp_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,63 +55,43 @@ static ng_pktqueue_t *_alloc_pkt_node(ng_pktsnip_t *pkt)
return NULL;
}

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)
bool ng_ndp_node_next_hop_ipv6_addr(ipv6_addr_t *next_hop_ip,
kernel_pid_t *iface,
ipv6_addr_t *dst)
{
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);
if (next_hop_ip != NULL) {
return true;
}
#endif
#ifdef MODULE_FIB
/* 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))) {
size_t next_hop_size = sizeof(ipv6_addr_t);
uint32_t next_hop_flags = 0;
ipv6_addr_t next_hop_actual;

if ((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;
}
return true;
}
#endif

if ((next_hop_ip == NULL)) { /* no route to host */
if (iface == KERNEL_PID_UNDEF) {
/* ng_ipv6_netif_t doubles as prefix list */
iface = ng_ipv6_netif_find_by_prefix(&prefix, dst);
}
else {
/* ng_ipv6_netif_t doubles as prefix list */
prefix = ng_ipv6_netif_match_prefix(iface, dst);
}

if ((prefix != NULL) && /* prefix is on-link */
(ng_ipv6_netif_addr_get(prefix)->flags &
NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK)) {
next_hop_ip = dst;
}
}

/* dst has not an on-link prefix */
if (next_hop_ip == NULL) {
next_hop_ip = ng_ndp_internal_default_router();
next_hop_ip = ng_ndp_internal_default_router();
if (next_hop_ip != NULL) {
return true;
}
return false;
}

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)
{
assert(dst != NULL);

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) */
}

/* start address resolution */
nc_entry = ng_ipv6_nc_get(iface, next_hop_ip);
ng_ipv6_nc_t *nc_entry = ng_ipv6_nc_get(iface, dst);

if ((nc_entry != NULL) && ng_ipv6_nc_is_reachable(nc_entry)) {
DEBUG("ndp node: found reachable neighbor (%s => ",
Expand All @@ -133,8 +113,8 @@ kernel_pid_t ng_ndp_node_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
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);
nc_entry = ng_ipv6_nc_add(iface, dst, 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");
Expand All @@ -153,15 +133,15 @@ kernel_pid_t ng_ndp_node_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
}

/* address resolution */
ipv6_addr_set_solicited_nodes(&dst_sol, next_hop_ip);
ipv6_addr_set_solicited_nodes(&dst_sol, dst);

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);
ng_ndp_internal_send_nbr_sol(ifs[i], dst, &dst_sol);
}

vtimer_remove(&nc_entry->nbr_sol_timer);
Expand All @@ -171,7 +151,7 @@ kernel_pid_t ng_ndp_node_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
else {
ng_ipv6_netif_t *ipv6_iface = ng_ipv6_netif_get(iface);

ng_ndp_internal_send_nbr_sol(iface, next_hop_ip, &dst_sol);
ng_ndp_internal_send_nbr_sol(iface, dst, &dst_sol);

mutex_lock(&ipv6_iface->mutex);
vtimer_remove(&nc_entry->nbr_sol_timer);
Expand All @@ -180,9 +160,9 @@ kernel_pid_t ng_ndp_node_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry);
mutex_unlock(&ipv6_iface->mutex);
}
}
}

return KERNEL_PID_UNDEF;
return KERNEL_PID_UNDEF;
}


Expand Down

0 comments on commit 8b15b9c

Please sign in to comment.