From 0886ad4840a02fe6bf11e1bfc760b0c05d5e230b Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sun, 20 Nov 2022 19:00:49 +0100 Subject: [PATCH 1/3] gnrc_ipv6_nib: factor out resolve from nc --- .../gnrc/network_layer/ipv6/nib/_nib-arsm.h | 2 +- sys/net/gnrc/network_layer/ipv6/nib/nib.c | 39 +++++++++++-------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.h b/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.h index 135034b5e352..ab69e40d4f6e 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.h +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.h @@ -249,7 +249,7 @@ bool _is_reachable(_nib_onl_entry_t *entry); #define _set_reachable(netif, nce) (void)netif; (void)nce #define _get_nud_state(nbr) (GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED) -#define _set_nud_state(netif, nce, state) (void)netif; (void)nbr; (void)state +#define _set_nud_state(netif, nce, state) (void)netif; (void)nce; (void)state #define _is_reachable(entry) (true) #endif /* CONFIG_GNRC_IPV6_NIB_ARSM || defined(DOXYGEN) */ diff --git a/sys/net/gnrc/network_layer/ipv6/nib/nib.c b/sys/net/gnrc/network_layer/ipv6/nib/nib.c index 3d4cd0cad6fd..8245ca214c17 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/nib.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/nib.c @@ -1264,6 +1264,28 @@ static gnrc_pktqueue_t *_alloc_queue_entry(gnrc_pktsnip_t *pkt) } #endif /* CONFIG_GNRC_IPV6_NIB_QUEUE_PKT */ +static bool _resolve_addr_from_nc(gnrc_netif_t *netif, _nib_onl_entry_t *entry) +{ + if (entry == NULL) { + return false; + } + + if (!IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM)) { + return true; + } + + if (_is_reachable(entry)) { + if (_get_nud_state(entry) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE) { + _set_nud_state(netif, entry, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY); + _evtimer_add(entry, GNRC_IPV6_NIB_DELAY_TIMEOUT, + &entry->nud_timeout, NDP_DELAY_FIRST_PROBE_MS); + } + return true; + } + + return false; +} + static bool _resolve_addr(const ipv6_addr_t *dst, gnrc_netif_t *netif, gnrc_pktsnip_t *pkt, gnrc_ipv6_nib_nc_t *nce, _nib_onl_entry_t *entry) @@ -1279,28 +1301,13 @@ static bool _resolve_addr(const ipv6_addr_t *dst, gnrc_netif_t *netif, nce->l2addr_len = 0; return true; } -#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) - if ((entry != NULL) && _is_reachable(entry)) { - if (_get_nud_state(entry) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE) { - _set_nud_state(netif, entry, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY); - _evtimer_add(entry, GNRC_IPV6_NIB_DELAY_TIMEOUT, - &entry->nud_timeout, NDP_DELAY_FIRST_PROBE_MS); - } + else if (_resolve_from_nc(netif, entry)) { DEBUG("nib: resolve address %s%%%u from neighbor cache\n", ipv6_addr_to_str(addr_str, &entry->ipv6, sizeof(addr_str)), _nib_onl_get_if(entry)); _nib_nc_get(entry, nce); res = true; } -#else /* CONFIG_GNRC_IPV6_NIB_ARSM */ - if (entry != NULL) { - DEBUG("nib: resolve address %s%%%u from neighbor cache\n", - ipv6_addr_to_str(addr_str, &entry->ipv6, sizeof(addr_str)), - _nib_onl_get_if(entry)); - _nib_nc_get(entry, nce); - res = true; - } -#endif /* CONFIG_GNRC_IPV6_NIB_ARSM */ else if (!(res = _resolve_addr_from_ipv6(dst, netif, nce))) { #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) bool reset = false; From 2e2414cef66e06ebe6fd1229c3e7c716e2d4f859 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sun, 20 Nov 2022 20:28:05 +0100 Subject: [PATCH 2/3] gnrc_ipv6_nib: factor out enqueue on resolve --- sys/net/gnrc/network_layer/ipv6/nib/nib.c | 88 ++++++++++++----------- 1 file changed, 46 insertions(+), 42 deletions(-) diff --git a/sys/net/gnrc/network_layer/ipv6/nib/nib.c b/sys/net/gnrc/network_layer/ipv6/nib/nib.c index 8245ca214c17..07839af11eb7 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/nib.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/nib.c @@ -1251,18 +1251,20 @@ static void _handle_nbr_adv(gnrc_netif_t *netif, const ipv6_hdr_t *ipv6, } } -#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_QUEUE_PKT) static gnrc_pktqueue_t *_alloc_queue_entry(gnrc_pktsnip_t *pkt) { +#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_QUEUE_PKT) for (int i = 0; i < CONFIG_GNRC_IPV6_NIB_NUMOF; i++) { if (_queue_pool[i].pkt == NULL) { _queue_pool[i].pkt = pkt; return &_queue_pool[i]; } } +#else + (void)pkt; +#endif /* CONFIG_GNRC_IPV6_NIB_QUEUE_PKT */ return NULL; } -#endif /* CONFIG_GNRC_IPV6_NIB_QUEUE_PKT */ static bool _resolve_addr_from_nc(gnrc_netif_t *netif, _nib_onl_entry_t *entry) { @@ -1286,6 +1288,46 @@ static bool _resolve_addr_from_nc(gnrc_netif_t *netif, _nib_onl_entry_t *entry) return false; } +static bool _enqueue_for_resolve(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt, + _nib_onl_entry_t *entry) +{ + if (!IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_QUEUE_PKT) || + _get_nud_state(entry) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE) { + gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_ADDR, pkt); + gnrc_pktbuf_release_error(pkt, EHOSTUNREACH); + return true; + } + + gnrc_pktqueue_t *queue_entry = _alloc_queue_entry(pkt); + + if (queue_entry == NULL) { + DEBUG("nib: can't allocate entry for packet queue " + "dropping packet\n"); + gnrc_pktbuf_release(pkt); + return false; + } + + if (netif != NULL) { + gnrc_pktsnip_t *netif_hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0); + + if (netif_hdr == NULL) { + DEBUG("nib: can't allocate netif header for queue\n"); + gnrc_pktbuf_release(pkt); + queue_entry->pkt = NULL; + return false; + } + gnrc_netif_hdr_set_netif(netif_hdr->data, netif); + queue_entry->pkt = gnrc_pkt_prepend(queue_entry->pkt, netif_hdr); + } + +#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_QUEUE_PKT) + gnrc_pktqueue_add(&entry->pktqueue, queue_entry); +#else + (void)entry; +#endif + return true; +} + static bool _resolve_addr(const ipv6_addr_t *dst, gnrc_netif_t *netif, gnrc_pktsnip_t *pkt, gnrc_ipv6_nib_nc_t *nce, _nib_onl_entry_t *entry) @@ -1341,46 +1383,8 @@ static bool _resolve_addr(const ipv6_addr_t *dst, gnrc_netif_t *netif, entry->ns_sent = 3; } #endif /* CONFIG_GNRC_IPV6_NIB_ARSM */ - if (pkt != NULL) { -#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_QUEUE_PKT) - if (_get_nud_state(entry) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE) { - gnrc_pktqueue_t *queue_entry = _alloc_queue_entry(pkt); - - if (queue_entry != NULL) { - if (netif != NULL) { - gnrc_pktsnip_t *netif_hdr = gnrc_netif_hdr_build( - NULL, 0, NULL, 0 - ); - if (netif_hdr == NULL) { - DEBUG("nib: can't allocate netif header for queue\n"); - gnrc_pktbuf_release(pkt); - queue_entry->pkt = NULL; - return false; - } - gnrc_netif_hdr_set_netif(netif_hdr->data, netif); - queue_entry->pkt = gnrc_pkt_prepend(queue_entry->pkt, - netif_hdr); - } - gnrc_pktqueue_add(&entry->pktqueue, queue_entry); - } - else { - DEBUG("nib: can't allocate entry for packet queue " - "dropping packet\n"); - gnrc_pktbuf_release(pkt); - return false; - } - } - /* pkt != NULL already checked above */ - else { - gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_ADDR, - pkt); - gnrc_pktbuf_release_error(pkt, EHOSTUNREACH); - } -#else /* CONFIG_GNRC_IPV6_NIB_QUEUE_PKT */ - gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_ADDR, - pkt); - gnrc_pktbuf_release_error(pkt, EHOSTUNREACH); -#endif /* CONFIG_GNRC_IPV6_NIB_QUEUE_PKT */ + if (pkt != NULL && !_enqueue_for_resolve(netif, pkt, entry)) { + return false; } #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) _probe_nbr(entry, reset); From 64a2fbcebd35a86d60ce4346a220e9aff4e4774f Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sun, 20 Nov 2022 20:39:33 +0100 Subject: [PATCH 3/3] gnrc_ipv6_nib: clean up _resolve_addr() --- sys/net/gnrc/network_layer/ipv6/nib/nib.c | 94 ++++++++++++----------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/sys/net/gnrc/network_layer/ipv6/nib/nib.c b/sys/net/gnrc/network_layer/ipv6/nib/nib.c index 07839af11eb7..766da7137bf1 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/nib.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/nib.c @@ -1266,26 +1266,27 @@ static gnrc_pktqueue_t *_alloc_queue_entry(gnrc_pktsnip_t *pkt) return NULL; } -static bool _resolve_addr_from_nc(gnrc_netif_t *netif, _nib_onl_entry_t *entry) +static bool _resolve_addr_from_nc(_nib_onl_entry_t *entry, gnrc_netif_t *netif, + gnrc_ipv6_nib_nc_t *nce) { if (entry == NULL) { return false; } - if (!IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM)) { - return true; - } + if (IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM)) { + if (!_is_reachable(entry)) { + return false; + } - if (_is_reachable(entry)) { if (_get_nud_state(entry) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE) { _set_nud_state(netif, entry, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY); _evtimer_add(entry, GNRC_IPV6_NIB_DELAY_TIMEOUT, &entry->nud_timeout, NDP_DELAY_FIRST_PROBE_MS); } - return true; } - return false; + _nib_nc_get(entry, nce); + return true; } static bool _enqueue_for_resolve(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt, @@ -1332,8 +1333,6 @@ static bool _resolve_addr(const ipv6_addr_t *dst, gnrc_netif_t *netif, gnrc_pktsnip_t *pkt, gnrc_ipv6_nib_nc_t *nce, _nib_onl_entry_t *entry) { - bool res = false; - if ((netif != NULL) && (netif->device_type == NETDEV_TYPE_SLIP)) { /* XXX: Linux doesn't do neighbor discovery for SLIP so no use sending * NS and since SLIP doesn't have link-layer addresses anyway, we can @@ -1343,54 +1342,57 @@ static bool _resolve_addr(const ipv6_addr_t *dst, gnrc_netif_t *netif, nce->l2addr_len = 0; return true; } - else if (_resolve_from_nc(netif, entry)) { + + /* first check if address is cached */ + if (_resolve_addr_from_nc(entry, netif, nce)) { DEBUG("nib: resolve address %s%%%u from neighbor cache\n", ipv6_addr_to_str(addr_str, &entry->ipv6, sizeof(addr_str)), _nib_onl_get_if(entry)); - _nib_nc_get(entry, nce); - res = true; + return true; + } + + /* directly resolve address if it uses 6lo addressing mode */ + if (_resolve_addr_from_ipv6(dst, netif, nce)) { + DEBUG("nib: resolve l2 address from IPv6 address\n"); + return true; } - else if (!(res = _resolve_addr_from_ipv6(dst, netif, nce))) { -#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) - bool reset = false; -#endif /* CONFIG_GNRC_IPV6_NIB_ARSM */ - DEBUG("nib: resolve address %s by probing neighbors\n", - ipv6_addr_to_str(addr_str, dst, sizeof(addr_str))); + bool reset = false; + DEBUG("nib: resolve address %s by probing neighbors\n", + ipv6_addr_to_str(addr_str, dst, sizeof(addr_str))); + if (entry == NULL) { + entry = _nib_nc_add(dst, netif ? netif->pid : 0, + GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE); if (entry == NULL) { - entry = _nib_nc_add(dst, (netif != NULL) ? netif->pid : 0, - GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE); - if (entry == NULL) { - DEBUG("nib: can't resolve address, neighbor cache full\n"); - gnrc_pktbuf_release(pkt); - return false; - } -#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER) - if (netif != NULL) { - _call_route_info_cb(netif, - GNRC_IPV6_NIB_ROUTE_INFO_TYPE_NSC, - dst, - (void *)GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE); - } -#endif /* CONFIG_GNRC_IPV6_NIB_ROUTER */ -#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) - reset = true; -#endif /* CONFIG_GNRC_IPV6_NIB_ARSM */ - } -#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) - else if (_get_nud_state(entry) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE) { - /* reduce back-off to possibly resolve neighbor sooner again */ - entry->ns_sent = 3; - } -#endif /* CONFIG_GNRC_IPV6_NIB_ARSM */ - if (pkt != NULL && !_enqueue_for_resolve(netif, pkt, entry)) { + DEBUG("nib: can't resolve address, neighbor cache full\n"); + gnrc_pktbuf_release(pkt); return false; } + if (IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER) && netif != NULL) { + _call_route_info_cb(netif, + GNRC_IPV6_NIB_ROUTE_INFO_TYPE_NSC, + dst, + (void *)GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE); + } + reset = true; + } #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) + else if (_get_nud_state(entry) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE) { + /* reduce back-off to possibly resolve neighbor sooner again */ + entry->ns_sent = 3; + } +#endif + + /* queue packet as we have to do address resolution first */ + if (pkt != NULL && !_enqueue_for_resolve(netif, pkt, entry)) { + return false; + } + + if (IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM)) { _probe_nbr(entry, reset); -#endif /* CONFIG_GNRC_IPV6_NIB_ARSM */ } - return res; + + return false; } static void _handle_snd_na(gnrc_pktsnip_t *pkt)