<?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-ecmp-adaptive-load-balance-00"
     xml:lang="en"
     tocInclude="true"
     sortRefs="true"
     symRefs="true"
     version="3">

  <front>
    <title abbrev="Adaptive ECMP Load Balancing">Adaptive Load
    Balancing for Equal-Cost Multipath (ECMP)</title>
    <seriesInfo name="Internet-Draft"
                value="draft-yang-rtgwg-ecmp-adaptive-load-balance-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="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="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="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="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>ECMP</keyword>
    <keyword>load balancing</keyword>
    <keyword>flow placement</keyword>
    <keyword>next-hop selection</keyword>
    <keyword>LAG</keyword>

    <abstract>
      <t>
        Equal-Cost Multipath (ECMP) forwarding assigns a flow to a
        next-hop by computing a hash over packet header fields when
        the flow is first seen. Because the assignment does not
        change after that, the load across the paths of an ECMP
        group can become uneven when the set of paths changes or
        when traffic shifts among existing flows. This document
        defines procedures for adaptive ECMP load balancing in which
        a forwarding node periodically measures per-path load,
        determines whether the load is sufficiently uneven to act
        on, and makes a bounded number of incremental flow placement
        changes toward less-used paths. The procedures preserve
        per-flow packet ordering for all but the small number of
        flows that are moved in any interval, and they converge
        toward a balanced distribution across the group. The
        procedures operate within a single forwarding node and add
        no new packet formats or inter-node signaling.
      </t>
    </abstract>
  </front>

  <middle>
    <section anchor="intro" numbered="true" toc="include">
      <name>Introduction</name>

      <t>
        Equal-Cost Multipath (ECMP) routing <xref target="RFC2991"/>
        lets a forwarding node distribute IP traffic over several
        next-hops of equal routing cost. The forwarding decision is
        commonly made by hashing selected packet header fields and
        mapping each flow to one path. <xref target="RFC2992"/>
        analyzes the hash-threshold algorithm that is widely used
        for this purpose and discusses the trade-off between
        distribution uniformity and the disruption that occurs when
        paths are added or removed.
      </t>

      <t>
        Hash-based path selection gives a reasonable initial
        distribution and preserves per-flow packet ordering, but the
        assignment is fixed: once a flow is mapped to a path it stays
        there regardless of later changes to the group or to traffic.
        As a result the load across the paths of a group can become
        uneven over time. This is a known operational effect.
      </t>

      <t>
        <xref target="RFC7424"/> describes techniques for
        identifying large ("elephant") flows and selectively moving
        them across LAG or ECMP component links to improve
        utilization. That document is Informational, addresses
        primarily the classification of large flows, and does not
        define normative requirements for general load-aware path
        selection.
      </t>

      <t>
        This document defines normative procedures for load-aware
        ECMP path selection that apply to all flows in an ECMP
        group, not only to large flows. The procedures rest on three
        elements: periodic measurement of per-path load, a bounded
        number of flow placement changes per interval to limit the
        rate of path changes, and operator-controlled parameters
        that govern the behavior. The procedures supplement, and do
        not replace, the existing hash-based path selection: they add
        a load-aware feedback loop on top of the hash function. The
        procedures carry MUST-level requirements on forwarding-node
        behavior and are therefore on the Standards Track.
      </t>

      <t>
        The relationship of these procedures to entropy-improving
        mechanisms and to other load-balancing work is described in
        <xref target="related"/>.
      </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="problem" numbered="true" toc="include">
      <name>Problem Statement</name>

      <t>
        Hash-based ECMP next-hop selection gives a one-time,
        deterministic mapping from a flow identifier to a path. The
        mapping does not account for runtime conditions, which leads
        to uneven load in at least the following cases.
      </t>

      <dl newline="true" spacing="normal">
        <dt>Path Addition</dt>
        <dd>
          When a new equal-cost next-hop becomes available, for
          example when a link comes up or a route is installed, only
          newly arriving flows are candidates for the new path.
          Existing flows stay on their assigned paths. The new path
          can remain under-used until enough flows turn over
          naturally, which takes an unpredictable time that depends
          on flow lifetimes.
        </dd>

        <dt>Asymmetric Flow Departure</dt>
        <dd>
          When flows end unevenly across paths, for example when
          several long-lived flows on one path end while flows on
          other paths continue, the load becomes uneven. The capacity
          freed on the path with departing flows is not taken up by
          flows on the more heavily used paths.
        </dd>

        <dt>Traffic Rate Variation</dt>
        <dd>
          Even when the set of active flows is stable, changes in
          per-flow rate, for example a flow entering a bulk-transfer
          phase, can make the load on one path diverge from the
          others. A static hash assignment does not respond to such
          rate changes.
        </dd>
      </dl>

      <t>
        In each case the forwarding node has enough local
        information, in the form of per-path counters and flow-table
        state, to detect the imbalance, but a hash-only ECMP
        implementation does not act on it. This document specifies
        how a forwarding node uses locally available load data to
        make incremental changes to flow placement.
      </t>
    </section>

    <section anchor="terminology" numbered="true" toc="include">
      <name>Terminology</name>

      <t>
        This document uses the following terms. Where applicable, the
        definitions of <xref target="RFC2991"/> and
        <xref target="RFC7424"/> are reused.
      </t>

      <dl newline="true" spacing="normal">
        <dt>ECMP Group</dt>
        <dd>
          A set of equal-cost next-hops toward the same destination
          prefix, among which traffic is forwarded. A Link
          Aggregation Group (LAG) is treated as the logical
          equivalent of an ECMP group in this document.
        </dd>

        <dt>Path (Component Link)</dt>
        <dd>
          An individual next-hop within an ECMP group. The term
          "component link" is used interchangeably, consistent with
          <xref target="RFC7424"/>.
        </dd>

        <dt>Flow</dt>
        <dd>
          A sequence of packets that share common header fields and
          are treated as a unit for path selection. The flow
          granularity, for example a 5-tuple or a 3-tuple, is set by
          the hashing policy and is outside the scope of this
          document.
        </dd>

        <dt>Load Metric</dt>
        <dd>
          A quantitative measure of the traffic carried by a path
          over a measurement window, for example a forwarded byte
          count, a forwarded packet count, or a count of active
          flows.
        </dd>

        <dt>Imbalance Ratio (IR)</dt>
        <dd>
          A dimensionless measure of the degree of load skew across
          the paths of an ECMP group, defined in
          <xref target="imbalance-eval"/>.
        </dd>

        <dt>Reassignment Limit</dt>
        <dd>
          An upper bound on the number of flow placement changes that
          may be made within one evaluation interval. It is derived
          from the observed imbalance and controls the rate of
          change.
        </dd>

        <dt>Evaluation Interval</dt>
        <dd>
          The periodic window at which the forwarding node collects
          load metrics, assesses imbalance, and determines whether
          placement changes are warranted.
        </dd>
      </dl>
    </section>

    <section anchor="objectives" numbered="true" toc="include">
      <name>Design Objectives</name>

      <t>
        The procedures defined in this document follow these
        objectives.
      </t>

      <dl newline="true" spacing="normal">
        <dt>Minimal Disruption</dt>
        <dd>
          The number of flows whose paths change in any interval
          <bcp14>MUST</bcp14> be bounded. Unbounded path changes would
          cause widespread packet reordering and degrade transport
          performance <xref target="RFC2992"/>.
        </dd>

        <dt>Proportional Response</dt>
        <dd>
          The number of flow placement changes
          <bcp14>SHOULD</bcp14> be proportional to the severity of
          the imbalance. When the load is within bounds, no changes
          are made; when the imbalance is large, more changes are
          permitted per interval to converge faster.
        </dd>

        <dt>Incremental Convergence</dt>
        <dd>
          Load balancing <bcp14>SHOULD</bcp14> converge over
          successive intervals rather than attempting to reach a
          balanced state in a single step. Incremental convergence
          avoids oscillation and gives stable behavior.
        </dd>

        <dt>Operational Control</dt>
        <dd>
          All parameters, including thresholds, limits, intervals,
          and eligible flow classes, <bcp14>MUST</bcp14> be
          configurable by the operator. The procedures
          <bcp14>MUST</bcp14> be able to be disabled on a per-group
          basis without affecting other groups.
        </dd>
      </dl>

      <figure anchor="fig-overview">
        <name>High-Level Operation</name>
        <artwork type="ascii-art"><![CDATA[
    +---------------------+
    | Evaluation Interval |
    | Timer Expires       |
    +----------+----------+
               |
               v
    +---------------------+
    | Collect per-path    |
    | load metrics        |
    +----------+----------+
               |
               v
    +---------------------+
    | Compute Imbalance   |
    | Ratio (IR)          |
    +----------+----------+
               |
        +------+------+
        | IR < thresh?|-----> No action; wait for
        +------+------+       next interval
               | no
               v
    +---------------------+
    | Derive reassignment |
    | limit from IR       |
    +----------+----------+
               |
               v
    +---------------------+
    | Adjust flow         |
    | placement (up to    |
    | limit) on eligible  |
    | events              |
    +---------------------+
]]></artwork>
      </figure>
    </section>

    <section anchor="assessment" numbered="true" toc="include">
      <name>Load Measurement</name>

      <section anchor="util-metrics" numbered="true" toc="include">
        <name>Load Metrics</name>

        <t>
          A forwarding node that implements these procedures
          <bcp14>MUST</bcp14> maintain per-path load metrics for each
          ECMP group on which adaptive load balancing is enabled. The
          node <bcp14>MUST</bcp14> support at least one of the
          following metric types.
        </t>

        <ul spacing="normal">
          <li>
            Forwarded byte count over the evaluation interval. This
            reflects bandwidth use and is <bcp14>RECOMMENDED</bcp14>
            as the default.
          </li>
          <li>
            Forwarded packet count over the evaluation interval.
          </li>
          <li>
            Number of distinct active flows observed during the
            evaluation interval.
          </li>
        </ul>

        <t>
          A node <bcp14>MAY</bcp14> support a weighted combination of
          metrics or additional implementation-defined metrics. The
          active metric type <bcp14>SHOULD</bcp14> be configurable per
          group.
        </t>

        <t>
          The evaluation interval <bcp14>MUST</bcp14> be configurable
          with a granularity of at least 100 milliseconds. The
          default interval <bcp14>SHOULD</bcp14> be 1 second. An
          interval shorter than 100 milliseconds is
          <bcp14>NOT RECOMMENDED</bcp14> because of the processing
          cost of frequent measurement.
        </t>
      </section>

      <section anchor="imbalance-eval" numbered="true"
               toc="include">
        <name>Imbalance Assessment</name>

        <t>
          At each evaluation interval the forwarding node computes
          the imbalance ratio (IR) across the N paths of the ECMP
          group. Let U_i be the measured load metric for path i,
          where 1 &lt;= i &lt;= N.
        </t>

        <sourcecode type="pseudocode"><![CDATA[
    U_max = max(U_1, U_2, ..., U_N)
    U_min = min(U_1, U_2, ..., U_N)
    U_avg = (sum of all U_i) / N

    IR = (U_max - U_min) / U_avg,  when U_avg > 0
    IR = 0,                        when U_avg = 0
]]></sourcecode>

        <t>
          The IR is compared with a configurable imbalance threshold
          (T_imb). When IR is below T_imb, the load is considered
          acceptable and no flow placement change is made during the
          interval.
        </t>

        <t>
          The default T_imb <bcp14>SHOULD</bcp14> be 0.3, which
          corresponds to a 30 percent normalized deviation. An
          operator <bcp14>MAY</bcp14> change this value: a lower
          threshold reacts to smaller imbalances at the cost of more
          frequent changes, and a higher threshold reduces the
          frequency of changes at the cost of tolerating more skew.
        </t>
      </section>

      <section anchor="limit-derivation" numbered="true"
               toc="include">
        <name>Reassignment Limit Derivation</name>

        <t>
          When IR &gt;= T_imb, the forwarding node derives a
          reassignment limit (R_lim) that bounds the number of flow
          placement changes made during the interval. The derivation
          of R_lim <bcp14>MUST</bcp14> satisfy the following
          properties.
        </t>

        <dl newline="true" spacing="normal">
          <dt>Non-decreasing</dt>
          <dd>
            R_lim <bcp14>MUST</bcp14> be a non-decreasing function of
            IR, so that a larger imbalance permits more changes per
            interval.
          </dd>

          <dt>Bounded</dt>
          <dd>
            R_lim <bcp14>MUST NOT</bcp14> exceed a configurable upper
            bound (R_max), which prevents excessive changes under
            extreme conditions. The default R_max
            <bcp14>SHOULD</bcp14> be proportional to the number of
            active flows in the group, with a
            <bcp14>RECOMMENDED</bcp14> default of min(F/10, 16), where
            F is the number of active flows. A node
            <bcp14>MAY</bcp14> use a fixed default, for example 8,
            when the active flow count is not readily available.
          </dd>

          <dt>Zero Below Threshold</dt>
          <dd>
            When IR &lt; T_imb, R_lim <bcp14>MUST</bcp14> be zero.
          </dd>
        </dl>

        <t>
          The function used to map IR to R_lim is an implementation
          choice. Linear, piecewise-linear, and step functions are
          all acceptable, provided the properties above hold.
        </t>

        <t>
          The following is a non-normative example of a compliant
          function.
        </t>

        <sourcecode type="pseudocode"><![CDATA[
    R_lim = 0,                          when IR < T_imb
    R_lim = min(R_max, ceil(IR * S)),   when IR >= T_imb

    where S is a configurable scaling factor (default: 10).
]]></sourcecode>

        <t>
          This example is given for clarity only. An implementation
          may use any function that satisfies the stated properties.
        </t>
      </section>
    </section>

    <section anchor="placement" numbered="true" toc="include">
      <name>Flow Placement Adjustment</name>

      <section anchor="eligible-events" numbered="true"
               toc="include">
        <name>Eligible Events</name>

        <t>
          Flow placement changes are made in response to specific
          forwarding-plane events, subject to the reassignment limit
          for the interval. Each change consumes one unit of the
          reassignment limit. The following event types are defined.
        </t>

        <dl newline="true" spacing="normal">
          <dt>New Flow Arrival</dt>
          <dd>
            On the first packet of a previously unseen flow, the node
            <bcp14>MAY</bcp14> assign the flow to the least-used path
            rather than to the path given by the hash function. A
            node <bcp14>MUST</bcp14> support this event type.
          </dd>

          <dt>Flow Expiration</dt>
          <dd>
            When a flow entry ages out or is cleared, the resulting
            change in per-path load <bcp14>MAY</bcp14> trigger the
            reassignment of another flow from a more heavily used
            path to a less used path. Support for this event type is
            <bcp14>RECOMMENDED</bcp14>.
          </dd>

          <dt>Periodic Sweep</dt>
          <dd>
            A background process <bcp14>MAY</bcp14> iterate over local
            flow state and select flows on the most-used path for
            reassignment to the least-used path. Support for this
            event type is <bcp14>OPTIONAL</bcp14>.
          </dd>

          <dt>Operator-Initiated</dt>
          <dd>
            A management action <bcp14>MAY</bcp14> request that the
            node make flow placement changes, for example during a
            maintenance window. Support for this event type is
            <bcp14>OPTIONAL</bcp14>.
          </dd>
        </dl>

        <t>
          The set of active event types <bcp14>SHOULD</bcp14> be
          configurable. When more than one event type is enabled, any
          of them may trigger a change while the reassignment limit
          for the interval has not been reached.
        </t>
      </section>

      <section anchor="path-selection" numbered="true"
               toc="include">
        <name>Target Path Selection</name>

        <t>
          When a flow placement change is made, the target path
          <bcp14>MUST</bcp14> be the path with the lowest current
          load metric in the group at the time of the decision. When
          more than one path shares the lowest load, the node
          <bcp14>MAY</bcp14> choose any of them, for example by a
          secondary hash or round-robin among the candidates.
        </t>

        <t>
          When a change is triggered by a periodic sweep or a flow
          expiration, the source path from which a flow is selected
          <bcp14>MUST</bcp14> be the path with the highest current
          load metric. The choice of which flow to move from the
          source path is an implementation decision. A node
          <bcp14>SHOULD</bcp14> prefer flows with lower instantaneous
          rate, to limit the effect of reordering on any single flow.
        </t>
      </section>

      <section anchor="rate-control" numbered="true" toc="include">
        <name>Rate of Path Changes</name>

        <t>
          The reassignment limit is the primary means of controlling
          the rate of flow placement changes. Each change reduces the
          remaining limit by one for the interval. When the remaining
          limit reaches zero, no further changes are made until the
          next interval begins with a freshly derived limit.
        </t>

        <t>
          A node <bcp14>MUST NOT</bcp14> carry over unused
          reassignment capacity from one interval to the next. The
          limit is derived anew at each interval from the load
          observed for that interval. This prevents the accumulation
          of unused capacity that could otherwise cause a burst of
          path changes.
        </t>

        <t>
          The combination of a bounded limit and periodic evaluation
          forms a self-regulating feedback loop. Over successive
          intervals the per-path load converges toward the threshold.
          Once IR falls below T_imb, the limit becomes zero and
          changes stop until conditions change.
        </t>
      </section>
    </section>

    <section anchor="interactions" numbered="true" toc="include">
      <name>Interaction with Existing Forwarding Behavior</name>

      <section anchor="int-hash" numbered="true" toc="include">
        <name>Coexistence with Hash-Based Path Selection</name>

        <t>
          These procedures supplement, and do not replace, the
          existing hash-based ECMP next-hop selection. The hash
          function remains the default path selection method for all
          flows. A load-aware placement change overrides the
          hash-based assignment only for a specific flow and only
          when the derived reassignment limit permits it.
        </t>

        <t>
          When adaptive load balancing is disabled, or when the
          reassignment limit is zero, the node <bcp14>MUST</bcp14> use
          the standard hash-based path selection for all flows.
        </t>
      </section>

      <section anchor="int-lag" numbered="true" toc="include">
        <name>Applicability to Link Aggregation Groups</name>

        <t>
          A LAG selects a member link by a hash in a manner analogous
          to ECMP next-hop selection. These procedures apply equally
          to LAG member selection. When applied to a LAG, the
          references in this document to "ECMP group" and "path" apply
          to the LAG and its component links respectively.
        </t>

        <t>
          A node that implements adaptive load balancing for both
          ECMP groups and LAGs <bcp14>SHOULD</bcp14> manage them
          independently, since each has its own membership, load, and
          parameters.
        </t>
      </section>

      <section anchor="int-mpls" numbered="true" toc="include">
        <name>MPLS Environments</name>

        <t>
          In MPLS environments, entropy labels
          <xref target="RFC6790"/> add input to the hash and improve
          the uniformity of the initial flow placement. Even with
          entropy labels, the fixed nature of the hash assignment
          means that imbalance can develop over time, so these
          procedures remain applicable as a complementary technique.
        </t>
      </section>
    </section>

    <section anchor="related" numbered="true" toc="include">
      <name>Relationship to Other Work</name>

      <t>
        The procedures in this document make the path-selection
        decision load-aware. A separate class of mechanisms instead
        improves the entropy that is fed into a static hash, so that
        the initial distribution is more uniform; examples are MPLS
        entropy labels <xref target="RFC6790"/>, the IPv6 flow label
        <xref target="RFC6438"/>, and, for IPsec ESP traffic, the ESP
        Entropy Header
        <xref target="I-D.yang-ipsecme-esp-entropy-header"/>. These
        entropy-improving mechanisms and the load-aware procedures of
        this document address different aspects of the same problem
        and are complementary: better entropy improves the initial
        distribution, while load-aware placement corrects the skew
        that develops after flows are assigned. Neither removes the
        need for the other.
      </t>

      <t>
        <xref target="I-D.li-adaptive-load-balance-enhancement"/>
        also addresses adaptive load balancing for ECMP, with an
        emphasis on flowlet-based methods and the difficulty of
        configuring a flowlet timeout. The procedures in this
        document differ in that they operate as a node-local feedback
        loop with an explicit imbalance assessment and a bounded,
        proportional number of flow placement changes per interval,
        and they are not tied to flowlet detection. The two
        approaches may inform each other; this document does not
        depend on flowlet detection.
      </t>
    </section>

    <section anchor="applicability" numbered="true" toc="include">
      <name>Applicability Considerations</name>

      <section anchor="app-dc" numbered="true" toc="include">
        <name>Data Center Fabrics</name>

        <t>
          Data center leaf-spine fabrics commonly use large numbers
          of ECMP paths <xref target="RFC7938"/>. The combination of
          high path count, a mix of flow sizes including long-lived
          storage and compute flows, and high utilization targets
          makes these environments prone to hash-induced load skew.
          These procedures can improve fabric-wide load balancing
          without a central controller.
        </t>
      </section>

      <section anchor="app-wan" numbered="true" toc="include">
        <name>Wide Area Networks</name>

        <t>
          In WAN environments where ECMP is used across parallel
          links or tunnels, the smaller number of concurrent flows
          and their longer lifetimes increase the effect of each flow
          placement decision on the aggregate load. An operator that
          deploys these procedures in a WAN <bcp14>SHOULD</bcp14>
          consider a longer evaluation interval and a lower
          reassignment limit, to reflect the higher cost of a path
          change in a wide-area topology.
        </t>
      </section>
    </section>

    <section anchor="operations" numbered="true" toc="include">
      <name>Operational Considerations</name>

      <section anchor="op-params" numbered="true" toc="include">
        <name>Configuration Parameters</name>

        <t>
          The following parameters govern the behavior described in
          this document. A node <bcp14>MUST</bcp14> allow these
          parameters to be configured per ECMP group, or per LAG.
        </t>

        <table anchor="tab-params">
          <name>Configuration Parameters</name>
          <thead>
            <tr>
              <th>Parameter</th>
              <th>Description</th>
              <th>Default</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Enable/Disable</td>
              <td>Activate or deactivate adaptive load balancing for
              the group</td>
              <td>Disabled</td>
            </tr>
            <tr>
              <td>Evaluation Interval</td>
              <td>Time between consecutive load assessments</td>
              <td>1 second</td>
            </tr>
            <tr>
              <td>Load Metric Type</td>
              <td>Metric used for per-path comparison</td>
              <td>Byte count</td>
            </tr>
            <tr>
              <td>Imbalance Threshold (T_imb)</td>
              <td>IR below which no change is made</td>
              <td>0.3</td>
            </tr>
            <tr>
              <td>Maximum Reassignment Limit (R_max)</td>
              <td>Upper bound on flow placement changes per
              interval</td>
              <td>8</td>
            </tr>
            <tr>
              <td>Active Event Types</td>
              <td>Which events may trigger a change</td>
              <td>New flow arrival</td>
            </tr>
          </tbody>
        </table>

        <t>
          A parameter change <bcp14>SHOULD</bcp14> take effect at the
          start of the next evaluation interval, to avoid
          inconsistent behavior during a running interval. Disabling
          the feature <bcp14>MUST</bcp14> cause the node to stop
          making load-aware changes immediately and to revert to
          hash-based path selection for subsequent flows. Flows that
          were previously moved <bcp14>MAY</bcp14> remain on their
          current paths; the node is not required to return them to
          their hash-computed paths on disablement.
        </t>
      </section>

      <section anchor="op-exclusion" numbered="true" toc="include">
        <name>Flow Exclusion Policies</name>

        <t>
          Some traffic classes require path persistence and
          <bcp14>MUST NOT</bcp14> be subject to flow placement
          change. A node <bcp14>MUST</bcp14> support the configuration
          of exclusion policies that identify flows exempt from
          change. Examples of traffic that requires exclusion are the
          following.
        </t>

        <ul spacing="normal">
          <li>
            Flows that traverse stateful middleboxes such as
            firewalls, NAT gateways, or intrusion prevention systems,
            where a path change would invalidate session state.
          </li>
          <li>
            Real-time media flows, such as voice or video, that are
            sensitive to jitter and reordering.
          </li>
          <li>
            Flows marked with a DSCP value that indicates a path
            affinity requirement.
          </li>
        </ul>

        <t>
          An exclusion policy <bcp14>SHOULD</bcp14> support matching
          on standard packet header fields, including source and
          destination address prefixes, protocol numbers, port
          ranges, and DSCP values. An excluded flow
          <bcp14>MUST NOT</bcp14> consume reassignment capacity and
          <bcp14>MUST</bcp14> remain on its hash-assigned path.
        </t>
      </section>

      <section anchor="op-monitoring" numbered="true"
               toc="include">
        <name>Monitoring</name>

        <t>
          A node <bcp14>SHOULD</bcp14> expose the following
          operational state for each ECMP group on which adaptive
          load balancing is enabled.
        </t>

        <ul spacing="normal">
          <li>Current per-path load metric values.</li>
          <li>Most recently computed imbalance ratio.</li>
          <li>
            Reassignment limit derived for the current interval and
            the portion consumed.
          </li>
          <li>
            Cumulative count of flow placement changes since the
            feature was enabled.
          </li>
          <li>Number of flows currently excluded by policy.</li>
        </ul>

        <t>
          This state <bcp14>SHOULD</bcp14> be accessible through
          standard management interfaces, such as a YANG-based
          management protocol <xref target="RFC8343"/>, SNMP, or
          streaming telemetry. This document does not define a data
          model.
        </t>
      </section>

      <section anchor="op-deployment" numbered="true"
               toc="include">
        <name>Deployment Guidance</name>

        <t>
          An operator is advised to adopt a conservative initial
          posture.
        </t>

        <ul spacing="normal">
          <li>
            Enable the feature on a small number of ECMP groups first
            and observe the imbalance ratio and change counts before
            wider rollout.
          </li>
          <li>
            Use a higher imbalance threshold, for example 0.5, and a
            lower reassignment limit initially, then tighten the
            parameters as confidence grows.
          </li>
          <li>
            Ensure that all stateful middlebox traversals are covered
            by exclusion policies before enabling the feature.
          </li>
        </ul>
      </section>
    </section>

    <section anchor="conformance" numbered="true" toc="include">
      <name>Conformance and Interoperability</name>

      <t>
        The procedures in this document constrain the
        forwarding-plane behavior of a single node and do not define
        any new packet format, header field, or inter-node protocol.
        The packets a conforming node emits are bit-for-bit
        indistinguishable from those of a node that performs only
        hash-based path selection; a flow placement change alters
        which member of an ECMP group or LAG a flow egresses on, not
        the contents of the flow's packets. Interoperability with
        neighbors, with transport endpoints, and with existing ECMP
        and LAG deployments is therefore preserved unconditionally.
      </t>

      <t>
        The normative requirements in this document are stated as
        externally observable properties so that conformance can be
        verified without access to a node's internal implementation.
        In particular, a conforming implementation:
      </t>

      <ul spacing="normal">
        <li>
          changes the path of no more than the derived reassignment
          limit (<xref target="limit-derivation"/>) of flows in any
          evaluation interval, and makes no changes while the
          imbalance ratio is below the configured threshold
          (<xref target="imbalance-eval"/>);
        </li>
        <li>
          preserves per-flow ordering for every flow that is not
          moved in a given interval, and moves a flow at most as a
          single, atomic change of egress member;
        </li>
        <li>
          never moves a flow that matches a configured exclusion
          policy (<xref target="op-exclusion"/>);
        </li>
        <li>
          reverts to hash-based path selection for subsequent flows
          when the feature is disabled
          (<xref target="op-params"/>); and
        </li>
        <li>
          exposes the operational state of
          <xref target="op-monitoring"/> through which the preceding
          properties can be observed.
        </li>
      </ul>

      <t>
        These properties are testable at a node's interfaces: an
        operator or test harness can offer a controlled traffic
        pattern, observe per-path load and the reported imbalance
        ratio, and confirm that the number and rate of flow
        movements respect the configured bounds and exclusions. The
        normative requirements thus give operators an enforceable
        basis for procurement and conformance testing, which is the
        reason this document is placed on the Standards Track even
        though it introduces no on-the-wire protocol element.
      </t>
    </section>

    <section anchor="security" numbered="true" toc="include">
      <name>Security Considerations</name>

      <t>
        The procedures in this document operate within the local
        forwarding plane of a single node. They introduce no new
        protocol messages, packet formats, or inter-node signaling,
        and so do not expand the control-plane attack surface.
      </t>

      <t>
        The following data-plane considerations apply.
      </t>

      <dl newline="true" spacing="normal">
        <dt>Stateful Middlebox Bypass</dt>
        <dd>
          A flow placement change causes a flow's packets to use a
          different path, which may bypass a stateful inspection
          device. An operator <bcp14>MUST</bcp14> configure exclusion
          policies (<xref target="op-exclusion"/>) for all flows
          subject to stateful processing.
        </dd>

        <dt>Induced Path Changes</dt>
        <dd>
          An attacker that can inject traffic with chosen flow
          identifiers could try to concentrate load on one path and
          cause repeated changes. The reassignment limit bounds the
          per-interval cost of such an attempt, the imbalance
          threshold prevents reaction to minor fluctuations, and the
          evaluation interval imposes a minimum time between rounds of
          changes. Together these bound the amplification.
        </dd>

        <dt>Flow State Resource Consumption</dt>
        <dd>
          A node that keeps per-flow state to support placement
          changes, for example to record which flows have been moved,
          <bcp14>SHOULD</bcp14> bound the size of that state to
          prevent memory exhaustion, especially where flow counts are
          high.
        </dd>
      </dl>
    </section>

    <section anchor="iana" numbered="true" toc="include">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </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>

      </references>

      <references>
        <name>Informative References</name>

        <reference anchor="RFC2991"
            target="https://www.rfc-editor.org/info/rfc2991">
          <front>
            <title>Multipath Issues in Unicast and Multicast Next-Hop
            Selection</title>
            <author fullname="D. Thaler" initials="D."
                    surname="Thaler"/>
            <author fullname="C. Hopps" initials="C."
                    surname="Hopps"/>
            <date month="November" year="2000"/>
          </front>
          <seriesInfo name="RFC" value="2991"/>
          <seriesInfo name="DOI" value="10.17487/RFC2991"/>
        </reference>

        <reference anchor="RFC2992"
            target="https://www.rfc-editor.org/info/rfc2992">
          <front>
            <title>Analysis of an Equal-Cost Multi-Path
            Algorithm</title>
            <author fullname="C. Hopps" initials="C."
                    surname="Hopps"/>
            <date month="November" year="2000"/>
          </front>
          <seriesInfo name="RFC" value="2992"/>
          <seriesInfo name="DOI" value="10.17487/RFC2992"/>
        </reference>

        <reference anchor="RFC6438"
            target="https://www.rfc-editor.org/info/rfc6438">
          <front>
            <title>Using the IPv6 Flow Label for Equal Cost Multipath
            Routing and Link Aggregation in Tunnels</title>
            <author fullname="B. Carpenter" initials="B."
                    surname="Carpenter"/>
            <author fullname="S. Amante" initials="S."
                    surname="Amante"/>
            <date month="November" year="2011"/>
          </front>
          <seriesInfo name="RFC" value="6438"/>
          <seriesInfo name="DOI" value="10.17487/RFC6438"/>
        </reference>

        <reference anchor="RFC6790"
            target="https://www.rfc-editor.org/info/rfc6790">
          <front>
            <title>The Use of Entropy Labels in MPLS
            Forwarding</title>
            <author fullname="K. Kompella" initials="K."
                    surname="Kompella"/>
            <author fullname="J. Drake" initials="J."
                    surname="Drake"/>
            <author fullname="S. Amante" initials="S."
                    surname="Amante"/>
            <author fullname="W. Henderickx" initials="W."
                    surname="Henderickx"/>
            <author fullname="L. Yong" initials="L."
                    surname="Yong"/>
            <date month="November" year="2012"/>
          </front>
          <seriesInfo name="RFC" value="6790"/>
          <seriesInfo name="DOI" value="10.17487/RFC6790"/>
        </reference>

        <reference anchor="RFC7424"
            target="https://www.rfc-editor.org/info/rfc7424">
          <front>
            <title>Mechanisms for Optimizing Link Aggregation Group
            (LAG) and Equal-Cost Multipath (ECMP) Component Link
            Utilization in Networks</title>
            <author fullname="R. Krishnan" initials="R."
                    surname="Krishnan"/>
            <author fullname="L. Yong" initials="L."
                    surname="Yong"/>
            <author fullname="A. Ghanwani" initials="A."
                    surname="Ghanwani"/>
            <author fullname="N. So" initials="N."
                    surname="So"/>
            <author fullname="B. Khasnabish" initials="B."
                    surname="Khasnabish"/>
            <date month="January" year="2015"/>
          </front>
          <seriesInfo name="RFC" value="7424"/>
          <seriesInfo name="DOI" value="10.17487/RFC7424"/>
        </reference>

        <reference anchor="RFC7938"
            target="https://www.rfc-editor.org/info/rfc7938">
          <front>
            <title>Use of BGP for Routing in Large-Scale Data
            Centers</title>
            <author fullname="P. Lapukhov" initials="P."
                    surname="Lapukhov"/>
            <author fullname="A. Premji" initials="A."
                    surname="Premji"/>
            <author fullname="J. Mitchell" initials="J."
                    surname="Mitchell" role="editor"/>
            <date month="August" year="2016"/>
          </front>
          <seriesInfo name="RFC" value="7938"/>
          <seriesInfo name="DOI" value="10.17487/RFC7938"/>
        </reference>

        <reference anchor="RFC8343"
            target="https://www.rfc-editor.org/info/rfc8343">
          <front>
            <title>A YANG Data Model for Interface
            Management</title>
            <author fullname="M. Bjorklund" initials="M."
                    surname="Bjorklund"/>
            <date month="March" year="2018"/>
          </front>
          <seriesInfo name="RFC" value="8343"/>
          <seriesInfo name="DOI" value="10.17487/RFC8343"/>
        </reference>

        <reference anchor="I-D.yang-ipsecme-esp-entropy-header">
          <front>
            <title>An Entropy Header for Load Balancing of IPsec ESP
            Traffic</title>
            <author fullname="J. Yang" initials="J."
                    surname="Yang"/>
            <author fullname="W. Cheng" initials="W."
                    surname="Cheng"/>
            <author fullname="J. Wang" initials="J."
                    surname="Wang"/>
            <author fullname="G. Zhang" initials="G."
                    surname="Zhang"/>
            <date year="2026"/>
          </front>
          <seriesInfo name="Internet-Draft"
              value="draft-yang-ipsecme-esp-entropy-header-00"/>
        </reference>

        <reference
            anchor="I-D.li-adaptive-load-balance-enhancement">
          <front>
            <title>Adaptive Load Balance Enhancement</title>
            <author fullname="Z. Li" initials="Z."
                    surname="Li"/>
            <date year="2025"/>
          </front>
          <seriesInfo name="Internet-Draft"
              value="draft-li-adaptive-load-balance-enhancement-00"/>
        </reference>
      </references>
    </references>

    <section anchor="ack" numbered="false" toc="include">
      <name>Acknowledgements</name>
      <t>
        The authors thank the members of the IETF Routing Area
        Working Group for their review and feedback.
      </t>
    </section>
  </back>
</rfc>
