Skip to content

ipv6: a unicast datagram with a pinned output interface goes to the Ethernet broadcast address #1151

Description

@adamgeorge309

Summary

Ipv6::datagramLocalOut() (src/inet/networklayer/ipv6/Ipv6.cc:433) hands every
locally-originated unicast datagram that carries a pinned output interface to the link layer
with MacAddress::BROADCAST_ADDRESS. The Neighbour Cache is never consulted, even when it already
holds the correct entry.

void Ipv6::datagramLocalOut(Packet *packet, const NetworkInterface *destIE, Ipv6Address requestedNextHopAddress)
{
    const auto& ipv6Header = packet->peekAtFront<Ipv6Header>();
    // route packet
    if (destIE != nullptr) {
        if (!ipv6Header->getDestAddress().isMulticast())
            fragmentPostRouting(packet, destIE, MacAddress::BROADCAST_ADDRESS, true);   // <-- here
        else
            fragmentPostRouting(packet, destIE, ipv6Header->getDestAddress().mapToMulticastMacAddress(), true);
    }
    ...

destIE is non-null exactly when the upper layer pinned an output interface, and
Ipv6NeighbourDiscovery::sendPacketToIpv6Module() always pins one. Two Neighbour Discovery (ND)
messages are addressed to a unicast IPv6 destination and therefore leave the node as an Ethernet
broadcast:

  • the solicited Neighbour Advertisement (NA), sent to the address that solicited it;
  • the Neighbour Unreachability Detection (NUD) probe, a unicast Neighbour Solicitation (NS) that
    processNudTimeout() sends with createAndSendNsPacket(nceKey->address, nceKey->address, ...).

What the standard says

RFC 4861 Section 5.2, Conceptual Sending Algorithm:

Once the IP address of the next-hop node is known, the sender examines the Neighbor Cache for
link-layer information about that neighbor. If no entry exists, the sender creates one, sets its
state to INCOMPLETE, initiates Address Resolution, and then queues the data packet pending
completion of address resolution.

RFC 4861 Section 7.2.4, Sending Solicited Neighbor Advertisements:

If the source of the solicitation is the unspecified address, the node MUST set the Solicited flag
to zero and multicast the advertisement to the all-nodes address. Otherwise, the node MUST set the
Solicited flag to one and unicast the advertisement to the Source Address of the solicitation.

INET gets the network layer right — sendSolicitedNa() sets the Solicited flag and addresses the
advertisement to the solicitor, and the responder has, moments earlier, created a Neighbour Cache
entry for the solicitor from the solicitation's Source Link-Layer Address option. The link-layer
destination then discards all of it.

Replacing ARP's broadcast with multicast and unicast so that uninvolved nodes are not disturbed is a
central design goal of IPv6 Neighbour Discovery over Ethernet (RFC 2464 Section 6 defers unicast
address mapping to RFC 4861).

Why it matters

Measured on a plain switched IPv6 link (an EthernetSwitch, one Router6, three StandardHost6,
addresses from Ipv6FlatNetworkConfigurator, one host sending UDP to another so that address
resolution has to run), 120 s, origin/master at 434658d729:

frames count
Neighbour Advertisement to FF-FF-FF-FF-FF-FF 112
Neighbour Solicitation (NUD probe) to FF-FF-FF-FF-FF-FF 84
broadcast frames of any kind 196

Correlating the Ethernet header with the IPv6 header shows which solicitations are affected and
which are not:

dest = 33-33-FF-00-00-07  ->  destinationAddress = ff02::1:ff00:7            (address resolution: correct)
dest = FF-FF-FF-FF-FF-FF  ->  destinationAddress = fe80::8aa:ff:fe00:7       (NUD probe: broadcast)

Three consequences follow, all observed:

  1. Every node on the link receives the advertisement, although none of them solicited anything.
  2. A router accepts the broadcast frame, finds an IPv6 destination that is not one of its own
    addresses, forwards it, and answers with a spurious ICMPv6 Redirect.
  3. The solicitor receives the advertisement twice — once directly, once relayed by the router.

Anyone measuring link load, per-node reception counts, energy, or medium occupancy on an IPv6 link
is measuring the broadcast, not the protocol. On a wireless link the cost is larger: in
examples/manetrouting/gpsr -c IPv6 over 20 s, 158 of the IEEE 802.11 frames go to the broadcast
address, and all 158 are Neighbour Discovery.

Not affected: address-resolution and Duplicate Address Detection solicitations (solicited-node
multicast), Router Solicitations and Router Advertisements (ff02::2 / ff02::1), and the
unsolicited advertisement answering a Duplicate Address Detection probe (ff02::1). All of them
take the multicast branch, so a scenario that only autoconfigures addresses never trips over this.

Relationship to the multicast half of the same branch

The multicast branch of this same if was corrected in 3be7618 ("IPv6: fix: use correct
multicast MAC instead of broadcast (RFC 2464 Section 7)"
), which came out of #1104. The unicast
branch was left on the broadcast address and was never discussed there.

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