Skip to content

ipv6: the Override flag of a solicited Neighbor Advertisement is decided from the wrong option #1168

Description

@adamgeorge309

Summary

Ipv6NeighbourDiscovery::sendSolicitedNa()
(src/inet/networklayer/icmpv6/Ipv6NeighbourDiscovery.cc:1974) decides the Override flag of an
outgoing Neighbor Advertisement (NA) from whether the incoming Neighbor Solicitation (NS)
carried a Source Link-Layer Address option. RFC 4861 keys the flag on whether the outgoing
Neighbor Advertisement (NA) carries a Target Link-Layer Address option. Those are two
different options, on two different messages, travelling in opposite directions.

The function quotes the rule correctly in the comment above the test and then tests the other
option (lines 1999-2013):

/*If the (NS)Target Address is either an anycast address or a unicast
   address for which the node is providing proxy service, or the Target
   Link-Layer Address option is not included,*/
// TODO: anycast target address handling is not implemented

MacAddress sourceLinkLayerAddress;
if (auto sla = check_and_cast_nullable<const Ipv6NdSourceLinkLayerAddress *>(ns->getOptions().findOption(IPv6ND_SOURCE_LINK_LAYER_ADDR_OPTION)))
    sourceLinkLayerAddress = sla->getLinkLayerAddress();

if (sourceLinkLayerAddress.isUnspecified())
    // the Override flag SHOULD be set to zero.
    na->setOverrideFlag(false);
else
    // Otherwise, the Override flag SHOULD be set to one.
    na->setOverrideFlag(true);

The same function appends a Target Link-Layer Address option to the Neighbor Advertisement (NA)
unconditionally, nine lines earlier (lines 1990-1993), and both call sites
(processNsForNonTentativeAddress() at line 1923 and processNsWithSpecifiedSrcAddr() at line
1971) go through that code. Anycast targets are an unimplemented TODO and Neighbour Discovery
proxy service is not modelled either, so all three of the RFC's exceptions are out of reach and
the correct value on master is 1 for every solicited Neighbor Advertisement (NA) the model can
produce.

What the standard says

RFC 4861, Section 7.2.4 (Sending Solicited Neighbor Advertisements):

If the Target Address is either an anycast address or a unicast
address for which the node is providing proxy service, or the Target
Link-Layer Address option is not included, the Override flag SHOULD
be set to zero. Otherwise, the Override flag SHOULD be set to one.
Proper setting of the Override flag ensures that nodes give
preference to non-proxy advertisements, even when received after
proxy advertisements, and also ensures that the first advertisement
for an anycast address "wins".

RFC 4861, Section 4.4 (Neighbor Advertisement Message Format), on the O bit:

Override flag. When set, the O-bit indicates that
the advertisement should override an existing cache
entry and update the cached link-layer address.
When it is not set the advertisement will not
update a cached link-layer address though it will
update an existing Neighbor Cache entry for which
no link-layer address is known. It SHOULD NOT be
set in solicited advertisements for anycast
addresses and in solicited proxy advertisements.
It SHOULD be set in other solicited advertisements
and in unsolicited advertisements.

Why it matters

Neighbor Solicitations (NS) reach sendSolicitedNa() without a Source Link-Layer Address option
on two ordinary paths, because createAndSendNsPacket() (line 1781) adds that option only when
the solicitation goes to a solicited-node multicast address and has a specified source:

  1. Duplicate Address Detection (DAD) defence. A Duplicate Address Detection (DAD) probe is
    sent from the unspecified address, and RFC 4861 Section 4.3 forbids a Source Link-Layer
    Address option on such a solicitation. The node that already owns the address answers through
    processNsForNonTentativeAddress(), and its Neighbor Advertisement (NA) goes out with
    Override clear.
  2. Neighbour Unreachability Detection (NUD). processNudTimeout() (line 516) sends a
    unicast Neighbor Solicitation (NS) to the cached address, so the destination is not a
    solicited-node multicast address and no Source Link-Layer Address option is added. Every
    answer to a Neighbour Unreachability Detection (NUD) probe therefore also carries Override
    clear.

INET honours the flag on receipt. processNaForOtherNceStates() (line 2268) implements RFC 4861
Section 7.2.5: with Override clear and a Target Link-Layer Address that differs from the cached
one, a REACHABLE entry is downgraded to STALE and any other entry is ignored, with the cache left
unchanged. So a wrong Override flag suppresses exactly the cache updates the standard intends to
happen — which is what makes this matter after a link-layer address change, and in any scenario
where a node has to correct a stale entry in a neighbour's cache. It also matters for emulation:
a real host outside the simulation applies the same RFC 4861 Section 7.2.5 rules to INET's
advertisements.

Duplicate Address Detection (DAD) itself keeps working, because the prober only needs an answer
to exist, whatever its flags. That is why the defect has gone unnoticed.

Reproduction

On origin/master (7aef79d5c0), release build, examples/ipv6/mipv6roaming, which reaches the
Neighbour Unreachability Detection (NUD) path twice:

cd examples/ipv6/mipv6roaming
inet -u Cmdenv -c Roaming -r 0 -f omnetpp.ini \
     --**.checksumMode='"computed"' --**.fcsMode='"computed"' \
     --*.Home_Agent.numPcapRecorders=1 \
     --*.Home_Agent.pcapRecorder[0].pcapFile='"ha.pcap"'
tshark -r ha.pcap -Y "icmpv6.type == 136" -T fields \
       -e frame.number -e frame.time_relative -e icmpv6.nd.na.flag

Every solicited Neighbor Advertisement (NA) captured at the home agent (R = Router,
S = Solicited, O = Override):

Frame t (s) Answers Source Link-Layer Address option in the solicitation Flags O
8 2.2338 address resolution present 0xe0000000 R+S+O 1
18 4.2353 address resolution present 0x60000000 S+O 1
35 4.2830 address resolution present 0xe0000000 R+S+O 1
84 9.2377 Neighbour Unreachability Detection (NUD) probe absent 0xc0000000 R+S 0
234 47.1651 Neighbour Unreachability Detection (NUD) probe absent 0xc0000000 R+S 0

Frame 83, the unicast Neighbor Solicitation (NS) that frame 84 answers, carries only the Reserved
field and the Target Address — no Source Link-Layer Address option. Frame 84 nevertheless carries
a Target Link-Layer Address option and its target fe80::8aa:ff:fe00:2 is an ordinary unicast
address the home agent owns, so RFC 4861 Section 7.2.4 asks for Override = 1.

The Duplicate Address Detection (DAD) defence path needs a node that joins the link after
another node already holds the address permanently, which no example on master arranges. A small
purpose-built network reproduces it on master alone: host1 and host2 on one Ethernet switch
with the same MAC address, host2 held down and started by a ScenarioManager <startup> at
t = 10 s, and a packet capture on host1.

Build Solicitation Answer at t = 10.1799 Flags
unmodified origin/master DAD probe from :: at t = 10.1799 Neighbor Advertisement (NA) with a Target Link-Layer Address option 0x00000000, Override 0
with the fix same same 0x20000000, Override 1

Router clear is correct (host1 is a host) and Solicited clear is correct (the probe came from
the unspecified address). Override clear is the defect.

Not a regression

The condition appears to be original to the function; git log -S over
sourceLinkLayerAddress.isUnspecified() finds only file moves and the 2019 option-model redesign.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions