<?xml version="1.0" encoding="utf-8"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     ipr="trust200902"
     submissionType="IETF"
     category="std"
     consensus="true"
     docName="draft-yang-rtgwg-mclag-failure-recovery-00"
     xml:lang="en"
     tocInclude="true"
     sortRefs="true"
     symRefs="true"
     version="3">
  <front>
    <title abbrev="MC-LAG Failure Recovery">Forwarding-Plane
    Failure Recovery Procedures for Multi-Chassis Link Aggregation
    Groups</title>
    <seriesInfo name="Internet-Draft"
        value="draft-yang-rtgwg-mclag-failure-recovery-00" />
    <author fullname="Jin Yang" initials="J." surname="Yang">
      <organization>China Mobile</organization>
      <address>
        <postal>
          <street/>
          <city>Beijing</city>
          <code>100053</code>
          <country>China</country>
        </postal>
        <email>yangjinwl@chinamobile.com</email>
      </address>
    </author>
 <author fullname="Tingting Han" initials="T." surname="Han">
      <organization>China Mobile</organization>
      <address>
        <postal>
          <city>Beijing</city>
          <code>100053</code>
          <country>China</country>
        </postal>
        <email>hantingting@chinamobile.com</email>
      </address>
    </author>
    <author fullname="Weiqiang Cheng" initials="W." surname="Cheng">
      <organization>China Mobile</organization>
      <address>
        <postal>
          <street/>
          <city>Beijing</city>
          <code>100053</code>
          <country>China</country>
        </postal>
        <email>chengweiqiang@chinamobile.com</email>
      </address>
    </author>
<author fullname="Yuchi Tian" initials="Y." surname="Tian">
      <organization>China Mobile</organization>
      <address>
        <postal>
          <city>Beijing</city>
          <code>100053</code>
          <country>China</country>
        </postal>
        <email>tianyuchi@chinamobile.com</email>
      </address>
    </author>
    <author fullname="Junjie Wang" initials="J." surname="Wang">
      <organization>Centec</organization>
      <address>
        <postal>
          <city>Suzhou</city>
          <code>215000</code>
          <country>China</country>
        </postal>
        <email>wangjj@centec.com</email>
      </address>
    </author>
    <author fullname="Guoying Zhang" initials="G." surname="Zhang">
      <organization>Centec</organization>
      <address>
        <postal>
          <city>Suzhou</city>
          <code>215000</code>
          <country>China</country>
        </postal>
        <email>zhanggy@centec.com</email>
      </address>
    </author>

    <date year="2026" month="10" day="30" />
    <area>RTG</area>
    <workgroup>RTGWG</workgroup>
    <keyword>MC-LAG</keyword>
    <keyword>inter-chassis link</keyword>
    <keyword>redundancy group</keyword>
    <keyword>forwarding continuity</keyword>
    <keyword>failure recovery</keyword>
    <abstract>
      <t>When a downlink member of a Multi-Chassis Link Aggregation
      Group (MC-LAG) fails, a common recovery method flushes the MAC
      forwarding table and relies on flooding to re-establish the
      forwarding paths, which can cause a period of congestion and
      disruption. This document specifies two complementary
      forwarding-plane failure recovery procedures for MC-LAG. The
      first procedure preserves the forwarding state by adjusting the
      LAG group's member set, adding an inter-chassis link (ICL) port
      in place of the failed downlink, so that MAC table entries
      remain valid and traffic is redistributed without a table flush
      and without flooding. The second procedure extends recovery
      beyond a single Provider Edge (PE) pair: when the immediate peer
      cannot satisfy a failover request, the request is relayed over a
      secondary ICL to the next PE along a configured relay path,
      which allows recovery across three or more PEs in the redundancy
      domain. The procedures operate primarily in the forwarding plane
      and do not require Ethernet VPN (EVPN) infrastructure.</t>
    </abstract>
  </front>
  <middle>
    <section anchor="intro" numbered="true" toc="include">
      <name>Introduction</name>
      <t>Multi-Chassis Link Aggregation Group (MC-LAG) technology
      allows two or more Provider Edge (PE) devices to present a
      single Link Aggregation Group (LAG) interface toward a Customer
      Edge (CE) device <xref target="RFC7275"/>
      <xref target="IEEE802.1AX"/>. An inter-chassis link (ICL, also
      called a peer link) connects the PE devices and carries both
      Inter-Chassis Communication Protocol (ICCP) signaling
      <xref target="RFC7275"/> and redirected data traffic.</t>

      <t>When a downlink member fails, a common recovery method
      flushes the MAC address table entries associated with the
      affected LAG group and relies on flooding of unknown unicast to
      relearn the forwarding paths. In a large deployment the
      flooding phase can last for hundreds of milliseconds and cause
      congestion and application-level disruption. EVPN-based
      solutions <xref target="RFC7432"/> reduce this through
      control-plane mass-withdraw signaling, but require EVPN
      infrastructure.</t>

      <t>This document specifies two procedures that operate primarily
      in the forwarding plane and do not require EVPN
      infrastructure.</t>

      <t>The first procedure, forwarding state preservation
      (<xref target="fwd-preserve"/>), responds to the removal of a
      downlink member from a LAG group by adding an ICL port to the
      same group. Because MAC table entries reference the LAG group
      identifier rather than an individual port, the entries remain
      valid and traffic is redistributed by the LAG hash function
      without a table flush and without flooding.</t>

      <t>The second procedure, ICL relay
      (<xref target="icl-relay"/>), applies in topologies with three
      or more PEs. A PE that receives a failover request but cannot
      satisfy it locally relays the request over a secondary ICL to
      the next PE. The relay continues hop by hop until a PE with an
      operational downlink is reached.</t>

      <t>The two procedures are independent and can be deployed
      separately or together. When combined, forwarding state
      preservation handles local failover within a PE pair and ICL
      relay extends recovery to additional PEs in the redundancy
      domain.</t>

      <t>The procedures carry MUST-level requirements on PE forwarding
      and signaling behavior and request an IANA code point for the
      relay messages, and so this document is on the Standards
      Track.</t>

      <section anchor="reqlang" numbered="true" toc="include">
        <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>
      </section>
    </section>

    <section anchor="terminology" numbered="true" toc="include">
      <name>Terminology</name>
      <t>This document uses the terminology of
      <xref target="RFC7275"/> and <xref target="IEEE802.1AX"/>. The
      following terms are defined.</t>
      <dl>
        <dt>Downlink Member:</dt>
        <dd>A port that belongs to an MC-LAG group and connects to a
        downstream CE device.</dd>

        <dt>ICL:</dt>
        <dd>Inter-Chassis Link (peer link). A link or LAG that
        connects two PEs in an MC-LAG redundancy group (RG).</dd>

        <dt>Primary ICL:</dt>
        <dd>The ICL between the two PEs that form the normal MC-LAG
        peer pair for a given RG.</dd>

        <dt>Secondary ICL:</dt>
        <dd>An ICL between two PEs that are not direct MC-LAG peers
        for a given RG. A secondary ICL provides a relay path toward
        additional PEs.</dd>

        <dt>LAG Group ID:</dt>
        <dd>The forwarding-plane identifier of a LAG group. MAC table
        entries reference this identifier, and the forwarding engine
        selects an egress member by a hash function.</dd>

        <dt>Member Set:</dt>
        <dd>The current set of physical ports that belong to a given
        LAG group.</dd>

        <dt>Relay Path:</dt>
        <dd>An ordered set of PEs and ICLs along which a failover
        request may be forwarded, configured administratively on each
        participating PE.</dd>

        <dt>Downstream Isolation:</dt>
        <dd>A condition in which a PE has lost all operational
        downlink members for a given MC-LAG group.</dd>
      </dl>
    </section>

    <section anchor="overview" numbered="true" toc="include">
      <name>Reference Topology</name>
      <t>The topology in <xref target="fig-topology"/> is the
      reference for both procedures. PE1 and PE2 are connected by a
      primary ICL, and PE2 and PE3 by a secondary ICL. Each PE has
      downlink members toward the CE.</t>

      <figure anchor="fig-topology">
        <name>Reference Topology</name>
        <artwork type="ascii-art"><![CDATA[
       +------+ primary +------+ secondary +------+
       | PE1  |---ICL---| PE2  |----ICL----| PE3  |
       +------+         +------+           +------+
         |  |              |  |               |
        m1 m2             m3 m4              m5
         |  |              |  |               |
       +-+--+--------------+--+---------------+-+
       |              CE Device                 |
       +----------------------------------------+

  PE1: LAG group G1, member set = {m1, m2}
  PE2: LAG group G2, member set = {m3, m4}
  PE3: LAG group G3, member set = {m5}
  MAC table on PE1: <dst-MAC> -> G1
]]></artwork>
      </figure>
    </section>

    <section anchor="fwd-preserve" numbered="true" toc="include">
      <name>Forwarding State Preservation</name>
      <t>This procedure preserves the forwarding state during a
      downlink member failure by adjusting the LAG group's member
      set.</t>

      <section anchor="fsp-preconditions" numbered="true"
               toc="include">
        <name>Preconditions</name>
        <t>The ICL port <bcp14>MUST</bcp14> be pre-provisioned with
        the VLAN membership, quality-of-service (QoS) policies, and
        access control lists (ACLs) of every MC-LAG group for which it
        may serve as a member. This ensures that adding the ICL to a
        member set requires only a forwarding-plane table update.</t>

        <t>A configurable threshold determines when the ICL is added
        to the member set. The default threshold is the loss of all
        local downlink members. An implementation <bcp14>MAY</bcp14>
        allow the operator to specify a minimum local member count
        below which the ICL is added.</t>
      </section>

      <section anchor="fsp-failover" numbered="true" toc="include">
        <name>Failover</name>
        <t>When a PE detects a link-down event on a downlink member,
        it removes the failed port from the affected LAG group's
        member set. If the remaining local member count falls below
        the configured threshold, the PE <bcp14>MUST</bcp14> add one
        or more ICL ports to the member set.</t>

        <t>The LAG Group ID does not change. MAC table entries
        continue to resolve to the same group, and the hash function
        redistributes traffic across the updated member set. A flow
        hashed to the ICL reaches the peer PE, which performs its own
        lookup and forwards the flow over its operational
        downlinks.</t>

        <figure anchor="fig-fsp">
          <name>Forwarding State Preservation</name>
          <artwork type="ascii-art"><![CDATA[
   +--------+           +--------+
   |  PE1   |----ICL----|  PE2   |
   +--------+           +--------+
     |    |                |    |
    m1   m2              m3   m4
  (down)X |                |    |

  G1 member set: {m1} removed, ICL added -> {m2, ICL}
  MAC table: <dst-MAC> -> G1   (UNCHANGED)
  Hash over {m2, ICL}: some flows via m2, some via ICL
  Flows via ICL -> PE2 -> forwarded via m3/m4
]]></artwork>
        </figure>

        <t>After modifying the member set, the PE
        <bcp14>SHOULD</bcp14> notify its MC-LAG peer over ICCP that
        the ICL now carries redirected traffic for the affected group.
        The peer uses this notification to adjust split-horizon
        behavior: traffic that arrives from the ICL for this group
        <bcp14>MUST</bcp14> be eligible for forwarding out local
        downlinks and <bcp14>MUST NOT</bcp14> be sent back to the
        ICL.</t>
      </section>

      <section anchor="fsp-reversion" numbered="true" toc="include">
        <name>Reversion</name>
        <t>When a failed downlink recovers, the PE adds the recovered
        port back to the member set and removes the ICL. The LAG Group
        ID does not change and no MAC table flush occurs. The PE
        <bcp14>SHOULD</bcp14> notify its peer that the ICL is no longer
        carrying redirected traffic.</t>

        <t>A configurable hold timer, with a default of 1 second,
        <bcp14>SHOULD</bcp14> delay reversion to prevent repeated
        membership changes when the downlink flaps.</t>
      </section>

      <section anchor="fsp-traffic" numbered="true" toc="include">
        <name>Traffic Handling</name>
        <t>For known unicast, the MAC table entry resolves to the LAG
        Group ID and the hash function distributes frames across the
        current member set. No relearning is needed.</t>

        <t>For broadcast, unknown unicast, and multicast (BUM)
        traffic, the ICL is typically already part of the flooding
        domain in an MC-LAG deployment. Adding the ICL to the member
        set does not change BUM behavior, but an implementation
        <bcp14>MUST</bcp14> enforce split-horizon rules to prevent
        duplicate frames.</t>
      </section>

      <section anchor="fsp-state" numbered="true" toc="include">
        <name>ICL Membership State</name>
        <t>The ICL port maintains a per-MC-LAG-group state.</t>
        <dl>
          <dt>Standby:</dt>
          <dd>Default. The ICL is not part of the group's member
          set.</dd>

          <dt>Joining:</dt>
          <dd>Transient. The ICL is being added to the member
          set.</dd>

          <dt>Active-Member:</dt>
          <dd>The ICL is part of the member set and carries redirected
          traffic.</dd>

          <dt>Leaving:</dt>
          <dd>Transient. A downlink has recovered and the ICL is being
          removed from the member set.</dd>
        </dl>

        <figure anchor="fig-icl-state">
          <name>ICL Membership State Machine</name>
          <artwork type="ascii-art"><![CDATA[
    +---------+
    | Standby |<---------------------+
    +---------+                      |
        |                            |
  threshold crossed          table update done
        |                            |
        v                       +----------+
    +---------+                 | Leaving  |
    | Joining |                 +----------+
    +---------+                      ^
        |                            |
  table update done        downlink recovered
        |                            |
        v                            |
    +---------------+----------------+
    | Active-Member |
    +---------------+
]]></artwork>
        </figure>
      </section>
    </section>

    <!-- ================ ICL RELAY ================ -->
    <section anchor="icl-relay" numbered="true" toc="include">
      <name>ICL Relay for Multi-PE Recovery</name>
      <t>This section specifies procedures for relaying failover
      requests across multiple PEs when the immediate peer cannot
      satisfy the request.</t>

      <section anchor="relay-applicability" numbered="true" toc="include">
        <name>Applicability</name>
        <t>The ICL relay procedures apply to MC-LAG domains
        comprising three or more PEs where correlated downlink
        failures can exhaust the failover capacity of the
        immediate peer pair. Each participating PE MUST have a
        pre-configured relay path that identifies its secondary
        ICL and the next-hop PE in the relay sequence.</t>
      </section>

      <section anchor="relay-origination" numbered="true" toc="include">
        <name>Failover Request Origination</name>
        <t>A PE that detects downstream isolation for a given
        MC-LAG group MUST first attempt local recovery (including
        the forwarding state preservation procedure of
        <xref target="fsp-failover"/> if configured). If the PE
        remains unable to reach the CE, it originates a
        Failover-Request message and sends it to its primary
        MC-LAG peer over the primary ICL.</t>

        <t>The message carries the originating PE's identifier
        (Originator-PE-ID), a sequence number, the affected MC-LAG
        Group ID, and a hop count initialized to one.</t>
      </section>

      <section anchor="relay-processing" numbered="true" toc="include">
        <name>Failover Request Processing</name>
        <t>A PE receiving a Failover-Request evaluates whether it
        can satisfy the request:</t>

        <t>If the PE has an available downlink member, it brings
        the member into service (or confirms it is already
        operational) and replies with a Failover-Response
        indicating success. Redirected traffic then flows along
        the chain of ICLs from the originating PE to this PE.</t>

        <t>If the PE cannot satisfy the request and a secondary ICL
        toward a next-hop PE exists, the PE increments the hop
        count and forwards the Failover-Request over the secondary
        ICL.</t>

        <t>If no further relay path exists, or if the hop count has
        reached the configured maximum (see
        <xref target="loop-prevention"/>), the PE replies with a
        Failover-Response indicating No-Resource, or the more
        specific Hop-Limit-Exceeded status when the hop count is the
        cause.</t>
      </section>

      <section anchor="relay-liveness" numbered="true" toc="include">
        <name>Relay Path Liveness</name>
        <t>After a successful relay, each PE along the path MUST
        exchange periodic Liveness messages with its neighbors on
        the path. The default interval is 1 second; the default
        failure threshold is 3 missed messages. If liveness is
        lost, the PE MUST attempt an alternate path or notify the
        originator of path failure.</t>
      </section>

      <section anchor="relay-reversion" numbered="true" toc="include">
        <name>Reversion</name>
        <t>When the originating PE's downlinks recover, it sends a
        Revert-Request along the relay path. Each PE restores its
        ICL segment to standby forwarding state and confirms with a
        Revert-Response. Reversion SHOULD be delayed by a
        configurable hold timer (default: 3 seconds).</t>
      </section>
    </section>

    <!-- ================ MESSAGE FORMATS ================ -->
    <section anchor="messages" numbered="true" toc="include">
      <name>Message Formats</name>
      <t>The messages defined in this section support the ICL relay
      procedures of <xref target="icl-relay"/>. They
      <bcp14>MUST</bcp14> be carried as a new ICCP Application TLV
      type (<xref target="rel-iccp"/>) over the ICCP connection
      between adjacent PEs on the relay path, using the registry
      allocation requested in <xref target="iana"/>. Defining the
      messages over a transport other than ICCP is outside the
      scope of this document; a future specification that does so
      <bcp14>MUST</bcp14> preserve the field semantics, the loop
      prevention rules of <xref target="loop-prevention"/>, and the
      security requirements of <xref target="security"/>.</t>

      <section anchor="common-header" numbered="true" toc="include">
        <name>Common Header</name>
        <figure anchor="fig-common-header">
          <name>Common Message Header</name>
          <artwork type="ascii-art"><![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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Version    |   Msg Type    |         Total Length          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Originator-PE-ID                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       Sequence Number         |   Hop Count   |   Reserved    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Authentication Data ...                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
]]></artwork>
        </figure>
        <dl>
          <dt>Version (8 bits):</dt>
          <dd>Protocol version. This document defines version
          1.</dd>

          <dt>Msg Type (8 bits):</dt>
          <dd>Failover-Request (1), Failover-Response (2), Liveness
          (3), Revert-Request (4), Revert-Response (5).</dd>

          <dt>Total Length (16 bits):</dt>
          <dd>Length of the entire message in octets.</dd>

          <dt>Originator-PE-ID (32 bits):</dt>
          <dd>Domain-unique identifier of the PE that originated
          the failover sequence. Used for loop detection.</dd>

          <dt>Sequence Number (16 bits):</dt>
          <dd>Monotonically increasing per originator, for ordering
          and duplicate suppression.</dd>

          <dt>Hop Count (8 bits):</dt>
          <dd>Incremented at each relay hop. Messages exceeding the
          configured maximum are discarded.</dd>

          <dt>Reserved (8 bits):</dt>
          <dd>MUST be zero on transmission; ignored on receipt.</dd>

          <dt>Authentication Data (variable):</dt>
          <dd>Optional keyed digest for message integrity, aligned
          with <xref target="RFC7275"/> Section 10.</dd>
        </dl>
      </section>

      <section anchor="msg-types" numbered="true" toc="include">
        <name>Message Types and Fields</name>
        <t>All messages begin with the common header of
        <xref target="common-header"/>. The message-specific content
        is as follows.</t>

        <t>Failover-Request (Type 1) carries one MC-LAG Group ID
        TLV (<xref target="fig-groupid-tlv"/>) identifying the group
        that requires recovery.</t>

        <figure anchor="fig-groupid-tlv">
          <name>MC-LAG Group ID TLV</name>
          <artwork type="ascii-art"><![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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          TLV Type (1)         |          Length (4)           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        MC-LAG Group ID         |           Reserved            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
]]></artwork>
        </figure>

        <t>The TLV Type is 1 (MC-LAG Group ID). The Length is the
        length in octets of the TLV value (4). The MC-LAG Group ID
        is a 16-bit identifier of the affected group, unique within
        the redundancy domain. The Reserved field
        <bcp14>MUST</bcp14> be set to zero on transmission and
        ignored on receipt.</t>

        <t>Failover-Response (Type 2) carries an 8-bit Status field
        followed by the MC-LAG Group ID TLV copied from the
        corresponding request. The Status values are defined in
        <xref target="tab-status"/>.</t>

        <table anchor="tab-status">
          <name>Failover-Response Status Values</name>
          <thead>
            <tr><th>Value</th><th>Name</th><th>Meaning</th></tr>
          </thead>
          <tbody>
            <tr><td>0</td><td>Success</td><td>A downlink member was
            brought into service for the group.</td></tr>
            <tr><td>1</td><td>No-Resource</td><td>No PE on the relay
            path could satisfy the request.</td></tr>
            <tr><td>2</td><td>Loop-Detected</td><td>The request was
            discarded for loop prevention
            (<xref target="loop-prevention"/>).</td></tr>
            <tr><td>3</td><td>Hop-Limit-Exceeded</td><td>The request
            reached the configured maximum hop count.</td></tr>
          </tbody>
        </table>

        <t>Liveness (Type 3) contains only the common header.
        Revert-Request (Type 4) and Revert-Response (Type 5) each
        carry the MC-LAG Group ID TLV and manage relay path teardown
        and restoration.</t>

        <t>A PE <bcp14>MUST</bcp14> suppress duplicate requests: it
        maintains, per relay path, the highest Sequence Number seen
        for each Originator-PE-ID, and <bcp14>MUST</bcp14> silently
        discard a Failover-Request or Revert-Request whose
        (Originator-PE-ID, Sequence Number) pair has already been
        processed. Sequence Number comparison
        <bcp14>MUST</bcp14> use the serial number arithmetic of
        <xref target="RFC1982"/> to handle wrap-around.</t>
      </section>
    </section>

    <!-- ================ LOOP PREVENTION ================ -->
    <section anchor="loop-prevention" numbered="true" toc="include">
      <name>Loop Prevention</name>
      <t>Two mechanisms bound message propagation in topologies
      that contain cycles:</t>

      <t>The Originator-PE-ID field uniquely identifies the PE that
      began the failover sequence. A PE receiving a Failover-Request
      carrying its own identifier <bcp14>MUST</bcp14> discard the
      message and return a Failover-Response with status
      Loop-Detected.</t>

      <t>The Hop Count field is incremented at each hop. A PE
      <bcp14>MUST</bcp14> discard any message whose Hop Count
      exceeds a locally configured maximum (default: 8) and return a
      Failover-Response with status Hop-Limit-Exceeded.</t>
    </section>

    <!-- ================ COMBINED OPERATION ================ -->
    <section anchor="combined" numbered="true" toc="include">
      <name>Combined Operation</name>
      <t>When both procedures are deployed together, the following
      sequence occurs upon a downlink failure on PE1:</t>

      <figure anchor="fig-combined">
        <name>Combined Operation Sequence</name>
        <artwork type="ascii-art"><![CDATA[
   Event                          PE1 Action
   -----                          ----------
   m1 link-down detected          Remove m1 from G1.
                                  Threshold crossed: add ICL
                                  to G1 (Section 4.2).
                                  G1 = {m2, ICL}; MAC table
                                  unchanged.

   m2 also fails                  Remove m2 from G1.
   (correlated failure)           G1 = {ICL}; traffic flows
                                  entirely via ICL to PE2.

   PE2 also lost m3, m4           PE1's traffic arrives at PE2
   (multi-PE failure)             via ICL, but PE2 cannot
                                  deliver it.
                                  PE1 originates Failover-
                                  Request (Section 5.2).
                                  PE2 relays to PE3 via
                                  secondary ICL (Section 5.3).
                                  PE3 has m5; returns success.
                                  Data path: PE1 -> ICL ->
                                  PE2 -> secondary ICL ->
                                  PE3 -> m5 -> CE.

   Recovery: m1 link-up           PE1 adds m1 to G1, removes
                                  ICL. Sends Revert-Request
                                  to tear down relay path.
]]></artwork>
      </figure>
    </section>

    <!-- ================ PE STATE MACHINE ================ -->
    <section anchor="per-group-state" numbered="true" toc="include">
      <name>Per-Group PE States for ICL Relay</name>
      <t>Each PE maintains the following per-MC-LAG-group state for
      the relay function:</t>
      <dl>
        <dt>Operational:</dt>
        <dd>The PE has at least one working downlink member and
        forwards traffic locally.</dd>

        <dt>Requesting:</dt>
        <dd>The PE has lost all downlink members and has originated
        a Failover-Request.</dd>

        <dt>Relaying:</dt>
        <dd>The PE has received a Failover-Request that it cannot
        satisfy locally and has forwarded it along the relay
        path.</dd>

        <dt>Serving:</dt>
        <dd>The PE has satisfied a relayed request by providing one
        of its downlink members.</dd>

        <dt>Reverting:</dt>
        <dd>The original failure has been resolved and the relay
        path is being torn down.</dd>
      </dl>

      <figure anchor="fig-pe-state">
        <name>Per-Group PE State Machine</name>
        <artwork type="ascii-art"><![CDATA[
      +--------------+
      | Operational  |<--------------------------+
      +--------------+                            |
            |                                     |
  all downlinks lost                  reversion complete
            |                                     |
            v                                     |
      +--------------+                    +--------------+
      | Requesting   |                    | Reverting    |
      +--------------+                    +--------------+
            |                                     ^
   response received                              |
   (success)                            downlink recovered
            |                                     |
  +---------+---------+              +------------+
  | (local) |(relayed)|              |
  v         v         v              |
 [done]  +----------+ +---------+    |
         | Relaying |-| Serving |----+
         +----------+ +---------+
]]></artwork>
      </figure>
    </section>

    <!-- ================ RELATIONSHIP ================ -->
    <section anchor="relationship" numbered="true" toc="include">
      <name>Relationship to Other Protocols</name>

      <section anchor="rel-iccp" numbered="true" toc="include">
        <name>ICCP</name>
        <t>The procedures in this document do not modify the ICCP
        state machine defined in <xref target="RFC7275"/>. ICCP
        continues to manage the primary peer relationship. The
        relay messages are carried in the new ICCP Application TLV
        type allocated in <xref target="iana-apptype"/>; the version
        negotiation procedures of <xref target="RFC7275"/>
        Section 4.4.1 apply.</t>
      </section>

      <section anchor="rel-evpn" numbered="true" toc="include">
        <name>EVPN Multi-Homing</name>
        <t>In deployments using EVPN multi-homing
        <xref target="RFC7432"/> <xref target="RFC9786"/> rather
        than ICCP, the procedures in this document can serve as a
        forwarding-plane complement. EVPN mass-withdraw provides
        control-plane convergence; the procedures here provide
        pre-provisioned data-plane recovery that does not depend on
        control-plane reconvergence timing.</t>
      </section>
    </section>

    <!-- ================ OPERATIONAL ================ -->
    <section anchor="operational" numbered="true" toc="include">
      <name>Operational Considerations</name>

      <section anchor="op-bandwidth" numbered="true" toc="include">
        <name>ICL Capacity Planning</name>
        <t>During failure conditions the ICL carries redirected
        traffic in addition to its normal load. Operators MUST
        provision ICL capacity for the worst-case scenario. The
        recommended capacity is at least equal to the aggregate
        downlink capacity of the largest MC-LAG group.</t>
      </section>

      <section anchor="op-hash" numbered="true" toc="include">
        <name>Hash Redistribution</name>
        <t>Modifying the LAG member set causes the hash function to
        remap some flows. This may produce transient packet
        reordering bounded by the depth of in-flight packets.
        Applications requiring strict ordering should employ
        higher-layer reordering tolerance.</t>
      </section>

      <section anchor="op-dampening" numbered="true" toc="include">
        <name>Flap Dampening</name>
        <t>Implementations MUST support configurable dampening of
        member-set changes and relay state transitions to prevent
        rapid oscillation caused by link flapping.</t>
      </section>
    </section>

    <!-- ================ SECURITY ================ -->
    <section anchor="security" numbered="true" toc="include">
      <name>Security Considerations</name>
      <t>The forwarding state preservation procedure
      (<xref target="fwd-preserve"/>) is a local forwarding-plane
      operation with no signaling-based attack surface. The peer
      notification via ICCP MUST be protected using the
      authentication mechanisms of <xref target="RFC7275"/>.</t>

      <t>The ICL relay procedure (<xref target="icl-relay"/>)
      introduces relay messages that alter the forwarding topology.
      All relay messages MUST be authenticated. Implementations
      SHOULD support HMAC-SHA-256 keyed digests with pre-shared
      keys, consistent with <xref target="RFC7275"/>. All secondary
      ICLs MUST traverse network segments under common
      administrative control.</t>

      <t>Implementations MUST support rate limiting of relay
      messages. The hop count ceiling provides an additional bound
      on message amplification.</t>

      <t>During failure conditions the ICL carries increased
      traffic. Operators SHOULD apply monitoring to detect unusual
      patterns that may indicate an attack.</t>
    </section>

    <!-- ================ IANA ================ -->
    <section anchor="iana" numbered="true" toc="include">
      <name>IANA Considerations</name>

      <section anchor="iana-apptype" numbered="true" toc="include">
        <name>ICCP Application Type</name>
        <t>IANA is requested to allocate one Application Type value
        for "MC-LAG ICL Relay" from the "ICC RG Parameter Type"
        registry established by <xref target="RFC7275"/>. The
        reference is this document.</t>
      </section>

      <section anchor="iana-msgtypes" numbered="true" toc="include">
        <name>MC-LAG ICL Relay Message Types Registry</name>
        <t>IANA is requested to create a new registry, "MC-LAG ICL
        Relay Message Types", with an 8-bit value range (0-255).
        The assignment policy is "IETF Review"
        <xref target="RFC8126"/>. The initial contents are below.
        Value 0 is Reserved.</t>
        <table anchor="tab-msgtypes">
          <name>Initial MC-LAG ICL Relay Message Types</name>
          <thead>
            <tr><th>Value</th><th>Name</th><th>Reference</th></tr>
          </thead>
          <tbody>
            <tr><td>0</td><td>Reserved</td><td>This document</td></tr>
            <tr><td>1</td><td>Failover-Request</td><td>This document</td></tr>
            <tr><td>2</td><td>Failover-Response</td><td>This document</td></tr>
            <tr><td>3</td><td>Liveness</td><td>This document</td></tr>
            <tr><td>4</td><td>Revert-Request</td><td>This document</td></tr>
            <tr><td>5</td><td>Revert-Response</td><td>This document</td></tr>
            <tr><td>6-255</td><td>Unassigned</td><td></td></tr>
          </tbody>
        </table>
      </section>

      <section anchor="iana-status" numbered="true" toc="include">
        <name>MC-LAG ICL Relay Status Codes Registry</name>
        <t>IANA is requested to create a new registry, "MC-LAG ICL
        Relay Failover-Response Status Codes", with an 8-bit value
        range (0-255). The assignment policy is "IETF Review"
        <xref target="RFC8126"/>. The initial contents are the
        values defined in <xref target="tab-status"/> (0 = Success,
        1 = No-Resource, 2 = Loop-Detected, 3 = Hop-Limit-Exceeded);
        values 4-255 are Unassigned.</t>
      </section>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/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"/>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/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"/>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="RFC7275" target="https://www.rfc-editor.org/info/rfc7275">
          <front>
            <title>Inter-Chassis Communication Protocol for Layer 2 Virtual Private Network (L2VPN) Provider Edge (PE) Redundancy</title>
            <author fullname="L. Martini" initials="L." surname="Martini"/>
            <author fullname="S. Salam" initials="S." surname="Salam"/>
            <author fullname="A. Sajassi" initials="A." surname="Sajassi"/>
            <author fullname="M. Bocci" initials="M." surname="Bocci"/>
            <author fullname="S. Matsushima" initials="S." surname="Matsushima"/>
            <author fullname="T. Nadeau" initials="T." surname="Nadeau"/>
            <date month="June" year="2014"/>
          </front>
          <seriesInfo name="RFC" value="7275"/>
          <seriesInfo name="DOI" value="10.17487/RFC7275"/>
        </reference>
        <reference anchor="RFC1982" target="https://www.rfc-editor.org/info/rfc1982">
          <front>
            <title>Serial Number Arithmetic</title>
            <author fullname="R. Elz" initials="R." surname="Elz"/>
            <author fullname="R. Bush" initials="R." surname="Bush"/>
            <date month="August" year="1996"/>
          </front>
          <seriesInfo name="RFC" value="1982"/>
          <seriesInfo name="DOI" value="10.17487/RFC1982"/>
        </reference>
        <reference anchor="RFC8126" target="https://www.rfc-editor.org/info/rfc8126">
          <front>
            <title>Guidelines for Writing an IANA Considerations
            Section in RFCs</title>
            <author fullname="M. Cotton" initials="M." surname="Cotton"/>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <author fullname="T. Narten" initials="T." surname="Narten"/>
            <date month="June" year="2017"/>
          </front>
          <seriesInfo name="BCP" value="26"/>
          <seriesInfo name="RFC" value="8126"/>
          <seriesInfo name="DOI" value="10.17487/RFC8126"/>
        </reference>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="RFC7432" target="https://www.rfc-editor.org/info/rfc7432">
          <front>
            <title>BGP MPLS-Based Ethernet VPN</title>
            <author fullname="A. Sajassi" initials="A." surname="Sajassi"/>
            <author fullname="R. Aggarwal" initials="R." surname="Aggarwal"/>
            <author fullname="N. Bitar" initials="N." surname="Bitar"/>
            <author fullname="A. Isaac" initials="A." surname="Isaac"/>
            <author fullname="J. Uttaro" initials="J." surname="Uttaro"/>
            <author fullname="J. Drake" initials="J." surname="Drake"/>
            <author fullname="W. Henderickx" initials="W." surname="Henderickx"/>
            <date month="February" year="2015"/>
          </front>
          <seriesInfo name="RFC" value="7432"/>
          <seriesInfo name="DOI" value="10.17487/RFC7432"/>
        </reference>
        <reference anchor="RFC9786" target="https://www.rfc-editor.org/info/rfc9786">
          <front>
            <title>EVPN Port-Active Redundancy Mode</title>
            <author fullname="P. Brissette" initials="P." surname="Brissette"/>
            <author fullname="S. Thoria" initials="S." surname="Thoria"/>
            <author fullname="A. Sajassi" initials="A." surname="Sajassi"/>
            <date year="2025"/>
          </front>
          <seriesInfo name="RFC" value="9786"/>
          <seriesInfo name="DOI" value="10.17487/RFC9786"/>
        </reference>
        <reference anchor="IEEE802.1AX" target="https://standards.ieee.org/standard/802_1AX-2020.html">
          <front>
            <title>IEEE Standard for Local and Metropolitan Area Networks - Link Aggregation</title>
            <author>
              <organization>IEEE</organization>
            </author>
            <date year="2020"/>
          </front>
          <seriesInfo name="IEEE" value="802.1AX-2020"/>
        </reference>
      </references>
    </references>

    <section anchor="appendix-comparison" numbered="true" toc="include">
      <name>Comparison with Existing Approaches</name>
      <figure anchor="fig-comparison">
        <name>Failover Approach Comparison</name>
        <artwork type="ascii-art"><![CDATA[
+---------------------+----------+----------+-----------+
|                     | MAC      | EVPN     | Fwd-Plane |
| Property            | Table    | Mass-    | Recovery  |
|                     | Flush    | Withdraw | (Herein)  |
+---------------------+----------+----------+-----------+
| MAC Table Impact    | Full     | Partial  | None      |
|                     | flush    | update   |           |
+---------------------+----------+----------+-----------+
| Flooding During     | Yes      | Brief    | No        |
| Failover            |          |          |           |
+---------------------+----------+----------+-----------+
| Convergence         | Seconds  | Sub-     | Forwarding|
| Timescale           |          | second   | plane     |
+---------------------+----------+----------+-----------+
| Multi-PE Recovery   | No       | Yes      | Yes       |
|                     |          | (BGP)    | (ICL)     |
+---------------------+----------+----------+-----------+
| Infrastructure      | None     | EVPN     | MC-LAG    |
| Dependency          |          |          | ICL       |
+---------------------+----------+----------+-----------+
]]></artwork>
      </figure>
    </section>

    <section anchor="appendix-timeline" numbered="true" toc="include">
      <name>Detailed Failover Timeline</name>
      <figure anchor="fig-timeline">
        <name>Failover and Reversion Timeline</name>
        <artwork type="ascii-art"><![CDATA[
Time  Event                     G1 Member Set   MAC Table
----  -----                     -------------   ---------
T0    Normal operation          {m1, m2}        X -> G1
T1    m1 link-down              {m2}            X -> G1
T2    ICL added to G1           {m2, ICL}       X -> G1
                                                (unchanged)
T3    Traffic via ICL to PE2    PE2 forwards    No flooding
                                via m3/m4
 ...
T10   m1 link-up                {m1, m2, ICL}   X -> G1
T11   ICL removed (hold timer)  {m1, m2}        X -> G1
                                                (unchanged)
]]></artwork>
      </figure>
    </section>
  </back>
</rfc>
