A YANG Data Model for Resilient Next-Hop Groups
draft-xu-rtgwg-resilient-nexthop-group-yang-01
This document is an Internet-Draft (I-D).
Anyone may submit an I-D to the IETF.
This I-D is not endorsed by the IETF and has no formal standing in the
IETF standards process.
| Document | Type | Active Internet-Draft (individual) | |
|---|---|---|---|
| Authors | Bohua Xu , Chang Liu , Yu Zhou , Chenyang Wen , Wei Cheng , Junjie Wang , Mingyu Wu , Yongtao Yang | ||
| Last updated | 2026-10-27 | ||
| RFC stream | (None) | ||
| Intended RFC status | (None) | ||
| Formats | |||
| Stream | Stream state | (No stream defined) | |
| Consensus boilerplate | Unknown | ||
| RFC Editor Note | (None) | ||
| IESG | IESG state | I-D Exists | |
| Telechat date | (None) | ||
| Responsible AD | (None) | ||
| Send notices to | (None) |
draft-xu-rtgwg-resilient-nexthop-group-yang-01
Individual Submission B. Xu
Internet-Draft C. Liu
Intended status: Standards Track Y. Zhou
Expires: 3 May 2027 C. Wen
China Unicom
W. Cheng
J. Wang
M. Wu
Y. Yang
Centec
30 October 2026
A YANG Data Model for Resilient Next-Hop Groups
draft-xu-rtgwg-resilient-nexthop-group-yang-01
Abstract
This document defines a YANG data model for configuring and observing
resilient next-hop groups. A fixed bucket table separates flow
hashing from member selection. The model augments the routing
management model with shared groups, static route bindings, weighted
bucket targets, restoration policies, and forwarding-confirmed
operational state.
The specification defines distinct quota and reference restoration
policies, consistent timer semantics, and an administrative rebalance
action protected by a state-generation precondition. It standardizes
management behavior for this class of implementation; it does not
define a new routing protocol, hash algorithm, or transport ordering
guarantee.
Discussion and Implementation Status
This note is to be removed before publishing as an RFC.
This is an individual proposal intended for the Standards Track. No
working group adoption or independent interoperability implementation
is claimed. The authors invite review of the problem statement,
overlap with existing work, and implementation experience.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Xu, et al. Expires 3 May 2027 [Page 1]
Internet-Draft Resilient Next-Hop Groups October 2026
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on 3 May 2027.
Copyright Notice
Copyright (c) 2026 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents (https://trustee.ietf.org/
license-info) in effect on the date of publication of this document.
Please review these documents carefully, as they describe your rights
and restrictions with respect to this document. Code Components
extracted from this document must include Revised BSD License text as
described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Revised BSD License.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Existing Models and Scope of the Proposal . . . . . . . . 3
2. Requirements Language . . . . . . . . . . . . . . . . . . . . 4
3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 4
4. Forwarding and Restoration Behavior . . . . . . . . . . . . . 5
4.1. Mapping and Configuration Boundary . . . . . . . . . . . 5
4.2. Failure Repair and Loss of Forwarding . . . . . . . . . . 5
4.3. Quota Policy . . . . . . . . . . . . . . . . . . . . . . 6
4.4. Reference Policy . . . . . . . . . . . . . . . . . . . . 7
4.5. Recovery, Eligibility, and Timer Semantics . . . . . . . 7
5. State Publication and Concurrency . . . . . . . . . . . . . . 10
5.1. Administrative Rebalance . . . . . . . . . . . . . . . . 10
5.2. Observability and Notifications . . . . . . . . . . . . . 11
6. YANG Model and Route Binding . . . . . . . . . . . . . . . . 12
7. YANG Module . . . . . . . . . . . . . . . . . . . . . . . . . 14
8. Worked Examples and Interoperability Checks . . . . . . . . . 32
8.1. Integer Targets . . . . . . . . . . . . . . . . . . . . . 32
8.2. Restoration to a Reference Assignment . . . . . . . . . . 33
8.3. Waiting and Stale Actions . . . . . . . . . . . . . . . . 33
8.4. Example IPv4 Static Route Configuration . . . . . . . . . 33
Xu, et al. Expires 3 May 2027 [Page 2]
Internet-Draft Resilient Next-Hop Groups October 2026
8.5. Implementation Review Checklist . . . . . . . . . . . . . 35
9. Operational Considerations . . . . . . . . . . . . . . . . . 35
10. Security Considerations . . . . . . . . . . . . . . . . . . . 35
11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 36
11.1. XML Namespace . . . . . . . . . . . . . . . . . . . . . 36
11.2. YANG Module . . . . . . . . . . . . . . . . . . . . . . 36
12. Normative References . . . . . . . . . . . . . . . . . . . . 36
13. Informative References . . . . . . . . . . . . . . . . . . . 38
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 39
1. Introduction
Changing a multipath group can change the next hop selected for an
existing flow. The extent depends on the selection algorithm
[RFC2992]. A bucket indirection table permits an implementation to
repair buckets associated with a failed member while retaining other
assignments. Linux resilient groups provide one public
implementation of this approach [LINUX].
A controller managing this class of forwarding needs to distinguish
capabilities from configured policy, decide whether an active bucket
may move on recovery, and determine whether a reported table has
reached the forwarding plane. A group name and weighted member list
do not fully express these decisions.
This document proposes a common YANG interface for those decisions
and observable invariants. A controller can select a policy, read
current assignments and their generation, then issue a guarded
rebalance. It does not select a particular internal hash, memory
layout, or failure detector. The requirements apply only to
implementations claiming support for this module.
1.1. Existing Models and Scope of the Proposal
The routing model [RFC8349] defines routing configuration and
operational RIB state. This module augments its next-hop choices
rather than changing their existing meaning. The first version is
limited to IPv4 and IPv6 unicast static-route configuration and group
references on operational RIB routes. Routing-protocol signaling,
recursive group composition, encapsulation policy, and cross-router
synchronized hashing are outside scope.
OpenConfig already models static next-hop groups [OC-STATIC] and
abstract forwarding state [OC-AFT]. gRIBI distinguishes RIB and FIB
programming acknowledgments [GRIBI]. SAI provides indexed fine-
grained ECMP groups [SAI-NHG]. Consequently, neither a shared group,
bucket indirection, nor a forwarding acknowledgment is claimed here
as a new mechanism.
Xu, et al. Expires 3 May 2027 [Page 3]
Internet-Draft Resilient Next-Hop Groups October 2026
The proposed addition is a coherent policy and observation contract
for bucket restoration within the IETF NMDA routing model. The
combination of per-group restoration selection, invariant timer
semantics, and a generation-guarded operation requires review against
existing interfaces. An extension to an established model may be
preferable if it meets the same operator need; this individual
proposal does not establish working group demand.
Weighted HRW [I-D.ietf-bess-weighted-hrw] addresses an algorithmic
selection approach. This module does not require HRW or replace it.
Implementations with no persistent bucket table should not claim
conformance by fabricating bucket observations.
2. Requirements Language
The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT,
RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted
as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they
appear in all capitals, as shown here.
3. Terminology
A member has a stable group-scoped identifier, positive weight, and
an interface and/or next-hop address. Usability is the local
forwarding subsystem assessment that the member can carry traffic.
The assessment can depend on interface state, neighbor resolution, or
liveness detection; it is not prescribed by this model.
B is the configured number of logical buckets. A(b) is the confirmed
effective usable owner of bucket b; it is absent when forwarding
through that bucket is confirmed suppressed or unassigned. R(b) is a
reference owner used only by the reference policy. Raw hardware
programming that is known to be unusable is not a usable assignment.
A migration changes a confirmed owner to another confirmed owner.
Initial assignment and removal are separately observable mapping
changes and are not owner-to-owner migration counts. A bucket is
idle when no packet has been observed for it over the configured
monotonic interval. An idle bucket can still represent a live but
temporarily silent connection.
The quota policy seeks integer weighted shares of all B buckets over
usable members. The reference policy seeks a stable reference
ownership for every currently usable reference member. These are
distinct balance conditions; neither promises equal traffic rates
because bucket traffic can be uneven.
Xu, et al. Expires 3 May 2027 [Page 4]
Internet-Draft Resilient Next-Hop Groups October 2026
Flow-invariant fields -> fixed hash parameters -> bucket b -> A(b)
|
Member usability -> safety repair ------------------------+
Per-group policy -> quota targets T or reference R -------+
Recovery timers -> eligible discretionary movements ------+
Controller action -> generation check -> confirmed moves -+
4. Forwarding and Restoration Behavior
4.1. Mapping and Configuration Boundary
The mapping from packet fields to bucket index MUST remain
independent of member count, member usability, and member weights.
Changes to B or hash parameters are explicit administrative changes
and MAY remap all flows. Implementations MUST document their hash
inputs and supported bucket sizes. This model does not configure
hash inputs or a hash seed.
A server MUST reject unsupported bucket counts or address-family
combinations before accepting configuration. It MUST NOT silently
substitute a different B. Weights express relative bucket allocation
rather than guaranteed bandwidth. A member can receive zero buckets
when B is small relative to the number or weight distribution of
members; this does not make that member unusable.
Configuration commits MUST be serialized with group control
operations. Configuration values in the operational datastore
describe the applied configuration under NMDA [RFC8342]. If intended
configuration cannot be applied, the server MUST retain and expose
the actual applied state and report the error; an accepted edit is
not a forwarding acknowledgment. Changes of B, members, weights, or
policy MAY migrate usable buckets and are outside the failure-only
minimal-change rule.
4.2. Failure Repair and Loss of Forwarding
When a member becomes unusable, safety repair MUST take priority over
discretionary restoration. The repair pass MUST target buckets whose
effective owner became unusable; it MUST NOT move a bucket with a
still-usable owner merely to improve balance. It MUST proceed
without waiting for hold-down, idle-timer, or unbalanced-timer. This
is a scheduling requirement, not a zero-time hardware repair
guarantee.
Each affected bucket MUST be assigned to a currently usable member,
or have forwarding through the failed owner suppressed when no usable
assignment can be installed. Before programming each new assignment
the implementation MUST recheck destination usability. An unusable
Xu, et al. Expires 3 May 2027 [Page 5]
Internet-Draft Resilient Next-Hop Groups October 2026
member MUST NOT remain eligible for packet selection. If the
platform cannot suppress a failed member or confirm the result, it
MUST report failed programming and MUST NOT claim successful repair.
In quota policy, receivers SHOULD be selected to reduce current
deficits against T where possible; the repair pass need not achieve T
because that could require moving unaffected buckets. In reference
policy, an affected bucket MUST use its reference owner when that
owner is usable; otherwise any usable temporary owner MAY be
selected. Safety repair can use a member whose recovery hold-down
has not expired.
If no member is usable, forwarding through the group MUST be
suppressed. When members become usable from that condition, all
unassigned buckets MUST be assigned without recovery hold-down. In
reference policy a usable reference owner takes precedence; remaining
buckets can use another usable owner. Programming can be partial:
oper-status is up only if all buckets have usable confirmed
assignments, degraded if some do, and down if none do.
4.3. Quota Policy
restoration/policy=quota is the default. With usable set U nonempty,
let W be the sum of usable weights. The server MUST select a fixed
integer T_i for each member, zero for unusable members, with T_i in
{floor(B*w_i/W), ceil(B*w_i/W)} for usable members and sum(T_i)=B.
It MUST expose target-buckets and retain these targets until B,
membership, weights, or usability changes. Calculations MUST avoid
intermediate integer overflow.
Largest-remainder apportionment with ties resolved by ascending
member ID is one conforming algorithm. Identical target choices
across devices are not required; the selected targets are observable.
After safety repair has assigned all B buckets, every discretionary
quota migration MUST move one bucket from a member with active-
buckets>T_i to a usable eligible receiver with active-buckets<T_i.
This rule removes a common rounding deadlock: if an integer deficit
exists, an integer surplus must also exist. Each successful quota
migration reduces the sum of absolute deficits by two. It does not
ensure prompt convergence when receiver hold-down, activity, non-
revertive mode, or programming errors prevent movements. With U
empty all target-buckets values MUST be zero.
Xu, et al. Expires 3 May 2027 [Page 6]
Internet-Draft Resilient Next-Hop Groups October 2026
4.4. Reference Policy
A server advertising reference-restoration supports restoration/
policy=reference; advertising the feature MUST NOT switch a group
from quota policy. On selecting reference policy, the server MUST
establish R across all configured members, independently of current
usability. Its per-member counts MUST be floor or ceiling of the
configured weighted share and total B.
R MUST remain unchanged across usability transitions. Configuration
changes affecting B, membership, weights, or policy MAY establish a
new R; unchanged assignments SHOULD be retained where the new
constraints allow. The reference-generation MUST advance whenever R
is created or changed. No cross-device equality of R is required.
For discretionary reference restoration, a bucket is eligible to move
only to its usable reference owner and only if A(b) differs from
R(b). Quota donor and receiver limits MUST NOT constrain this move.
Mixing these policies can prevent restoration when a temporary owner
is not above its instantaneous weighted share.
With all members usable, stable R, and every required move eventually
permitted and confirmed, A converges to R independently of the order
of prior failures. This is a conditional convergence property: non-
revertive mode, disabled force timers, continuously busy buckets, or
hardware errors can leave convergence pending indefinitely. While a
member is down, reference policy does not guarantee proportional
allocation among surviving members.
4.5. Recovery, Eligibility, and Timer Semantics
In revertive mode a recovering member becomes eligible for
discretionary receipt after hold-down seconds of continuous
usability. A fresh failure cancels its hold-down. A continuously
usable member remains eligible. An initial applied configuration is
allowed to assign traffic directly; hold-down is a recovery
safeguard, not a deployment delay.
For each eligible receiver with unmet policy work, the server starts
a monotonic rebalance episode. The episode is cleared when that
receiver has no unmet work or loses eligibility. Changes to B,
weights, membership, usability, or restoration policy restart
episodes against the new target set. A member that becomes eligible
later starts its own episode then. rebalance-start is only a wall-
clock display of the episode start.
Xu, et al. Expires 3 May 2027 [Page 7]
Internet-Draft Resilient Next-Hop Groups October 2026
The idle-timer describes a bucket observation interval. The
unbalanced-timer describes how long an eligible receiver waits before
forced movement to it is permitted. Zero unbalanced-timer MUST
always mean that timer-forced movement is disabled, irrespective of
activity support. The expiry of a timer does not guarantee
completion within a deadline; hardware programming can fail or be
delayed.
In non-revertive mode recovery MUST NOT automatically migrate
buckets, even if they are idle or a force interval would expire.
Safety repair, explicit configuration changes, and an accepted
rebalance action remain permitted. Targets and pending work MUST
still be observable.
Xu, et al. Expires 3 May 2027 [Page 8]
Internet-Draft Resilient Next-Hop Groups October 2026
+============+=============+==================+=====================+
| Activity | idle-timer | unbalanced-timer | Movement |
| capability | | | allowed after |
| | | | receiver |
| | | | eligibility |
+============+=============+==================+=====================+
| Present | >0 | 0 | Only buckets |
| | | | with measured |
| | | | idle duration |
| | | | >= idle-timer |
+------------+-------------+------------------+---------------------+
| Present | >0 | >0 | Idle buckets |
| | | | first; active |
| | | | buckets after |
| | | | receiver |
| | | | episode expires |
+------------+-------------+------------------+---------------------+
| Present | 0 | Any | All donor |
| | | | buckets are |
| | | | treated as idle |
| | | | immediately |
+------------+-------------+------------------+---------------------+
| Absent | Unavailable | 0 | No automatic |
| | | | discretionary |
| | | | movement; wait |
| | | | for action or |
| | | | configuration |
+------------+-------------+------------------+---------------------+
| Absent | Unavailable | >0 | Force eligible |
| | | | movement after |
| | | | receiver |
| | | | episode expires |
+------------+-------------+------------------+---------------------+
Table 1: Discretionary Automatic Movement in Revertive Mode
Liveness safety is outside this table. Absence of activity
information MUST NOT be treated as evidence of idleness. An
implementation SHOULD show pending work to the operator when the
configured timer policy permits indefinite waiting. Timer behavior
is consistent with the Linux meaning of a disabled force timer
[LINUX], while the additional reference policy is a separate proposed
capability.
Xu, et al. Expires 3 May 2027 [Page 9]
Internet-Draft Resilient Next-Hop Groups October 2026
5. State Publication and Concurrency
boot-id is a UUID for a group incarnation. It MUST change on group
deletion and recreation, loss of generation state, or any generation
reset. Numeric generations MUST NOT wrap within an incarnation. It
need not change for an unrelated device process restart if the group
state is fully preserved.
state-generation MUST increase with each coherent publication that
changes applied configuration, member usability or eligibility,
targets, R, confirmed A, rebalance episode identity, or programming
state. applied-generation MUST increase for a forwarding-confirmed
change to effective A, including confirmed suppression or removal.
reference-generation changes only when R is created or changed.
Counter values and elapsed activity ages do not participate in state-
generation.
The server MUST publish each revision as an internally consistent
control-state view. While programming is outstanding it MUST show
pending; after a failure it MUST show failed and last-programming-
error. A still-usable confirmed owner MAY be retained when a
replacement fails. The server MUST NOT expose an unconfirmed owner
as active or increment applied-generation merely because a command
was accepted.
A client collecting a group in several reads MUST bracket them with
boot-id and state-generation reads. If either changes, the assembled
control-state view MUST be discarded and retried. This mechanism
covers the defined control state only; activity ages, statistics, and
packet observations do not become a simultaneous snapshot. A server
that cannot offer consistent revisions cannot claim this behavior by
exposing an arbitrary counter.
5.1. Administrative Rebalance
The rebalance action requires boot-id and expected-state-generation.
Under the same serialization used for group updates, the server MUST
compare both before moving any bucket. A mismatch MUST return a
protocol operation error with error-app-tag stale-generation and
perform no action movement. A pending or failed programming state
MUST reject a new action with error-app-tag group-not-ready until the
server has reconciled its forwarding state.
Xu, et al. Expires 3 May 2027 [Page 10]
Internet-Draft Resilient Next-Hop Groups October 2026
An accepted action bypasses hold-down, idle-timer, and unbalanced-
timer. It MUST obey the selected policy, current destination
usability, and an optional receiving-member filter. It performs a
bounded pass over the current B buckets; it MUST NOT wait
indefinitely for an unusable target to recover. An explicitly
selected unusable receiver MUST be rejected with error-app-tag
member-unusable before any move.
A liveness event MUST interrupt further discretionary action
movements so safety repair can run. The action returns interrupted
with the number of its already confirmed migrations. A programming
failure returns failed and updates operational diagnostics.
Otherwise complete means no work for the requested scope remains
against the accepted stable state; it does not mean the whole group
is balanced if a member filter was used.
The output state-generation identifies the view at action completion.
A later asynchronous event can change it before the client reads
again. Clients MUST re-read before retrying a stale or interrupted
action. Confirmed changes are not rolled back merely because an
action is interrupted. The migrated-buckets count excludes
independent safety repair and counts no planned or unconfirmed moves.
5.2. Observability and Notifications
The server MUST expose the required control-state leaves in the
module, including per-member usable, eligible, pending work, and
active counts. target-buckets is present only in quota policy.
Reference counts and assignments are present only in reference
policy. A server advertising bucket-table MUST return B bucket
entries; an entry has no active-member when no effective usable
assignment is confirmed.
The model exposes cumulative failure and migration counters with a
discontinuity timestamp. Each confirmed migration MUST be counted
once in the appropriate failure, idle, or forced category; a manual
rebalance is forced even if its selected bucket happens to be idle.
Initial assignment, removal, and configuration-driven replacement are
not included in those three migration categories. A counter
discontinuity MUST update discontinuity-time.
Xu, et al. Expires 3 May 2027 [Page 11]
Internet-Draft Resilient Next-Hop Groups October 2026
resilient-group-event includes group, event category, boot-id, state-
generation, and the count of confirmed migrations for that event. A
failure event can report zero migrations while repair is pending.
Notifications MAY be coalesced or rate-limited and MUST NOT be
treated as a lossless transaction log. Reading the current state is
the recovery procedure. Time correlation with buffer telemetry is an
operational analysis; it neither proves causality nor creates a
dependency between the two protocols.
6. YANG Model and Route Binding
The module uses YANG 1.1 [RFC7950] and NMDA [RFC8342], importing the
common types [RFC9911], interfaces [RFC8343], and routing modules
[RFC8349]. The three independent features are bucket-activity,
bucket-table, and reference-restoration. They advertise server
capabilities; restoration/policy and restoration/mode select behavior
per group.
Static IPv4 and IPv6 routes gain a next-hop choice that references a
configured group. The reference MUST resolve and its address family
MUST match the route. Deleting a referenced group is invalid unless
the referencing routes are changed in the same valid configuration.
Operational RIB references do not require the configuration to remain
present indefinitely.
An IPv6 link-local next-hop address requires an outgoing interface.
The model uses case-independent prefix checking and no-zone address
types; a zone suffix is not an alternative to an explicit interface
reference. Other next hops may identify an interface, an address, or
both. Recursive resolution is a local implementation matter and MUST
not create a forwarding loop or violate the usability rules.
The following tree is generated from the accompanying module and uses
[RFC8340] notation. The module organization and contact identify an
individual proposal rather than asserting working group ownership.
RFC XXXX is an RFC Editor placeholder to be replaced upon
publication.
module: ietf-resilient-next-hop-group
augment /rt:routing:
+--rw resilient-next-hop-groups
+--rw group* [name]
+---x rebalance
| +---w input
| | +---w boot-id yang:uuid
| | +---w expected-state-generation uint64
| | +---w member?
Xu, et al. Expires 3 May 2027 [Page 12]
Internet-Draft Resilient Next-Hop Groups October 2026
| | -> ../../member/id
| +--ro output
| +--ro result enumeration
| +--ro migrated-buckets uint32
| +--ro state-generation uint64
+--rw name string
+--rw description? string
+--rw address-family identityref
+--rw bucket-count? uint32
+--rw idle-timer? uint32 {bucket-activity}?
+--rw unbalanced-timer? uint32
+--rw restoration
| +--rw mode? identityref
| +--rw hold-down? uint32
| +--rw policy? enumeration
+--rw member* [id]
| +--rw id uint32
| +--rw outgoing-interface? if:interface-ref
| +--rw next-hop-ipv4-address?
| | inet:ipv4-address-no-zone
| +--rw next-hop-ipv6-address?
| | inet:ipv6-address-no-zone
| +--rw weight? uint32
| +--ro usable boolean
| +--ro rebalance-pending boolean
| +--ro target-buckets? uint32
| +--ro active-buckets uint32
| +--ro reference-buckets? uint32
| | {reference-restoration}?
| +--ro last-transition? yang:date-and-time
| +--ro eligible boolean
| +--ro rebalance-start? yang:date-and-time
+--ro oper-status enumeration
+--ro boot-id yang:uuid
+--ro applied-generation uint64
+--ro programming-status enumeration
+--ro last-programming-error? string
+--ro reference-restored? boolean
| {reference-restoration}?
+--ro usable-members uint32
+--ro balanced boolean
+--ro reference-generation? uint64
| {reference-restoration}?
+--ro bucket* [index] {bucket-table}?
| +--ro index uint32
| +--ro active-member? -> ../../member/id
| +--ro reference-member? -> ../../member/id
| | {reference-restoration}?
Xu, et al. Expires 3 May 2027 [Page 13]
Internet-Draft Resilient Next-Hop Groups October 2026
| +--ro idle-time? uint32 {bucket-activity}?
+--ro statistics
| +--ro discontinuity-time? yang:date-and-time
| +--ro member-failures? yang:counter64
| +--ro member-restorations? yang:counter64
| +--ro failure-migrations? yang:counter64
| +--ro idle-migrations? yang:counter64
| +--ro forced-migrations? yang:counter64
+--ro state-generation uint64
augment /rt:routing/rt:control-plane-protocols
/rt:control-plane-protocol/rt:static-routes/v4ur:ipv4
/v4ur:route/v4ur:next-hop/v4ur:next-hop-options:
+--:(resilient-next-hop-group)
+--rw resilient-next-hop-group leafref
augment /rt:routing/rt:control-plane-protocols
/rt:control-plane-protocol/rt:static-routes/v6ur:ipv6
/v6ur:route/v6ur:next-hop/v6ur:next-hop-options:
+--:(resilient-next-hop-group)
+--rw resilient-next-hop-group leafref
augment /rt:routing/rt:ribs/rt:rib/rt:routes/rt:route/rt:next-hop
/rt:next-hop-options:
+--:(resilient-next-hop-group)
+--ro resilient-next-hop-group? leafref
notifications:
+---n resilient-group-event
+--ro group leafref
+--ro event identityref
+--ro member? uint32
+--ro migrated-buckets uint32
+--ro boot-id yang:uuid
+--ro state-generation uint64
7. YANG Module
module "ietf-resilient-next-hop-group" {
yang-version "1.1";
namespace
"urn:ietf:params:xml:ns:yang:ietf-resilient-next-hop-grou"
+ "p";
prefix "rnhg";
import "ietf-yang-types" {
prefix "yang";
reference
"RFC 9911: Common YANG Data Types";
}
import "ietf-inet-types" {
prefix "inet";
Xu, et al. Expires 3 May 2027 [Page 14]
Internet-Draft Resilient Next-Hop Groups October 2026
reference
"RFC 9911: Common YANG Data Types";
}
import "ietf-interfaces" {
prefix "if";
reference
"RFC 8343: A YANG Data Model for Interface Management";
}
import "ietf-routing" {
prefix "rt";
reference
"RFC 8349: A YANG Data Model for Routing Management (NMDA
Version)";
}
import "ietf-ipv4-unicast-routing" {
prefix "v4ur";
reference
"RFC 8349: A YANG Data Model for Routing Management (NMDA
Version)";
}
import "ietf-ipv6-unicast-routing" {
prefix "v6ur";
reference
"RFC 8349: A YANG Data Model for Routing Management (NMDA
Version)";
}
organization
"Authors of this individual Internet-Draft";
contact
"Bohua Xu <xubh15@chinaunicom.cn> Junjie Wang
<wangjj@centec.com> Discussion: <rtgwg@ietf.org> This
module has not been adopted by a working group.";
description
"Configuration and operational state for resilient next-hop
groups. This module augments the NMDA routing model with
bucket policies, forwarding confirmation, and guarded
administrative rebalancing.
The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL',
'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT
RECOMMENDED', 'MAY', and 'OPTIONAL' in this document are to
be interpreted as described in BCP 14 (RFC 2119) (RFC 8174)
when, and only when, they appear in all capitals, as shown
here.
Copyright (c) 2026 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Xu, et al. Expires 3 May 2027 [Page 15]
Internet-Draft Resilient Next-Hop Groups October 2026
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Revised BSD License
set forth in Section 4.c of the IETF Trust's Legal
Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC XXXX
(https://www.rfc-editor.org/info/rfcXXXX); see the RFC
itself for full legal notices.";
revision "2026-10-30" {
description
"Initial revision.";
reference
"RFC XXXX: A YANG Data Model for Resilient Next-Hop Groups";
}
feature "bucket-activity" {
description
"Supports idle-based migration and per-bucket activity
measurement. Activity support does not imply that an idle
bucket has no live transport sessions. Independent of
bucket-table support.";
}
feature "bucket-table" {
description
"Indicates that the server exposes the per-bucket
operational indirection table.";
}
feature "reference-restoration" {
description
"Supports the reference value of restoration/policy and
its operational state. Advertising the feature does not
select that policy. It is independent of bucket-activity
and bucket-table.";
reference
"RFC XXXX: A YANG Data Model for Resilient Next-Hop Groups";
}
identity "restoration-mode" {
description
"Base identity for member recovery bucket restoration
modes.";
}
identity "revertive" {
base "restoration-mode";
description
"Buckets are automatically eligible for migration back to
a recovered member after the hold-down timer expires,
governed by the idle-timer and unbalanced-timer.";
Xu, et al. Expires 3 May 2027 [Page 16]
Internet-Draft Resilient Next-Hop Groups October 2026
reference
"RFC XXXX: A YANG Data Model for Resilient Next-Hop Groups";
}
identity "non-revertive" {
base "restoration-mode";
description
"Buckets are not automatically migrated when a member
recovers; rebalancing occurs only when explicitly invoked
via the 'rebalance' action.";
reference
"RFC XXXX: A YANG Data Model for Resilient Next-Hop Groups";
}
identity "group-event" {
description
"Base identity for operational lifecycle events reported
for a resilient next-hop group.";
}
identity "member-failure" {
base "group-event";
description
"A member became unusable; repair may still be pending or
failed.";
}
identity "member-restoration" {
base "group-event";
description
"Buckets were migrated to a recovered usable member.";
}
identity "rebalance" {
base "group-event";
description
"Buckets were migrated in response to an explicit
'rebalance' action.";
}
identity "configuration-change" {
base "group-event";
description
"Buckets were recomputed and migrated due to an
administrative configuration change.";
}
identity "group-down" {
base "group-event";
description
"All members of the resilient next-hop group became
unusable.";
}
grouping "group-ref" {
description
Xu, et al. Expires 3 May 2027 [Page 17]
Internet-Draft Resilient Next-Hop Groups October 2026
"Reusable reference to a configured resilient next-hop
group.";
leaf "resilient-next-hop-group" {
type "leafref" {
path
"/rt:routing/rnhg:resilient-next-hop-groups/rnhg:gr"
+ "oup/rnhg:name";
}
mandatory "true";
description
"Name of the resilient next-hop group used as the route
next hop.";
}
}
notification "resilient-group-event" {
description
"Reports a published control-state change. Notification
delivery is not a durable event log; clients read current
state to recover. boot-id and state-generation identify
the state publication.";
leaf "group" {
type "leafref" {
path
"/rt:routing/rnhg:resilient-next-hop-groups/rnhg:gr"
+ "oup/rnhg:name";
require-instance "false";
}
mandatory "true";
description
"The resilient next-hop group that experienced the
event.";
}
leaf "event" {
type "identityref" {
base "group-event";
}
mandatory "true";
description
"The category of group lifecycle or migration event.";
}
leaf "member" {
type "uint32";
description
"The member identifier associated with the event, when
applicable.";
}
leaf "migrated-buckets" {
type "uint32";
Xu, et al. Expires 3 May 2027 [Page 18]
Internet-Draft Resilient Next-Hop Groups October 2026
mandatory "true";
description
"Confirmed owner-to-owner changes in this event, zero if
none. An event does not assert that all planned repairs
succeeded.";
}
leaf "boot-id" {
type "yang:uuid";
mandatory "true";
description
"Group incarnation for this event.";
}
leaf "state-generation" {
type "uint64";
mandatory "true";
description
"State publication associated with this event.";
}
}
augment "/rt:routing" {
description
"Augments the routing subsystem with resilient next-hop
groups.";
container "resilient-next-hop-groups" {
description
"Container for resilient next-hop group configurations
and operational state.";
list "group" {
key "name";
description
"A resilient group. Configuration nodes in operational
represent the applied configuration. A server
publishes state coherently under state-generation. A
new group incarnation has a new boot-id.";
action "rebalance" {
description
"Force a bounded administrative rebalance. Bypasses
hold-down, idle and unbalanced timers, while
preserving current usability and policy
constraints. The precondition is checked atomically
before any movement. Liveness changes interrupt
remaining work. The reply counts confirmed moves
only; the operation is not rollback-atomic.";
input {
leaf "boot-id" {
type "yang:uuid";
mandatory "true";
description
Xu, et al. Expires 3 May 2027 [Page 19]
Internet-Draft Resilient Next-Hop Groups October 2026
"Expected group boot-id; mismatch returns
stale-generation.";
}
leaf "expected-state-generation" {
type "uint64";
mandatory "true";
description
"Expected state-generation, checked at action
acceptance under the group serialization lock.
Mismatch returns stale-generation.";
}
leaf "member" {
type "leafref" {
path "../../member/id";
}
description
"Optional receiving member. If absent, process
all usable receivers.";
}
}
output {
leaf "result" {
type "enumeration" {
enum "complete" {
description
"No eligible work for the requested scope
remains.";
}
enum "interrupted" {
description
"A liveness or control-state change stopped
further work.";
}
enum "failed" {
description
"Forwarding programming failed; inspect
operational state.";
}
}
mandatory "true";
description
"Outcome of this accepted action.";
}
leaf "migrated-buckets" {
type "uint32";
mandatory "true";
description
"Number of confirmed owner-to-owner changes made
Xu, et al. Expires 3 May 2027 [Page 20]
Internet-Draft Resilient Next-Hop Groups October 2026
by this action. Safety repair after an
interruption is excluded.";
}
leaf "state-generation" {
type "uint64";
mandatory "true";
description
"State-generation at completion of this action
reply.";
}
}
}
leaf "name" {
type "string" {
length "1..64";
}
description
"Unique administrative name of the resilient
next-hop group.";
}
leaf "description" {
type "string";
description
"Human-readable description of the group.";
}
leaf "address-family" {
type "identityref" {
base "rt:address-family";
}
must
"derived-from-or-self(., 'rt:ipv4') or derived-fr"
+ "om-or-self(., 'rt:ipv6')" {
error-message
"Only IPv4 and IPv6 unicast groups are defined.";
}
mandatory "true";
description
"IPv4 or IPv6 unicast address family for this group.";
}
leaf "bucket-count" {
type "uint32" {
range "1..65535";
}
default "128";
description
"Number B of logical buckets. Hardware limitations
are validated before accepting configuration; an
unsupported size is rejected. Changing B can remap
Xu, et al. Expires 3 May 2027 [Page 21]
Internet-Draft Resilient Next-Hop Groups October 2026
all flows and requires a configuration commit.";
reference
"RFC XXXX: A YANG Data Model for Resilient Next-Hop
Groups";
}
leaf "idle-timer" {
if-feature "bucket-activity";
type "uint32" {
range "0..65535";
}
units "seconds";
default "120";
description
"Seconds without observed packets before a bucket is
idle. Zero explicitly makes all buckets eligible
for idle-based movement. Idleness does not imply
the absence of established sessions.";
reference
"RFC XXXX: A YANG Data Model for Resilient Next-Hop
Groups";
}
leaf "unbalanced-timer" {
type "uint32" {
range "0..65535";
}
units "seconds";
default "0";
description
"Seconds after an eligible receiver develops unmet
work before automatic forced movement to that
receiver is permitted. Zero always disables
timer-forced movement, including when bucket
activity is unavailable. Uses monotonic elapsed
time. It is not a guarantee on hardware programming
completion time.";
reference
"RFC XXXX: A YANG Data Model for Resilient Next-Hop
Groups";
}
container "restoration" {
description
"Parameters governing bucket restoration when a
failed member becomes usable again.";
leaf "mode" {
type "identityref" {
base "restoration-mode";
}
default "rnhg:revertive";
Xu, et al. Expires 3 May 2027 [Page 22]
Internet-Draft Resilient Next-Hop Groups October 2026
description
"Specifies whether bucket restoration occurs
automatically (revertive) or only via explicit
action (non-revertive).";
}
leaf "hold-down" {
type "uint32" {
range "0..3600";
}
units "seconds";
default "0";
description
"Seconds of continuous usability after recovery
before a member can receive discretionary
automatic migrations. Does not delay failure
repair, allocation from a down group,
configuration application, or an explicit
rebalance action.";
}
leaf "policy" {
type "enumeration" {
enum "quota" {
description
"Use integer weighted targets for usable
members.";
}
enum "reference" {
if-feature "reference-restoration";
description
"Restore the reference assignment for usable
owners.";
}
}
default "quota";
description
"Select the per-group restoration policy.";
}
}
list "member" {
must
"outgoing-interface or next-hop-ipv4-address or n"
+ "ext-hop-ipv6-address" {
error-message
"Each member must specify an outgoing-interface"
+ ", a\nnext-hop address, or both.";
description
"Ensures each member identifies a valid forwarding
next hop.";
Xu, et al. Expires 3 May 2027 [Page 23]
Internet-Draft Resilient Next-Hop Groups October 2026
}
must
"not(starts-with(translate(next-hop-ipv6-address,"
+ " 'ABCDEF', 'abcdef'), 'fe8') or starts-with(tran"
+ "slate(next-hop-ipv6-address, 'ABCDEF', 'abcdef')"
+ ", 'fe9') or starts-with(translate(next-hop-ipv6-"
+ "address, 'ABCDEF', 'abcdef'), 'fea') or starts-w"
+ "ith(translate(next-hop-ipv6-address, 'ABCDEF', '"
+ "abcdef'), 'feb')) or outgoing-interface" {
error-message
"An IPv6 link-local next hop requires outgoing-"
+ "interface.";
description
"Case-independent fe80::/10 interface-scope
validation.";
}
key "id";
min-elements "1";
description
"Configured next-hop members of the resilient group.";
leaf "id" {
type "uint32";
description
"Unique numeric identifier of the member within
the group.";
}
leaf "outgoing-interface" {
type "if:interface-ref";
description
"Outgoing interface for this next-hop member.";
}
leaf "next-hop-ipv4-address" {
when
"derived-from-or-self(../../address-family, 'rt"
+ ":ipv4')";
type "inet:ipv4-address-no-zone";
description
"IPv4 next-hop address of the member.";
}
leaf "next-hop-ipv6-address" {
when
"derived-from-or-self(../../address-family, 'rt"
+ ":ipv6')";
type "inet:ipv6-address-no-zone";
description
"IPv6 next-hop address of the member.";
}
leaf "weight" {
Xu, et al. Expires 3 May 2027 [Page 24]
Internet-Draft Resilient Next-Hop Groups October 2026
type "uint32" {
range "1..max";
}
default "1";
description
"Relative load-sharing weight of the member (w_i).
Target bucket allocation is proportional to w_i.";
}
leaf "usable" {
type "boolean";
config "false";
mandatory "true";
description
"Indicates whether this member is currently
resolved and usable for packet forwarding.";
}
leaf "rebalance-pending" {
type "boolean";
config "false";
mandatory "true";
description
"True if the member is usable and currently holds
fewer buckets than its target quota (or has
un-restored reference buckets) awaiting
migration.";
}
leaf "target-buckets" {
when "../../restoration/policy = 'quota'";
type "uint32";
config "false";
description
"Current integer target bucket count (T_i) in
proportional quota mode; omitted when operating
under reference-restoration policy.";
}
leaf "active-buckets" {
type "uint32";
config "false";
mandatory "true";
description
"Count of logical buckets with a confirmed usable
assignment to this member. A suppressed unusable
hardware entry is not counted.";
}
leaf "reference-buckets" {
when "../../restoration/policy = 'reference'";
if-feature "reference-restoration";
type "uint32";
Xu, et al. Expires 3 May 2027 [Page 25]
Internet-Draft Resilient Next-Hop Groups October 2026
config "false";
description
"Number of buckets whose canonical baseline
reference assignment R(b) points to this member.";
}
leaf "last-transition" {
type "yang:date-and-time";
config "false";
description
"Timestamp of the most recent change in this
member's 'usable' state.";
}
leaf "eligible" {
type "boolean";
config "false";
mandatory "true";
description
"True when usable and the hold-down for automatic
receipt has expired. Safety repair and
administrative action may bypass it.";
}
leaf "rebalance-start" {
type "yang:date-and-time";
config "false";
description
"Wall-clock display of the start of the current
eligible unmet-work episode. Absent without such
an episode. Timers use monotonic time, not
subtraction of this timestamp.";
}
}
leaf "oper-status" {
type "enumeration" {
enum "up" {
description
"Every bucket has a confirmed usable effective
owner.";
}
enum "down" {
description
"No bucket has a confirmed usable effective
owner.";
}
enum "degraded" {
description
"Some, but not all, buckets have confirmed
usable owners.";
}
Xu, et al. Expires 3 May 2027 [Page 26]
Internet-Draft Resilient Next-Hop Groups October 2026
}
config "false";
mandatory "true";
description
"Forwarding availability of the group, derived from
confirmed effective bucket assignments, not merely
member liveness.";
}
leaf "boot-id" {
type "yang:uuid";
config "false";
mandatory "true";
description
"UUID identifying this group incarnation and counter
epoch. Changes on recreation or any loss/reset of
generation state. It is not necessarily a device
reboot identifier.";
}
leaf "applied-generation" {
type "uint64";
config "false";
mandatory "true";
description
"Counter advanced on each forwarding-confirmed
change of effective active assignments, including
confirmed removal or suppression. State-generation
also advances for the publication. No wrap within
boot-id. This is not a general configuration
revision.";
}
leaf "programming-status" {
type "enumeration" {
enum "ready" {
description
"The latest bucket table update has been
confirmed by the forwarding plane.";
}
enum "pending" {
description
"A bucket table update is in progress and not
yet confirmed by the forwarding plane.";
}
enum "failed" {
description
"The most recent forwarding-plane update failed.";
}
}
config "false";
Xu, et al. Expires 3 May 2027 [Page 27]
Internet-Draft Resilient Next-Hop Groups October 2026
mandatory "true";
description
"Status of hardware/forwarding-plane programming for
the group.";
}
leaf "last-programming-error" {
type "string";
config "false";
description
"Last programming error. Absent after a subsequent
successful programming transaction has cleared the
error.";
}
leaf "reference-restored" {
when "../restoration/policy = 'reference'";
if-feature "reference-restoration";
type "boolean";
config "false";
description
"True when at least one member is usable, all
buckets have confirmed usable assignments, and
every usable reference owner owns its reference
buckets. This does not promise intermediate weight
balance.";
}
leaf "usable-members" {
type "uint32";
config "false";
mandatory "true";
description
"Current count of usable members in the group.";
}
leaf "balanced" {
type "boolean";
config "false";
mandatory "true";
description
"True if all buckets are assigned to usable members
and the active restoration policy's balance
condition is satisfied.";
}
leaf "reference-generation" {
when "../restoration/policy = 'reference'";
if-feature "reference-restoration";
type "uint64";
config "false";
description
"Advanced whenever R is created or changed.
Xu, et al. Expires 3 May 2027 [Page 28]
Internet-Draft Resilient Next-Hop Groups October 2026
Usability transitions never change R. Meaningful
only in reference policy. No wrap within boot-id.";
}
list "bucket" {
if-feature "bucket-table";
key "index";
config "false";
description
"Operational state of individual hash buckets in the
group's indirection table.";
leaf "index" {
type "uint32";
must ". < ../../bucket-count" {
error-message
"Bucket index must be less than bucket-count.";
}
description
"Zero-based bucket index (0 .. bucket-count - 1).";
}
leaf "active-member" {
type "leafref" {
path "../../member/id";
require-instance "false";
}
description
"Confirmed effective usable owner. Absent for a
confirmed suppressed or unassigned bucket.
Unknown hardware state is reported as failed
programming and must not be presented as
successful repair.";
}
leaf "reference-member" {
when "../../restoration/policy = 'reference'";
if-feature "reference-restoration";
type "leafref" {
path "../../member/id";
require-instance "false";
}
description
"Canonical reference member ID for this bucket
(R(b)).";
}
leaf "idle-time" {
if-feature "bucket-activity";
type "uint32";
units "seconds";
description
"Monotonic seconds since a packet was observed for
Xu, et al. Expires 3 May 2027 [Page 29]
Internet-Draft Resilient Next-Hop Groups October 2026
this bucket, saturated at 4294967295. Not covered
by state-generation; absent when activity data is
unavailable.";
}
}
container "statistics" {
config "false";
description
"Cumulative operational counters for the resilient
next-hop group.";
leaf "discontinuity-time" {
type "yang:date-and-time";
description
"Timestamp of the most recent occasion on which
one or more counters experienced a discontinuity.";
}
leaf "member-failures" {
type "yang:counter64";
description
"Total number of transitions of any member from
usable to unusable.";
}
leaf "member-restorations" {
type "yang:counter64";
description
"Total number of transitions of any member from
unusable to usable.";
}
leaf "failure-migrations" {
type "yang:counter64";
description
"Total number of immediate bucket migrations
triggered by member failures.";
}
leaf "idle-migrations" {
type "yang:counter64";
description
"Total number of idle-based bucket migrations
performed while the migrated bucket was idle.";
}
leaf "forced-migrations" {
type "yang:counter64";
description
"Total number of bucket migrations performed on
active buckets due to unbalanced-timer expiry or
explicit 'rebalance' action invocation.";
}
}
Xu, et al. Expires 3 May 2027 [Page 30]
Internet-Draft Resilient Next-Hop Groups October 2026
leaf "state-generation" {
type "uint64";
config "false";
mandatory "true";
description
"Revision of applied configuration, usability,
eligibility, targets, reference and active
assignments, and programming state. Increment on
each coherent publication affecting these values.
Excludes activity ages and statistics. Does not
wrap within boot-id.";
}
}
}
}
augment
"/rt:routing/rt:control-plane-protocols/rt:control-plane-"
+ "protocol/rt:static-routes/v4ur:ipv4/v4ur:route/v4ur:next"
+ "-hop/v4ur:next-hop-options" {
description
"Enables an IPv4 static route to reference a resilient
next-hop group.";
case "resilient-next-hop-group" {
uses "group-ref" {
refine "resilient-next-hop-group" {
must
"derived-from-or-self(/rt:routing/rnhg:resilient-"
+ "next-hop-groups/rnhg:group[rnhg:name = current()"
+ "]/rnhg:address-family, 'rt:ipv4')" {
error-message
"The referenced resilient next-hop group must b"
+ "e\nconfigured for the IPv4 address family.";
}
}
}
}
}
augment
"/rt:routing/rt:control-plane-protocols/rt:control-plane-"
+ "protocol/rt:static-routes/v6ur:ipv6/v6ur:route/v6ur:next"
+ "-hop/v6ur:next-hop-options" {
description
"Enables an IPv6 static route to reference a resilient
next-hop group.";
case "resilient-next-hop-group" {
uses "group-ref" {
refine "resilient-next-hop-group" {
must
Xu, et al. Expires 3 May 2027 [Page 31]
Internet-Draft Resilient Next-Hop Groups October 2026
"derived-from-or-self(/rt:routing/rnhg:resilient-"
+ "next-hop-groups/rnhg:group[rnhg:name = current()"
+ "]/rnhg:address-family, 'rt:ipv6')" {
error-message
"The referenced resilient next-hop group must b"
+ "e\nconfigured for the IPv6 address family.";
}
}
}
}
}
augment
"/rt:routing/rt:ribs/rt:rib/rt:routes/rt:route/rt:next-ho"
+ "p/rt:next-hop-options" {
description
"Exposes the resilient next-hop group bound to an active
route in the Routing Information Base (RIB).";
case "resilient-next-hop-group" {
leaf "resilient-next-hop-group" {
type "leafref" {
path
"/rt:routing/rnhg:resilient-next-hop-groups/rnhg:"
+ "group/rnhg:name";
require-instance "false";
}
description
"Name of the resilient next-hop group used by this
active RIB route.";
}
}
}
}
8. Worked Examples and Interoperability Checks
8.1. Integer Targets
For B=5 and two usable equal-weight members, valid targets are (3,2)
or (2,3). If A has counts (4,1) and the selected targets are (3,2),
one permitted donor-to-receiver migration reaches the target.
Testing against real shares (2.5,2.5) instead of fixed integer
targets can incorrectly keep the group pending or cause oscillation.
The wire model exposes the selected integer values.
Xu, et al. Expires 3 May 2027 [Page 32]
Internet-Draft Resilient Next-Hop Groups October 2026
8.2. Restoration to a Reference Assignment
+===================================+===============+===============+
| Step | Reference R | Active A |
+===================================+===============+===============+
| Initial | [1,2,3,1,2,3] | [1,2,3,1,2,3] |
+-----------------------------------+---------------+---------------+
| 1 fails | Unchanged | [2,2,3,2,2,3] |
+-----------------------------------+---------------+---------------+
| 2 fails | Unchanged | [3,3,3,3,3,3] |
+-----------------------------------+---------------+---------------+
| 1 recovers and its | Unchanged | [1,3,3,1,3,3] |
| work completes | | |
+-----------------------------------+---------------+---------------+
| 2 recovers and its | Unchanged | [1,2,3,1,2,3] |
| work completes | | |
+-----------------------------------+---------------+---------------+
Table 2: Reference Restoration with Two Failures
Temporary holders in this example are choices, not a prescribed
allocation algorithm. Reversing recovery order also reaches R when
the same conditional convergence requirements hold. Recovery of a
reference owner moves only its reference buckets; it does not impose
quota balance on the temporary holders.
8.3. Waiting and Stale Actions
With no bucket-activity capability and unbalanced-timer=0, a
recovered member can remain pending in revertive mode. This is
intentional: the server has neither evidence of idleness nor
permission for timer-forced movement. Setting a positive force timer
or invoking a guarded action can progress the work.
If a client reads state-generation=8 and a member becomes unusable
without any mapping update yet confirmed, state-generation still
advances for the liveness change. An action carrying 8 is rejected.
Comparing only applied-generation would miss this change, which is
why the action precondition uses state-generation.
8.4. Example IPv4 Static Route Configuration
This JSON configuration is validated against the module and its
dependencies. It uses the default quota policy. The address and
interface values are illustrative.
Xu, et al. Expires 3 May 2027 [Page 33]
Internet-Draft Resilient Next-Hop Groups October 2026
{
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "eth0",
"type": "iana-if-type:ethernetCsmacd"
}
]
},
"ietf-routing:routing": {
"ietf-resilient-next-hop-group:resilient-next-hop-groups": {
"group": [
{
"name": "fabric",
"address-family": "ietf-routing:ipv4",
"bucket-count": 8,
"member": [
{
"id": 1,
"next-hop-ipv4-address": "192.0.2.1",
"outgoing-interface": "eth0"
}
]
}
]
},
"control-plane-protocols": {
"control-plane-protocol": [
{
"type": "ietf-routing:static",
"name": "static",
"static-routes": {
"ietf-ipv4-unicast-routing:ipv4": {
"route": [
{
"destination-prefix": "192.0.2.0/24",
"next-hop": {
"ietf-resilient-next-hop-group:resilient-next-hop-group":
"fabric"
}
}
]
}
}
}
]
}
}
Xu, et al. Expires 3 May 2027 [Page 34]
Internet-Draft Resilient Next-Hop Groups October 2026
}
8.5. Implementation Review Checklist
Interoperability testing SHOULD exercise all eight feature
combinations, both restoration modes, the timer combinations in
Table 1, fractional weighted shares, B smaller than member count,
all-members-down recovery, hardware rejection after partial
programming, action interruption, configuration changes during
pending work, counter discontinuity, and group recreation with the
same name.
Schema validation SHOULD cover address-family mismatches, unresolved
route references, uppercase and lowercase IPv6 link-local addresses
without an interface, invalid weights and bucket counts, and
reference policy selection when the feature is absent. Behavior
simulations and schema tests do not substitute for two independent
forwarding implementations.
9. Operational Considerations
Idle intervals should be chosen with expected traffic gaps and
session affinity in mind. No finite idle interval proves that a
stateful service has forgotten a flow. Non-revertive mode can avoid
automatic recovery movements, but cannot prevent required failure
repair or administrator-initiated changes.
Reference policy provides repeatable placement within one reference
generation. It can require more movements than a policy that merely
reaches current quotas, and can temporarily produce uneven survivor
allocation. Operators should select it only when restoration to the
recorded baseline matters.
Resilient local assignment does not guarantee transport ordering,
losslessness, or availability of state at a replacement middlebox. A
changed path can have different latency; even a flow that keeps its
local next hop can encounter changes downstream. These limits SHOULD
be disclosed in implementation documentation.
10. Security Considerations
This section follows the YANG security guidance in [RFC9907]. The
module is intended for use with authenticated management protocols
such as NETCONF [RFC6241] and RESTCONF [RFC8040], over their secure
transport mappings. Deployments MUST authenticate peers and protect
confidentiality and integrity. The Network Configuration Access
Control Model [RFC8341] can restrict both data access and operations.
Xu, et al. Expires 3 May 2027 [Page 35]
Internet-Draft Resilient Next-Hop Groups October 2026
All configuration under /routing/resilient-next-hop-groups is
sensitive. Changing membership or next-hop addresses can redirect
traffic; changing weights, bucket-count, or policy can move active
flows; setting idle-timer to zero or reducing unbalanced-timer can
permit disruptive movement. These writes MUST be restricted to
authorized administrators.
The rebalance action bypasses recovery timers and can move active
traffic. Authorization MUST be checked independently of its
generation precondition. Repeated reads, rejected actions,
notifications, and large bucket-table retrievals can consume
resources; servers MUST impose suitable request, work, and
notification limits. A generation token prevents a stale decision
from executing; it is not a secret or an authorization credential.
Operational next hops, interface bindings, bucket assignments, member
transitions, and error diagnostics reveal topology and traffic-
handling policy. Access SHOULD be limited to authorized consumers.
Implementations SHOULD avoid exposing secrets or unnecessary internal
details in diagnostic strings. Malicious liveness inputs can induce
repeated repair, so liveness sources and their authentication require
deployment-specific protection.
11. IANA Considerations
11.1. XML Namespace
IANA is requested to register urn:ietf:params:xml:ns:yang:ietf-
resilient-next-hop-group in the IETF XML Registry [RFC3688].
Registrant Contact: The IESG. XML: N/A; the requested URI is an XML
namespace.
11.2. YANG Module
IANA is requested to register the module under the YANG Module Names
registry [RFC6020]: Name: ietf-resilient-next-hop-group; Namespace:
urn:ietf:params:xml:ns:yang:ietf-resilient-next-hop-group; Prefix:
rnhg; Reference: RFC XXXX. No assignment or working group ownership
is implied before approval.
12. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
Xu, et al. Expires 3 May 2027 [Page 36]
Internet-Draft Resilient Next-Hop Groups October 2026
[RFC3688] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688,
DOI 10.17487/RFC3688, January 2004,
<https://www.rfc-editor.org/info/rfc3688>.
[RFC6020] Bjorklund, M., Ed., "YANG - A Data Modeling Language for
the Network Configuration Protocol (NETCONF)", RFC 6020,
DOI 10.17487/RFC6020, October 2010,
<https://www.rfc-editor.org/info/rfc6020>.
[RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed.,
and A. Bierman, Ed., "Network Configuration Protocol
(NETCONF)", RFC 6241, DOI 10.17487/RFC6241, June 2011,
<https://www.rfc-editor.org/info/rfc6241>.
[RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language",
RFC 7950, DOI 10.17487/RFC7950, August 2016,
<https://www.rfc-editor.org/info/rfc7950>.
[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, "RESTCONF
Protocol", RFC 8040, DOI 10.17487/RFC8040, January 2017,
<https://www.rfc-editor.org/info/rfc8040>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8341] Bierman, A. and M. Bjorklund, "Network Configuration
Access Control Model", STD 91, RFC 8341,
DOI 10.17487/RFC8341, March 2018,
<https://www.rfc-editor.org/info/rfc8341>.
[RFC8342] Bjorklund, M., Schoenwaelder, J., Shafer, P., Watsen, K.,
and R. Wilton, "Network Management Datastore Architecture
(NMDA)", RFC 8342, DOI 10.17487/RFC8342, March 2018,
<https://www.rfc-editor.org/info/rfc8342>.
[RFC8343] Bjorklund, M., "A YANG Data Model for Interface
Management", RFC 8343, DOI 10.17487/RFC8343, March 2018,
<https://www.rfc-editor.org/info/rfc8343>.
[RFC8349] Lhotka, L., Lindem, A., and Y. Qu, "A YANG Data Model for
Routing Management (NMDA Version)", RFC 8349,
DOI 10.17487/RFC8349, March 2018,
<https://www.rfc-editor.org/info/rfc8349>.
[RFC9911] Schoenwaelder, J., Ed., "Common YANG Data Types",
RFC 9911, DOI 10.17487/RFC9911, December 2025,
<https://www.rfc-editor.org/info/rfc9911>.
Xu, et al. Expires 3 May 2027 [Page 37]
Internet-Draft Resilient Next-Hop Groups October 2026
13. Informative References
[GRIBI] OpenConfig, "gRIBI Service Definition",
<https://github.com/openconfig/gribi/blob/master/v1/proto/
service/gribi.proto>.
[I-D.ietf-bess-weighted-hrw]
Mohanty, S. R., Mishra, M. P., Lindem, A., Sajassi, A.,
and J. Drake, "Weighted HRW and its applications", Work in
Progress, Internet-Draft, draft-ietf-bess-weighted-hrw-02,
7 July 2025, <https://datatracker.ietf.org/doc/html/draft-
ietf-bess-weighted-hrw-02>.
[LINUX] Linux contributors, "Resilient Next-hop Groups",
<https://docs.kernel.org/networking/nexthop-group-
resilient.html>.
[OC-AFT] OpenConfig, "OpenConfig Abstract Forwarding Table Common
Model, revision 2026-10-04",
<https://github.com/openconfig/public/blob/master/release/
models/aft/openconfig-aft-common.yang>.
[OC-STATIC]
OpenConfig, "OpenConfig Network Instance Static Model,
revision 2026-05-12",
<https://github.com/openconfig/public/blob/master/release/
models/network-instance/openconfig-network-instance-
static.yang>.
[RFC2992] Hopps, C., "Analysis of an Equal-Cost Multi-Path
Algorithm", RFC 2992, DOI 10.17487/RFC2992, November 2000,
<https://www.rfc-editor.org/info/rfc2992>.
[RFC8340] Bjorklund, M. and L. Berger, Ed., "YANG Tree Diagrams",
BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018,
<https://www.rfc-editor.org/info/rfc8340>.
[RFC9907] Bierman, A., Boucadair, M., Ed., and Q. Wu, "Guidelines
for Authors and Reviewers of Documents Containing YANG
Data Models", BCP 216, RFC 9907, DOI 10.17487/RFC9907,
March 2026, <https://www.rfc-editor.org/info/rfc9907>.
[SAI-NHG] Open Compute Project, "Switch Abstraction Interface: Next
Hop Group API",
<https://github.com/opencomputeproject/SAI/blob/master/
inc/sainexthopgroup.h>.
Xu, et al. Expires 3 May 2027 [Page 38]
Internet-Draft Resilient Next-Hop Groups October 2026
Authors' Addresses
Bohua Xu
China Unicom
Beijing
100000
China
Email: xubh15@chinaunicom.cn
Chang Liu
China Unicom
Beijing
100000
China
Email: liuc131@chinaunicom.cn
Yu Zhou
China Unicom
Beijing
100000
China
Email: zhouy739@chinaunicom.cn
Chenyang Wen
China Unicom
Beijing
100000
China
Email: wency15@chinaunicom.cn
Wei Cheng
Centec
Suzhou
215000
China
Email: chengw@centec.com
Junjie Wang
Centec
Suzhou
215000
China
Email: wangjj@centec.com
Xu, et al. Expires 3 May 2027 [Page 39]
Internet-Draft Resilient Next-Hop Groups October 2026
Mingyu Wu
Centec
Suzhou
215000
China
Email: wumy@centec.com
Yongtao Yang
Centec
Suzhou
215000
China
Email: yangyt@centec.com
Xu, et al. Expires 3 May 2027 [Page 40]