From 8ec7b211423920806fbf2475f0b5bb51f36c40c4 Mon Sep 17 00:00:00 2001 From: Erik van Luijk Date: Thu, 8 Apr 2021 16:36:06 +0200 Subject: [PATCH] Send queued packets upon receiving a multicast NA When a node receives a multicast NA (non-solicited) the node should also send any queued packets. This is described in RFC 4861 7.2.5 Also added a check for the validation rule: RFC MUST: if IP destination is multicast, Solicited flag is zero --- src/core/ipv6/nd6.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c index d4673ca6..d194bdd5 100644 --- a/src/core/ipv6/nd6.c +++ b/src/core/ipv6/nd6.c @@ -332,14 +332,14 @@ nd6_input(struct pbuf *p, struct netif *inp) /* Check a subset of the other RFC 4861 Sec. 7.1.2 requirements. */ if (IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || na_hdr->code != 0 || - ip6_addr_ismulticast(&target_address)) { + ip6_addr_ismulticast(&target_address)) || + (ip6_addr_ismulticast(ip6_current_dest_addr()) && na_hdr->flags & ND6_FLAG_SOLICITED)) { pbuf_free(p); ND6_STATS_INC(nd6.proterr); ND6_STATS_INC(nd6.drop); return; } - /* @todo RFC MUST: if IP destination is multicast, Solicited flag is zero */ /* @todo RFC MUST: all included options have a length greater than zero */ /* Unsolicited NA?*/ @@ -382,11 +382,24 @@ nd6_input(struct pbuf *p, struct netif *inp) return; } - /* This is an unsolicited NA, most likely there was a LLADDR change. */ + /* This is an unsolicited NA */ i = nd6_find_neighbor_cache_entry(&target_address); if (i >= 0) { - if (na_hdr->flags & ND6_FLAG_OVERRIDE) { + if (neighbor_cache[i].state == ND6_INCOMPLETE || + na_hdr->flags & ND6_FLAG_OVERRIDE) { + /* Record link-layer address */ MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); + neighbor_cache[i].netif = inp; + if (neighbor_cache[i].state == ND6_INCOMPLETE) { + /* In the ND6_INCOMPLETE state there may be packets queued. */ + neighbor_cache[i].state = ND6_STALE; + /* Send queued packets, if any. */ + if (neighbor_cache[i].q != NULL) { + nd6_send_q(i); + } + } else { + neighbor_cache[i].state = ND6_STALE; + } } } } else { -- 2.30.1.windows.1