IPv6 conformance test failures

Folks,

I'm working on a NAS device that uses FreeBSD 11.1 as the host OS. I'm running through the UNH "INTACT" IPv6 conformance test suite and I see a lot of failures. One common theme seems to be that FreeBSD fails to resolve the test node's MAC before responding. The result is that the Ethernet header contains junk, but beyond that the IPv6 and ICMP6 headers make sense. Please see the attached pcap.

The test node sends two packets. Frame 1 is a Router Advertisement. Note that it has no SLL option. So the FreeBSD side can't glean the test node's MAC from any of the packet contents.

In frame 7 the test sends an Echo Request. Note that the test environment configuration contains, among other things, the MAC address of the "device under test". So it doesn't bother to first send a Neighbor Solicitation to resolve FreeBSD's MAC.

Frames 8-11 originate from FreeBSD. The Ethernet headers appear to contain junk. But if the payload beyond that is decoded as IPv6 then it looks reasonable. Frame 8 is an Echo Reply; frames 9-11 are Neighbor Unreachability Detection kicking in. Except, the FreeBSD side cannot know the MAC address of the test node since it never attempted to solicit for it. It should send a NS back to the test node and look for a corresponding NA before any of this.

This test (and a number of other similar tests that start this way) previously passed (e.g. in 10.3).

Thanks!
 

Attachments

  • v6LC_1_2_09b.pcapng.zip
    589 bytes · Views: 349
I might have found an answer to my own question. The following code change was made about 2.5 years ago:

https://svnweb.freebsd.org/base/head/sys/netinet6/nd6.c?r1=287985&r2=288060

This breaks state 6, where we have a new llentry but no link-level address is passed into nd6_cache_lladdr. If we have a new llentry and no lladdr is passed in then the initial state of the llentry must be set to ND6_LLINFO_NOSTATE. Instead it's getting set to ND6_LLINFO_STALE, which implies that we do have a link-level address already in the cache, that can be used now, but that needs to be refreshed (via NUD).

Beginning at line 2032 of nd6.c in nd6_cache_lladdr() I suggest changing this:
Code:
        if (ln_tmp == NULL) {
                /* No existing lle, mark as new entry (6,7) */
                is_newentry = 1;
                nd6_llinfo_setstate(ln, ND6_LLINFO_STALE);
                if (lladdr != NULL) /* (7) */
                        EVENTHANDLER_INVOKE(lle_event, ln,
                                LLENTRY_RESOLVED); 
        } else ...
to this:
Code:
        if (ln_tmp == NULL) {
                /* No existing lle, mark as new entry (6,7) */
                is_newentry = 1;
                if (lladdr != NULL) { /* (7) */
                        nd6_llinfo_setstate(ln, ND6_LLINFO_STALE);
                        EVENTHANDLER_INVOKE(lle_event, ln,
                                LLENTRY_RESOLVED)
                }
        } else ...
 
Back
Top