<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.18 (Ruby 3.0.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-wh-rtgwg-adaptive-routing-arn-02" category="std" consensus="true" submissionType="IETF" xml:lang="en" version="3">
  <!-- xml2rfc v2v3 conversion 3.22.0 -->
  <front>
    <title abbrev="ARN">Adaptive Routing Notification</title>
    <seriesInfo name="Internet-Draft" value="draft-wh-rtgwg-adaptive-routing-arn-02"/>
    <author initials="H." surname="Wang" fullname="Haibo Wang">
      <organization>Huawei</organization>
      <address>
        <email>rainsword.wang@huawei.com</email>
      </address>
    </author>
    <author initials="H." surname="Huang" fullname="Hongyi  Huang">
      <organization>Huawei</organization>
      <address>
        <email>hongyi.huang@huawei.com</email>
      </address>
    </author>
    <date year="2024" month="August" day="01"/>
    <area>General</area>
    <workgroup>Network Working Group</workgroup>
    <keyword>keyword1</keyword>
    <keyword>keyword2</keyword>
    <keyword>keyword3</keyword>
    <abstract>
      <?line 42?>

<t>Large-scale supercomputing and AI data centers utilize multipath to implement load balancing and/or improve transport reliability. Adaptive routing (AR), widely used in direct topologies such as dragonfly, is growing popular in commodity data centers to dynamically adjust routing policies based on path congestion and failures.
When congestion or failure occurs, the sensing node can not only apply AR locally but also send the congestion/failure information to other nodes in a timely and accurate manner to enforce AR on other nodes, thus avoiding exacerbating congestion on the reported path.
This document specifies Adaptive Routing Notification (ARN), a general mechanism to proactively disseminate congestion detection and congestion elimination information for remote nodes to perform re-routing policies.</t>
    </abstract>
  </front>
  <middle>
    <?line 50?>

<section anchor="intro">
      <name>Introduction</name>
      <t>Adaptive routing (AR) is widely used in high-performance computing (HPC) environments with directly connected topologies like Dragonfly<xref target="I-D.draft-agt-rtgwg-dragonfly-routing"/>. These topologies offer advantages such as scalability with small network diameters, making them widely adopted in HPC and supercomputing systems.</t>
      <t>In networks with directly connected topologies, multiple non-equivalent paths exist to reach the destination node. Typically, the shortest path is preferred for forwarding traffic. However, traffic congestion can occur on these shortest paths. AR addresses this by enabling nodes to make dynamic routing decisions based on network traffic variations, such as link congestion.</t>
      <t>AR is also applicable to symmetrical topologies, which are the most prevalent in current AI data centers, like the Clos topology. In symmetrical topologies, multiple equivalent paths (ECMP) are available. When congestion occurs on one path, AR can adjust traffic flows to avoid the congested path, thus ensuring balanced traffic distribution and optimal path usage.</t>
      <t>For example, by proactively detecting link congestion status or receiving remote congestion notifications, network nodes can forward packets along shorter, non-congested paths, improving overall throughput and resilience while reducing latency. When the link is non-congested, packets are forwarded over the shortest paths. When congestion occurs on any shortest path, the local node that detects it applies adaptive routing immediately and advertises congestion signals to other remote nodes. This allows the network to select another non-congested but non-shortest path temporarily until a congestion elimination signal is received. Adaptive routing helps mitigate traffic collisions and utilize idle links, enhancing bandwidth utilization.</t>
      <t>When data centers using symmetrical topologies employ ECMP, AR can correct the membership of ECMP groups by providing timely congestion updates. This ensures traffic is balanced across optimal paths and prevents overload on specific links.</t>
      <t>AR mechanisms are also effective in handling path failure scenarios, as path failures can be considered severe congestion cases. The re-routing strategy differs in these cases: when a link failure occurs, no traffic can pass through the failed link, necessitating a complete re-route of all affected traffic. In contrast, when congestion occurs, some traffic can still flow through the link, so AR ensures that only the excess or partial traffic is re-routed, maintaining some level of flow through the congested link.</t>
      <t>To standardize the process of disseminating information for triggering re-routing, including but not limited to congestion and failures, the concept of Adaptive Routing Notification (ARN) is introduced. ARN allows for a unified approach to adaptive routing across different network environments, ensuring consistent and efficient handling of network changes and improving overall network performance and reliability. Additionally, standardizing ARN reduces the need for multiple implementations by switch vendors, simplifying network management and deployment.</t>
      <t>This document proposes a proactive notification mechanism for adaptive routing and describes the conditions for triggering dissemination and the information carried in ARN to notify remote nodes for re-routing. ARN can be used for congestion notifications, failure notifications, and even to convey other relevant network information for re-routing. ARN is applicable to both directly connected topologies and indirectly connected topologies. The detailed mechanisms for detecting congestion or failures are beyond the scope of this document.</t>
      <section anchor="terminology">
        <name>Terminology</name>
        <t>AR: Adaptive Routing</t>
        <t>ARN: Adaptive Routing Notification</t>
        <t>BPT: Best Path Table</t>
      </section>
      <section anchor="requirements-language">
        <name>Requirements Language</name>
        <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
        <?line -18?>

</section>
    </section>
    <section anchor="arn-mechanism">
      <name>ARN Mechanism</name>
      <t>The ARN mechanism primarily consists of three steps:</t>
      <ol spacing="normal" type="1"><li>
          <t>Detect changes in the status of network links/nodes (such as link congestion, link signal interruption, etc.).</t>
        </li>
        <li>
          <t>Assess the impact range of the status change and, if local measures cannot completely mitigate the impact, send an ARN message to specified remote nodes.</t>
        </li>
        <li>
          <t>When remote nodes receive the ARN message, they make rerouting decisions based on the specific information carried by the ARN, thus minimizing the impact on subsequent traffic (e.g., selecting a new path for subsequent traffic).</t>
        </li>
      </ol>
      <t>Here, link congestion is taken as an example to show how ARN works. ARN can be triggered whenever link congestion (e.g., by analyzing the queue length of the output port) is detected to appear or disappear. A congestion signal carried through ARN is sent by the detected node to other nodes of interest (usually the upstream nodes).</t>
      <t><xref target="topology"/> depicts a simplified dragonfly topology (only relevant links are drawn). The nodes in each Group are directly connected to each other. The groups are all connected with direct links. As shown in <xref target="topology"/>, Node1 has a direct link connecting Group1 and Group2. When the direct link (Node1 &lt;-&gt; Group2) is congested, all nodes of Group1 should be notified and immediately update the path selection policy. For example, partial or all flows originating from Group1 to Group2 may choose Group3 as a transmission path instead of using the direct link (Node1 &lt;-&gt; Group2) until congestion elimination.</t>
      <figure anchor="topology">
        <name>ARN Example in Dragonfly</name>
        <artwork><![CDATA[
            +----------------+            +----------------+
            |                |            |                |
            |     Group 2    | -----------|     Group 3    |
            |                |            |                |
            +----------------+            +----------------+
                     |                             |
                     |                             |
                     |                             |
  +------------------|-------------------+         |
  |                  *                   |         |
  |      @@     +----*---+     @@        |         |
  |     +-------+  Node1 +--------+      |         |
  |     |       +----+---+        |      |         |
  |     |            |            |      |         |
  | +---v----+       |       +----v---+  |         |
  | | Node2  |       |@      |  Node4 +------------+
  | +--------+       |@      +--------+  |
  |                  |                   |
  |             +----v---+               |
  |             |  Node3 |               |
  |             +--------+               |   **: congestion
  |  Group 1                             |   @@: ARN
  +--------------------------------------+
]]></artwork>
      </figure>
      <t><xref target="example2"/></t>
      <figure anchor="example2">
        <name>ARN Example in Spine-Leaf</name>
        <artwork><![CDATA[
    +---------+       +---------+               
    |  spine1 |       |  spine2 |               
    +--+---+--+       +-+----+--+               
       |   |**          |    |                  
       |   +------------+-+  |                  
     @@|                | |  |                  
       |   +------------+ |  |                  
       |   |              |  |       **: failure
    +--+---+--+       +---+--+--+    @@: ARN    
    |  leaf1  |       |  leaf2  |               
    +---------+       +---------+               
]]></artwork>
      </figure>
      <t><xref target="example2"/> depicts a reduced Spine-Leaf topology with an example of how ARN is triggered in case of a failure. Specifically, when Spine1 detects a failure on the link to Leaf2, and finds no local backup path, Spine1 sends an ARN message to Leaf1, instructing it to reroute subsequent traffic destined for Leaf2 through Spine2.</t>
      <section anchor="triggering-arn">
        <name>Triggering ARN</name>
        <t>The local node can sense the change of network states by monitoring interface status, such as bandwidth utilization and queue depth of the interface. The sensing method is out of scope in this document.</t>
        <t>When the monitored value exceeds the preset threshold, the state is determined to be congested and a congestion notification is triggered.
When the monitored value falls back below the preset threshold, the state is determined to be non-congested and a notification of congestion elimination is triggered.</t>
        <t>When the local node detects any change in congestion status, it can send the corresponding ARN continuously to other network nodes in the same group.
The notifications can be sent to multiple nodes using multicast technology provided by the network.
ARN packets <bcp14>SHOULD</bcp14> be set as high priority to ensure timely processing.
The congestion level is <bcp14>RECOMMENDED</bcp14> to be included in ARN for fine-grained control of adaptive routing.</t>
        <t>The local node can sense the change of network states by monitoring interface status, such as bandwidth utilization and queue depth of the interface. The methods for detection and sensing can vary widely, including techniques such as active probing, passive monitoring, and others. However, the specific methods are out of scope in this document.</t>
        <t>However, the detection of a state change does not necessarily trigger the ARN mechanism. Nodes can decide whether to trigger remote notifications based on predefined rules. For instance, local measures might be sufficient to handle the issue. If a link failure occurs but the local node has multiple backup links available, the local rerouting might suffice to resolve the problem without needing to trigger an ARN.</t>
        <t>When the local node decides to trigger ARN based on the change in specific network status, it can send the corresponding ARN continuously to other network nodes. The ARNs could be sent by unicast or multicast. ARN packets <bcp14>SHOULD</bcp14> be set as high priority to ensure timely processing.</t>
      </section>
      <section anchor="receiving-arn">
        <name>Receiving ARN</name>
        <t>After receiving an ARN, the node generally performs re-route operations, which include but not limited to:</t>
        <ul spacing="normal">
          <li>
            <t>Selecting a new optimal path for the traffic that avoids the congested or failed link.</t>
          </li>
          <li>
            <t>Adjusting the sending rate of traffic to prevent overload and reduce congestion.</t>
          </li>
        </ul>
        <t>If the node determines that it cannot effectively re-route the traffic based on the received ARN, it may propagate the ARN information to other nodes in the network, continuing the dissemination process to ensure network-wide adaptation and optimal traffic flow.</t>
      </section>
    </section>
    <section anchor="adaptive-routing-notification">
      <name>Adaptive Routing Notification</name>
      <section anchor="basic-concept">
        <name>Basic Concept</name>
        <t>An ARN packet should include two kinds of information:</t>
        <ul spacing="normal">
          <li>
            <t>Information reflecting the type of notification and quantifiable metrics (e.g., congestion level). The Metric value helps in quantifying the severity of the congestion or failure, enabling fine-grained control of adaptive routing.</t>
          </li>
          <li>
            <t>Information carrying details about the affected object (e.g., affected traffic, affected paths), for example, router identifier connected by the compromised link or identifiers of flows that are impacted by the congestion or failure.</t>
          </li>
        </ul>
        <t>These details are essential to assist remote nodes in making informed rerouting decisions, ensuring minimal disruption and optimal network performance despite the presence of congestion or failures.</t>
        <t>Whenever a network node receives an ARN packet indicating congestion detection, for example, it would evaluate the optimal forwarding path in its local best path table (BPT). If the optimal path passes through the affected interface, the network node deletes this path from the BPT and selects other sub-optimal paths. How to respond to ARN packets is typically related to the specific device's rerouting implementation mechanism for AR.</t>
        <t>ARN can also be used to notify the elimination of specific network conditions (e.g., congestion recovery). When such an ARN message is received, the previously made rerouting decisions can be revoked. In this case, each ARN message should be configured with an identifier (carried through parameters) to ensure the correspondence between the state notification and the state revocation notification. If ARN is not used for elimination, mechanisms such as timeouts can be employed to revoke rerouting decisions.</t>
        <t>Simple and direct ARN messages may cause routing oscillation issues and packet reordering problems within the same flow. These issues can be better addressed in future enhancements. Additionally, ARN is primarily a rapid rerouting mechanism and is typically used in conjunction with robust BGP mechanisms. Once BGP routes converge, they will replace the rerouting strategies triggered by ARN, ensuring routing correctness, loop-freeness, and reducing the side effects caused by the simplistic ARN mechanism.</t>
      </section>
      <section anchor="packet-format">
        <name>Packet Format</name>
        <figure anchor="ref-to-fig">
          <name>ARN Format</name>
          <artwork><![CDATA[
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      Type     |Version|  Rvsd |     Metric    |    Para-Type  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                                                               |
+                      Parameters(Optional)                     +
|                                                               |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
]]></artwork>
        </figure>
        <t>where:</t>
        <dl>
          <dt>Type:</dt>
          <dd>
            <t>This field indicates the purposes of ARN. 
Type 1 indicates this notification is for notifying congestion detection remotely to trigger adaptive routing.
Type 2 indicates this notification is for notifying congestion elimination remotely to revoke adaptive routing.
Type 3 indicates this notification is for notifying failure detection remotely to trigger adaptive routing.
Type 4 indicates this notification is for notifying failure elimination remotely to revoke adaptive routing.</t>
          </dd>
          <dt>Version:</dt>
          <dd>
            <t>This field indicates the version number. The default value is 0.</t>
          </dd>
          <dt>Rvsd:</dt>
          <dd>
            <t>Reserved.</t>
          </dd>
          <dt>Metric:</dt>
          <dd>
            <t>Quantified value. For example, it can be used to notify the degree of congestion or indicate the variation in available bandwidth.</t>
          </dd>
          <dt>Para-Type:</dt>
          <dd>
            <t>The Para-Type field is an 8-bit bitmap that specifies which parameters are included in the Parameters field of the ARN packet. Each bit in this field corresponds to a specific parameter. When a bit is set to 1, it indicates the presence of the corresponding parameter. The following subsections detail the explanation of each bit in the Para-Type field.</t>
          </dd>
          <dt>Parameters:</dt>
          <dd>
            <t>The parameters field can carry the information of affected object to help other devices determine the target of adaptive routing. The presence of parameters is indicated by the Para-Type bitmap. The packing order of the parameters follows the bit order specified in the Para-Type bitmap field.</t>
          </dd>
        </dl>
        <section anchor="illustration-of-para-type-and-corresponding-parameter">
          <name>Illustration of Para-Type and Corresponding Parameter</name>
          <section anchor="para-type-bit-0">
            <name>Para-Type Bit 0</name>
            <t>When bit0 of Para-Type is 1, the following parameter is concluded in Parameters to indicate the identifier of affected flow (five-tuple from packet header):</t>
            <artwork><![CDATA[
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Opcode |   Mask  |             Rsvd            |    Protocol   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~                         Source IPv4/v6                        ~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~                      Destination IPv4/v6                      ~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Source Port         |        Destination Port       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
]]></artwork>
            <t>where:</t>
            <dl>
              <dt>Opcode:</dt>
              <dd>
                <t>This field indicates either IPv4 address or IPv6 address is used in the parameter.</t>
              </dd>
              <dt>Rsvd:</dt>
              <dd>
                <t>Reserved for future use.</t>
              </dd>
              <dt>Mask:</dt>
              <dd>
                <t>A bitmap used to indicate the presence of the subsequent 5 fields, excluding the reserved field. Each bit in this field corresponds to a specific domain, with a value of 1 indicating the presence of the domain and 0 indicating its absence.</t>
              </dd>
            </dl>
            <t>Here's the breakdown of each bit in the Mask field:</t>
            <ul spacing="normal">
              <li>
                <t>Bit 0 (Protocol): Indicates whether the Protocol field is present.</t>
              </li>
              <li>
                <t>Bit 1 (Source IPv4/v6): Indicates whether the Source IP address field is present.</t>
              </li>
              <li>
                <t>Bit 2 (Destination IPv4/v6): Indicates whether the Destination IP address field is present.</t>
              </li>
              <li>
                <t>Bit 3 (Source Port): Indicates whether the Source Port field is present.</t>
              </li>
              <li>
                <t>Bit 4 (Destination Port): Indicates whether the Destination Port field is present.</t>
              </li>
            </ul>
            <dl>
              <dt>Protocol:</dt>
              <dd>
                <t>Indicates the specific protocol type used by the packet, such as TCP or UDP.</t>
              </dd>
            </dl>
            <t>Source IPv4/v6: 
：  The IP address of the sender, which can be in IPv4 or IPv6 format determined by Opcode.</t>
            <t>Destination IPv4/v6: 
：  The IP address of the receiver, which can be in IPv4 or IPv6 format determined by Opcode.</t>
            <t>Source Port: 
：  The port number used by the sender.</t>
            <t>Destination Port: 
：The port number used by the receiver.</t>
          </section>
          <section anchor="para-type-bit-1">
            <name>Para-Type Bit 1</name>
            <t>When bit1 of Para-Type is 1, the following parameter is concluded in Parameters to indicate the identifier of affected path:</t>
            <artwork><![CDATA[
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Path ID                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
]]></artwork>
            <dl>
              <dt>Path ID:</dt>
              <dd>
                <t>The 32-bit field is used to uniquely identify the affected path in the network.</t>
              </dd>
            </dl>
          </section>
          <section anchor="para-type-bit-2-to-bit-7">
            <name>Para-Type Bit 2 to Bit 7</name>
            <t>Bits 2-7: Reserved for future use or other parameter types.</t>
            <t>In scenarios such as VXLAN tunnels, there may be both inner and outer five-tuple flow identifiers. Different parameters can be used to distinguish between these two types of identifiers, allowing for more granular routing control. Specifically:</t>
            <ul spacing="normal">
              <li>
                <t>Bit 0 is used for the outer five-tuple identifier (related to the VXLAN tunnel).</t>
              </li>
              <li>
                <t>Additional bits (e.g., Bit 2) can be used for the inner five-tuple identifier (related to the actual payload traffic within the tunnel).</t>
              </li>
            </ul>
            <t>By using different bits in the Para-Type field, the ARN mechanism can indicate the presence of these different parameters, enabling precise and fine-grained adaptive routing decisions.</t>
          </section>
        </section>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>TBD.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>TBD.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="I-D.draft-agt-rtgwg-dragonfly-routing">
          <front>
            <title>Routing in Dragonfly+ Topologies</title>
            <author fullname="Dmitry Afanasiev" initials="D." surname="Afanasiev">
         </author>
            <author fullname="Roman" initials="" surname="Roman">
              <organization>Yandex</organization>
            </author>
            <author fullname="Jeff Tantsura" initials="J." surname="Tantsura">
              <organization>Nvidia</organization>
            </author>
            <date day="4" month="March" year="2024"/>
            <abstract>
              <t>   This document provides an overview of Dragonfly+ network topology and
   describes routing implementation for IP networks with Dragonfly+
   topology with support for non-minimal routing.t

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-agt-rtgwg-dragonfly-routing-01"/>
        </reference>
      </references>
    </references>
    <?line 355?>

<section numbered="false" anchor="acknowledgements">
      <name>Acknowledgements</name>
    </section>
    <section numbered="false" anchor="contributors">
      <name>Contributors</name>
    </section>
  </back>
  <!-- ##markdown-source:
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
945Kkv8Ddy0VBHJPAAA=

-->

</rfc>
