From 10cd95fb8f1e59b1da5dd4c5c309b0494c34ed84 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, as 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 - When a NA message is received the S-flag must be used to determine if it is a solicited NA. --- src/core/ipv6/nd6.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c index d4673ca6..d91671b1 100644 --- a/src/core/ipv6/nd6.c +++ b/src/core/ipv6/nd6.c @@ -332,18 +332,18 @@ 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?*/ - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { + if (!(na_hdr->flags & ND6_FLAG_SOLICITED)) { /* This is an unsolicited NA. * link-layer changed? * part of DAD mechanism? */ @@ -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