RFC 8990
GeneRic Autonomic Signaling Protocol (GRASP)
GeneRic Autonomic Signaling Protocol (GRASP) ๐ฆ
Okay so this is RFC 8990, published by the IETF in May 2021 as a Standards Track document (ISSN 2070-1721) ๐ It's written by C. Bormann (Universitรคt Bremen TZI), B. Carpenter, Ed. (Univ. of Auckland), and B. Liu, Ed. (Huawei Technologies Co., Ltd). "Ed." means editor, so those two did the heavy lifting on the text ๐ The title block doesn't list anything it obsoletes or updates, so this one stands on its own โจ
Abstract
This doc specifies the GeneRic Autonomic Signaling Protocol (GRASP) ๐ GRASP lets autonomic nodes and Autonomic Service Agents find peers on their own, sync state with each other, and negotiate parameter settings together. It depends on an external security environment that's described somewhere else. The technical objectives and parameters for specific application scenarios will live in separate documents. The appendices briefly talk about requirements for the protocol and about existing protocols with similar features ๐
Status of This Memo
This is an Internet Standards Track document. ๐ธ
This document is a product of the Internet Engineering Task Force (IETF) ๐ It represents the consensus of the IETF community, it got public review, and it was approved for publication by the Internet Engineering Steering Group (IESG). For more on Internet Standards, check Section 2 of RFC 7841 ๐
Info about the current status of this document, any errata, and how to give feedback on it lives at https://www.rfc-editor.org/info/rfc8990 ๐ง
Copyright Notice
Copyright (c) 2021 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 (https://trustee.ietf.org/license-info) as they stand on the date this document was published. Please read these carefully, because they spell out your rights and restrictions for this document ๐ซถ Code Components extracted from this document must include the Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as described in the Simplified BSD License ๐
Table of Contents
1. Introduction
2. Protocol Overview
2.1. Terminology
2.2. High-Level Deployment Model
2.3. High-Level Design
2.4. Quick Operating Overview
2.5. GRASP Basic Properties and Mechanisms
2.5.1. Required External Security Mechanism
2.5.2. Discovery Unsolicited Link-Local (DULL) GRASP
2.5.3. Transport Layer Usage
2.5.4. Discovery Mechanism and Procedures
2.5.5. Negotiation Procedures
2.5.6. Synchronization and Flooding Procedures
2.6. GRASP Constants
2.7. Session Identifier (Session ID)
2.8. GRASP Messages
2.8.1. Message Overview
2.8.2. GRASP Message Format
2.8.3. Message Size
2.8.4. Discovery Message
2.8.5. Discovery Response Message
2.8.6. Request Messages
2.8.7. Negotiation Message
2.8.8. Negotiation End Message
2.8.9. Confirm Waiting Message
2.8.10. Synchronization Message
2.8.11. Flood Synchronization Message
2.8.12. Invalid Message
2.8.13. No Operation Message
2.9. GRASP Options
2.9.1. Format of GRASP Options
2.9.2. Divert Option
2.9.3. Accept Option
2.9.4. Decline Option
2.9.5. Locator Options
2.10. Objective Options
2.10.1. Format of Objective Options
2.10.2. Objective Flags
2.10.3. General Considerations for Objective Options
2.10.4. Organizing of Objective Options
2.10.5. Experimental and Example Objective Options
3. Security Considerations
4. CDDL Specification of GRASP
5. IANA Considerations
6. References
6.1. Normative References
6.2. Informative References
Appendix A. Example Message Formats
A.1. Discovery Example
A.2. Flood Example
A.3. Synchronization Example
A.4. Simple Negotiation Example
A.5. Complete Negotiation Example
Appendix B. Requirement Analysis of Discovery, Synchronization,
and Negotiation
B.1. Requirements for Discovery
B.2. Requirements for Synchronization and Negotiation Capability
B.3. Specific Technical Requirements
Appendix C. Capability Analysis of Current Protocols
Acknowledgments
Authors' Addresses
1. Introduction โจ
The success of the Internet has made IP-based networks bigger and more complicated ๐ Large-scale ISP and enterprise networks have become more and more of a hassle for humans to manage by hand, and operational costs are climbing fast ๐ So there's a growing need for autonomic behavior in networks. General aspects of Autonomic Networks are discussed in [RFC7575] and [RFC7576] ๐ฆ
One approach is to decentralize network management a lot by moving its logic into network elements. A reference model for Autonomic Networking built on this idea is given in [RFC8993]. You should check that document to see how all the autonomic components fit together ๐งฉ To get autonomy, devices that embody Autonomic Service Agents (ASAs, [RFC7575]) have specific signaling needs. In particular, they need to discover each other, sync state with each other, and negotiate parameters and resources directly with each other ๐ค There's no limit on the types of parameters and resources involved, which can include super basic info needed for addressing and routing, plus anything else that might get configured in a conventional non-autonomic network. The atomic unit of discovery, synchronization, or negotiation is called a technical objective, i.e., a configurable parameter or set of parameters (defined more precisely in Section 2.1) ๐
Negotiation is an iterative process. It takes multiple message exchanges that form a closed loop between the negotiating entities ๐ Those entities are ASAs, usually but not necessarily in different network devices. State synchronization, when it's needed, can be seen as a special case of negotiation without the iteration โจ Both negotiation and synchronization must logically follow discovery. More details on the requirements are in Appendix B. Section 2.3 describes a behavior model for a protocol meant to support discovery, synchronization, and negotiation, and the design of GeneRic Autonomic Signaling Protocol (GRASP) in Section 2 is based on that model. The relevant capabilities of various existing protocols are reviewed in Appendix C ๐ธ
The proposed discovery mechanism is aimed at synchronization and negotiation objectives ๐ฏ It's based on a neighbor discovery process on the local link, but it also supports diversion to peers on other links. There's no assumption about any particular network topology. When a device starts up with no preconfiguration, it knows nothing about the topology ๐ The protocol itself can be used in a small and/or flat network, like a small office or home network, as well as in a large, professionally managed network ๐ ๐ข So the discovery mechanism needs to let a device bootstrap itself without making any prior assumptions about network structure. Iconic, honestly ๐
Because GRASP can be used as part of a decision process among distributed devices or between networks, it must run in a secure and strongly authenticated environment ๐ Not a vibe you can skip.
In realistic deployments, not all devices will support GRASP ๐ญ So some Autonomic Service Agents will directly manage a group of non-autonomic nodes, and other non-autonomic nodes will be managed the traditional way. Those mixed scenarios are not discussed in this specification ๐ซถ
2. Protocol Overview ๐
2.1. Terminology โจ
okay bestie, let's get the vocab sorted ๐ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this doc mean what BCP 14 [RFC2119] [RFC8174] says they mean, but only when they show up in all caps, like we just did ๐
This document uses terminology defined in [RFC7575]. ๐ง
Here are some extra terms that pop up everywhere:
Discovery: An ASA finds peers that match a specific discovery objective. The results can look different depending on which discovery objective is in play. The peers it finds can later become negotiation counterparts or sources of synchronization data ๐
Negotiation: Two ASAs go back and forth, step by step, until they agree on parameter settings that best meet the objectives of both of them ๐ค
State Synchronization: ASAs share the current state of the parameter values stored in other ASAs. This is a special case of negotiation where information gets sent, but the ASAs don't ask their peers to change any parameter settings. Everything else in the definitions applies to both negotiation and synchronization ๐
Technical Objective (usually abbreviated as Objective): An objective is a data structure whose main contents are a name and a value. The value is a single configurable parameter or a set of parameters of some kind. The exact format of an objective is defined in Section 2.10.1. An objective shows up in three contexts: discovery, negotiation, and synchronization. Normally, a given objective won't be in negotiation and synchronization contexts at the same time ๐ฏ
- One ASA can support multiple independent objectives.
- The parameter(s) in an objective's value apply to a specific service, function, or action. In principle they can be anything a network node can set to a specific logical, numerical, or string value, or a more complex data structure. Each node is expected to contain one or more ASAs, and each of those may manage subsidiary non-autonomic nodes. ๐ธ
- Discovery Objective: an objective used in the process of discovery. Its value may be undefined.
- Synchronization Objective: an objective whose specific technical content needs to be synchronized among two or more ASAs. So each ASA keeps its own copy of the objective.
- Negotiation Objective: an objective whose specific technical content needs to be decided in coordination with another ASA. Again, each ASA keeps its own copy of the objective.
- A detailed discussion of objectives, including their format, is in Section 2.10.
Discovery Initiator: An ASA that kicks off discovery by sending a Discovery message that refers to a specific discovery objective ๐
Discovery Responder: A peer that either has an ASA supporting the discovery objective the discovery initiator named, or caches the locator(s) of the ASA(s) that support that objective. It sends a Discovery Response, which we'll get to later ๐ฌ
Synchronization Initiator: An ASA that starts synchronization by sending a request message that refers to a specific synchronization objective ๐โโ๏ธ
Synchronization Responder: A peer ASA that answers with the value of a synchronization objective ๐
Negotiation Initiator: An ASA that starts negotiation by sending a request message that refers to a specific negotiation objective ๐ฌ
Negotiation Counterpart: A peer that the negotiation initiator negotiates a specific negotiation objective with ๐ซถ
GRASP Instance: One instantiation of a GRASP protocol engine. It probably has multiple threads or processes plus dynamic data structures, like a discovery cache, all running in a given security environment on a single device ๐ฅ๏ธ
GRASP Core: The code and shared data structures of a GRASP instance. It talks to individual ASAs through a suitable Application Programming Interface (API) ๐
Interface or GRASP Interface: Unless stated otherwise, this means a network interface (physical or virtual) that a specific GRASP instance is currently using. A device might have other interfaces that GRASP doesn't use, and those are outside the scope of the Autonomic Network ๐
2.2. High-Level Deployment Model ๐
a GRASP implementation lives inside the Autonomic Networking Infrastructure (ANI) of an autonomic node, and the node also has to provide an appropriate security environment ๐ Following [RFC8993], this SHOULD be the Autonomic Control Plane (ACP) [RFC8994]. That means every autonomic node in the ACP can trust every other one. GRASP is expected to get into the ACP using a typical socket programming interface, and the ACP only makes available network interfaces inside the Autonomic Network. If there's no ACP, the considerations in Section 2.5.1 kick in ๐ก๏ธ
there are also one or more Autonomic Service Agents (ASAs) ๐ค In the minimal case of a single-purpose device, these pieces might be fully integrated with GRASP and the ACP. The more common setup is a multipurpose device that can hold several ASAs, like a router or a big switch. In that case, the ACP, GRASP, and the ASAs are expected to be separate processes that can run asynchronous and simultaneous operations, for example through multithreading ๐งต
in some scenarios, a limited negotiation model might be deployed. That happens when there's only a limited trust relationship, like the one between two administrative domains. The ASAs might then swap limited information and negotiate some particular configurations ๐ค
GRASP is explicitly designed to operate inside a single addressing realm. Its discovery and flooding mechanisms do not support autonomic operations that cross any form of address translator or upper-layer proxy ๐ซ
an ASA will need a suitable Application Programming Interface (API) to talk to GRASP. In some implementations, ASAs run in user space with a GRASP library providing the API, and that library talks to the core GRASP functions via system calls ๐ The details of the API are out of scope for this document. For more possible deployment models, check [RFC8993] ๐
A GRASP instance has to know which network interfaces it's going to use, plus the right global-scope and link-local addresses. When the ACP is present, that info comes from the adjacency table discussed in [RFC8993]. Otherwise, GRASP has to figure it out for itself, and the details depend on the device and operating system โ ๏ธ
GRASP needs to be super reliable, especially during bootstrapping and fault conditions, so it's essential that every implementation keeps working in adverse conditions ๐ช For example, discovery failures, or any kind of socket exception at any time, must not cause irrecoverable failures in GRASP itself. They must return suitable error codes through the API so the ASAs can recover too ๐ฉน
GRASP must not depend on nonvolatile data storage. All runtime error conditions, plus events like address renumbering, network interface failures, and CPU sleep/wake cycles, must be handled so that GRASP still operates correctly and securely afterwards (Section 2.5.1) โจ
an autonomic node will normally run a single instance of GRASP, which is shared by multiple ASAs. There are possible exceptions, which are mentioned below ๐
2.3. High-Level Design ๐ง
okay so this section is the vibe check for GRASP ๐ It describes the behavior model and general design, and it's all about discovery, synchronization, and negotiation, so GRASP can act as a platform for lots of different technical objectives โจ
A generic platform: ๐ธ
The protocol design is generic and independent of the synchronization or negotiation contents. The technical contents will vary according to the various technical objectives and the different pairs of counterparts ๐
Multiple instances: ๐ฆ
Normally, a single main instance of the GRASP protocol engine will exist in an autonomic node, and each ASA will run as an independent asynchronous process. However, scenarios where multiple instances of GRASP run in a single node, perhaps with different security properties, are possible (Section 2.5.2). In this case, each instance MUST listen independently for GRASP link-local multicasts, and all instances MUST be woken by each such multicast in order for discovery and flooding to work correctly ๐ฅ
Security infrastructure: ๐
As noted above, the protocol itself has no built-in security functionality and relies on a separate secure infrastructure. so it needs a buddy for that part ๐ซถ
Discovery, synchronization, and negotiation are designed together: ๐ค
The discovery method and the synchronization and negotiation methods are designed in the same way and can be combined when this is useful, allowing a rapid mode of operation described in Section 2.5.4. These processes can also be performed independently when appropriate โจ
Thus, for some objectives, especially those concerned with application-layer services, another discovery mechanism such as DNS-based Service Discovery [RFC7558] MAY be used. The choice is left to the designers of individual ASAs ๐
A uniform pattern for technical objectives: ๐
The synchronization and negotiation objectives are defined according to a uniform pattern. The values that they contain could be carried either in a simple binary format or in a complex object format. The basic protocol design uses the Concise Binary Object Representation (CBOR) [RFC8949], which is readily extensible for unknown, future requirements. so it's future-proof, periodt ๐ง
A flexible model for synchronization: ๐
GRASP supports synchronization between two nodes, which could be used repeatedly to perform synchronization among a small number of nodes. It also supports an unsolicited flooding mode when large groups of nodes, possibly including all autonomic nodes, need data for the same technical objective ๐
There may be some network parameters for which a more traditional flooding mechanism such as the Distributed Node Consensus Protocol (DNCP) [RFC7787] is considered more appropriate. GRASP can coexist with DNCP ๐ซง
A simple initiator/responder model for negotiation: ๐
Multiparty negotiations are very complicated to model and cannot readily be guaranteed to converge. GRASP uses a simple bilateral model and can support multiparty negotiations by indirect steps. keeping it simple is iconic, no cap ๐
Organizing of synchronization or negotiation content: ๐
The technical content transmitted by GRASP will be organized according to the relevant function or service. The objectives for different functions or services are kept separate because they may be negotiated or synchronized with different counterparts or have different response times. Thus a normal arrangement is a single ASA managing a small set of closely related objectives, with a version of that ASA in each relevant autonomic node. Further discussion of this aspect is out of scope for the current document ๐๏ธ
Requests and responses in negotiation procedures: ๐ฌ
The initiator can negotiate a specific negotiation objective with relevant counterpart ASAs. It can request relevant information from a counterpart so that it can coordinate its local configuration. It can request the counterpart to make a matching configuration. It can request simulation or forecast results by sending some dry-run conditions ๐ฎ
Beyond the traditional yes/no answer, the responder can reply with a suggested alternative value for the objective concerned. This would start a bidirectional negotiation ending in a compromise between the two ASAs. the vibe is literally "let's meet in the middle" ๐ค๐
Convergence of negotiation procedures: ๐
To enable convergence when a responder suggests a new value or condition in a negotiation step reply, it should be as close as possible to the original request or previous suggestion. The suggested value of later negotiation steps should be chosen between the suggested values from the previous two steps. GRASP provides mechanisms to guarantee convergence (or failure) in a small number of steps, namely a timeout and a maximum number of iterations โฑ๏ธ
Extensibility: โญ
GRASP intentionally does not have a version number, and it can be extended by adding new message types and options. The Invalid message (M_INVALID) will be used to signal that an implementation does not recognize a message or option sent by another implementation. In normal use, new semantics will be added by defining new synchronization or negotiation objectives. no version number?? that's so iconic, it grows by vibes ๐ฆโจ
2.4. Quick Operating Overview โก
An instance of GRASP is expected to run as a separate core module, providing an API (such as [RFC8991]) to interface to various ASAs. These ASAs may operate without special privilege, unless they need it for other reasons (such as configuring IP addresses or manipulating routing tables) ๐ ๏ธ
The GRASP mechanisms used by the ASA are built around GRASP objectives defined as data structures containing administrative information such as the objective's unique name and its current value. The format and size of the value is not restricted by the protocol, except that it must be possible to serialize it for transmission in CBOR, which is no restriction at all in practice ๐
GRASP provides the following mechanisms: ๐ง
- A discovery mechanism (
M_DISCOVERY,M_RESPONSE) by which an ASA can discover other ASAs supporting a given objective ๐ - A negotiation request mechanism (
M_REQ_NEG) by which an ASA can start negotiation of an objective with a counterpart ASA. Once a negotiation has started, the process is symmetrical, and there is a negotiation step message (M_NEGOTIATE) for each ASA to use in turn. Two other functions support negotiating steps (M_WAIT,M_END) ๐ - A synchronization mechanism (
M_REQ_SYN) by which an ASA can request the current value of an objective from a counterpart ASA. With this, there is a corresponding response function (M_SYNCH) for an ASA that wishes to respond to synchronization requests ๐ - A flood mechanism (
M_FLOOD) by which an ASA can cause the current value of an objective to be flooded throughout the Autonomic Network so that any ASA can receive it. One application of this is to act as an announcement, avoiding the need for discovery of a widely applicable objective ๐ฃ
Some example messages and simple message flows are provided in Appendix A ๐
2.5. GRASP Basic Properties and Mechanisms ๐
2.5.1. Required External Security Mechanism ๐
GRASP does not specify transport security because it is meant to be adapted to different environments. Every solution adopting GRASP MUST specify a security and transport substrate used by GRASP in that solution ๐
The substrate MUST enforce sending and receiving GRASP messages only between members of a mutually trusted group running GRASP. Each group member is an instance of GRASP. The group members are nodes of a connected graph. The group and graph are created by the security and transport substrate and are called the GRASP domain. The substrate must support unicast messages between any group members and (link-local) multicast messages between adjacent group members. It must deny messages between group members and non-group members. With this model, security is provided by enforcing group membership, but any member of the trusted group can attack the entire network until revoked ๐ณ
Substrates MUST use cryptographic member authentication and message integrity for GRASP messages. This can be end to end or hop by hop across the domain. The security and transport substrate MUST provide mechanisms to remove untrusted members from the group ๐ซ
If the substrate does not mandate and enforce GRASP message encryption, then any service using GRASP in such a solution MUST provide protection and encryption for message elements whose exposure could constitute an attack vector. this part is seriously important, bestie, don't skip it ๐จ
The security and transport substrate for GRASP in the ANI is the ACP. Unless otherwise noted, we assume this security and transport substrate in the remainder of this document. The ACP does mandate the use of encryption; therefore, GRASP in the ANI can rely on GRASP messages being encrypted. The GRASP domain is the ACP: all nodes in an autonomic domain connected by encrypted virtual links formed by the ACP. The ACP uses hop-by-hop security (authentication and encryption) of messages. Removal of nodes relies on standard PKI certificate revocation or expiry of sufficiently short-lived certificates. Refer to [RFC8994] for more details ๐โจ
As mentioned in Section 2.3, some GRASP operations might be performed across an administrative domain boundary by mutual agreement, without the benefit of an ACP. Such operations MUST be confined to a separate instance of GRASP with its own copy of all GRASP data structures running across a separate GRASP domain with a security and transport substrate. In the most simple case, each point-to-point interdomain GRASP peering could be a separate domain, and the security and transport substrate could be built using transport or network-layer security protocols. This is subject to future specifications ๐
An exception to the requirements for the security and transport substrate exists for highly constrained subsets of GRASP meant to support the establishment of a security and transport substrate, described in the following section ๐ซถ
2.5.2. Discovery Unsolicited Link-Local (DULL) GRASP ๐ฆ
okay so some services need to do insecure GRASP discovery, response, and flood messages WITHOUT having any preexisting security associations to lean on ๐ญ like, that's literally how you bootstrap a security substrate for GRASP in the first place, so it's kind of a chicken-and-egg situation ๐ฅ
because these operations are intrinsically insecure, they have to be confined to link-local use so nobody can pull off malicious stuff from far away ๐ possible examples are discovering candidate ACP neighbors [RFC8994], discovering bootstrap proxies [RFC8995], or maybe initialization services in networks that use GRASP without being fully autonomic (e.g., no ACP) ๐ธ this usage MUST be limited to link-local operations on a single interface, and it MUST be confined to a separate insecure instance of GRASP with its own copy of all GRASP data structures. this instance is nicknamed DULL, which stands for Discovery Unsolicited Link-Local ๐ (yes, it's giving main character energy, I love it for it)
here are the detailed rules for the DULL instance of GRASP:
- an initiator MAY send Discovery or Flood Synchronization link-local multicast messages, and those MUST have a loop count of 1, so they can't go off-link ๐ง other unsolicited GRASP message types MUST NOT be sent. not me sending them ๐
- a responder MUST silently discard any message whose loop count is not 1 ๐คซ
- a responder MUST silently discard any message referring to a GRASP objective that is not directly part of a service that requires this insecure mode ๐ซ
- a responder MUST NOT relay any multicast messages ๐
- a Discovery Response MUST indicate a link-local address ๐
- a Discovery Response MUST NOT include a Divert option โจ
- a node MUST silently discard any message whose source address is not link-local ๐ซถ
to keep the traffic that third parties might see down to a minimum, GRASP traffic SHOULD be minimized by using only Flood Synchronization to announce objectives and their associated locators, instead of Discovery and Discovery Response messages ๐ฆ further details are out of scope for this document, so we're leaving that for another day ๐
2.5.3. Transport Layer Usage ๐
all GRASP messages, once they're serialized as a CBOR byte string, get transmitted as-is directly over the transport protocol in use ๐ the transport protocol(s) for a GRASP domain are specified by the security and transport substrate we introduced in Section 2.5.1, so go check that if you forgot ๐ซฃ
GRASP discovery and flooding messages are designed for GRASP domain-wide flooding, using hop-by-hop link-local multicast forwarding between adjacent GRASP nodes ๐ the GRASP security and transport substrate needs to specify how those link-local multicasts get transported. this CAN be unreliable transport (UDP), but it SHOULD be reliable transport (e.g., TCP) ๐
if the substrate specifies an unreliable transport such as UDP for discovery and flooding messages, then it MUST NOT use IP fragmentation, because of its loss characteristics, especially in multi-hop flooding ๐ญ GRASP MUST then enforce, at the user API level, a limit on the size of discovery and flooding messages so that no fragmentation can happen. for IPv6 transport, that means the size of those messages' IPv6 packets must be at most 1280 bytes (unless there's a known larger minimum link MTU across the whole GRASP domain) ๐
all other GRASP messages are unicast between group members of the GRASP domain. these MUST use a reliable transport protocol, because GRASP itself does not provide error detection, retransmission, or flow control ๐ฅ unless the security and transport substrate says otherwise, TCP MUST be used ๐
the security and transport substrate for GRASP in the ANI is the ACP ๐ธ unless otherwise noted, we assume this substrate for the rest of this document when we describe GRASP's message transport. in the ACP, TCP is used for GRASP unicast messages. GRASP discovery and flooding messages also use TCP: these link-local messages get forwarded by replicating them to all adjacent GRASP nodes on the link, via TCP connections to those neighbors ๐ฆ because of this, GRASP in the ANI has no limits on the size of discovery and flooding messages with respect to fragmentation issues, so no stress there โจ while the ACP is being built using a DULL instance of GRASP, native UDP multicast is used to discover ACP/GRASP neighbors on links ๐ง
for link-local UDP multicast, GRASP listens to the well-known GRASP Listen Port (Section 2.6) ๐ transport connections for discovery and flooding on relay nodes MUST terminate in GRASP instances (e.g., GRASP ASAs), so that link-local multicast, hop-by-hop flooding of M_DISCOVERY and M_FLOOD messages, and hop-by-hop forwarding of M_RESPONSE responses and caching of those responses along the path all work correctly ๐
unicast transport connections used for synchronization and negotiation CAN terminate directly in ASAs that implement objectives, so this traffic does not need to pass through GRASP instances ๐ for this, the ASA listens on its own dynamically assigned ports, which get communicated to its peers during discovery. alternatively, the GRASP instance can also terminate the unicast transport connections and pass the traffic from or to the ASA, if that's preferable in some implementations (e.g., to better decouple ASAs from network connections) ๐ซถ
2.5.4. Discovery Mechanism and Procedures ๐ธ
2.5.4.1. Separated Discovery and Negotiation Mechanisms โญ
although discovery and negotiation or synchronization are defined together in GRASP, they are separate mechanisms ๐ฆ the discovery process could run independently from the negotiation or synchronization process. when a recipient node receives a Discovery message (Section 2.8.4), it SHOULD return a Discovery Response message in which it either indicates itself as a discovery responder or diverts the initiator towards another, more suitable ASA ๐ however, this response may be delayed if the recipient needs to relay the Discovery message onward, as described in Section 2.5.4.4 โจ
the discovery action (M_DISCOVERY) will normally be followed by a negotiation (M_REQ_NEG) or synchronization (M_REQ_SYN) action ๐ the discovery results could be used by the negotiation protocol to decide which ASA the initiator will negotiate with ๐
the initiator of a discovery action for a given objective does not need to be capable of responding to that objective as a negotiation counterpart, as a synchronization responder, or as a source for flooding ๐ for example, an ASA might perform discovery even if it only wants to act as a synchronization initiator or negotiation initiator. such an ASA does not itself need to respond to Discovery messages ๐ง
it's also entirely possible to use GRASP discovery without any subsequent negotiation or synchronization action ๐ in that case, the discovered objective is simply used as a name during the discovery process, and any later operations between the peers are outside the scope of GRASP ๐
2.5.4.2. Discovery Overview ๐ฆ
a complete discovery process starts with a multicast Discovery message (M_DISCOVERY) on the local link ๐ on-link neighbors supporting the discovery objective will respond directly with Discovery Response (M_RESPONSE) messages. a neighbor with multiple interfaces MAY respond with a cached Discovery Response ๐ซถ if it has no cached response, it will relay the Discovery message on its other GRASP interfaces. if a node receiving the relayed Discovery message supports the discovery objective, it will respond to the relayed Discovery message. if it has a cached response, it will respond with that. if not, it will repeat the discovery process, which makes the whole thing iterative ๐ the loop count and timeout will make sure the process ends ๐ further details are in Section 2.5.4.4 โจ
a Discovery message MAY be sent unicast to a peer node, which SHOULD then proceed exactly as if the message had been multicast, except that when TCP is used, the response will be on the same socket as the query ๐ธ however, this mode does not guarantee successful discovery in the general case ๐
2.5.4.3. Discovery Procedures โจ
okay so discovery always starts as an on-link thing ๐ซถ. The Divert option is how the discovery initiator gets pointed at an off-link ASA for that discovery objective ๐ฆ. If the security and transport substrate of the GRASP domain (see Section 2.5.3) uses UDP link-local multicast, the discovery initiator sends these to the ALL_GRASP_NEIGHBORS link-local multicast address (Section 2.6), and all GRASP nodes need to listen to that address to act as discovery responders ๐. Because this port is unique on a device, it's a function of the GRASP instance and not of an individual ASA. So each ASA will need to register the objectives it supports with the local GRASP instance ๐
.
If an ASA in a neighbor device supports the requested discovery objective, the device SHOULD respond to the link-local multicast with a unicast Discovery Response message (Section 2.8.5) carrying locator option(s) (Section 2.9.5), unless it's temporarily unavailable ๐ธ. Otherwise, if the neighbor has cached info about an ASA that supports the requested objective (usually because it discovered that same objective before), it SHOULD respond with a Discovery Response message containing a Divert option that points to the appropriate discovery responder โจ. Still, it SHOULD NOT respond with a cached response on an interface if it learned that info from the same interface, because the peer in question will answer directly if it's still operational ๐.
If a device has no info about the requested discovery objective and isn't acting as a discovery relay (see Section 2.5.4.4), it MUST silently discard the Discovery message ๐.
The discovery initiator MUST set a reasonable timeout on the discovery process ๐. A suggested value is 100 milliseconds multiplied by the loop count embedded in the objective โฑ๏ธ.
If no Discovery Response is received within the timeout, the Discovery message MAY be repeated with a newly generated Session ID (Section 2.7) ๐. An exponential backoff SHOULD be used for subsequent repetitions so the load stays under control during busy periods ๐. The details of the backoff algorithm depend on the use case for the objective concerned, but they MUST be consistent with the recommendations in [RFC8085] for low data-volume multicast ๐. Frequent repetition might be symptomatic of a denial-of-service attack ๐จ.
After a GRASP device successfully discovers a locator for a discovery responder supporting a specific objective, it SHOULD cache this info, including the interface index [RFC3493] it was discovered on ๐๏ธ. This cache record MAY be used for future negotiation or synchronization, and the locator SHOULD be passed on as a Divert option to another discovery initiator when that's appropriate ๐ฆ.
The cache mechanism MUST include a lifetime for each entry ๐ฐ๏ธ. The lifetime is derived from a time-to-live (ttl) parameter in each Discovery Response message. Cached entries MUST be ignored or deleted once their lifetime expires ๐๏ธ. In some environments, unplanned address renumbering might happen ๐ฌ. When it does, the lifetime SHOULD be short compared to the typical address lifetime. The discovery mechanism needs to track the node's current address so Discovery Responses always indicate the correct address ๐.
If multiple discovery responders are found for the same objective, they SHOULD all be cached, unless that creates a resource shortage ๐งบ. How you choose between multiple responders is an implementation choice ๐คทโโ๏ธ. That choice MUST be available to each ASA, but the GRASP implementation SHOULD provide a default choice ๐ฏ.
Because discovery responders get cached in a finite cache, they might be deleted at any time ๐ต. If that happens, discovery will need to be repeated. If an ASA exits for any reason, its locator might still be cached for some time, and attempts to connect to it will fail ๐. So ASAs need to be robust in these circumstances ๐ช.
2.5.4.4. Discovery Relaying ๐
A GRASP instance with multiple link-layer interfaces (typically running in a router) MUST support discovery on all GRASP interfaces ๐ฃ๏ธ. We call this a 'relaying instance' ๐ง.
DULL instances (Section 2.5.2) are always single-interface instances, so they MUST NOT perform discovery relaying ๐ โโ๏ธ.
If a relaying instance receives a Discovery message on a given interface for a specific objective that it doesn't support, and for which it hasn't previously cached a discovery responder, it MUST relay the query by reissuing a new Discovery message as a link-local multicast on its other GRASP interfaces ๐ฃ.
The relayed Discovery message MUST have the same Session ID and 'initiator' field as the incoming message (see Section 2.8.4) ๐ชช. The IP address in the 'initiator' field is only used to disambiguate the Session ID and is never used to address Response packets. Response packets are sent back to the relaying instance, not the original initiator ๐.
The M_DISCOVERY message doesn't encode the transport address of the originator or relay. So Response packets must be sent to the transport-layer address of the connection on which the M_DISCOVERY message was received ๐ฌ. If the M_DISCOVERY was relayed via a reliable hop-by-hop transport connection, the response is simply sent back via that same connection ๐.
If the M_DISCOVERY was relayed via link-local (e.g., UDP) multicast, the response is sent back via a reliable hop-by-hop transport connection with the same port number as the source port of the link-local multicast ๐งต. So if link-local multicast is used and M_RESPONSE messages are required (which is the case in almost all GRASP instances, except for the limited use of DULL instances in the ANI) ๐ฅน, GRASP needs to be able to bind to one port number on UDP to originate the link-local multicast M_DISCOVERY messages. It also needs the same port number on the reliable hop-by-hop transport (e.g., TCP by default) so it can respond to transport connections from responders that want to send M_RESPONSE messages back ๐. Note that this port doesn't need to be the GRASP_LISTEN_PORT ๐.
The relaying instance MUST decrement the loop count within the objective, and MUST NOT relay the Discovery message if the result is zero ๐ข. It also MUST limit the total rate at which it relays Discovery messages to a reasonable value, to mitigate possible denial-of-service attacks ๐ฆ. For example, the rate limit could be set to a small multiple of the observed rate of Discovery messages during normal operation ๐. The relaying instance MUST cache the Session ID value and initiator address of each relayed Discovery message until any Discovery Responses have arrived or the discovery process has timed out ๐ง . To prevent loops, it MUST NOT relay a Discovery message that carries a given cached Session ID and initiator address more than once ๐๐ซ. These precautions avoid discovery loops and mitigate potential overload ๐ซถ.
Since the relay device is unaware of the timeout set by the original initiator, it SHOULD set a suitable timeout for the relayed Discovery message. A suggested value is 100 milliseconds multiplied by the remaining loop count โณ.
The discovery results received by the relaying instance MUST in turn be sent as a Discovery Response message to the Discovery message that caused the relay action ๐.
2.5.4.5. Rapid Mode (Discovery with Negotiation or Synchronization) โก
A Discovery message MAY include an objective option ๐งฉ. That lets you use a rapid mode of negotiation (Section 2.5.5.1) or synchronization (Section 2.5.6.3) ๐๏ธ. Rapid mode is currently limited to a single objective, for simplicity of design and implementation. A possible future extension is to allow multiple objectives in rapid mode for greater efficiency ๐ฎ.
2.5.5. Negotiation Procedures ๐ค
okay so a negotiation initiator opens a transport connection to a counterpart ASA, using the address, protocol, and port it got during discovery ๐. Then it sends a negotiation request (using M_REQ_NEG) to the counterpart, including a specific negotiation objective ๐จ. It may ask the negotiation counterpart to make a specific configuration ๐ ๏ธ. Or it may request a certain simulation or forecast result by sending a dry-run configuration ๐ฎ. The details, including the difference between a dry run and a live configuration change, will be defined separately for each type of negotiation objective ๐. Any state linked to a dry-run operation, like temporarily reserving a resource for later use in a live run, is totally up to the designer of the ASA concerned ๐จ.
Each negotiation session as a whole is subject to a timeout (default GRASP_DEF_TIMEOUT milliseconds, Section 2.6), which gets initialized when the request is sent (see Section 2.8.6) โฒ๏ธ. If no reply message of any kind comes back within the timeout, the negotiation request MAY be repeated with a newly generated Session ID (Section 2.7) ๐. An exponential backoff SHOULD be used for subsequent repetitions ๐. The details of the backoff algorithm depend on the use case for the objective concerned ๐งฎ.
If the counterpart can apply the requested configuration right away, it gives an immediate positive (O_ACCEPT) answer using the Negotiation End (M_END) message โ . That ends the negotiation phase immediately ๐. Otherwise, it negotiates (using M_NEGOTIATE) ๐ฃ๏ธ. It replies with a proposed alternative configuration that it can apply (typically one that uses fewer resources than the negotiation initiator asked for) ๐ชถ. That starts a bidirectional negotiation using the Negotiate (M_NEGOTIATE) message, to reach a compromise between the two ASAs ๐คโจ.
The negotiation procedure ends when one of the negotiation peers sends a Negotiation End (M_END) message. That message contains an Accept (O_ACCEPT) or Decline (O_DECLINE) option and doesn't need a response from the negotiation peer ๐. Negotiation may also end in failure (equivalent to a decline) if a timeout is exceeded or a loop count is exceeded ๐. When the procedure ends for whatever reason, the transport connection SHOULD be closed ๐. A transport session failure is treated as a negotiation failure ๐ฅ.
A negotiation procedure concerns one objective and one counterpart ๐ฏ. Both the initiator and the counterpart may take part in simultaneous negotiations with various other ASAs, or in simultaneous negotiations about different objectives ๐. So GRASP is expected to be used in a multithreaded mode, or its logical equivalent ๐งต. Certain negotiation objectives may have restrictions on multithreading, for example to avoid over-allocating resources ๐ง.
Some configuration actions, like wavelength switching in optical networks, might take a good while to execute ๐. The ASA concerned needs to allow for this by design. GRASP does allow a peer to insert latency into a negotiation process if necessary (Section 2.8.9, M_WAIT) ๐ซง.
2.5.5.1. Rapid Mode (Discovery/Negotiation Linkage) โจ
okay so a Discovery message MAY include a Negotiation Objective option ๐
when it does, it's like the initiator sent M_DISCOVERY and then immediately sent M_REQ_NEG, back to back. this is a big deal for the GRASP core, because it has to carefully pass the Negotiation Objective option contents up to the ASA so the ASA can check the objective right away ๐ง once that's in place, the ASA answers with an M_NEGOTIATE (or an M_END with O_ACCEPT if it's already happy with the proposal) instead of an M_RESPONSE. the vibe is "skip the middle step" ๐ฆ but if the recipient node doesn't support rapid mode, discovery just keeps going normally, no drama ๐ซถ
there's a catch though ๐ญ a Discovery Response could show up from a responder that doesn't do rapid mode before the Negotiation message arrives. if that happens, rapid mode just won't happen. it's giving "the plan got cancelled, we're doing it the regular way" ๐
rapid mode could cut down on how many messages nodes swap, so it could be way more efficient ๐ฅ BUT a network where some nodes do rapid mode and others don't gets super complicated and timing-dependent ๐ so the rapid negotiation function SHOULD be disabled by default. no cap, that's the safe move ๐ธ
2.5.6. Synchronization and Flooding Procedures โจ
2.5.6.1. Unicast Synchronization
okay bestie, here's how a synchronization initiator gets its data ๐ it opens a transport connection to a counterpart ASA, using the address, protocol, and port it got during discovery ๐ฆ then it sends a Request Synchronization message (M_REQ_SYN, Section 2.8.6) with a specific synchronization objective. the counterpart replies with a Synchronization message (M_SYNCH, Section 2.8.10) that has the current value of the requested objective ๐ that's it, no more messages needed, and the transport connection SHOULD be closed ๐ if the transport session fails, that counts as a synchronization failure, sadly ๐ญ
if no reply of any kind shows up within a timeout (the default is GRASP_DEF_TIMEOUT milliseconds, see Section 2.6), the synchronization request MAY be repeated with a brand new Session ID (Section 2.7) โจ for the repeats after that, an exponential backoff SHOULD be used. how that backoff works depends on the use case for the objective, so it's not one-size-fits-all ๐
2.5.6.2. Flooding
so that unicast thing only deals with one objective between two nodes ๐ but when you've got a big group of nodes that all need the same data, synchronization flooding is the move ๐ a flooding initiator MAY send an unsolicited Flood Synchronization message (Section 2.8.11) with one or more Synchronization Objective options, but only if the spec for those objectives allows it ๐ it goes out as a multicast to the ALL_GRASP_NEIGHBORS multicast address (Section 2.6).
receiving flood multicasts is the GRASP core's job, same as with discovery multicasts (Section 2.5.4.3) ๐ซถ
now, loops. the originator of the Flood Synchronization message MUST set the loop count in the objectives to a suitable value (the default is GRASP_DEF_LOOPCT) ๐ bestie, that's how you stop a message from circling forever. you also need a way to stop excessive multicast traffic, and this mechanism MUST be defined as part of the spec for the synchronization objectives ๐ it could be a simple rate limit, or something fancier like the Trickle algorithm [RFC6206] โจ
a GRASP device with multiple link-layer interfaces (usually a router) MUST support synchronization flooding on all of its GRASP interfaces ๐ if it gets a multicast Flood Synchronization message on one interface, it MUST relay it by reissuing the message as a link-local multicast on its other GRASP interfaces ๐ฆ the relayed message MUST keep the same Session ID as the incoming one and MUST be tagged with the IP address of its original initiator ๐
link-layer flooding works by setting the loop count to 1 and sending with a link-local source address ๐ธ floods that have link-local source addresses but a loop count other than 1 are invalid, and those messages MUST be discarded ๐
the relaying device MUST decrement the loop count within the first objective, and it MUST NOT relay the Flood Synchronization message if the result is zero ๐ฅ it also MUST limit the total rate it relays Flood Synchronization messages at, to a reasonable value, so denial-of-service attacks don't stand a chance ๐ก๏ธ for example, the rate limit could be a small multiple of the flood message rate you see during normal operation ๐ the relaying device MUST cache the Session ID value and initiator address of each relayed Flood Synchronization message for at least twice GRASP_DEF_TIMEOUT milliseconds ๐ง and to prevent loops, it MUST NOT relay a Flood Synchronization message carrying a given cached Session ID and initiator address more than once. these precautions avoid synchronization loops and keep overload in check ๐ซถ
heads up though, this mechanism is unreliable for sleeping nodes, new nodes that join the network, or nodes that rejoin after a fault ๐ญ so an ASA that starts a flood SHOULD repeat it at a suitable frequency, and that frequency MUST be consistent with the recommendations in [RFC8085] for low data-volume multicast ๐ the ASA SHOULD also act as a synchronization responder for the objectives concerned. that way, nodes that need a flooded objective can either wait for the next flood or just request unicast synchronization for it ๐
โ ๏ธ the multicast messages for synchronization flooding are subject to the security rules in Section 2.5.1. in practice, that means they MUST NOT be transmitted, and they MUST be ignored on receipt, unless there's an operational ACP or equivalent strong security in place. and because link-local multicast has a security weakness (Section 3), flooded synchronization objectives SHOULD NOT contain unencrypted private information, and they SHOULD be validated by the recipient ASA ๐ this part is serious, so don't skip it!
2.5.6.3. Rapid Mode (Discovery/Synchronization Linkage)
a Discovery message MAY include a Synchronization Objective option โจ when it does, that Discovery message also acts as a Request Synchronization message, telling the discovery responder that it could reply straight to the discovery initiator with a Synchronization message (Section 2.8.10) holding the synchronization data, so it can be processed fast ๐ this only works if the discovery target supports the matching synchronization objective. the design implications are pretty much the same as in Section 2.5.5.1 ๐ฆ
same catch as before: a Discovery Response could arrive from a responder that doesn't do rapid mode before the Synchronization message shows up, and then rapid mode just won't happen ๐ญ it could also make things more efficient, but mixed networks get complicated and timing-dependent ๐ so the rapid synchronization function SHOULD be configured off by default, and it MAY be configured on or off by Intent ๐
2.6. GRASP Constants ๐
these are the magic numbers everyone needs to agree on, so nobody gets confused ๐ง
ALL_GRASP_NEIGHBORS: a link-local scope multicast address that a GRASP-enabled device uses to find GRASP-enabled neighbor (i.e., on-link) devices. every device that supports GRASP is a member of this multicast group ๐- IPv6 multicast address:
ff02::13 - IPv4 multicast address:
224.0.0.119
- IPv6 multicast address:
GRASP_LISTEN_PORT(7017): a well-known UDP user port that every GRASP-enabled network device MUST listen to for link-local multicasts when UDP is used forM_DISCOVERYorM_FLOODmessages in the GRASP instance ๐ this user port MAY also be used to listen for TCP or UDP unicast messages in a simple GRASP implementation (Section 2.5.3) ๐GRASP_DEF_TIMEOUT(60000milliseconds): the default timeout for deciding that an operation has failed to complete โฐGRASP_DEF_LOOPCT(6): the default loop count for deciding that a negotiation has failed to complete, and for avoiding looping messages ๐GRASP_DEF_MAX_SIZE(2048): the default maximum message size, in bytes ๐ฆ
2.7. Session Identifier (Session ID) ๐ฆ
this is an up to 32-bit opaque value used to tell apart multiple sessions between the same two devices ๐ every new Discovery, Flood Synchronization, or Request message MUST get a new Session ID generated by the initiator ๐ซถ and every response and follow-up message in that same discovery, synchronization, or negotiation procedure MUST carry that same Session ID. it's giving "one ID per conversation" ๐
the Session ID SHOULD have a very low collision rate locally ๐ธ it MUST come from a pseudorandom number generator (PRNG) seeded with a locally generated seed that's unlikely to be used by any other device on the same network ๐ฒ the PRNG SHOULD be cryptographically strong [RFC4086]. when allocating a new Session ID, GRASP MUST check that the value isn't already in use, and SHOULD check that it hasn't been used recently by looking through a cache of current and recent sessions ๐ if there's a clash (super unlikely, but still), GRASP MUST generate a new value ๐
but there's still a tiny chance two nodes pick the same Session ID ๐ญ so whenever a Session ID gets communicated over GRASP, the receiving node MUST tag it with the initiator's IP address to keep things straight ๐ท๏ธ if two peers somehow open sessions with the same Session ID, that tag lets you tell the two sessions apart. this is why multicast GRASP messages and their responses, which can get relayed between links, include a field carrying the initiator's global IP address ๐
one more highly unlikely race condition: two peers start simultaneous negotiation sessions with each other using the same Session ID value ๐ depending on implementation choices, that could mix the two sessions up. see Section 2.8.6 for how to avoid it ๐ก
2.8. GRASP Messages ๐
2.8.1. Message Overview โจ
this section defines the GRASP message format and message types ๐ any message types not listed here are reserved for future use ๐ฎ
the messages currently defined are:
- Discovery and Discovery Response (
M_DISCOVERY,M_RESPONSE). - Request Negotiation, Negotiation, Confirm Waiting, and Negotiation End (
M_REQ_NEG,M_NEGOTIATE,M_WAIT,M_END). - Request Synchronization, Synchronization, and Flood Synchronization (
M_REQ_SYN,M_SYNCH,M_FLOOD). - No Operation and Invalid (
M_NOOP,M_INVALID).
2.8.2. GRASP Message Format
GRASP messages share an identical header format and a variable format area for options. GRASP message headers and options are transmitted in Concise Binary Object Representation (CBOR) [RFC8949]. In this specification, they are described using Concise Data Definition Language (CDDL) [RFC8610]. Fragmentary CDDL is used to describe each item in this section. A complete and normative CDDL specification of GRASP is given in Section 4, including constants such as message types.
Every GRASP message, except the No Operation message, carries a Session ID (Section 2.7). Options are then presented serially.
In fragmentary CDDL, every GRASP message follows the pattern:
grasp-message = (message .within message-structure) / noop-message
message-structure = [MESSAGE_TYPE, session-id, ?initiator, *grasp-option]
MESSAGE_TYPE = 0..255 session-id = 0..4294967295 ; up to 32 bits grasp-option = any
The MESSAGE_TYPE indicates the type of the message and thus defines the expected options. Any options received that are not consistent with the MESSAGE_TYPE SHOULD be silently discarded.
The No Operation (noop) message is described in Section 2.8.13.
The various MESSAGE_TYPE values are defined in Section 4.
All other message elements are described below and formally defined in Section 4.
If an unrecognized MESSAGE_TYPE is received in a unicast message, an Invalid message (Section 2.8.12) MAY be returned. Otherwise, the message MAY be logged and MUST be discarded. If an unrecognized MESSAGE_TYPE is received in a multicast message, it MAY be logged and MUST be silently discarded.
2.8.3. Message Size
GRASP nodes MUST be able to receive unicast messages of at least GRASP_DEF_MAX_SIZE bytes. GRASP nodes MUST NOT send unicast messages longer than GRASP_DEF_MAX_SIZE bytes unless a longer size is explicitly allowed for the objective concerned. For example, GRASP negotiation itself could be used to agree on a longer message size.
The message parser used by GRASP should be configured to know about the GRASP_DEF_MAX_SIZE, or any larger negotiated message size, so that it may defend against overly long messages.
The maximum size of multicast messages (M_DISCOVERY and M_FLOOD) depends on the link-layer technology or the link-adaptation layer in use.
2.8.4. Discovery Message
In fragmentary CDDL, a Discovery message follows the pattern:
discovery-message = [M_DISCOVERY, session-id, initiator, objective]
A discovery initiator sends a Discovery message to initiate a discovery process for a particular objective option.
The discovery initiator sends all Discovery messages via UDP to port GRASP_LISTEN_PORT at the link-local ALL_GRASP_NEIGHBORS multicast address on each link-layer interface in use by GRASP. It then listens for unicast TCP responses on a given port and stores the discovery results, including responding discovery objectives and corresponding unicast locators.
The listening port used for TCP MUST be the same port as used for sending the Discovery UDP multicast, on a given interface. In an implementation with a single GRASP instance in a node, this MAY be GRASP_LISTEN_PORT. To support multiple instances in the same node, the GRASP discovery mechanism in each instance needs to find, for each interface, a dynamic port that it can bind to for both sending UDP link-local multicast and listening for TCP before initiating any discovery.
The 'initiator' field in the message is a globally unique IP address of the initiator for the sole purpose of disambiguating the Session ID in other nodes. If for some reason the initiator does not have a globally unique IP address, it MUST use a link-local address that is highly likely to be unique for this purpose, for example, using [RFC7217]. Determination of a node's globally unique IP address is implementation dependent.
A Discovery message MUST include exactly one of the following:
- A Discovery Objective option (Section 2.10.1). Its loop count MUST be set to a suitable value to prevent discovery loops (default value is GRASP_DEF_LOOPCT). If the discovery initiator requires only on-link responses, the loop count MUST be set to 1.
- A Negotiation Objective option (Section 2.10.1). This is used both for the purpose of discovery and to indicate to the discovery target that it MAY directly reply to the discovery initiator with a Negotiation message for rapid processing, if it could act as the corresponding negotiation counterpart. The sender of such a Discovery message MUST initialize a negotiation timer and loop count in the same way as a Request Negotiation message (Section 2.8.6).
- A Synchronization Objective option (Section 2.10.1). This is used both for the purpose of discovery and to indicate to the discovery target that it MAY directly reply to the discovery initiator with a Synchronization message for rapid processing, if it could act as the corresponding synchronization counterpart. Its loop count MUST be set to a suitable value to prevent discovery loops (default value is GRASP_DEF_LOOPCT).
As mentioned in Section 2.5.4.2, a Discovery message MAY be sent unicast to a peer node, which SHOULD then proceed exactly as if the message had been multicast.
2.8.5. Discovery Response Message
In fragmentary CDDL, a Discovery Response message follows the pattern:
response-message = [M_RESPONSE, session-id, initiator, ttl, (+locator-option // divert-option), ?objective]
ttl = 0..4294967295 ; in milliseconds
A node that receives a Discovery message SHOULD send a Discovery Response message if and only if it can respond to the discovery.
It MUST contain the same Session ID and initiator as the Discovery message.
It MUST contain a time-to-live (ttl) for the validity of the response, given as a positive integer value in milliseconds. Zero implies a value significantly greater than GRASP_DEF_TIMEOUT milliseconds (Section 2.6). A suggested value is ten times that amount.
It MAY include a copy of the discovery objective from the Discovery message.
It is sent to the sender of the Discovery message via TCP at the port used to send the Discovery message (as explained in Section 2.8.4). In the case of a relayed Discovery message, the Discovery Response is thus sent to the relay, not the original initiator.
In all cases, the transport session SHOULD be closed after sending the Discovery Response. A transport session failure is treated as no response.
If the responding node supports the discovery objective of the discovery, it MUST include at least one kind of locator option (Section 2.9.5) to indicate its own location. A sequence of multiple kinds of locator options (e.g., IP address option and FQDN option) is also valid.
If the responding node itself does not support the discovery objective, but it knows the locator of the discovery objective, then it SHOULD respond to the Discovery message with a Divert option (Section 2.9.2) embedding a locator option or a combination of multiple kinds of locator options that indicate the locator(s) of the discovery objective.
More details on the processing of Discovery Responses are given in Section 2.5.4.
2.8.6. Request Messages
In fragmentary CDDL, Request Negotiation and Request Synchronization messages follow the patterns:
request-negotiation-message = [M_REQ_NEG, session-id, objective]
request-synchronization-message = [M_REQ_SYN, session-id, objective]
A negotiation or synchronization requesting node sends the appropriate Request message to the unicast address of the negotiation or synchronization counterpart, using the appropriate protocol and port numbers (selected from the discovery result). If the discovery result is an FQDN, it will be resolved first.
A Request message MUST include the relevant objective option. In the case of Request Negotiation, the objective option MUST include the requested value.
When an initiator sends a Request Negotiation message, it MUST initialize a negotiation timer for the new negotiation thread. The default is GRASP_DEF_TIMEOUT milliseconds. Unless this timeout is modified by a Confirm Waiting message (Section 2.8.9), the initiator will consider that the negotiation has failed when the timer expires.
Similarly, when an initiator sends a Request Synchronization, it SHOULD initialize a synchronization timer. The default is GRASP_DEF_TIMEOUT milliseconds. The initiator will consider that synchronization has failed if there is no response before the timer expires.
When an initiator sends a Request message, it MUST initialize the loop count of the objective option with a value defined in the specification of the option or, if no such value is specified, with GRASP_DEF_LOOPCT.
If a node receives a Request message for an objective for which no ASA is currently listening, it MUST immediately close the relevant socket to indicate this to the initiator. This is to avoid unnecessary timeouts if, for example, an ASA exits prematurely but the GRASP core is listening on its behalf.
To avoid the highly unlikely race condition in which two nodes simultaneously request sessions with each other using the same Session ID (Section 2.7), a node MUST verify that the received Session ID is not already locally active when it receives a Request message. In case of a clash, it MUST discard the Request message, in which case the initiator will detect a timeout.
2.8.7. Negotiation Message
In fragmentary CDDL, a Negotiation message follows the pattern:
negotiation-message = [M_NEGOTIATE, session-id, objective]
A negotiation counterpart sends a Negotiation message in response to a Request Negotiation message, a Negotiation message, or a Discovery message in rapid mode. A negotiation process MAY include multiple steps.
The Negotiation message MUST include the relevant Negotiation Objective option, with its value updated according to progress in the negotiation. The sender MUST decrement the loop count by 1. If the loop count becomes zero, the message MUST NOT be sent. In this case, the negotiation session has failed and will time out.
2.8.8. Negotiation End Message
In fragmentary CDDL, a Negotiation End message follows the pattern:
end-message = [M_END, session-id, accept-option / decline-option]
A negotiation counterpart sends a Negotiation End message to close the negotiation. It MUST contain either an Accept option or a Decline option, defined in Section 2.9.3 and Section 2.9.4. It could be sent either by the requesting node or the responding node.
2.8.9. Confirm Waiting Message ๐ซถ
okay so, the Confirm Waiting message is basically a "hold on, bestie, I'm still working on it" text ๐ In fragmentary CDDL it looks like this:
wait-message = [M_WAIT, session-id, waiting-time]
waiting-time = 0..4294967295 ; in milliseconds
A responding node sends one to ask the requesting node to keep waiting for a further negotiation response โณ Maybe the local process needs more time, or the negotiation is waiting on some other negotiation it triggered. Either way, this message MUST NOT include any other options. ๐ โโ๏ธ When it's received, the waiting time value overwrites and restarts the current negotiation timer (Section 2.8.6). So it's like hitting refresh on the timer โจ
The responding node SHOULD send a Negotiation, Negotiation End, or another Confirm Waiting message before the negotiation timer expires ๐ If it doesn't, then once the initiator's timer runs out, the initiator MUST treat the negotiation procedure as failed. ๐ No drama, just the rules being the rules.
2.8.10. Synchronization Message ๐ธ
The Synchronization message format in fragmentary CDDL:
synch-message = [M_SYNCH, session-id, objective]
When a node gets a Request Synchronization, or a Discovery message in rapid mode, it sends back a unicast Synchronization message ๐ฆ That reply carries the synchronization data as a GRASP option for the specific synchronization objective that was asked for in the Request Synchronization. It's giving "here's exactly what you asked for, bestie" ๐
2.8.11. Flood Synchronization Message ๐
In fragmentary CDDL, a Flood Synchronization message looks like this:
flood-message = [M_FLOOD, session-id, initiator, ttl,
+[objective, (locator-option / [])]]
ttl = 0..4294967295 ; in milliseconds
A node MAY start flooding by sending an unsolicited Flood Synchronization message carrying synchronization data ๐ฃ It MAY be sent to port GRASP_LISTEN_PORT at the link-local ALL_GRASP_NEIGHBORS multicast address, following the rules in Section 2.5.6. Basically it's a group shoutout to everyone nearby ๐ง
The initiator address is included, the same way it is for Discovery messages (Section 2.8.4), but only to tell Session IDs apart. It's not there for any other reason ๐
The message MUST contain a time-to-live (ttl) for how long the contents are valid, given as a positive integer in milliseconds. There's no default here. A zero means the lifetime is indefinite โพ๏ธ
The synchronization data comes as GRASP option(s) for specific synchronization objective(s). The loop count(s) MUST be set to a suitable value so the flood doesn't loop forever ๐ If you don't pick one, the default value is GRASP_DEF_LOOPCT.
Each objective option MAY be followed by a locator option (Section 2.9.5) tied to the flooded objective. If there's no locator option, an empty option MUST be included to say "this is a null locator" ๐ซง
A node that receives a Flood Synchronization message MUST cache the received objectives so that local ASAs can use them ๐พ Each cached objective MUST be tagged with the locator option that came with it, or with a null tag if an empty locator option was sent. If a later Flood Synchronization message has an objective with the same name and the same tag, the cached copy MUST be overwritten ๐ But if a later message has an objective with the same name and a different tag, a new cached entry MUST be created. Two senders, two entries, no mix-ups ๐
Note: the whole point of this mechanism is so the recipient can tell apart different senders of the same objective. If needed, it can use the locator, protocol, and port in the locator option to talk back to them. Plenty of objectives won't need this, so they'll get flooded with a null locator. ๐
Cached entries MUST be ignored or deleted once their lifetime expires โฐ
2.8.12. Invalid Message ๐ซ
In fragmentary CDDL, an Invalid message looks like this:
invalid-message = [M_INVALID, session-id, ?any]
An implementation MAY send this in response to an incoming unicast message that it thinks is invalid ๐ โโ๏ธ The Session ID value MUST be copied from the incoming message. The content SHOULD be diagnostic information, like a partial copy of the invalid message up to the maximum message size ๐ A recipient MAY silently ignore an M_INVALID message. Still, it could be really useful for extensibility, since it tells the other node that it doesn't support a new or obsolete message or option ๐งฉ
An M_INVALID message MUST NOT be sent in response to an M_INVALID message. No infinite ping-pong, please and thank you ๐
2.8.13. No Operation Message ๐ด
In fragmentary CDDL, a No Operation message looks like this:
noop-message = [M_NOOP]
An implementation MAY send this one when, for practical reasons, it needs to initialize a socket ๐ A recipient MUST silently ignore it. It's basically the "just vibing" message ๐
2.9. GRASP Options ๐
This section defines the GRASP options used for negotiation and synchronization protocol signaling. More options may be defined in the future, so stay tuned โจ
2.9.1. Format of GRASP Options ๐ง
GRASP options SHOULD be CBOR arrays, and they MUST start with an unsigned integer that identifies the specific option type carried in the option. These option types are formally defined in Section 4 ๐
GRASP options may be defined to include encapsulated GRASP options too, so nesting is possible ๐ช
2.9.2. Divert Option ๐
The Divert option is used to redirect a GRASP request to another node that might be a better fit for the intended negotiation or synchronization ๐งญ It can redirect to an entity known as a specific negotiation or synchronization counterpart (on-link or off-link), or to a default gateway.
The Divert option MUST only be encapsulated in Discovery Response messages. If it shows up anywhere else, it SHOULD be silently ignored ๐
A discovery initiator MAY ignore a Divert option if it only needs direct Discovery Responses. No pressure, you're allowed to skip it ๐ซถ
In fragmentary CDDL, the Divert option looks like this:
divert-option = [O_DIVERT, +locator-option]
The embedded locator option(s) (Section 2.9.5) point to the diverted destination target(s) in response to a Discovery message ๐
2.9.3. Accept Option โ
The Accept option is how you tell the negotiation counterpart, "yep, the proposed negotiation content is accepted" ๐
The Accept option MUST only be encapsulated in Negotiation End messages. If it's found anywhere else, it SHOULD be silently ignored.
In fragmentary CDDL, the Accept option looks like this:
accept-option = [O_ACCEPT]
2.9.4. Decline Option โ
The Decline option is the opposite energy ๐ It tells the negotiation counterpart that the proposed negotiation content is declined, and that the negotiation process is over.
The Decline option MUST only be encapsulated in Negotiation End messages. If it's found elsewhere, it SHOULD be silently ignored.
In fragmentary CDDL, the Decline option looks like this:
decline-option = [O_DECLINE, ?reason]
reason = text ; optional UTF-8 error message
Note: sometimes an ASA wants to turn down the proposed value and start the negotiation over. In that case, it's up to the implementation whether to send a Decline option or to keep going with a Negotiation message. That Negotiation message can carry an objective option with a null value, or one with a new value that might get everyone to converge ๐
2.9.5. Locator Options ๐ก
Locator options present reachability information for an ASA, a device, or an interface ๐บ๏ธ There are four of them: Locator IPv6 Address option, Locator IPv4 Address option, Locator FQDN option, and Locator URI option.
ASAs usually run as independent user programs, so locator options need to say which network-layer locator to use, plus the transport protocol and port number for reaching the target. That's why the IP address and FQDN locator options include this info explicitly. With the Locator URI option, that info can be encoded inside the URI itself ๐
Note: all locators used in locator options are assumed to be in scope throughout the GRASP domain. As Section 2.2 says, GRASP is not meant to work across disjoint addressing or naming realms ๐ โโ๏ธ
2.9.5.1. Locator IPv6 Address Option ๐
In fragmentary CDDL, the Locator IPv6 Address option looks like this:
ipv6-locator-option = [O_IPv6_LOCATOR, ipv6-address,
transport-proto, port-number]
ipv6-address = bytes .size 16
transport-proto = IPPROTO_TCP / IPPROTO_UDP
IPPROTO_TCP = 6
IPPROTO_UDP = 17
port-number = 0..65535
The content is a binary IPv6 address, then the protocol number and port number to use ๐
Note 1: the IPv6 address MUST normally have global scope. However, during initialization, a link-local address MAY be used, but only for specific objectives (Section 2.5.2). In that case, the matching Discovery Response message MUST be sent via the interface the link-local address applies to ๐
Note 2: a link-local IPv6 address MUST NOT be used when this option is included in a Divert option. Absolutely not, don't do it ๐ โโ๏ธ
Note 3: the IPPROTO values come from the existing IANA Protocol Numbers registry, so they can specify TCP or UDP. If GRASP ever needs values that aren't in that registry, a new registry for values outside the range 0..255 will be needed ๐
2.9.5.2. Locator IPv4 Address Option ๐ท
In fragmentary CDDL, the Locator IPv4 Address option looks like this:
ipv4-locator-option = [O_IPv4_LOCATOR, ipv4-address,
transport-proto, port-number]
ipv4-address = bytes .size 4
The content is a binary IPv4 address, then the protocol number and port number to use ๐
Note: if an operator has internal network address translation for IPv4, this option MUST NOT be used within the Divert option. NAT plus Divert is a no-go ๐
2.9.5.3. Locator FQDN Option ๐ค
In fragmentary CDDL, the Locator FQDN option looks like this:
fqdn-locator-option = [O_FQDN_LOCATOR, text,
transport-proto, port-number]
The content is the FQDN of the target, then the protocol number and port number to use ๐
Note 1: any FQDN that might not be valid throughout the network in question, such as a Multicast DNS name [RFC6762], MUST NOT be used when this option is used within the Divert option. Local-only names are not invited to this party ๐ซ
Note 2: normal GRASP operations aren't expected to use this option. It's meant for special purposes, like discovering external services ๐
2.9.5.4. Locator URI Option ๐
In fragmentary CDDL, the Locator URI option looks like this:
uri-locator-option = [O_URI_LOCATOR, text,
transport-proto / null, port-number / null]
The content is the URI of the target, then the protocol number and port number to use. If those aren't required, you can use null values instead [RFC3986] ๐ฆ
Note 1: any URI that might not be valid throughout the network in question, such as one based on a Multicast DNS name [RFC6762], MUST NOT be used when this option is used within the Divert option. Same rule as before, bestie ๐
Note 2: normal GRASP operations aren't expected to use this option. It's meant for special purposes, like discovering external services. Because of that, its use is not further described in this specification ๐
2.10. Objective Options โจ
2.10.1. Format of Objective Options โจ
okay so bestie, this is where objectives get their shape ๐ every objective MUST follow this format, written in fragmentary CDDL:
objective = [objective-name, objective-flags,
loop-count, ?objective-value]
objective-name = text
objective-value = any
loop-count = 0..255
objective names are UTF-8 strings [RFC3629], and GRASP compares them byte by byte ๐ no vibes-based matching here, it's giving strict. ๐ธ
generic objective names MUST NOT include a colon (":") and MUST be registered with IANA (Section 5) ๐ฆ but privately defined ones MUST include at least one colon (":"). the stuff before the last colon MUST be globally unique and somehow identify whoever made the objective ๐ฅ there are three methods that MAY be used to make that unique string:
- a decimal number for a registered 32-bit Private Enterprise Number (PEN) [RFC5612] that uniquely identifies the enterprise defining the objective ๐ขโจ
- a FQDN that uniquely identifies the entity or person defining the objective ๐๐
- an email address that uniquely identifies the entity or person defining the objective ๐ง๐
GRASP treats the name as an opaque string, so "EX1", "32473:EX1", "example.com:EX1", "example.org:EX1", and "user@example.org:EX1" are five totally different objectives ๐ no cap, they're all separate bffs.
the 'objective-flags' field gets its own section (2.10.2) ๐ง the 'loop-count' field is used for ending negotiation (Section 2.8.7), ending discovery (Section 2.5.4), and ending flooding (Section 2.5.6.2) ๐ it lives in the objective instead of the GRASP message format because, from the ASA's point of view, it's a property of the objective itself. iconic. ๐
the 'objective-value' field carries the actual value of a negotiation or synchronization objective ๐ its format is defined in the objective's spec and can be a simple value or any kind of data structure, as long as it can be represented in CBOR ๐ it is optional only in a Discovery or Discovery Response message. โจ
2.10.2. Objective Flags โจ
an objective might be relevant for discovery only, for discovery and negotiation, or for discovery and synchronization ๐ that's expressed with logical flag bits:
objective-flags = uint .bits objective-flag
objective-flag = &(
F_DISC: 0 ; valid for discovery
F_NEG: 1 ; valid for negotiation
F_SYNCH: 2 ; valid for synchronization
F_NEG_DRY: 3 ; negotiation is a dry run
)
the bits are independent and can be combined, e.g., (F_DISC and F_SYNCH) or (F_DISC and F_NEG) or (F_DISC and F_NEG and F_NEG_DRY) ๐ซถ
one thing to remember: in a given negotiation session, an objective MUST be used either for negotiation or for dry-run negotiation ๐ โโ๏ธ mixing the two modes in one negotiation is not possible. no mixing, periodt. ๐
2.10.3. General Considerations for Objective Options โจ
ok so, objective options MUST be assigned a unique name ๐ as long as privately defined objective options follow the rules above, this document doesn't restrict their choice of name, but the entity or person concerned SHOULD publish the names in use. ๐ฃ
names are expressed as UTF-8 strings so localized designs are easy ๐ธ for generic usage, names in the ASCII subset of UTF-8 are RECOMMENDED. if you're planning non-ASCII names, you're strongly advised to check out [RFC8264] or its successor to understand the complexities ๐ง since GRASP compares names byte by byte, all issues of Unicode profiling and canonicalization MUST be specified in the design of the objective option. ๐ฅ
all objective options MUST respect the CBOR patterns defined above as "objective" and MUST replace the 'any' field with a valid CBOR data definition for the relevant use case and application. ๐
an objective option with no fields beyond its 'loop-count' can only be a discovery objective and MUST only be used in Discovery and Discovery Response messages. ๐ฆ
the Negotiation Objective options contain negotiation objectives, which vary by function and/or service ๐ง they MUST be carried by Discovery, Request Negotiation, or Negotiation messages only. the negotiation initiator MUST set the initial 'loop-count' to a value specified in the objective's spec or, if none is specified, to GRASP_DEF_LOOPCT. ๐
for most scenarios there should be initial values in negotiation requests, so the Negotiation Objective options MUST always be completely presented in a Request Negotiation message, or in a Discovery message in rapid mode. ๐ if there's no initial value, the 'value' field SHOULD be set to the 'null' value defined by CBOR. ๐
Synchronization Objective options are similar, but MUST be carried by Discovery, Discovery Response, Request Synchronization, or Flood Synchronization messages only โจ they include 'value' fields only in Synchronization or Flood Synchronization messages. ๐
the design of an objective interacts with the design of the ASAs that use it ๐ ASA design considerations are discussed in [ASA-GUIDELINES]. ๐ซถ
2.10.4. Organizing of Objective Options โจ
generic objective options MUST be specified in documents available to the public and SHOULD be designed to use either the negotiation or the synchronization mechanism described above. ๐ฃ
as noted earlier, each GRASP negotiation thread handles one negotiation objective ๐งต so a negotiation objective based on a specific function or action SHOULD be organized as a single GRASP option. it is NOT RECOMMENDED to bundle multiple negotiation objectives into one option, nor to split a single function or action into multiple negotiation objectives. ๐ โโ๏ธ
important: GRASP negotiation does NOT support transactional integrity ๐ญ if an objective needs it, the ASA has to make sure of that. for example, an ASA might need to ensure it only takes part in one negotiation thread at a time. such an ASA would need to stop listening for incoming negotiation requests before sending an outgoing negotiation request. ๐ฅ
a synchronization objective SHOULD be organized as a single GRASP option. ๐ธ
some objectives support more than one operational mode ๐ฆ for example, a negotiation objective with both a dry-run mode (where the negotiation checks whether the other end can actually make the requested change without problems) and a live mode, as explained in Section 2.5.5. the semantics of those modes are defined in the objectives' specs, and these objectives SHOULD include flags indicating the applicable mode(s). ๐ง
big one: GRASP itself is NOT a transactionally safe protocol ๐จ any state tied to a dry-run, like temporarily reserving a resource for a later live run, is entirely up to the ASA designer. ๐
as indicated in Section 2.1, an objective's value may include multiple parameters ๐ these can be sorted into two classes: the obligatory ones, presented as fixed fields, and the optional ones, presented in some other structure embedded in CBOR. the format might be inherited from an existing management or configuration protocol, with the objective option just acting as a carrier ๐ the data structure might be defined in a formal language, but that's up to each objective's spec. candidates include ABNF, RBNF, XML Schema, YANG, and so on ๐ GRASP itself doesn't care about any of that. the only restriction is that the format can be mapped into CBOR. โจ
it is NOT RECOMMENDED to mix parameters with significantly different response-time characteristics in a single objective ๐ โโ๏ธ separate objectives are more suitable for that. ๐
all objectives MUST support GRASP discovery. however, as mentioned in Section 2.3, it's acceptable for an ASA to use an alternative discovery method. ๐ซถ
normally a GRASP objective refers to specific technical parameters, as explained in Section 2.1 ๐ but it's acceptable to define an abstract objective for managing or coordinating ASAs ๐ and it's also acceptable to define a special-purpose objective for things like trust bootstrapping or forming the ACP. ๐
to guarantee convergence, each negotiation objective needs a limited number of rounds or a timeout ๐ฐ๏ธ so the definition of each negotiation objective SHOULD clearly specify this, for example a default loop count and timeout, so negotiation can always end properly. if it doesn't, the GRASP defaults apply. ๐
there MUST be a well-defined procedure for concluding that a negotiation cannot succeed, and for deciding what happens next (e.g., deadlock resolution, tie-breaking, or reverting to best-effort service) ๐ฅบ this MUST be specified for individual negotiation objectives. ๐
2.10.5. Experimental and Example Objective Options โจ
the names "EX0" through "EX9" are reserved for experimental options ๐งช multiple names are assigned because one experiment might use several options at once. these experimental options are highly likely to mean different things in different experiments ๐ so they SHOULD NOT be used without an explicit human decision, and they MUST NOT be used in unmanaged networks such as home networks. ๐ ๐ซ
these names are also RECOMMENDED for use in documentation examples. ๐ง
3. Security Considerations ๐จ
okay bestie, this is the scary part ๐ญ if an attacker successfully messes with a negotiation-enabled node, that node could end up with a totally undesirable config, and that would also mess up its peers. so GRASP nodes and messages need full protection, no cap. As Section 2.5.1 explains, GRASP MUST run within a secure environment such as the ACP [RFC8994], except for the constrained instances described in Section 2.5.2 ๐
Authentication
every device in an Autonomic Network needs a cryptographically authenticated identity ๐ชช it's not safe to assume a big network is physically locked down or that every person with access is trustworthy ๐ Each autonomic node MUST be capable of proving its identity and authenticating its messages. GRASP leans on a separate, external certificate-based security mechanism for authentication, data integrity protection, and anti-replay protection ๐ฆ
since GRASP has to be deployed inside an existing secure environment, the protocol itself says nothing about the trust anchor and certification authority. That's not a gap, it's the design ๐ For example, in the ACP [RFC8994], all nodes can trust each other and the ASAs installed in them ๐ค
if GRASP gets used temporarily without an external security mechanism, like during system bootstrap (Section 2.5.1), the Session ID (Section 2.7) acts as a nonce. That gives limited protection against third parties injecting responses ๐ A full analysis of the secure bootstrap process is in [RFC8995] ๐
Authorization and roles
GRASP doesn't care about the roles and capabilities of individual ASAs, or about which objectives a particular ASA is allowed to support ๐คทโโ๏ธ An implementation might add precautions, like only letting one ASA on a given node modify a given objective, but that might not be right in every case ๐ธ For example, it could be operationally useful to let an old and a new version of the same ASA run at the same time during an overlap period ๐ These questions are out of scope for the present specification โจ
Privacy and confidentiality
GRASP is meant for network-management stuff involving network elements, not end hosts ๐ฅ๏ธ So no personal information is expected in the signaling protocol, and there should be no direct impact on personal privacy ๐ That said, applications that do carry personal information can't be ruled out ๐ Also, traffic flow paths, VPNs, and so on could get negotiated, and that could be super interesting for traffic analysis ๐ต๏ธโโ๏ธ Operators generally want to hide their network topology and traffic density from outsiders ๐ Since insider attacks can't be excluded in a large network, the security mechanism for the protocol MUST provide message confidentiality. That's why Section 2.5.1 requires either an ACP or an alternative security mechanism ๐
Link-local multicast security
GRASP has no real alternative to link-local multicast for Discovery or Flood Synchronization messages, and these messages go out in the clear with no authentication ๐ฌ They're only sent on interfaces inside the Autonomic Network (see Section 2.1 and Section 2.5.1). Still, on-link eavesdroppers can see them and on-link attackers can forge them ๐ป For discovery, the Discovery Responses are unicast and therefore protected (Section 2.5.1), so an untrusted forger won't be able to receive them ๐ For flood synchronization, an on-link eavesdropper can receive the flooded objectives, but there's no response message to worry about ๐ซฃ Some precautions for Flood Synchronization messages are suggested in Section 2.5.6.2 ๐ก
DoS attack protection
GRASP discovery partly relies on insecure link-local multicast ๐ค Routers taking part in GRASP sometimes relay Discovery messages from one link to another, and that could become a vector for denial-of-service attacks ๐ Some mitigations are specified in Section 2.5.4. However, malicious code installed inside the ACP could always launch DoS attacks using spurious Discovery messages or spurious Discovery Responses ๐ญ It's important that firewalls stop any GRASP messages from entering the domain from an unknown source ๐งฑ
Security during bootstrap and discovery
a node can't trust GRASP traffic from other nodes until the security environment (such as the ACP) has identified the trust anchor and can authenticate traffic by validating certificates for other nodes ๐ช Also, until it has successfully enrolled [RFC8995], a node can't assume other nodes are able to authenticate its own traffic ๐ซ So GRASP discovery during the bootstrap phase for a new device will inevitably be insecure ๐ฉ Secure synchronization and negotiation will be impossible until enrollment is complete. More details are in Section 2.5.2 ๐
Security of discovered locators
when GRASP discovery returns an IP address, it MUST be that of a node within the secure environment (Section 2.5.1). If it returns an FQDN or a URI, the ASA that receives it MUST NOT assume that the target of the locator is within the secure environment. Don't trust it just because it showed up ๐ซโจ
4. CDDL Specification of GRASP ๐
here's the CDDL, copied exactly so nothing gets lost in translation ๐
<CODE BEGINS> file "grasp.cddl"
grasp-message = (message .within message-structure) / noop-message
message-structure = [MESSAGE_TYPE, session-id, ?initiator,
*grasp-option]
MESSAGE_TYPE = 0..255
session-id = 0..4294967295 ; up to 32 bits
grasp-option = any
message /= discovery-message
discovery-message = [M_DISCOVERY, session-id, initiator, objective]
message /= response-message ; response to Discovery
response-message = [M_RESPONSE, session-id, initiator, ttl,
(+locator-option // divert-option), ?objective]
message /= synch-message ; response to Synchronization request
synch-message = [M_SYNCH, session-id, objective]
message /= flood-message
flood-message = [M_FLOOD, session-id, initiator, ttl,
+[objective, (locator-option / [])]]
message /= request-negotiation-message
request-negotiation-message = [M_REQ_NEG, session-id, objective]
message /= request-synchronization-message
request-synchronization-message = [M_REQ_SYN, session-id, objective]
message /= negotiation-message
negotiation-message = [M_NEGOTIATE, session-id, objective]
message /= end-message
end-message = [M_END, session-id, accept-option / decline-option]
message /= wait-message
wait-message = [M_WAIT, session-id, waiting-time]
message /= invalid-message
invalid-message = [M_INVALID, session-id, ?any]
noop-message = [M_NOOP]
divert-option = [O_DIVERT, +locator-option]
accept-option = [O_ACCEPT]
decline-option = [O_DECLINE, ?reason]
reason = text ; optional UTF-8 error message
waiting-time = 0..4294967295 ; in milliseconds
ttl = 0..4294967295 ; in milliseconds
locator-option /= [O_IPv4_LOCATOR, ipv4-address,
transport-proto, port-number]
ipv4-address = bytes .size 4
locator-option /= [O_IPv6_LOCATOR, ipv6-address,
transport-proto, port-number]
ipv6-address = bytes .size 16
locator-option /= [O_FQDN_LOCATOR, text, transport-proto,
port-number]
locator-option /= [O_URI_LOCATOR, text,
transport-proto / null, port-number / null]
transport-proto = IPPROTO_TCP / IPPROTO_UDP
IPPROTO_TCP = 6
IPPROTO_UDP = 17
port-number = 0..65535
initiator = ipv4-address / ipv6-address
objective-flags = uint .bits objective-flag
objective-flag = &(
F_DISC: 0 ; valid for discovery
F_NEG: 1 ; valid for negotiation
F_SYNCH: 2 ; valid for synchronization
F_NEG_DRY: 3 ; negotiation is a dry run
)
objective = [objective-name, objective-flags,
loop-count, ?objective-value]
objective-name = text ; see section "Format of Objective Options"
objective-value = any
loop-count = 0..255
; Constants for message types and option types
M_NOOP = 0
M_DISCOVERY = 1
M_RESPONSE = 2
M_REQ_NEG = 3
M_REQ_SYN = 4
M_NEGOTIATE = 5
M_END = 6
M_WAIT = 7
M_SYNCH = 8
M_FLOOD = 9
M_INVALID = 99
O_DIVERT = 100
O_ACCEPT = 101
O_DECLINE = 102
O_IPv6_LOCATOR = 103
O_IPv4_LOCATOR = 104
O_FQDN_LOCATOR = 105
O_URI_LOCATOR = 106
<CODE ENDS>
5. IANA Considerations ๐
okay so IANA is basically the official record-keeper of the internet, and this section tells them exactly what to write down for GRASP ๐ it's a lot of numbers but they're giving main character energy ๐ฆ
Section 2.6 explains the link-local multicast addresses that IANA assigned for GRASP to use. In the "Link-Local Scope Multicast Addresses" subregistry of the "IPv6 Multicast Address Space Registry" ๐ธ
Address(es): ff02::13
Description: ALL_GRASP_NEIGHBORS
Reference: RFC 8990
and in the "Local Network Control Block (224.0.0.0 - 224.0.0.255 (224.0.0/24))" subregistry of the "IPv4 Multicast Address Space Registry" ๐ง
Address(es): 224.0.0.119
Description: ALL_GRASP_NEIGHBORS
Reference: RFC 8990
Next up, Section 2.6 also explains the User Port (GRASP_LISTEN_PORT). IANA assigned it to GRASP for both UDP and TCP โจ
Service Name: grasp
Port Number: 7017
Transport Protocol: udp, tcp
Description GeneRic Autonomic Signaling Protocol
Assignee: IESG <iesg@ietf.org>
Contact: IETF Chair <chair@ietf.org>
Reference: RFC 8990
So IANA has created the "GeneRic Autonomic Signaling Protocol (GRASP) Parameters" registry ๐ It has two subregistries: "GRASP Messages and Options" and "GRASP Objective Names".
The "GRASP Messages and Options" subregistry is a list of names, each paired with a decimal integer ๐ Future values MUST be assigned using the Standards Action policy defined by [RFC8126]. Here are the initial values this document assigns:
+=======+================+
| Value | Message/Option |
+=======+================+
| 0 | M_NOOP |
+-------+----------------+
| 1 | M_DISCOVERY |
+-------+----------------+
| 2 | M_RESPONSE |
+-------+----------------+
| 3 | M_REQ_NEG |
+-------+----------------+
| 4 | M_REQ_SYN |
+-------+----------------+
| 5 | M_NEGOTIATE |
+-------+----------------+
| 6 | M_END |
+-------+----------------+
| 7 | M_WAIT |
+-------+----------------+
| 8 | M_SYNCH |
+-------+----------------+
| 9 | M_FLOOD |
+-------+----------------+
| 99 | M_INVALID |
+-------+----------------+
| 100 | O_DIVERT |
+-------+----------------+
| 101 | O_ACCEPT |
+-------+----------------+
| 102 | O_DECLINE |
+-------+----------------+
| 103 | O_IPv6_LOCATOR |
+-------+----------------+
| 104 | O_IPv4_LOCATOR |
+-------+----------------+
| 105 | O_FQDN_LOCATOR |
+-------+----------------+
| 106 | O_URI_LOCATOR |
+-------+----------------+
Table 1: Initial
Values of the "GRASP
Messages and Options"
Subregistry
Now the "GRASP Objective Names" subregistry ๐ฆ Its values are UTF-8 strings, and they MUST NOT include a colon (":"), per Section 2.10.1. Future values MUST be assigned using the Specification Required policy defined by [RFC8126].
For expert review of a new objective, the specification should include a precise description of the objective's format, plus enough explanation of its semantics to let independent implementations get it right ๐ซถ See Section 2.10.3 for more details. And if the new objective is similar in name or purpose to one that's already registered, the specification should explain why a new objective is justified ๐
The initial objective names this document assigns are below โจ
+================+===========+
| Objective Name | Reference |
+================+===========+
| EX0 | RFC 8990 |
+----------------+-----------+
| EX1 | RFC 8990 |
+----------------+-----------+
| EX2 | RFC 8990 |
+----------------+-----------+
| EX3 | RFC 8990 |
+----------------+-----------+
| EX4 | RFC 8990 |
+----------------+-----------+
| EX5 | RFC 8990 |
+----------------+-----------+
| EX6 | RFC 8990 |
+----------------+-----------+
| EX7 | RFC 8990 |
+----------------+-----------+
| EX8 | RFC 8990 |
+----------------+-----------+
| EX9 | RFC 8990 |
+----------------+-----------+
Table 2: Initial Values of
the "GRASP Objective
Names" Subregistry
6. References ๐
6.1. Normative References
These are the references ๐ they're the stuff you absolutely need to know to read this spec properly ๐
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO
10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November
2003, <https://www.rfc-editor.org/info/rfc3629>.
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
Resource Identifier (URI): Generic Syntax", STD 66,
RFC 3986, DOI 10.17487/RFC3986, January 2005,
<https://www.rfc-editor.org/info/rfc3986>.
[RFC4086] Eastlake 3rd, D., Schiller, J., and S. Crocker,
"Randomness Requirements for Security", BCP 106, RFC 4086,
DOI 10.17487/RFC4086, June 2005,
<https://www.rfc-editor.org/info/rfc4086>.
[RFC7217] Gont, F., "A Method for Generating Semantically Opaque
Interface Identifiers with IPv6 Stateless Address
Autoconfiguration (SLAAC)", RFC 7217,
DOI 10.17487/RFC7217, April 2014,
<https://www.rfc-editor.org/info/rfc7217>.
[RFC8085] Eggert, L., Fairhurst, G., and G. Shepherd, "UDP Usage
Guidelines", BCP 145, RFC 8085, DOI 10.17487/RFC8085,
March 2017, <https://www.rfc-editor.org/info/rfc8085>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8610] Birkholz, H., Vigano, C., and C. Bormann, "Concise Data
Definition Language (CDDL): A Notational Convention to
Express Concise Binary Object Representation (CBOR) and
JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610,
June 2019, <https://www.rfc-editor.org/info/rfc8610>.
[RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object
Representation (CBOR)", STD 94, RFC 8949,
DOI 10.17487/RFC8949, December 2020,
<https://www.rfc-editor.org/info/rfc8949>.
[RFC8994] Eckert, T., Ed., Behringer, M., Ed., and S. Bjarnason, "An
Autonomic Control Plane (ACP)", RFC 8994,
DOI 10.17487/RFC8994, May 2021,
<https://www.rfc-editor.org/info/rfc8994>.
6.2. Informative References ๐โจ
okay so these are the informative refs, meaning they're just background reading and not required to implement anything, bestie ๐ I'm listing every single one with its full details so nothing gets lost ๐ซถ
[ADNCP] Stenberg, M., "Autonomic Distributed Node Consensus Protocol", Work in Progress, Internet-Draft, draft-stenberg-anima-adncp-00, 5 March 2015, <https://tools.ietf.org/html/draft-stenberg-anima-adncp-00>.
[ASA-GUIDELINES] Carpenter, B., Ciavaglia, L., Jiang, S., and P. Peloso, "Guidelines for Autonomic Service Agents", Work in Progress, Internet-Draft, draft-ietf-anima-asa-guidelines-00, 14 November 2020, <https://tools.ietf.org/html/draft-ietf-anima-asa-guidelines-00>.
[IGCP] Behringer, M. H., Chaparadza, R., Xin, L., Mahkonen, H., and R. Petre, "IP based Generic Control Protocol (IGCP)", Work in Progress, Internet-Draft, draft-chaparadza-intarea-igcp-00, 25 July 2011, <https://tools.ietf.org/html/draft-chaparadza-intarea-igcp-00>.
[RFC2205] Braden, R., Ed., Zhang, L., Berson, S., Herzog, S., and S. Jamin, "Resource ReSerVation Protocol (RSVP) -- Version 1 Functional Specification", RFC 2205, DOI 10.17487/RFC2205, September 1997, <https://www.rfc-editor.org/info/rfc2205>.
[RFC2334] Luciani, J., Armitage, G., Halpern, J., and N. Doraswamy, "Server Cache Synchronization Protocol (SCSP)", RFC 2334, DOI 10.17487/RFC2334, April 1998, <https://www.rfc-editor.org/info/rfc2334>.
[RFC2608] Guttman, E., Perkins, C., Veizades, J., and M. Day, "Service Location Protocol, Version 2", RFC 2608, DOI 10.17487/RFC2608, June 1999, <https://www.rfc-editor.org/info/rfc2608>.
[RFC2865] Rigney, C., Willens, S., Rubens, A., and W. Simpson, "Remote Authentication Dial In User Service (RADIUS)", RFC 2865, DOI 10.17487/RFC2865, June 2000, <https://www.rfc-editor.org/info/rfc2865>.
[RFC3416] Presuhn, R., Ed., "Version 2 of the Protocol Operations for the Simple Network Management Protocol (SNMP)", STD 62, RFC 3416, DOI 10.17487/RFC3416, December 2002, <https://www.rfc-editor.org/info/rfc3416>.
[RFC3493] Gilligan, R., Thomson, S., Bound, J., McCann, J., and W. Stevens, "Basic Socket Interface Extensions for IPv6", RFC 3493, DOI 10.17487/RFC3493, February 2003, <https://www.rfc-editor.org/info/rfc3493>.
[RFC4861] Narten, T., Nordmark, E., Simpson, W., and H. Soliman, "Neighbor Discovery for IP version 6 (IPv6)", RFC 4861, DOI 10.17487/RFC4861, September 2007, <https://www.rfc-editor.org/info/rfc4861>.
[RFC5612] Eronen, P. and D. Harrington, "Enterprise Number for Documentation Use", RFC 5612, DOI 10.17487/RFC5612, August 2009, <https://www.rfc-editor.org/info/rfc5612>.
[RFC5971] Schulzrinne, H. and R. Hancock, "GIST: General Internet Signalling Transport", RFC 5971, DOI 10.17487/RFC5971, October 2010, <https://www.rfc-editor.org/info/rfc5971>.
[RFC6206] Levis, P., Clausen, T., Hui, J., Gnawali, O., and J. Ko, "The Trickle Algorithm", RFC 6206, DOI 10.17487/RFC6206, March 2011, <https://www.rfc-editor.org/info/rfc6206>.
[RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., "Network Configuration Protocol (NETCONF)", RFC 6241, DOI 10.17487/RFC6241, June 2011, <https://www.rfc-editor.org/info/rfc6241>.
[RFC6733] Fajardo, V., Ed., Arkko, J., Loughney, J., and G. Zorn, Ed., "Diameter Base Protocol", RFC 6733, DOI 10.17487/RFC6733, October 2012, <https://www.rfc-editor.org/info/rfc6733>.
[RFC6762] Cheshire, S. and M. Krochmal, "Multicast DNS", RFC 6762, DOI 10.17487/RFC6762, February 2013, <https://www.rfc-editor.org/info/rfc6762>.
[RFC6763] Cheshire, S. and M. Krochmal, "DNS-Based Service Discovery", RFC 6763, DOI 10.17487/RFC6763, February 2013, <https://www.rfc-editor.org/info/rfc6763>.
[RFC6887] Wing, D., Ed., Cheshire, S., Boucadair, M., Penno, R., and P. Selkirk, "Port Control Protocol (PCP)", RFC 6887, DOI 10.17487/RFC6887, April 2013, <https://www.rfc-editor.org/info/rfc6887>.
[RFC7558] Lynn, K., Cheshire, S., Blanchet, M., and D. Migault, "Requirements for Scalable DNS-Based Service Discovery (DNS-SD) / Multicast DNS (mDNS) Extensions", RFC 7558, DOI 10.17487/RFC7558, July 2015, <https://www.rfc-editor.org/info/rfc7558>.
[RFC7575] Behringer, M., Pritikin, M., Bjarnason, S., Clemm, A., Carpenter, B., Jiang, S., and L. Ciavaglia, "Autonomic Networking: Definitions and Design Goals", RFC 7575, DOI 10.17487/RFC7575, June 2015, <https://www.rfc-editor.org/info/rfc7575>.
[RFC7576] Jiang, S., Carpenter, B., and M. Behringer, "General Gap Analysis for Autonomic Networking", RFC 7576, DOI 10.17487/RFC7576, June 2015, <https://www.rfc-editor.org/info/rfc7576>.
[RFC7787] Stenberg, M. and S. Barth, "Distributed Node Consensus Protocol", RFC 7787, DOI 10.17487/RFC7787, April 2016, <https://www.rfc-editor.org/info/rfc7787>.
[RFC7788] Stenberg, M., Barth, S., and P. Pfister, "Home Networking Control Protocol", RFC 7788, DOI 10.17487/RFC7788, April 2016, <https://www.rfc-editor.org/info/rfc7788>.
[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, "RESTCONF Protocol", RFC 8040, DOI 10.17487/RFC8040, January 2017, <https://www.rfc-editor.org/info/rfc8040>.
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>.
[RFC8264] Saint-Andre, P. and M. Blanchet, "PRECIS Framework: Preparation, Enforcement, and Comparison of Internationalized Strings in Application Protocols", RFC 8264, DOI 10.17487/RFC8264, October 2017, <https://www.rfc-editor.org/info/rfc8264>.
[RFC8368] Eckert, T., Ed. and M. Behringer, "Using an Autonomic Control Plane for Stable Connectivity of Network Operations, Administration, and Maintenance (OAM)", RFC 8368, DOI 10.17487/RFC8368, May 2018, <https://www.rfc-editor.org/info/rfc8368>.
[RFC8415] Mrugalski, T., Siodelski, M., Volz, B., Yourtchenko, A., Richardson, M., Jiang, S., Lemon, T., and T. Winters, "Dynamic Host Configuration Protocol for IPv6 (DHCPv6)", RFC 8415, DOI 10.17487/RFC8415, November 2018, <https://www.rfc-editor.org/info/rfc8415>.
[RFC8991] Carpenter, B., Liu, B., Ed., Wang, W., and X. Gong, "GeneRic Autonomic Signaling Protocol Application Program Interface (GRASP API)", RFC 8991, DOI 10.17487/RFC8991, May 2021, <https://www.rfc-editor.org/info/rfc8991>.
[RFC8993] Behringer, M., Ed., Carpenter, B., Eckert, T., Ciavaglia, L., and J. Nobre, "A Reference Model for Autonomic Networking", RFC 8993, DOI 10.17487/RFC8993, May 2021, <https://www.rfc-editor.org/info/rfc8993>.
[RFC8995] Pritikin, M., Richardson, M., Eckert, T., Behringer, M., and K. Watsen, "Bootstrapping Remote Secure Key Infrastructure (BRSKI)", RFC 8995, DOI 10.17487/RFC8995, May 2021, <https://www.rfc-editor.org/info/rfc8995>.
Appendix A. Example Message Formats ๐ง๐
bestie, if CBOR is new to you, don't stress ๐ this appendix shows a bunch of example GRASP messages that follow the CDDL syntax from Section 4. Every message is shown three times, in these formats:
- CBOR diagnostic notation.
- Similar, but showing the names of the constants. (Details of the flag bit encoding are omitted.)
- Hexadecimal version of the CBOR wire format.
Long lines get split up, but only so they fit on the screen ๐ธ
A.1. Discovery Example ๐
The initiator (2001:db8:f000:baaa:28cc:dc4c:9703:6781) multicasts a Discovery message looking for objective EX1:
[1, 13948744, h'20010db8f000baaa28ccdc4c97036781', ["EX1", 5, 2, 0]]
[M_DISCOVERY, 13948744, h'20010db8f000baaa28ccdc4c97036781',
["EX1", F_SYNCH_bits, 2, 0]]
h'84011a00d4d7485020010db8f000baaa28ccdc4c970367818463455831050200'
A peer (2001:0db8:f000:baaa:f000:baaa:f000:baaa) responds with a locator:
[2, 13948744, h'20010db8f000baaa28ccdc4c97036781', 60000,
[103, h'20010db8f000baaaf000baaaf000baaa', 6, 49443]]
[M_RESPONSE, 13948744, h'20010db8f000baaa28ccdc4c97036781', 60000,
[O_IPv6_LOCATOR, h'20010db8f000baaaf000baaaf000baaa',
IPPROTO_TCP, 49443]]
h'85021a00d4d7485020010db8f000baaa28ccdc4c9703678119ea6084186750
20010db8f000baaaf000baaaf000baaa0619c123'
A.2. Flood Example ๐
The initiator multicasts a Flood Synchronization message. The single objective has a null locator. There is no response:
[9, 3504974, h'20010db8f000baaa28ccdc4c97036781', 10000,
[["EX1", 5, 2, ["Example 1 value=", 100]],[] ] ]
[M_FLOOD, 3504974, h'20010db8f000baaa28ccdc4c97036781', 10000,
[["EX1", F_SYNCH_bits, 2, ["Example 1 value=", 100]],[] ] ]
h'85091a00357b4e5020010db8f000baaa28ccdc4c97036781192710
828463455831050282704578616d706c6520312076616c75653d186480'
A.3. Synchronization Example ๐
Following successful discovery of objective EX2, the initiator unicasts a Request Synchronization message:
[4, 4038926, ["EX2", 5, 5, 0]]
[M_REQ_SYN, 4038926, ["EX2", F_SYNCH_bits, 5, 0]]
h'83041a003da10e8463455832050500'
The peer responds with a value:
[8, 4038926, ["EX2", 5, 5, ["Example 2 value=", 200]]]
[M_SYNCH, 4038926, ["EX2", F_SYNCH_bits, 5, ["Example 2 value=", 200]]]
h'83081a003da10e8463455832050582704578616d706c6520322076616c75653d18c8'
A.4. Simple Negotiation Example ๐ค
Following successful discovery of objective EX3, the initiator unicasts a Request Negotiation message:
[3, 802813, ["EX3", 3, 6, ["NZD", 47]]]
[M_REQ_NEG, 802813, ["EX3", F_NEG_bits, 6, ["NZD", 47]]]
h'83031a000c3ffd8463455833030682634e5a44182f'
The peer responds with immediate acceptance. Note that no objective is needed because the initiator's request was accepted without change:
[6, 802813, [101]]
[M_END , 802813, [O_ACCEPT]]
h'83061a000c3ffd811865'
A.5. Complete Negotiation Example
okay bestie, this is the full negotiation drama ๐ฟ The initiator kicks things off by unicasting a Request Negotiation message ๐จ (first move energy โจ)
[3, 13767778, ["EX3", 3, 6, ["NZD", 410]]]
[M_REQ_NEG, 13767778, ["EX3", F_NEG_bits, 6, ["NZD", 410]]]
h'83031a00d214628463455833030682634e5a4419019a'
The responder starts negotiating by making an offer ๐
[5, 13767778, ["EX3", 3, 6, ["NZD", 80]]]
[M_NEGOTIATE, 13767778, ["EX3", F_NEG_bits, 6, ["NZD", 80]]]
h'83051a00d214628463455833030682634e5a441850'
The initiator keeps going and reduces its request. Watch the loop count tick down, because it gets decremented here ๐
[5, 13767778, ["EX3", 3, 5, ["NZD", 307]]]
[M_NEGOTIATE, 13767778, ["EX3", F_NEG_bits, 5, ["NZD", 307]]]
h'83051a00d214628463455833030582634e5a44190133'
The responder asks for more time โณ
[7, 13767778, 34965]
[M_WAIT, 13767778, 34965]
h'83071a00d21462198895'
The responder is still going, and this time it increases its offer ๐
[5, 13767778, ["EX3", 3, 4, ["NZD", 120]]]
[M_NEGOTIATE, 13767778, ["EX3", F_NEG_bits, 4, ["NZD", 120]]]
h'83051a00d214628463455833030482634e5a441878'
The initiator keeps negotiating and reduces its request again ๐
[5, 13767778, ["EX3", 3, 3, ["NZD", 246]]]
[M_NEGOTIATE, 13767778, ["EX3", F_NEG_bits, 3, ["NZD", 246]]]
h'83051a00d214628463455833030382634e5a4418f6'
The responder refuses to negotiate any further ๐
[6, 13767778, [102, "Insufficient funds"]]
[M_END , 13767778, [O_DECLINE, "Insufficient funds"]]
h'83061a00d2146282186672496e73756666696369656e742066756e6473'
This negotiation has failed ๐ If either side had sent [M_END, 13767778, [O_ACCEPT]] it would have succeeded, and they'd have converged on the objective value from the previous M_NEGOTIATE โจ Also, apart from the initial M_REQ_NEG, the whole process is symmetrical ๐ซถ
Appendix B. Requirement Analysis of Discovery, Synchronization, and Negotiation
okay so this appendix is the requirements breakdown for discovery, negotiation, and synchronization ๐ง The main user of the protocol is an Autonomic Service Agent (ASA), which means the requirements are mostly written as the features an ASA needs. One physical device might contain several ASAs, and a single ASA might manage several technical objectives. If a technical objective is managed by several ASAs, any coordination they need is outside the scope of GRASP ๐ Requirements for ASAs themselves, like the processing of Intent [RFC7575], are also out of scope for this document ๐
B.1. Requirements for Discovery
D1. ASAs may be designed to manage any type of configurable device or software, as required in Appendix B.2. So a basic requirement is that the protocol can represent and discover any kind of technical objective (as defined in Section 2.1) among arbitrary subsets of participating nodes ๐ฆ
In an Autonomic Network, we have to assume that when a device starts up, it knows nothing about its peer devices, the network structure, or the specific role it has to play ๐ซ The ASA(s) inside the device are in the same boat. Sometimes, when a new application session starts within a device, the device or ASA may again lack information about relevant peers. For example, resources might need to be set up on multiple other devices, coordinated and matched to each other so nothing gets wasted ๐ Security settings might also need updating to allow for the new device or user. The relevant peers may be different for different technical objectives, so discovery needs to be repeated as often as necessary to find peers that can act as counterparts for each objective a discovery initiator needs to handle. From this background we derive the next three requirements ๐
D2. When an ASA first starts up, it may have no knowledge of the specific network it's attached to ๐ธ So the discovery process must be able to support any network scenario, assuming only that the device concerned is bootstrapped from factory condition.
D3. When an ASA starts up, it must require no configured location information about any peers in order to discover them ๐งญ
D4. If an ASA supports multiple technical objectives, the relevant peers may be different for different discovery objectives, so discovery needs to be performed separately to find counterparts for each objective. Thus, there must be a mechanism by which an ASA can separately discover peer ASAs for each of the technical objectives that it needs to manage, whenever necessary ๐
D5. Following discovery, an ASA will normally perform negotiation or synchronization for the corresponding objectives. The design should allow for this by conveniently linking discovery to negotiation and synchronization. It may provide an optional mechanism to combine discovery and negotiation/synchronization in a single protocol exchange โญ
D6. Some objectives may only be significant on the local link, but others may be significant across the routed network and require off-link operations ๐ So the relevant peers might be immediate neighbors on the same layer 2 link, or they might be more distant and only reachable via layer 3. The mechanism must therefore provide both on-link and off-link discovery of ASAs supporting specific technical objectives.
D7. The discovery process should be flexible enough to handle special cases, such as the following ๐ฅ
- During initialization, a device must be able to establish mutual trust with autonomic nodes elsewhere in the network and take part in an authentication mechanism. Although this will inevitably start with a discovery action, it's a special case precisely because trust isn't established yet ๐ This topic is the subject of [RFC8995]. We require that once trust has been established for a device, all ASAs within the device inherit the device's credentials and are also trusted. This does not preclude the device having multiple credentials.
- Depending on the type of network involved, discovery of other central functions might be needed, such as the Network Operations Center (NOC) [RFC8368] ๐ข The protocol must be capable of supporting such discovery during initialization, as well as discovery during ongoing operation.
D8. The discovery process must not generate excessive traffic and must take account of sleeping nodes ๐ด๐ no notes, that's a whole vibe check
D9. There must be a mechanism for handling stale discovery results ๐๏ธ bestie, outdated info is not it, periodt ๐
B.2. Requirements for Synchronization and Negotiation Capability
Okay so autonomic networks have to juggle SO many kinds of parameters ๐ง โจ like latency, load, unused or limited resources, conflicting resource requests, security settings, power saving, load balancing, etc. Nodes need to share status info and resource metrics so they can adjust resources dynamically and keep an eye on things ๐. Existing protocols might cover this when they're available, but the new protocol still needs to support parameter exchange, including mutual synchronization, even when no negotiation as such is required. And honestly? These parameters usually don't apply to every node, just a subset ๐ฆ
SN1. A basic requirement for the protocol is therefore the ability to represent, discover, synchronize, and negotiate almost any kind of network parameter among selected subsets of participating nodes. ๐
SN2. Negotiation is an iterative request/response process that must be guaranteed to terminate (with success or failure). While tie-breaking rules must be defined specifically for each use case, the protocol should have some general mechanisms in support of loop and deadlock prevention, such as hop-count limits or timeouts. ๐
SN3. Synchronization must be possible for groups of nodes ranging from small to very large. ๐
SN4. To avoid "reinventing the wheel" ๐, the protocol should be able to encapsulate the data formats used by existing configuration protocols (such as Network Configuration Protocol (NETCONF) and YANG) in cases where that is convenient.
SN5. Human intervention in complex situations is costly and error prone ๐. Therefore, synchronization or negotiation of parameters without human intervention is desirable whenever the coordination of multiple devices can improve overall network performance. It follows that the protocol's resource requirements must be small enough to fit in any device that would otherwise need human intervention. The issue of running in constrained nodes is discussed in [RFC8993].
SN6. Human intervention in large networks is often replaced by use of a top-down network management system (NMS) ๐ฐ. It therefore follows that the protocol, as part of the Autonomic Networking Infrastructure, should be capable of running in any device that would otherwise be managed by an NMS, and that it can coexist with an NMS and with protocols such as SNMP and NETCONF. ๐ซถ
SN7. Specific autonomic features are expected to be implemented by individual ASAs, but the protocol must be general enough to allow them. Some examples follow: ๐
- Dependencies and conflicts: In order to decide upon a configuration for a given device, the device may need information from neighbors. This can be established through the negotiation procedure, or through synchronization if that is sufficient. However, a given item in a neighbor may depend on other information from its own neighbors, which may need another negotiation or synchronization procedure to obtain or decide. Therefore, there are potential dependencies and conflicts among negotiation or synchronization procedures. Resolving dependencies and conflicts is a matter for the individual ASAs involved. To allow this, there need to be clear boundaries and convergence mechanisms for negotiations. Also some mechanisms are needed to avoid loop dependencies or uncontrolled growth in a tree of dependencies. It is the ASA designer's responsibility to avoid or detect looping dependencies or excessive growth of dependency trees. The protocol's role is limited to bilateral signaling between ASAs and the avoidance of loops during bilateral signaling.
- Recovery from faults and identification of faulty devices should be as automatic as possible. The protocol's role is limited to discovery, synchronization, and negotiation. These processes can occur at any time, and an ASA may need to repeat any of these steps when the ASA detects an event such as a negotiation counterpart failing. ๐ง
- Since a major goal is to minimize human intervention, it is necessary that the network can in effect "think ahead" before changing its parameters. One aspect of this is an ASA that relies on a knowledge base to predict network behavior. This is out of scope for the signaling protocol. However, another aspect is forecasting the effect of a change by a "dry run" negotiation before actually installing the change. Signaling a dry run is therefore a desirable feature of the protocol. ๐ฎ
Note that management logging, monitoring, alerts, and tools for intervention are required. However, these can only be features of individual ASAs, not of the protocol itself. Another document [RFC8368] discusses how such agents may be linked into conventional Operations, Administration, and Maintenance (OAM) systems via an Autonomic Control Plane [RFC8994]. ๐
SN8. The protocol will be able to deal with a wide variety of technical objectives, covering any type of network parameter. Therefore the protocol will need a flexible and easily extensible format for describing objectives. At a later stage, it may be desirable to adopt an explicit information model. One consideration is whether to adopt an existing information model or to design a new one. ๐งฉ
B.3. Specific Technical Requirements
T1. It should be convenient for ASA designers to define new technical objectives and for programmers to express them, without excessive impact on runtime efficiency and footprint. In particular, it should be convenient for ASAs to be implemented independently of each other as user-space programs rather than as kernel code, where such a programming model is possible. The classes of device in which the protocol might run is discussed in [RFC8993]. ๐ป
T2. The protocol should be easily extensible in case the initially defined discovery, synchronization, and negotiation mechanisms prove to be insufficient. ๐ฑ
T3. To be a generic platform, the protocol payload format should be independent of the transport protocol or IP version. In particular, it should be able to run over IPv6 or IPv4. However, some functions, such as multicasting on a link, might need to be IP version dependent. By default, IPv6 should be preferred. ๐
T4. The protocol must be able to access off-link counterparts via routable addresses, i.e., must not be restricted to link-local operation. ๐ฃ๏ธ
T5. It must also be possible for an external discovery mechanism to be used, if appropriate for a given technical objective. In other words, GRASP discovery must not be a prerequisite for GRASP negotiation or synchronization. ๐
T6. The protocol must be capable of distinguishing multiple simultaneous operations with one or more peers, especially when wait states occur. ๐งต
T7. Intent: Although the distribution of Intent is out of scope for this document, the protocol must not by design exclude its use for Intent distribution. ๐ฏ
T8. Management monitoring, alerts, and intervention: Devices should be able to report to a monitoring system. Some events must be able to generate operator alerts, and some provision for emergency intervention must be possible (e.g., to freeze synchronization or negotiation in a misbehaving device). These features might not use the signaling protocol itself, but its design should not exclude such use. ๐จ
T9. Because this protocol may directly cause changes to device configurations and have significant impacts on a running network, all protocol exchanges need to be fully secured against forged messages and man-in-the-middle attacks, and secured as much as reasonably possible against denial-of-service attacks. There must also be an encryption mechanism to resist unwanted monitoring. However, it is not required that the protocol itself provides these security features; it may depend on an existing secure environment. ๐
Appendix C. Capability Analysis of Current Protocols ๐โจ
okay bestie, this appendix is the authors checking out every existing protocol to see if any of them can do discovery, state sync, AND negotiation in one go. ๐ The goal is to figure out whether any existing protocol, or a simple combo of them, can hit the Appendix B requirements. Spoiler: nobody fully does, but the reasons are so interesting ๐ค
Lots of protocols have some kind of discovery, but ngl they're all super specific ๐ Service Location Protocol (SLP) [RFC2608] does service discovery for managed networks, but you have to set up its own servers first. DNS-Based Service Discovery (DNS-SD) [RFC6763] plus Multicast DNS (mDNS) [RFC6762] handles discovery for small networks with a single link layer. [RFC7558] wants to stretch that to larger autonomous networks, but it's not standardized yet ๐ญ Also, SLP and DNS-SD both seem to target application-layer services, not the layer 2 and 3 objectives needed for basic network configuration. And both are text-based protocols, fr.
Simple Network Management Protocol (SNMP) [RFC3416] uses a command/response model that's not great for peer negotiation ๐ฅฒ NETCONF [RFC6241] uses an RPC model where the target system can send back positive or negative responses, which is better, but still not enough for negotiation.
There are a bunch of protocols with elementary negotiation skills, like Dynamic Host Configuration Protocol for IPv6 (DHCPv6) [RFC8415], Neighbor Discovery (ND) [RFC4861], Port Control Protocol (PCP) [RFC6887], Remote Authentication Dial-In User Service (RADIUS) [RFC2865], Diameter [RFC6733], etc. ๐ง Most of them are configuration or management protocols. They either give you a simple request/response model in a master/slave context, or very limited negotiation abilities. Not quite the vibe we need.
Then there are signaling protocols with a bit of negotiation in them ๐ธ Resource ReSerVation Protocol (RSVP) [RFC2205] was built to negotiate quality-of-service parameters along the path of a unicast or multicast flow. It's very specialized and aimed at end-to-end flows. General Internet Signalling Transport (GIST) [RFC5971] is the more generic design, but it tries to solve so many problems that it gets complex, and it's aimed at per-flow signaling across many hops instead of device-to-device signaling. Still, the authors can't completely rule out extended RSVP or GIST as a synchronization and negotiation protocol ๐ They just don't seem directly usable for peer discovery.
RESTCONF [RFC8040] is a protocol for conveying NETCONF information expressed in the YANG language via HTTP, including the ability to transit HTML intermediaries. (Okay, that one's a bit of a mouthful ๐) It's a powerful approach for centralized configuration of a complex network, but it's not well adapted to efficient interactive negotiation between peer devices, especially simple ones that might not already do YANG processing.
The Distributed Node Consensus Protocol (DNCP) [RFC7787] is defined as a generic form of a state synchronization protocol ๐ฆ Its proposed usage profile is the Home Networking Control Protocol (HNCP) [RFC7788], for configuring Homenet routers. A specific application of DNCP for Autonomic Networking was proposed in [ADNCP]. According to [RFC7787]:
| DNCP is designed to provide a way for each participating node to
| publish a set of TLV (Type-Length-Value) tuples (at most 64 KB)
| and to provide a shared and common view about the data
| published...
|
| DNCP is most suitable for data that changes only infrequently...
|
| If constant rapid state changes are needed, the preferable choice
| is to use an additional point-to-point channel...
Specific features of DNCP include:
- Every participating node has a unique node identifier.
- DNCP messages are encoded as a sequence of TLV objects and sent over unicast UDP or TCP, with or without (D)TLS security.
- Multicast is used only for discovery of DNCP neighbors when lower security is acceptable.
- Synchronization of state is maintained by a flooding process using the Trickle algorithm. There is no bilateral synchronization or negotiation capability.
- The HNCP profile of DNCP is designed to operate between directly connected neighbors on a shared link using UDP and link-local IPv6 addresses.
DNCP doesn't meet the needs of a general negotiation protocol because it's built specifically for flooding synchronization ๐ And in its HNCP profile, it's limited to link-local messages and to IPv6. Still, it's a super interesting test case for this style of device-to-device interaction without a central authority, and it's a proven method of network-wide state synchronization by flooding. Iconic, honestly โจ
The Server Cache Synchronization Protocol (SCSP) [RFC2334] also describes a method for cache synchronization and cache replication among a group of nodes ๐
A proposal was made some years ago for an IP based Generic Control Protocol (IGCP) [IGCP]. It was aimed at information exchange and negotiation, but not directly at peer discovery. Still, it has lots of points in common with this work, which is a little bit of a plot twist ๐
None of the above solutions completely meets the needs of generic discovery, state synchronization, and negotiation in a single solution ๐ค Most of them assume a traditional top-down or north-south scenario, rather than a fluid peer-to-peer one, and most are specialized in one way or another. So the authors haven't found a combo of existing protocols that meets the Appendix B requirements. They also haven't found a path where one of the existing protocols could be extended to meet them either. Main character energy for the new design, tbh ๐
Acknowledgments ๐ซถ
A huge thank you to Sheng Jiang, who made a major contribution to the original draft version of this document, and to Toerless Eckert, who made significant contributions too ๐ Significant early review inputs came from Joel Halpern, Barry Leiba, Charles E. Perkins, and Michael Richardson. William Atwood helped a lot with debugging a prototype implementation ๐ฅ
Valuable comments came from Michael Behringer, Jรฉferson Campos Nobre, Laurent Ciavaglia, Zongpeng Du, Yu Fu, Joel Jaeggli, Zhenbin Li, Dimitri Papadimitriou, Pierre Peloso, Reshad Rahman, Markus Stenberg, Martin Stiemerling, Rene Struik, Martin Thomson, Dacheng Zhang, and participants in the Network Management Research Group, the ANIMA Working Group, and the IESG. Everyone who showed up with feedback is literally a legend ๐
Authors' Addresses ๐ฆ
Carsten Bormann
Universitรคt Bremen TZI
Postfach 330440
D-28359 Bremen
Germany
Email: cabo@tzi.org
Brian Carpenter (editor)
School of Computer Science
University of Auckland
PB 92019
Auckland 1142
New Zealand
Email: brian.e.carpenter@gmail.com
Bing Liu (editor)
Huawei Technologies Co., Ltd
Q14, Huawei Campus
Hai-Dian District
No.156 Beiqing Road
Beijing
100095
China
Email: leo.liubing@huawei.com
That's the whole thing, bestie! ๐๐ Thanks for coming on this protocol journey with me ๐งโจ
๐ฆ where this page comes from
- ietf: rfc8990 2021-05
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms