RFC 7219

SEcure Neighbor Discovery (SEND) Source Address Validation Improvement (SAVI)

πŸ“… published May 2014, from ietf

RFC 7219 πŸŽ€ (Part 1 of 8)

Title: SEcure Neighbor Discovery (SEND) Source Address Validation Improvement (SAVI) πŸ’– Authors: M. Bagnulo and A. Garcia-Martinez (UC3M) 🫢 Category: Standards Track πŸ‘‘ Date: May 2014 🌸 ISSN: 2070-1721 ✨ Obsoletes / Updates: The title block doesn't list anything it obsoletes or updates. πŸ¦‹ Publisher: Internet Engineering Task Force (IETF) 🧚

Abstract ✨

Okay so this doc specifies SEcure Neighbor Discovery (SEND) Source Address Validation Improvement (SAVI) πŸ’…, which is a way to validate source addresses using the SEND protocol. It's giving extra control πŸ”₯. The mechanism works alongside ingress filtering, so you get finer-grained control over which IPv6 source addresses are allowed. Iconic. πŸ‘‘

Status of This Memo ✨

This is an Internet Standards Track document. πŸŽ€

It's a product of the Internet Engineering Task Force (IETF), so it reflects the consensus of the IETF community 🫢. It went through public review and got approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check out Section 2 of RFC 5741 πŸ’œ.

For the current status of this document, any errata, and how to send feedback, go to http://www.rfc-editor.org/info/rfc7219 🌈.

Copyright (c) 2014 IETF Trust and the persons identified as the document authors. All rights reserved. ✨

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as in effect on the date of publication. Please read these carefully, because they spell out your rights and restrictions for this document πŸ™ˆ. Code Components extracted from this document must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Simplified BSD License πŸ“.

Table of Contents 🧚

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   3
  1.1.  Requirements Language . . . . . . . . . . . . . . . . . .   4
2.  Background on SEND SAVI . . . . . . . . . . . . . . . . . . .   4
  2.1.  Address Validation Scope  . . . . . . . . . . . . . . . .   4
  2.2.  Binding Creation for SEND SAVI  . . . . . . . . . . . . .   4
  2.3.  SEND SAVI Protection Perimeter  . . . . . . . . . . . . .   7
  2.4.  Special Cases . . . . . . . . . . . . . . . . . . . . . .   9
3.  SEND SAVI Specification . . . . . . . . . . . . . . . . . . .  11
  3.1.  SEND SAVI Data Structures . . . . . . . . . . . . . . . .  11
  3.2.  SEND SAVI Device Configuration  . . . . . . . . . . . . .  12
  3.3.  Traffic Processing  . . . . . . . . . . . . . . . . . . .  13
    3.3.1.  Transit Traffic Processing  . . . . . . . . . . . . .  13
    3.3.2.  Local Traffic Processing  . . . . . . . . . . . . . .  13
  3.4.  SEND SAVI Port Configuration Guidelines . . . . . . . . .  27
  3.5.  VLAN Support  . . . . . . . . . . . . . . . . . . . . . .  28
  3.6.  Protocol Constants  . . . . . . . . . . . . . . . . . . .  28
4.  Protocol Walk-Through . . . . . . . . . . . . . . . . . . . .  29
  4.1.  Change of the Attachment Point of a Host  . . . . . . . .  29
    4.1.1.  Moving to a Port of the Same Switch . . . . . . . . .  29
    4.1.2.  Moving to a Port of a Different Switch  . . . . . . .  30
  4.2.  Attack of a Malicious Host  . . . . . . . . . . . . . . .  31
    4.2.1.  M Attaches to the Same Switch as the Victim's Switch   31
    4.2.2.  M Attaches to a Different Switch to the Victim's
            Switch  . . . . . . . . . . . . . . . . . . . . . . .  32
5.  Security Considerations . . . . . . . . . . . . . . . . . . .  33
  5.1.  Protection against Replay Attacks . . . . . . . . . . . .  33
  5.2.  Protection against Denial-of-Service Attacks  . . . . . .  34
  5.3.  Considerations on the Deployment Model for Trust Anchors   36
  5.4.  Residual Threats  . . . . . . . . . . . . . . . . . . . .  36
  5.5.  Privacy Considerations  . . . . . . . . . . . . . . . . .  37
6.  Acknowledgments . . . . . . . . . . . . . . . . . . . . . . .  37
7.  References  . . . . . . . . . . . . . . . . . . . . . . . . .  37
  7.1.  Normative References  . . . . . . . . . . . . . . . . . .  37
  7.2.  Informative References  . . . . . . . . . . . . . . . . .  38

1. Introduction ✨

Okay bestie, this memo specifies SEND SAVI πŸŽ€, a mechanism that does source address validation for IPv6 networks using the SEND protocol [RFC3971]. It complements ingress filtering techniques to give a finer granularity on control of the source addresses used. Main character energy πŸ‘‘.

SEND SAVI uses the DAD_NSOL (Duplicate Address Detection Neighbor SOLicitation) and DAD_NADV (DAD Neighbor ADVertisement) messages defined in [RFC4862], and the NUD_NSOL (Neighbor Unreachability Detection Neighbor SOLicitation) and NUD_NADV (NUD Neighbor ADVertisement) messages defined in [RFC4861]. It uses these to validate a node's address ownership claim πŸ”. The info in these messages links host IPv6 addresses to switch ports, so data packets get checked for consistency with that binding, as described in [RFC7039] πŸ¦‹. On top of that, SEND SAVI stops hosts from generating packets with off-link IPv6 source addresses πŸ™…β€β™€οΈ.

Scalability is the vibe here πŸ’œ. A distributed SAVI system made of several SEND SAVI devices keeps scaling thanks to a deployment scenario where those devices form a "protection perimeter". In that setup, the distributed system only validates packets when they ingress to the protection perimeter, not at every SEND SAVI device they pass through 🌸.

The SEND SAVI specification in this document is limited to links and prefixes where every IPv6 host and every IPv6 router uses the SEND protocol [RFC3971] to protect the exchange of Neighbor Discovery information πŸ”. If SEND isn't used, other SAVI solutions can work instead, ones that monitor different address configuration mechanisms to prove address ownership. For example, FCFS (First-Come, First-Served) SAVI [RFC6620] can be used by nodes that configure IPv6 addresses locally through the Stateless Address Autoconfiguration mechanism [RFC4862] 🧚.

SEND SAVI is designed to deploy in SEND networks with as few changes to deployed implementations as possible πŸ™Œ. Specifically, it doesn't require any changes in the nodes whose source address is being verified. That's because verification only relies on protocols that are already available. So SEND SAVI doesn't define a new protocol, doesn't define any new message on existing protocols, and doesn't require that a host or router use an existing protocol message in a different way πŸ’….

If you want the big picture on Source Address Validation Improvement, it's laid out in [RFC7039] πŸ“š.

1.1. Requirements Language πŸŽ€

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] 🫢.

2. Background on SEND SAVI 🌈

2.1. Address Validation Scope πŸ”₯

The application scenario of SEND SAVI is limited to the local link πŸ”—. So the goal is to verify that the source addresses of packets generated by nodes attached to the local link haven't been spoofed, and that only legitimate routers generate packets with off-link IPv6 source addresses πŸ•΅οΈβ€β™€οΈ.

A link usually has hosts and routers attached. Hosts generate packets with their own addresses as the source address, and that's called "local traffic" πŸ’–. Routers may send packets with a source address other than their own, since they can forward packets generated by other hosts (usually located on a different link). That's the so-called transit traffic 🚚.

SEND SAVI lets you validate the source address of local traffic. In other words, it verifies that the source addresses of packets from nodes on the local link haven't been spoofed ✨. It also gives you a way to stop hosts from generating packets with source addresses derived from off-link prefixes. But here's the tea: SEND SAVI does not provide a way to check whether a given router is actually authorized to forward packets with a particular off-link source address πŸ™ˆ. For validating transit traffic, other techniques like ingress filtering [RFC2827] are recommended 🌸.

2.2. Binding Creation for SEND SAVI πŸŽ€

okay bestie, so SEND SAVI devices filter packets based on bindings between a layer-2 anchor (the binding anchor) and an IPv6 address πŸ¦‹. These bindings should let legit nodes use their bound IPv6 address as the source address, and stop illegit nodes from doing the same thing πŸ’….

ngl, a SAVI solution is only as strong as the binding anchor it's built on 😭. If the anchor is super easy to spoof (like a Media Access Control (MAC) address), the whole solution is weak. So the way you treat non-compliant packets has to be tuned to match πŸ™ˆ. Like, if the anchor is spoofable AND the SEND SAVI device is set to drop non-compliant packets, then using SEND SAVI could open a brand new Denial-of-Service (DoS) attack vector based on spoofed binding anchors πŸ’€. That's why implementations of this spec use switch ports as their binding anchors 🌸. Other kinds of binding anchors are out of scope here, and you MUST NOT... well, the doc says proper analysis should be done before anyone uses them 🧚.

Quick sidebar: SEND [RFC3971] gives us tools to make sure a Neighbor Discovery (ND) message with a Cryptographically Generated Address (CGA) [RFC3972] option, signed by an RSA option, was really made by the legit owner of that CGA IPv6 address πŸ”βœ¨.

So SEND SAVI uses SEND-validated messages to create bindings between the CGA and the port of the SEND SAVI device where it makes sense to receive packets using that CGA as source 🫢. Here's what triggers the binding creation process:

  • The reception of a DAD_NSOL message, which means a node is trying to configure an address. This can happen the first time a node configures an address, after it's been idle for a while, or when the node has moved its physical attachment point to the layer-2 infrastructure πŸ“.
  • The reception of any other packet (including data packets) with a source address that has no binding yet. This can happen if DAD_NSOL messages got lost, a node moved its physical attachment point without sending a DAD_NSOL, a SAVI device lost a binding (like after a restart), or the link topology changed πŸ˜΅β€πŸ’«.

When binding creation gets triggered, the SEND SAVI device has to make sure the node getting the binding is the legit owner of the address πŸ‘‘. If the process started with a DAD_NSOL exchange, the device waits for a validated DAD_NADV message (proof the other node already configured the address before), or validated DAD_NSOL messages coming from other locations (which would mean another node is trying to configure the same address at the same time) πŸ‘€. If packets other than a DAD_NSOL started the process, the device explicitly requires the sending node to prove ownership by issuing a secured NUD_NSOL, which the probed node has to answer with a secured NUD_NADV πŸ’…πŸ”₯.

SEND SAVI devices also send secured NUD_NSOL messages periodically to refresh bindings. The node the binding belongs to has to answer those with a valid NUD_NADV message πŸ¦‹.

Last rule for this section: SEND SAVI devices only forward packets with off-link source addresses if they came in from a port manually configured to connect to a router πŸ›£οΈβœ¨.

Now let's talk replay attacks 😱. SEND SAVI needs protection against these, where an attacker replays a secured SEND message sent by another node. Remember, the binding is made between the address in the message (which has to be signed by a node holding the private key for that address) and the port the message came through πŸ”‘. If an attacker gets hold of such a message, maybe because it was sent to the all-nodes multicast address or because the attacker subscribed to a remote node's Solicited Node multicast address, they could replay it with the original signature intact πŸ₯Ί. That could create a fake binding in the SEND SAVI device, or abort address configuration at the other node πŸ’”.

SEND does give some ways to limit the damage from replayed ND messages, and the main goal is to keep the ND info in the message (like the relationship between an IPv6 address and a layer-2 address) valid for only a short window ⏰. That window has to be long enough that the legit sender's info still counts as valid even when the sender's and receiver's clocks are a bit out of sync πŸ•°οΈ. For example, using the values [RFC3971] recommends for TIMESTAMP_FUZZ and TIMESTAMP_DRIFT, a node getting a DAD_NSOL would not discard replays arriving within about 2 seconds (more precisely, 2/0.99 seconds) 😬. The assumption is that even if the message gets replayed in that window, the info ND shares is still the same 🀞. BUT, letting a node replay a SEND message still affects SEND SAVI no matter how much time has passed, because the node can make a new binding on the port an illegit node is plugged into 🚨. So yeah, SEND's protection alone isn't always enough for SEND SAVI 😀.

SEND SAVI adds extra replay protection on top of SEND, though πŸ’ͺ. First, every node has to connect to the SEND SAVI topology through a different port, so nobody can eavesdrop before entering the SAVI protection perimeter πŸ‘€. Second, SEND SAVI only updates bindings based on messages whose spread can be limited inside the SEND SAVI topology without messing up normal SEND operation 🧠. The messages SEND SAVI uses to create bindings are DAD_NSOL messages, which it only propagates to the ports where a previous binding for the same IPv6 address existed (see Section 3.3.2), and NUD_NADV messages sent in reply to a secured NUD_NSOL that the SEND SAVI device only sends through the tested port 🎯. Finally, SEND SAVI filtering rules stop nodes from replaying messages the SEND SAVI devices generated themselves πŸ™…β€β™€οΈ. Section 5.1 goes deeper into the replay protection SEND SAVI provides πŸ“–.


2.3. SEND SAVI Protection Perimeter 🏰

okay so to keep computing and state requirements low in SEND SAVI devices, you can deploy them to form a "protection perimeter" [RFC7039] πŸ§šβ€β™€οΈ. With this setup, SEND SAVI devices only do source-address validation when packets enter the protected realm that the perimeter defines πŸ’–. The perimeter comes from configuring each port's role, which can be either 'Validating' or 'Trusted' πŸŽ€:

  • Validating ports (VPs) are ports where SEND SAVI filtering and binding creation happen πŸ’….
  • Trusted ports (TPs) are ports where only limited processing happens 🫧. Only SEND messages related to certificates, prefix information, and DAD operation get processed, so they can update the state of the SEND SAVI device or the state tied to any of the switch's Validating ports ✨.

Here's the typical topology with trusted and untrusted infrastructure, as shown in Figure 1 🌈:

      +--+   +--+                          +--+   +--+
      |H1|   |H2|                          |H3|   |R1|
      +--+   +--+                          +--+   +--+
        |     |                              |     |
   +------------SEND SAVI PROTECTION PERIMETER-----------+
   |    |     |                              |     |     |
   |  +-1-----2-+                          +-1-----2-+   |
   |  |  SEND-  |                          |  SEND-  |   |
   |  |  SAVI1  |                          |  SAVI2  |   |
   |  +-3--4----+                          +--3--4---+   |
   |    |  |          +--------------+        |  |       |
   |    |  +----------|              |--------+  |       |
   |    |             |   SWITCH-A   |           |       |
   |    |  +----------|              |           |       |
   |    |  |          +--------------+           |       |
   |  +-1--2----+                          +-----1---+   |
   |  |  SEND-  |                          |  SEND-  |   |
   |  |  SAVI3  |                          |  SAVI4  |   |
   |  +-3-----4-+                          +----4----+   |
   |    |     |                                 |        |
   +------------SEND SAVI PROTECTION PERIMETER-----------+
        |     |                                 |
      +--+   +--+                             +--+
      |R2|   |H4|                             |H5|
      +--+   +--+                             +--+



                    Figure 1: SAVI Protection Perimeter

Trusted ports hook up to trusted infrastructure, like routers and other SEND SAVI devices 🚏. Port 2 of SEND-SAVI2 and port 3 of SEND-SAVI3 are Validating ports because they connect to routers πŸ›‘. Port 3 of SEND-SAVI1 and port 1 of SEND-SAVI3, plus port 4 of SEND-SAVI2 and port 1 of SEND-SAVI4, are trusted because they link two SAVI devices 🀝. Lastly, port 4 of SEND-SAVI1, port 3 of SEND-SAVI2, and port 2 of SEND-SAVI3 are trusted because they connect to SWITCH-A, which only has trusted nodes plugged in πŸ”’.

Validating ports are for connecting to non-trusted infrastructure, so hosts plug into Validating ports as usual πŸ™‹β€β™€οΈ. In Figure 1, ports 1 and 2 of SEND-SAVI1, port 1 of SEND-SAVI2, and port 4 of SEND-SAVI3 are Validating ports because they connect to hosts πŸ§‘β€πŸ’». Port 4 of SEND-SAVI4 is Validating too, since it's connected to host H5 πŸ’«.

For a deeper dive on this, check out Section 3.4 πŸ“šπŸ¦‹

2.4. Special Cases ✨

Okay bestie, now we get into the messy, real-life network setups πŸ’…

Multi-subnet links: Sometimes one subnet has several prefixes, and that's totally fine 🌸 SEND SAVI handles it because any port can support multiple prefixes.

Multihomed hosts: A multihomed host is just a host with multiple interfaces πŸ¦‹ Here's the tea. If each interface gets its own IP address, and every packet sent out of an interface uses that interface's own address as the source, then SEND SAVI sees it as two separate single-interface hosts, each with its own IP address. No extra fuss needed, it just slays πŸ‘‘ But if the interfaces share the same IP address, or they have different addresses and the host sends packets using one interface's address out of any interface, then SEND SAVI doesn't directly support that πŸ’€ To make it work, you'd have to either connect at least one interface of the multihomed host to a Trusted port, or manually configure the SEND SAVI bindings so the host's address can be bound to multiple anchors at the same time.

Virtual switches: A hypervisor or host OS can do bridging between virtual hosts running on the same machine 🧚 The hypervisor or host OS might then connect to a SEND SAVI system. Picture this, as shown in Figure 2: two virtual machines, VM1 and VM2, hook up through a virtual switch, VS1, to the SEND SAVI device SEND-SAVI1. The attachment points of VS1 to VM1 and VM2 are configured as Validating.

   Host1
   +----------------+
   | +---+   +---+  |
   | |VM1|   |VM2|  |
   | +---+   +---+  |
   |   |     |      |
   | +-1-----2--+   |
   | |   VS1    |   |
   | +--3-------+   |
   |    |           |
   +----|-----------+
        |
        |
     +--1-----2--+
     |   SEND-   |
     |   SAVI1   |
     +--3---4----+
        |   |

   Figure 2: Virtual Switches Connected to the SEND SAVI Device

Now, to protect against replay attacks, you want SEND SAVI filtering as close to untrusted hosts as possible (see Sections 3.4 and 5.1). In this setup, you can get that by turning on SEND SAVI validation in VS1 πŸ’– If the hypervisor or host OS at Host1 can be trusted (even though VM1 and VM2 can't be), VS1 could be part of the SEND SAVI protection perimeter. To do that, both the attachment to SEND-SAVI1 at VS1 and port 1 at SEND-SAVI1 get configured as Trusted ✨

If the network admin doesn't trust VS1, port 1 of SEND-SAVI1 gets configured as Validating, so every address used at Host1 is validated at SEND-SAVI1 by SEND SAVI πŸ™ˆ The attachment point to the physical network at VS1 should be configured as Trusted if the host admin knows it's connected to a SEND SAVI device. In that case, VS1 relies on the infrastructure made up of the physical SEND SAVI devices, but not the other way around. Packets leaving VM1 get validated twice: first at VS1, then at SEND-SAVI1. Packets going the other way (from an external host to VM1) only get validated once, when they first hit a SEND SAVI device. If the admin of VS1 doesn't trust the physical switch it attaches to, they can set the attachment to SEND-SAVI1 as Validating. In Figure 2, that means a packet going from another host to VM1 gets validated twice: once when it enters the SEND SAVI perimeter formed by the physical devices, and again when it enters at VS1 πŸŽ€

Untrusted routers: Picture routers dynamically attaching to a SEND SAVI network 🌈 A classic example is a phone connecting to a SEND SAVI switch while also acting as a router for other personal devices using it to get online. For source address validation at a SEND SAVI device, an untrusted router like that doesn't really count as trusted infrastructure (if it did, basically every device would be trusted, and that's not it 😭). So it can't go on a Trusted port. If it's on a Validating port, the SEND SAVI switch discards every packet from that device with an off-link source address. The SEND SAVI device the router attaches to could be set up to let through packets whose source addresses belong to prefixes reachable via the untrusted router. But that mechanism is out of scope for this document 🧐 So the default mechanism described in this specification can't be applied in that scenario.


3. SEND SAVI Specification 🌟

3.1. SEND SAVI Data Structures

The following three data structures are defined for SEND SAVI operations πŸ“

SEND SAVI Database: The SEND SAVI function relies on state information that binds the source IPv6 address used in data packets to the port the legit node connects through πŸ’œ That info gets stored in the SEND SAVI Database. The SEND SAVI Database is populated with the contents of validated SEND messages. Each entry contains the following:

  • IPv6 source address
  • Binding anchor: the port through which the packet was received
  • Lifetime
  • Status: TENTATIVE_DAD, TENTATIVE_NUD, VALID, TESTING_VP, TESTING_VP'
  • Alternative binding anchor: the port from which a DAD_NSOL message or any data packet has been received while a different port was stored in the binding anchor for the address
  • Creation time: the value of the local clock when the entry was first created

SEND SAVI Prefix List: SEND SAVI devices need to know which prefixes are link prefixes so they can tell local traffic from off-link traffic πŸ¦‹ A SEND SAVI device MUST support discovering this info from the Prefix Information option [RFC4861] with the L bit set, in Router Advertisement (RADV) messages coming from Trusted ports, as described in Section 3.3.2. The list of prefixes MAY also be configured manually. This info isn't specific to any given port. The SEND SAVI Prefix List has one entry per prefix in use, as follows:

  • Prefix: the prefix included in a Prefix Information option.
  • Prefix lifetime: time in seconds that the prefix is valid. It's initially set to the Valid Lifetime value of the Prefix Information option of a valid RADV message, or set to a value of all 1 bits (0xffffffff), which represents infinity, if configured manually.

When the SEND SAVI device boots, it MUST send a Router Solicitation (RSOL) message. That doesn't need to be secured if the unspecified address is used (see [RFC3971], Sections 5.1.1 and 5.2.1). The SAVI device SHOULD issue an RSOL message in case the prefix entry is about to expire ⏰

3.2. SEND SAVI Device Configuration

To run the SEND SAVI operation, some basic parameters of the SEND SAVI device have to be configured πŸŽ€ Since a SEND SAVI device acts as a SEND node to generate NUD_NSOL, RSOL, or Certification Path Solicitation (CPS) messages:

  • The SEND SAVI device MUST be configured with a valid CGA address. Once it configures this address, it MUST behave as a regular SEND node, meaning it uses secured NSOL messages to perform DAD and so on, on top of meeting the requirements for regular IPv6 nodes [RFC6434] ✨
  • The SEND SAVI device MAY be configured with at least one trust anchor if it's set up to validate RADV messages (see Section 3.3.2). In that case, the SEND SAVI device MAY be configured with certification paths. The alternative is getting them by issuing Certification Path Solicitation messages, as detailed in the SEND specification [RFC3971] πŸ’…

On top of that, the port role for each port of the SEND SAVI device MUST be configured. The guidelines for this are in Section 3.4 🫢

3.3. Traffic Processing

In this section, we get into how a SEND SAVI device processes packets πŸ”₯ The behaviour depends on whether the packet is local or transit traffic. That's decided by checking whether the prefix of the source address is in the SEND SAVI Prefix List, or is the unspecified address (local traffic), or is not in the SEND SAVI Prefix List (transit traffic).

3.3.1. Transit Traffic Processing

Transit traffic processing goes like this:

  • If the SEND SAVI device receives a transit traffic packet through a Trusted port, it forwards it without any SAVI processing βœ…
  • If the SEND SAVI device receives a transit traffic packet through a Validating port, it discards the packet 🚫

3.3.2. Local Traffic Processing

If the verification of a packet's source address shows it belongs to local traffic, the packet gets processed using the state machine described in this section 🧠

For the rest of the section, these assumptions hold:

  • When it's stated that a secured NUD_NSOL message is issued by a SEND SAVI device through a port P, it means the SEND SAVI device generates a NUD_NSOL message, following the Neighbor Unreachability Detection procedure described in [RFC4861]. It's addressed to the IPv6 target address, which is the source address of the packet that triggered the procedure. This message is secured by SEND as defined in [RFC3971]. The source address used for the NUD_NSOL message is the source address of the SEND SAVI device. The message is sent only through port P 🌸
  • When it's stated that a validated NUD_NADV message is received by a SEND SAVI device, it means a SEND secured NUD_NADV message came in through the same port P that the corresponding NUD_NSOL message went out of. The NUD_NADV message has been validated according to [RFC3971] to prove ownership of the IPv6 address under consideration, and to prove it's a response to the previous NUD_NSOL message issued by the SEND SAVI device (containing the same nonce value as the NUD_NSOL message it answers) πŸ’œ

We use VP to refer to a Validating port, and TP to refer to a Trusted port πŸ¦‹

The state machine is defined for a binding of a given source IPv6 address in a given SEND SAVI device. In the transitions considered, packets described as inputs refer to the IPaddr IPv6 address associated with the state machine 🧚

The possible states for a given IPaddr are NO_BIND, TENTATIVE_DAD, TENTATIVE_NUD, VALID, TESTING_VP, and TESTING_VP'. The NO_BIND state means no binding exists for IPaddr. This is the state for all addresses unless a binding is explicitly created πŸ“

The states can be sorted into 'forwarding' states (where packets received from the port associated with the IPv6 address get forwarded) and 'non-forwarding' states (where packets other than the ones used for signaling don't get forwarded). VALID, TENTATIVE_DAD, TESTING_VP, and TESTING_VP' are forwarding states, while NO_BIND and TENTATIVE_NUD are non-forwarding states 🌈

okay bestie, the SEND SAVI device MUST join the Solicited Node Multicast group for all the addresses whose state is other than NO_BIND πŸŽ€. This is what makes sure it actually gets the DAD_NSOL messages sent for those addresses ✨. ngl you can't just rely on the MLD messages the node on a Validating port sends for a binding that already exists πŸ™ˆ, because the node might move, and then packets for that group might stop being forwarded to the SEND SAVI device πŸ’€.

to figure out what's on-link and what's off-link 🧚, the SEND SAVI device MUST support discovering that from the Prefix Information option with the L bit set in RADV messages 🌈. In this case, at least one router SHOULD be configured to advertise RADV messages with a Prefix Information option holding the prefixes the untrusted nodes can use as source addresses, with the L bit set πŸ’œ. An alternative is to manually configure the SEND SAVI Prefix List or restrict the use of link-local addresses πŸ“.

SEND SAVI devices MUST discard RADV messages received from Validating ports 🚫. RADV messages are only accepted and processed when they come through Trusted ports πŸ”’.

SEND SAVI devices SHOULD NOT validate RADV messages to update the SEND SAVI Prefix List and forward them to other nodes πŸ™…. These messages can only be received from Trusted ports, and we assume routers are trusted πŸ‘‘. Validating RADV messages would be required in any SEND SAVI device the node is traversing πŸ’…. Besides, hosts will validate this message before using the information it contains 🫢.

in case SEND SAVI devices are configured to validate RADV messages, they SHOULD support processing validated Certification Path Advertisement (CPA) messages, sent in reply to CPS messages, to acquire the certificates used to validate router messages πŸŽ€. alternatively, it SHOULD be configured with a certification path πŸ”₯.

The state machine defined for the SEND SAVI operation adheres to the following design guidelines πŸ‘‘:

  • The only events that trigger state changes from forwarding to non-forwarding states, and vice versa, are the reception of DAD_NSOL, DAD_NADV, and NUD_NADV, or the expiration of a timer. The other possible input to consider is 'any other packet', which could generate changes to states belonging to the same forwarding or non-forwarding class as the original state. In other words, when 'any other packet' is received, the state cannot move from forwarding to non-forwarding, and vice versa πŸ’–. This smaller set of messages that can trigger a change simplifies the processing at SEND SAVI devices ✨.
  • DAD_NADV and NUD_NADV are only processed when they are a response to a DAD_NSOL or a NUD_NSOL message πŸ™ˆ.
  • SEND SAVI devices MUST only use ND messages received through Validating ports if they are valid; otherwise, they discard them 🚫. SEND SAVI devices SHOULD assume that such messages received from Trusted ports have been validated by other SEND SAVI devices, or come from a trusted device such a router, so they SHOULD NOT attempt to validate them in order to reduce the processing load at the SEND SAVI device 🧚.
  • The only messages the SEND SAVI device is required to generate specifically per each source IP address are MLD and NUD_NSOL messages. This also keeps the state machine simple πŸ’….
  • Well-behaved nodes are expected to initiate communication by sending secured DAD_NSOL messages 🫢. The SEND SAVI state machine is tailored to efficiently process these events. The reception of other packet types without receiving previously validated DAD_NSOL messages is assumed to be a consequence of bad-behaving nodes or infrequent events (such as packet loss, a change in the topology connecting the switches, etc.). While a binding will ultimately be created for nodes affected by such events, simplicity of the state machine is prioritized over any possible optimization for these cases πŸ™„.
  • If a node has a configured address, and it can prove that it owns this address, the binding is preserved regardless of any indication that a binding for the same source address could be configured in other SEND SAVI devices πŸ‘‘. Bindings for the same source address in two or more SEND SAVI devices may occur due to several reasons, for example, when a host moves (the two bindings exist just for a short period of time) or when many nodes generate the same address and the DAD procedure has failed πŸ¦‹. In these infrequent cases, SEND SAVI preserves connectivity for the resulting bindings 🌸.

Next, we describe how different inputs are processed, depending on the state of the binding of the IP address IPaddr. Note that every ND message is assumed to be validated according to the SEND specification πŸ”.

To help you get the most relevant transitions of the SEND SAVI state machine, a simplified version is depicted in Figure 3, which does not contain every possible transition πŸ“Έ:

                      +-------------+
                      |             |
                      | TESTING_VP' |
                      |             |
                      +-------------+
         Timeout/VP=VP'  |    ^
                         |    |
         VP_NUD_NADV/-   |    |  VP'_DAD_NSOL/
                         |    |    VP_NUD_NSOL
                         |    |
                         v    |
     VP_DAD_NSOL/-     +--------+
        +------------- |        |
        |              | VALID  |< -------------------+
        |   +-------- >|        |                     |
        |   |          +--------+                     |
        |   |            ^   |                        |
        |   |    VP_NUD_ |   | Timeout,               |
        |   |     NADV/- |   | TP_DAD_NSOL/VP_NUD_NSOL|
        |   |            |   v                        |
        |   |         +------------+                  |
        |   |         |            |                  |
        |   |         | TESTING_VP |                  |
        |   |         |            |                  |
        |   |         +------------+                  |
        |   |              |                          |
        |   |              | Timeout/-                |
        |   | VP*,         |                          |
        |   | Timeout/-    |            VP_NUD_NADV/- |
        v   |              |                          |
     +---------------+     |           +---------------+
     |               |     |           |               |
     | TENTATIVE_DAD |     |           | TENTATIVE_NUD |
     |               |     |           |               |
     +---------------+     |           +---------------+
        ^  |               |             |         ^
        |  |               |   Timeout/- |         |
        |  | TP_DAD_NSOL,  |             |         |
        |  | TP_DAD_NADV/- |             |         |
        |  |               v             |         |
        |  |           +---------+       |         |
        |  +--------- >|         |< -----+         |
        |              | NO_BIND |                 |
        +--------------|         |-----------------+
        VP_DAD_NSOL/-  +---------+    VP*/VP_NUD_NSOL

           Figure 3: Simplified SEND SAVI State Machine

Each state transition is characterized by any of the events that may trigger the change and the message(s) generated as a result of this change. Here's what some of the terms mean πŸ“–:

  • VP_DAD_NSOL as a triggering event means that a validated DAD_NSOL message has been received from the current BINDING_ANCHOR port VP.
  • VP* means any packet (data packet) received from the current BINDING_ANCHOR port VP.
  • TP_DAD_NSOL as a triggering event means that a DAD_NSOL message was received from a Trusted port.
  • - means that no message is sent. VP=VP' means that the BINDING_ANCHOR is set to VP'.

The notation

Timeout, TP_DAD_NSOL/VP_NUD_NSOL

means that the transition is triggered by either a timeout expiration or the reception of a DAD_NSOL message from a Trusted port, and in addition to the transition, a NUD_NSOL message is sent through port VP ✨.

For the rest of the description, we assume the following 🧐:

  • When a validated message is required (i.e., a 'validated DAD_NSOL'), messages are checked for validity in the considered switch according to [RFC3971], and messages not fulfilling these conditions are discarded πŸ”Ž.
  • When any SEND message is received from a validated port, the SEND SAVI SHOULD assume that the message has been validated by the SEND SAVI device through which the message accessed the SEND SAVI protection perimeter (unless the SEND SAVI perimeter has been breached), or the device generating it is trusted. In this case, the SAVI device does not perform any further validation. Performing validation for SEND messages received through a Trusted port may affect performance negatively 🐒.

NO_BIND πŸŒ™

When the node is in this state, there are no unresolved NUD_NSOL messages generated by SEND SAVI or DAD_NSOL propagated to any Validating port, so the only relevant inputs are DAD_NSOL messages coming either from a Validating port (VP) or Trusted port (TP), or any packet other than DAD_NSOL coming from a VP or TP. There are no timers configured for this state.

Messages received from a Validating port:

  • If a validated DAD_NSOL message is received from a Validating port VP, the SEND SAVI device forwards this message to all appropriate Trusted ports (the subset of Trusted ports that belong to the forwarding layer-2 topology, with the restrictions imposed by the MLD snooping mechanism, if applied). DAD_NSOL messages are not sent through any of the ports configured as Validating ports. The SEND SAVI device sets the LIFETIME to TENT_LT, stores all the information required for future validation of the corresponding DAD_NADV message (such as the nonce of the message), creates a new entry in the SEND SAVI Database for IPaddr, sets BINDING_ANCHOR to VP, and changes the state to TENTATIVE_DAD. Creation time is set to the current value of the local clock.

Note that in this case, it is not possible to check address ownership by sending a NUD_NSOL because while the node is waiting for a possible DAD_NADV, its address is in tentative state and the node cannot respond to NSOL messages [RFC4862].

  • If any packet other than a DAD_NSOL is received through a Validating port VP, the SEND SAVI device issues a secured NUD_NSOL through port VP. The SEND SAVI device sets the LIFETIME to TENT_LT. The SEND SAVI device creates a new entry in the SEND SAVI Database for IPaddr, sets BINDING_ANCHOR to VP, and the state is changed to TENTATIVE_NUD. Creation time is set to the current value of the local clock. The SAVI device MAY discard the packet while the NUD procedure is being executed or MAY store it in order to send it if the next transitions are (strictly) TENTATIVE_NUD and then VALID.

Messages received from a Trusted port:

Okay so if a DAD_NSOL with IPaddr as the target address shows up through a Trusted port, it MUST NOT get forwarded out any of the Validating ports πŸ™…β€β™€οΈ. It just gets sent through the proper Trusted ports instead, and the state stays exactly the same πŸ’….

  • Any packet that isn't a DAD_NSOL and comes in from a Trusted port gets forwarded to its destination πŸ“¬. This is giving "already verified" energy: it's assumed to come from a SEND SAVI device that securely validated the binding under the SEND SAVI rules (unless the SEND SAVI perimeter has been breached πŸ’€). The state doesn't change ✨.

TENTATIVE_DAD πŸ¦‹

To get here, the SEND SAVI device has received a validated DAD_NSOL from the BINDING_ANCHOR port and forwarded it to the appropriate TPs. The events that matter in this state are: a DAD_NADV from a TP, a DAD_NSOL from the BINDING_ANCHOR port, another Validating port, or a TP, a data packet from the BINDING_ANCHOR port, and the LIFETIME timer running out (the one that started when the DAD_NSOL came in at the BINDING_ANCHOR port) ⏰.

Messages received from a Trusted port:

  • A valid DAD_NADV from a Trusted port means the binding can't be configured for the BINDING_ANCHOR port πŸ™…β€β™€οΈ. The state switches to NO_BIND, and the LIFETIME gets cleared.
  • A valid DAD_NSOL from a Trusted port means a node connected to another SEND SAVI device might be trying to configure the same address at the same time πŸ‘€. The DAD_NSOL gets forwarded to the BINDING_ANCHOR port, so the node there won't configure the address, as stated in [RFC4862]. It's also forwarded to all appropriate Trusted ports. Then the LIFETIME is cleared and the state moves to NO_BIND.
  • Any packet other than a validated DAD_NSOL or DAD_NADV from a Trusted port gets forwarded to its destination πŸ“¬. It's assumed to come from a SEND SAVI device that securely validated the binding under the SEND SAVI rules (unless the SEND SAVI perimeter has been breached). The state doesn't change.

Messages received from a Validating port different from the BINDING_ANCHOR:

  • A validated DAD_NSOL from a Validating port VP' that isn't the BINDING_ANCHOR port is a whole moment 🌈. It means a node connected to VP' might be trying to configure the same address at the same time. The DAD_NSOL gets forwarded to the BINDING_ANCHOR port, so the node there won't configure the address, as stated in [RFC4862]. It's also forwarded to all appropriate Trusted ports. Then the BINDING_ANCHOR is set to VP' (the port the DAD_NSOL came in through), the LIFETIME is set to TENT_LT, and the state stays in TENTATIVE_DAD πŸ”.
  • Any packet other than a validated DAD_NSOL from a Validating port VP' that isn't the BINDING_ANCHOR port gets discarded πŸ—‘οΈ. The state doesn't change.

Messages received from the BINDING_ANCHOR port:

  • If a validated DAD_NSOL comes in from the BINDING_ANCHOR port, the LIFETIME is set to TENT_LT, and the state stays in TENTATIVE_DAD πŸ’–.
  • If any packet other than a DAD_NSOL comes in from the BINDING_ANCHOR port, it's assumed the node has configured its address, even though it did it faster than the SEND SAVI device expected (less than TENT_LT) πŸƒβ€β™€οΈ. Since the node already proved address ownership with the validated DAD_NSOL, the LIFETIME is set to DEFAULT_LT, and the state changes to VALID πŸ‘‘.

LIFETIME expires:

  • If the LIFETIME expires, it's assumed no other node has configured this address βŒ›. So the Validating port VP (currently stored in the BINDING_ANCHOR) could be bound to this IPv6 address. The LIFETIME is set to DEFAULT_LT, and the state changes to VALID ✨.

VALID πŸ’œ

To get here, the SEND SAVI device has successfully validated address ownership and created a binding for IPaddr. The transitions that matter for this state are triggered by a DAD_NSOL from the BINDING_ANCHOR port, another Validating port, or a TP, and by any packet other than a DAD_NSOL from a Validating port that isn't the BINDING_ANCHOR or a TP. The LIFETIME expiring is also relevant, since it triggers a check on address ownership for the node at the BINDING_ANCHOR port πŸ•΅οΈβ€β™€οΈ.

Messages received from the BINDING_ANCHOR port:

  • If a validated DAD_NSOL with IPaddr as a source address comes in through the BINDING_ANCHOR port, it's forwarded to the appropriate Trusted ports. The LIFETIME is set to TENT_LT, and the state changes to TENTATIVE_DAD πŸ¦‹.
  • Any packet other than a DAD_NSOL containing IPaddr as a source address that arrives from the BINDING_ANCHOR port is forwarded appropriately πŸ“¨. The state doesn't change.

Messages received from a Trusted port:

  • If a DAD_NSOL with IPaddr as a source address comes in through a Trusted port, the message is forwarded to VP. The LIFETIME is set to TENT_LT, a secured NUD_NSOL message is sent to IPaddr through VP, and the state changes to TESTING_VP πŸ”.
  • If any packet other than a DAD_NSOL with IPaddr as a source address comes in through a Trusted port, the packet is forwarded to VP and to other appropriate Trusted ports. A secured NUD_NSOL is sent to the BINDING_ANCHOR port, the LIFETIME is set to TENT_LT, and the state changes to TESTING_VP 🌸.

Messages received from a Validating port different from the BINDING_ANCHOR:

  • If a validated DAD_NSOL with IPaddr as a source address comes in through a Validating port VP' (a VP' that isn't the current BINDING ANCHOR), the message is forwarded to the BINDING_ANCHOR port. On top of that, a secured NUD_NSOL is sent to the BINDING_ANCHOR port, the ALTERNATIVE BINDING ANCHOR is set to port VP' (saved for later, in case the node at VP' ends up being the one selected), the LIFETIME is set to TENT_LT, and the state changes to TESTING_VP' πŸŽ€.
  • If any packet other than a DAD_NSOL with IPaddr as a source address comes in from a Validating port VP' that isn't the current BINDING_ANCHOR for this binding (VP), the packet is discarded πŸ—‘οΈ. The SEND SAVI device MAY issue a secured NUD_NSOL through the BINDING_ANCHOR port, store VP' in the ALTERNATIVE_BINDING_ANCHOR for possible future use, set the LIFETIME to TENT_LT, and change the state to TESTING_VP'. There's also an alternative: the SEND SAVI device MAY not do anything at all πŸ€·β€β™€οΈ. In that case the state eventually changes after a maximum of DEFAULT_LT, and if the node at VP doesn't respond to a NUD_NSOL in TESTING_VP, the state moves to NO_BIND. Then a packet arriving from VP' would kick off a process that could end with a binding for the node connected to VP' πŸ’«.

LIFETIME expires:

  • If the LIFETIME expires, a secured NUD_NSOL message is sent through the BINDING_ANCHOR port to IPaddr, the LIFETIME is set to TENT_LT, and the state changes to TESTING_VP ⏳. While in the TESTING_VP state, packets keep getting forwarded until the timer expires without a NUD_NADV being received πŸ“¦.

TESTING_VP πŸ§ͺ

When the SEND SAVI device enters the TESTING_VP state, the current Validating port is being checked through a secured NUD_NSOL message the SEND SAVI device generated itself πŸ•΅οΈβ€β™€οΈ. While testing, packets from the current Validating port keep getting forwarded, and packets coming from Trusted ports are forwarded too. The events that matter for this state are: a NUD_NADV message from VP; a DAD_NSOL message from VP, VP', or TP; any packet other than those cases from VP, VP', or TP; and the timer associated with receiving a NUD_NADV expiring ⏰.

Messages received from the BINDING_ANCHOR port:

  • If a validated NUD_NADV is received from VP, the LIFETIME changes to DEFAULT_LT, and the state changes to VALID. The message isn't forwarded to any other port 🀫.
  • If a validated DAD_NSOL message is received from VP, it's forwarded to the appropriate Trusted ports, the LIFETIME is set to DEFAULT_LT, and the state changes to TENTATIVE_DAD πŸ¦‹.
  • Any packet other than DAD_NSOL or NUD_NADV containing IPaddr as a source address that arrives from the BINDING_ANCHOR port is forwarded. Neither the LIFETIME nor the state changes ✨.

Messages received from a Trusted port:

  • If a DAD_NSOL packet is received from a Trusted port, the message is forwarded to VP and the appropriate Trusted ports. Neither the LIFETIME nor the state changes. The node at the BINDING_ANCHOR port is under check: if it's still at this port, it should answer with a NUD_NADV and also with a DAD_NADV. If it isn't there, neither the NUD_NADV nor the DAD_NADV will be received, the timer will expire, and the local state will move to NO_BIND 😬.
  • If a packet other than a DAD_NSOL arrives from a Trusted port, the packet is forwarded. Neither the LIFETIME nor the state changes πŸ“¬.

Messages received from a Validating port different from the BINDING_ANCHOR:

  • If a valid DAD_NSOL is received from a Validating port VP' other than the current BINDING_ANCHOR port, the message is forwarded to the BINDING_ANCHOR port and to the appropriate Trusted ports. On top of that, a secured NUD_NSOL is sent to the BINDING_ANCHOR port, the ALTERNATIVE BINDING ANCHOR is set to VP' (for future use if the node at VP' is finally selected), the LIFETIME is set to TENT_LT, and the state changes to TESTING_VP' πŸ’Œ.
  • Any other packet received from a Validating port VP' other than the BINDING_ANCHOR port is discarded πŸ—‘οΈ. This can happen because the node has moved but hasn't sent a DAD_NSOL, or because the DAD_NSOL got lost. The state will eventually move to NO_BIND, and after that, packets sent from VP' will trigger the creation of the binding for VP' 🌱.

LIFETIME expires:

  • If the LIFETIME expires, the LIFETIME is cleared and the state changes to NO_BIND πŸ«₯.

TESTING_VP' πŸ•΅οΈβ€β™€οΈ

To get here, the SEND SAVI device has received an indication that a node at VP' (a port that isn't the BINDING_ANCHOR port) wants to send data with IPaddr as a source address, and this happened while a binding existed for VP. The port VP' that triggered the change to TESTING_VP' was stored at the ALTERNATIVE_BINDING_ANCHOR, so it can be retrieved if the node at VP' turns out to be the legitimate owner of IPaddr 🫢. The SEND SAVI device has issued a NUD_NSOL to IPaddr through the BINDING_ANCHOR port. The events that may happen in this case are: a NUD_NADV from port VP (the BINDING_ANCHOR port); a DAD_NSOL from VP, VP', TP, and VP" (VP" different from VP and VP'); any other packet from VP, VP', TP, or VP"; and the expiration of the timer.

Messages received from the BINDING_ANCHOR port:

  • A validated NUD_NADV is received from the BINDING_ANCHOR port. A valid NUD_NADV means the node at VP is defending its address πŸ›‘οΈ. The BINDING_ANCHOR in use is kept, the LIFETIME is set to DEFAULT_LT, and the state changes to VALID πŸ‘‘.

The DAD_NSOL bits are sus if you don't keep the ports straight, so let's go πŸ’…

  • If a valid DAD_NSOL is received from the BINDING_ANCHOR port, it is forwarded to VP' (the port stored in the ALTERNATIVE_BINDING_ANCHOR). The BINDING_ANCHOR in use is kept, the LIFETIME is set to TENT_LT, and the state is changed to TENTATIVE_DAD. When the DAD_NSOL message is received by the node at VP', the address will not be configured. πŸ¦‹
  • Any packet other than a validated DAD_NSOL, or a validated NUD_NADV coming from the BINDING_ANCHOR port, is forwarded, and the state is not changed. 🌸

Messages received from the ALTERNATIVE_BINDING_ANCHOR Validating port:

  • If a valid DAD_NSOL is received from the port stored in the ALTERNATIVE_BINDING_ANCHOR, it is forwarded to the BINDING_ANCHOR port. The BINDING_ANCHOR and the ALTERNATIVE BINDING ANCHOR are kept, the LIFETIME is set to DEFAULT_LT, and the state is not changed. ✨
  • Any packet other than a validated DAD_NSOL coming from the ALTERNATIVE_BINDING_ANCHOR port is discarded, and the state is not changed. πŸ™ˆ

Messages received from a Validating port different from the BINDING_ANCHOR and the ALTERNATIVE_BINDING_ANCHOR ports:

  • If a validated DAD_NSOL is received from port VP", different from BINDING_ANCHOR and the ALTERNATIVE_BINDING_ANCHOR ports, it is forwarded to the BINDING_ANCHOR and the ALTERNATIVE_BINDING_ANCHOR ports. The node at the ALTERNATIVE BINDING ANCHOR port is expected to unconfigure its address if the message triggering the transition to this state was a DAD_NSOL message received from the ALTERNATIVE_BINDING_ANCHOR port (and not any other packet). The state remains in TESTING_VP', although VP" is stored in the ALTERNATIVE_BINDING_ANCHOR for future use if the node at VP" is finally selected. The LIFETIME is not changed. πŸ‘‘
  • Any packet other than a validated DAD_NSOL received from port VP" is discarded and does not affect the state. πŸ’€

Messages received from a Trusted port:

  • If a DAD_NSOL is received from a Trusted port, the message is forwarded to the BINDING_ANCHOR, ALTERNATIVE_BINDING_ANCHOR ports, and other appropriate Trusted ports. The LIFETIME is left unchanged, and the state is changed to TESTING_VP. The node at the ALTERNATIVE_BINDING_ANCHOR port is expected to unconfigure its address if the packet triggering the transition to this state was a DAD_NSOL message received from the ALTERNATIVE_BINDING_ANCHOR port. 🧚
  • Any packet other than a DAD_NSOL coming from a Trusted port is forwarded appropriately, but the state is not changed. 🫢

LIFETIME expires:

  • If LIFETIME expires, it is assumed that the node for which the binding existed is no longer connected through the BINDING_ANCHOR port. Therefore, the BINDING_ANCHOR is set to the ALTERNATIVE_BINDING_ANCHOR port value. The LIFETIME is set to DEFAULT_LT, and the state is changed to VALID. πŸ“

TENTATIVE_NUD

To arrive at this state, a data packet has been received through the BINDING_ANCHOR port without any existing binding in the SEND SAVI device. The SEND SAVI device has sent a NUD_NSOL message to the BINDING_ANCHOR port. The relevant events for this case are the reception of a NUD_NADV from the BINDING_ANCHOR port; the reception of a DAD_NSOL from the BINDING_ANCHOR port, other VP different from the BINDING_ANCHOR port, or a TP; and the reception of any packet other than a DAD_NSOL and a NUD_NADV from the BINDING_ANCHOR port and a DAD_NSOL for other VP different from the BINDING_ANCHOR port, or TP. In addition, the LIFETIME may expire. πŸ”₯

Messages received from the BINDING_ANCHOR port:

  • If a validated NUD_NADV message is received through the BINDING_ANCHOR port, the LIFETIME is set to TENT_LT, and the state is changed to VALID. The message is not forwarded to any port. πŸ’–
  • If a validated DAD_NSOL message is received through the BINDING_ANCHOR port, it is forwarded to the appropriate Trusted ports, the LIFETIME is set to TENT_LT, and the state is changed to TENTATIVE_DAD. 🌈
  • Any packet other than NUD_NADV or DAD_NSOL received through the BINDING_ANCHOR port is discarded. πŸ™ˆ

Messages received from a Validating port different from the BINDING_ANCHOR:

  • If a validated DAD_NSOL message is received through port VP' different from the BINDING_ANCHOR port, it is forwarded to the appropriate Trusted ports, the LIFETIME is set to TENT_LT, the BINDING_ANCHOR is set to VP', and the state is changed to TENTATIVE_DAD. πŸ¦‹
  • Any packet other than validated DAD_NSOL received through port VP' MUST NOT be forwarded unless the next state for the binding is VALID. The packets received MAY be discarded or MAY be stored to be sent if the state changes later to VALID. The state is left unchanged. πŸ›‘

Messages received from a Trusted port:

  • If a DAD_NSOL message is received through a Trusted port, it is forwarded to the BINDING_ANCHOR port, and the state is left unchanged. 🌸
  • Any other packet received from a Trusted port is forwarded appropriately. This packet may come from a SEND SAVI device that has securely validated the attachment of the node to its Validating port, according to SEND SAVI rules. The state is left unchanged. 🫢

LIFETIME expires:

  • If LIFETIME expires, the LIFETIME is cleared and the state is changed to NO_BIND. ⭐

3.4. SEND SAVI Port Configuration Guidelines πŸŽ€

The detailed guidelines for port configuration in SEND SAVI devices are:

  • Ports connected to another SEND SAVI device MUST be configured as Trusted ports. Not doing so will prevent off-link traffic from being forwarded, along with the following effects for on-link traffic: significantly increase the CPU time, memory consumption, and signaling traffic due to SEND SAVI validation, in both the SEND SAVI devices and the node whose address is being validated. 😭
  • Ports connected to hosts SHOULD be configured as Validating ports. Not doing so will allow the host connected to that port to send packets with a spoofed source address. πŸ•΅οΈ
  • No more than one host SHOULD be connected to each port. Connecting more than one host to a port will allow hosts to generate packets with the same source address as the other hosts connected to the same port, and will allow replaying attacks to be performed as described in Section 5.1. ⚠️
Replay attacks are the spicy part, so read Section 5.1 before you ship anything. πŸ’€
  • Ports connected to routers MUST be configured as Trusted ports. Not doing so results in SEND SAVI devices discarding off-link traffic. Note that this means that since routers are connected through Trusted ports, they can generate traffic with any source address, even those belonging to the link. πŸ‘‘
  • Ports connected to a chain of one or more legacy switches that have other SEND SAVI devices but have no routers or hosts attached to them SHOULD be configured as Trusted ports. Not doing so will significantly increase the memory consumption in the SEND SAVI devices and increase the signaling traffic due to SEND SAVI validation. πŸ“

3.5. VLAN Support 🌈

In the case where the SEND SAVI device is a switch that supports customer VLANs [IEEE.802-1Q.2005], the SEND SAVI specification MUST behave as if there was one SEND SAVI process per customer VLAN. The SEND SAVI process of each customer VLAN will store the binding information corresponding to the nodes attached to that particular customer VLAN. πŸ’…

3.6. Protocol Constants ⭐

TENT_LT is 500 milliseconds.

DEFAULT_LT is 5 minutes.


4. Protocol Walk-Through ✨

In this section, we include two cases that illustrate the behavior of SEND SAVI, the change of the attachment port of a host, and the attack of a malicious host. We use the topology depicted in Figure 4. 🧚

           +---+
           | H |
           +---+
             |
             |
           +-1-----2-+       +-1-----2-+
           |         |       |         |
           |  SAVI1  |       |  SAVI2  |
           |         |       |         |
           +-3-----4-+       +-3-----4-+
             |                 |
             -------------------

Figure 4: Reference SEND SAVI Topology for Protocol Walk-Through

4.1. Change of the Attachment Point of a Host πŸ¦‹

There are two cases, depending on whether the host H moves to a different port on the same switch or to a different switch.

4.1.1. Moving to a Port of the Same Switch 🌸

Host H is connected to port 1 of SAVI1 and moves to port 2 of the same switch. Before moving, the SEND SAVI state associated to IPH, the IP address of H, is:

SAVI1=VALID, BINDING_ANCHOR=1 / SAVI2=NO_BIND

In the general case, H issues a DAD_NSOL message for IPH when it is connected to a different port. When SAVI1 receives this message, it validates it and changes its state to:

SAVI1=TESTING_VP', BINDING_ANCHOR=1, ALTERNATIVE_BINDING_ANCHOR=2,
TIMER=TENT_LT / SAVI2=NO_BIND

The DAD_NSOL message is propagated to port 1, because it is the current BINDING_ANCHOR, and the Trusted port 3; it is not propagated to Validating port 4. SAVI1 configures a timer for TENT_LT seconds. In addition, SAVI1 generates a NUD_NSOL and sends it through port 1. When SAVI2 receives this message through its Trusted port, it discards it and remains in the NO_BIND state. πŸ”₯

SAVI1 waits for a NUD_NADV message to be received from port 1. Since there is no node attached to 1, there is no response for either of these messages. When TENT_LT expires at SAVI1, the state changes to:

SAVI1=VALID, BINDING_ANCHOR=2 / SAVI2=NO_BIND

If the node moving does not issue a DAD_NSOL when it attaches to port 2, then SAVI1 will receive a data packet through this port. The data packet is discarded, SAVI1 issues a secured NUD_NSOL through port 1, and the state changes to TESTING_VP'.

SAVI1=TESTING_VP', BINDING_ANCHOR=1, ALTERNATIVE_BINDING_ANCHOR=2
TIMER=TENT_LT / SAVI2=NO_BIND

SAVI1 waits for a NUD_NADV message to be received from port 1. Since there is no node attached to 1, there is no response for neither of these messages. When TENT_LT expires at SAVI1, the state changes to:

SAVI1=VALID, BINDING_ANCHOR=2 / SAVI2=NO_BIND

An alternative behavior allowed by the specification for the case in which the host does not issue a DAD_NSOL is that SAVI1 does nothing. In this case, after some time (bounded by DEFAULT_LT), the switch will change the state for IPH to TESTING_VP, check if H is still at port 1 (which it is not), and move the state to NO_BIND. Then, a packet arriving from port 2 would trigger a process that finishes with a VALID stated with BINDING_ANCHOR=2. ✨

4.1.2. Moving to a Port of a Different Switch πŸ¦‹

Okay, so picture this: Host H is plugged into port 1 of SAVI1, and then it hops over to port 4 of SAVI2 🧳✨ Before the move, the SEND SAVI state for IPH (H's IP address) looks like this:

SAVI1=VALID, BINDING_ANCHOR=1 / SAVI2=NO_BIND

If H sends a DAD_NSOL message for IPH as soon as it plugs into port 4 of SAVI2, the state changes to:

SAVI1=VALID, BINDING_ANCHOR=1 / SAVI2=TENTATIVE_DAD,
BINDING_ANCHOR=4, TIMER=TENT_LT

The DAD_NSOL message only gets passed along through the Trusted port of SAVI2 πŸ’… Then SAVI1 updates its state like this:

SAVI1=TESTING_VP, BINDING_ANCHOR=1, TIMER=TENT_LT /
SAVI2=TENTATIVE_DAD, BINDING_ANCHOR=4, TIMER=TENT_LT

SAVI1 forwards the DAD_NSOL message to port 1 πŸ™ˆ The only node that could answer with a secured DAD_NUD is the one that already left, so the timer at SAVI2 runs out and SAVI2 flips to VALID:

SAVI1=TESTING_VP, BINDING_ANCHOR=1, TIMER=TENT_LT / SAVI2=VALID,
BINDING_ANCHOR=4

Literally moments later, the timer at SAVI1 expires too, and it goes to NO_BIND:

SAVI1=NO_BIND / SAVI2=VALID, BINDING_ANCHOR=4

Now, what if H skips the DAD_NSOL when it moves to SAVI2 and just sends a regular data packet instead? πŸ‘€ Then SAVI2 goes to TENTATIVE_NUD:

SAVI1=VALID, BINDING_ANCHOR=1 / SAVI2=TENTATIVE_NUD,
BINDING_ANCHOR=4, TIMER=TENT_LT

SAVI2 sends a secured NUD_NSOL out through port 4 πŸ’Œ H is assumed to have the address configured (otherwise, it wouldn't have generated a data packet), so it can reply with a NUD_NADV. When SAVI1 gets that NUD_NADV and validates it, the state becomes:

SAVI1=VALID, BINDING_ANCHOR=1 / SAVI2=VALID, BINDING_ANCHOR=4

After some time (bounded by DEFAULT_LT), the state in SAVI1 expires, and SAVI1 goes and checks on host H πŸ”

SAVI1=TESTING_VP, BINDING_ANCHOR=1, TIMER=TENT_LT / SAVI2=VALID,
BINDING_ANCHOR=4

SAVI1 sends a NUD_NSOL through port 1 for IPH. Nobody answers this time 😭 so SAVI1 switches to NO_BIND:

SAVI1=NO_BIND / SAVI2=VALID, BINDING_ANCHOR=4

4.2. Attack of a Malicious Host 😈

Host H is hooked up to the SEND SAVI infrastructure through port 1 of SAVI1. Now we have host M, the villain 🦹 M starts sending data packets with IPH (H's IP address) as the source address, without ever sending a DAD_NSOL. (A similar analysis can be done for this case, bestie 🫢)

4.2.1. M Attaches to the Same Switch as the Victim's Switch 🏠

Before M does anything shady, the state looks like this:

SAVI1=VALID, BINDING_ANCHOR=1 / SAVI2=NO_BIND

M plugs into port 2 of SAVI1 and starts spamming data packets 😀 When SAVI1 gets one of those packets, it gets discarded. SEND SAVI may send a secured NUD_NSOL through port 1, and the state changes to:

SAVI1=TESTING_VP', BINDING_ANCHOR=1, ALTERNATIVE_BINDING_ANCHOR=2,
TIMER=TENT_LT / SAVI2=NO_BIND

Host H is still sitting on port 1, so it receives the NUD_NSOL and fires back a secured NUD_NADV πŸ’ͺ SAVI1 gets it, validates it, and goes back to:

SAVI1=VALID, BINDING_ANCHOR=1 / SAVI2=NO_BIND

To keep SAVI1's CPU from getting drained, the processing of further packets received from port 2 may be rate-limited, as discussed in Section 5.2. Protect that CPU, queen πŸ‘‘

Another option is for SAVI1 to do nothing at all when node M starts sending packets from port 2 🀷 In that case, when the timer to renew the state goes off (this time it's bounded by DEFAULT_LT), SAVI1 moves the state to TESTING_VP, sends a NUD_NSOL through port 1, host H responds, and the state stays in VALID for BINDING_ANCHOR=1. That's how host H's communication gets defended too πŸ›‘οΈβœ¨

4.2.2. M Attaches to a Different Switch to the Victim's Switch 🌍

The initial state before M's attack is:

SAVI1=VALID, BINDING_ANCHOR=1 / SAVI2=NO_BIND

M plugs into port 2 of SAVI2 and starts sending data packets. When SAVI2 receives a data packet, it changes the state to:

SAVI1=VALID, BINDING_ANCHOR=1 / SAVI2=TENTATIVE_DAD,
BINDING_ANCHOR=2, TIMER=TENT_LT

SAVI2 sends a secured NUD_NSOL through port 2. M doesn't own the IPH CGA, so it can't answer πŸ™…β€β™€οΈ When the timer expires, the state goes back to:

SAVI1=VALID, BINDING_ANCHOR=1 / SAVI2=NO_BIND

Again, to keep SAVI2's CPU from getting drained, the processing of further packets received from port 2 may be rate-limited, as discussed in Section 5.2. Rate limit that drama πŸ’…

5. Security Considerations πŸ”

Okay, this section is serious business, so let's go πŸ₯Ί SEND SAVI only uses validated SEND messages to create bindings. Also, IPv6 packets from non-SEND nodes get discarded by the first SEND SAVI device that receives them 🚫 So attackers can't get any benefit from skipping SEND. If you want address validation in a mixed setup with both SEND and non-SEND devices, you need a different solution, and that one should be covered in another document.

Nodes MUST NOT assume that every SEND message they get from a SEND SAVI device has been validated 🚨 These devices only validate the messages they strictly need for SEND SAVI operation. So, messages that SEND SAVI doesn't validate include NUD_NSOL messages from other nodes, their matching NUD_NADV responses, and RSOL messages.

SEND SAVI gives you better protection than conventional SAVI does, because SEND nodes are much better at proving they own an address πŸ’–

A really critical thing with SEND SAVI is setting up the roles of the ports properly in the deployment πŸŽ€ Security-wise, the main requirement is that the ports defining the protected perimeter SHOULD be configured as Validating ports. If you don't do this, an attacker can send packets with any source address they want, no matter what bindings are set up in other SEND SAVI devices 😱

5.1. Protection against Replay Attacks πŸ”

Here's a worry about SEND SAVI: what if an attacker tries to fake being a legit node by replaying SEND messages that SEND SAVI uses? An attacker could replay any of these to mess with SEND SAVI operation. For example, they could replay a DAD_NSOL message to abort a legit node's address configuration and grab the right to use that address for DEFAULT_LT seconds πŸ™ƒ

There are two cases to look at for SEND SAVI replay attacks:

  • When the SEND message being replayed is used to create or update binding information for SEND SAVI, the port it arrives on is key to SEND SAVI operation. SEND SAVI creates and maintains bindings from receiving DAD_NSOL messages and from exchanging NUD_NSOL/NUD_NADV messages.
  • When the SEND message being replayed doesn't change any binding information for SEND SAVI, so it isn't tied to the specific port it came in on. Examples are receiving CPA messages that carry certificates, and processing an RADV message that comes from a Trusted port, which can be used in SEND SAVI to fill the SEND SAVI Prefix List. In these two cases, the security risks are the same as for the SEND operation. In other words, we can assume the information won't be changed by its legitimate sender for the time during which the SEND specification allows replaying (which depends on the values of TIMESTAMP_FUZZ and TIMESTAMP_DRIFT [RFC3971]).

For replays in the second case, the messages that don't change SEND SAVI binding information, the security SEND already provides is enough ✨ For replays in the first case, which are DAD_NSOL and NUD_NSOL/NUD_NADV messages, the protection comes from how SEND SAVI behaves, as specified in Section 3.3.2. That section restricts which ports the messages involved in SEND SAVI binding updates get spread to. SEND SAVI devices only forward these messages to ports where a binding to the address being tested by the DAD_NSOL message already existed 🧠 So it isn't enough for an attacker to subscribe to a Solicited Node address to receive DAD_NSOL messages sent to that address. The attacker would also need to generate a valid DAD_NSOL message tied to the address whose binding is being tested, and that's deemed unfeasible [RFC3971] πŸ’€πŸ”₯

5.2. Protection against Denial-of-Service Attacks ✨

okay so attacks on a SEND SAVI device basically boil down to making it burn through its resources until it literally runs out 😭 a sneaky attacker could send packets with a bunch of different source addresses, and the device would create state for every single one and waste memory on them πŸ’€. eventually it runs out of memory and has to decide what to do, so some form of garbage collection is needed to prune the entries 🧹. when it runs out of the memory allocated for the SEND SAVI Database, it is RECOMMENDED that it makes room by deleting the entries with a higher Creation time. so older entries stay put and the newer ones overwrite each other. in an attack where the attacker sends a batch of data packets from different source addresses, each new one is likely to overwrite another address the attack itself made, iykyk πŸ™ˆ

entries also get garbage collected using the DEFAULT_LT, which gets updated by NUD_NSOL/NUD_NADV exchanges. so for an attacker to actually fill the SEND SAVI Database with false source addresses, they'd have to keep answering NUD_NSOL for all the different source addresses, so the entries stay fresh and compete with the legit ones. the cost of the attack goes way up for them, which is honestly iconic πŸ‘‘

in addition, it is also RECOMMENDED that a SEND SAVI device reserves a minimum amount of memory for each available port (in the case where the port is used as part of the L2 anchor) πŸŽ€. the REQUIRED minimum is the memory needed to store four bindings associated to the port, although it SHOULD be raised if the ratio between the maximum number of bindings allowed in the device and the number of ports is high. why does this matter? because an attacker plugged into one port can try to DoS the device by creating loads of bindings for different addresses, sending DAD_NSOL for each one, and then the attack eats all the memory 😀. reserving a minimum per port means nodes on other ports can still use their reserved memory even while the attack is happening somewhere else. main character energy for the innocent ports πŸ’…

the SEND SAVI device may also store data packets while an address is being verified. for example, a DAD_NSOL might get lost before it reaches the SEND SAVI device the host attaches to, or when the host sends data packets, they might get stored until the device verifies the binding with a NUD packet exchange πŸ“¦. in that case, the memory for storing data packets can also be a DoS target, so a SEND SAVI device MUST limit the amount of memory used to store data packets. that way the other stuff, like storing new bindings, still has memory available even when an attack like the ones above is happening πŸ›‘οΈ

and it gets even spicier: SEND SAVI DoS attacks are extra dangerous because the device does costly cryptography to validate the addresses of nodes πŸ₯΅. an attacker can generate packets with new source addresses to make the closest SEND SAVI device spend CPU time validating DAD_NSOL messages or generating a secure NUD_NSOL. that can drain the CPU of SEND SAVI devices at a very low cost for the attacker. to fix this, rate-limiting the processing of packets that trigger SEND SAVI events SHOULD be enforced on a per-port basis ⏱️


5.3. Considerations on the Deployment Model for Trust Anchors πŸ”

okay the SEND specification [RFC3971] suggests two ways to deploy trust anchors πŸ—ΊοΈ one is a centralized model that relies on a globally rooted public key infrastructure, and the other is a more local, decentralized model where end hosts get configured with a collection of public keys that are only trusted within a domain.

the appeal of the centralized model is that hosts can use SEND to validate routers as they roam across links owned by different organizations, without any extra configuration ✈️. but, without further protection, it also lets routers that have a certificate path rooted on a global trust anchor show up as legit routers on a link where they were never supposed to act as routers 😬. this threat already existed for SEND deployments, where links set up to accept centralized trust anchors may send outgoing traffic and use prefix info from alien routers. in a SEND SAVI deployment, those routers might be able to deliver off-link traffic to any node on the link, which is a whole mess πŸ™ƒ

so to handle this, SEND SAVI says nodes are only allowed to behave as routers if they connect through Trusted ports. specifically, RADV messages and traffic with off-link source addresses get discarded when they're received through Validating ports, which are the ports meant for non-trusted infrastructure, like moving nodes 🚫. filtering RADV messages means SEND nodes can't identify alien routers as legit routers, even when those routers' trust anchor is valid. protect the link, protect the bestie 🫢

and btw, SEND SAVI does support a decentralized deployment model 🌸


5.4. Residual Threats πŸ₯€

SEND SAVI assumes that a host will be able to defend its address when the DAD procedure runs for its addresses, and that it will answer a NUD_NSOL with a NUD_NADV when required πŸ’­. this is needed for mobility within a link, which means letting a host detach and reconnect to a different layer-2 anchor of the same IP subnetwork without changing its IP address πŸ¦‹

if the SEND SAVI device doesn't see the DAD_NADV or the NUD_NADV, it may grant the binding to a different binding anchor. so if an attacker manages to stop a host from defending its source address, they can destroy the existing binding and create a new one with a different binding anchor 😱. for example, an attacker could launch a DoS attack at the host so it can't send proper replies. not iconic behavior from the attacker, but it's a real residual threat πŸ’€


5.5. Privacy Considerations πŸ•΅οΈβ€β™€οΈ

a SEND SAVI device MUST delete binding anchor information as soon as possible (aka as soon as the state for a given address goes back to NO_BIND), except where there's an identified reason why that info is likely to be involved in detecting, preventing, or tracing actual source address spoofing πŸ—‘οΈ. info about the majority of hosts that never spoof SHOULD NOT be logged πŸ™ privacy is a vibe, and it's giving respect πŸ’œ


6. Acknowledgments πŸŽ€

thanks to Jean-Michel Combes, Ana Kukec, Ted Lemon, Adrian Farrel, Barry Leiba, Brian Haberman, Vicent Roca, and Benoit Claise for their reviews and comments on this document 🫢. the text also benefited from feedback from Tony Cheneau and Greg Daley ✨

Marcelo Bagnulo is partly funded by Trilogy 2, a research project supported by the European Commission under its Seventh Framework Program πŸ‡ͺπŸ‡Ί. Alberto Garcia-Martinez was supported, in part, by project TEC2012-38362-C03-01, granted by the Spanish Economy and Competitiveness Ministry πŸ‡ͺπŸ‡Έ


7. References πŸ“š

7.1. Normative References

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC3971]  Arkko, J., Kempf, J., Zill, B., and P. Nikander, "SEcure
           Neighbor Discovery (SEND)", RFC 3971, March 2005.

[RFC3972]  Aura, T., "Cryptographically Generated Addresses (CGA)",
           RFC 3972, March 2005.

[RFC4861]  Narten, T., Nordmark, E., Simpson, W., and H. Soliman,
           "Neighbor Discovery for IP version 6 (IPv6)", RFC 4861,
           September 2007.

[RFC4862]  Thomson, S., Narten, T., and T. Jinmei, "IPv6 Stateless
           Address Autoconfiguration", RFC 4862, September 2007.

7.2. Informative References

[IEEE.802-1Q.2005]
           Institute of Electrical and Electronics Engineers, "IEEE
           Standard for Local and Metropolitan Area Networks /
           Virtual Bridged Local Area Networks", IEEE Standard
           802.1Q, May 2005.

[RFC2827]  Ferguson, P. and D. Senie, "Network Ingress Filtering:
           Defeating Denial of Service Attacks which employ IP Source
           Address Spoofing", BCP 38, RFC 2827, May 2000.

[RFC6434]  Jankiewicz, E., Loughney, J., and T. Narten, "IPv6 Node
           Requirements", RFC 6434, December 2011.

[RFC6620]  Nordmark, E., Bagnulo, M., and E. Levy-Abegnoli, "FCFS
           SAVI: First-Come, First-Served Source Address Validation
           Improvement for Locally Assigned IPv6 Addresses", RFC
           6620, May 2012.

[RFC7039]  Wu, J., Bi, J., Bagnulo, M., Baker, F., and C. Vogt,
           "Source Address Validation Improvement (SAVI) Framework",
           RFC 7039, October 2013.

Authors' Addresses 🏑

Marcelo Bagnulo
Universidad Carlos III de Madrid
Av. Universidad 30
Leganes, Madrid  28911
Spain

Phone: 34 91 6248814
EMail: marcelo@it.uc3m.es
URI:   http://www.it.uc3m.es


Alberto Garcia-Martinez
Universidad Carlos III de Madrid
Av. Universidad 30
Leganes, Madrid  28911
Spain

Phone: 34 91 6248782
EMail: alberto@it.uc3m.es
URI:   http://www.it.uc3m.es
πŸ“¦ where this page comes from