RFC 9403

A YANG Data Model for RIB Extensions

πŸ“… published November 2023, from ietf

A YANG Data Model for RIB Extensions πŸŽ€

  • Request for Comments: 9403 πŸ¦‹
  • Authors: A. Lindem (LabN Consulting, L.L.C.) and Y. Qu (Futurewei Technologies) πŸ’œ
  • Category: Standards Track ✨
  • Date: November 2023 πŸ“…
  • ISSN: 2070-1721 🌸
  • Obsoletes / Updates: Neither. The title block doesn't list anything it obsoletes or updates πŸ™ˆ

Okay bestie, this RFC is a YANG data model. It's the blueprint for how a router's RIB (Routing Information Base) gets described in structured data, so tools can read and manage it. It's by Acee Lindem and Yingzhen Qu, and it's a full Standards Track document, which means the IETF community reviewed it and the IESG approved it for publication πŸ”₯

Internet Engineering Task Force (IETF)                         A. Lindem
Request for Comments: 9403                       LabN Consulting, L.L.C.
Category: Standards Track                                          Y. Qu
ISSN: 2070-1721                                   Futurewei Technologies
                                                           November 2023

Abstract πŸ’…

Okay so, a Routing Information Base (RIB) is basically a list of routes, plus the admin data and operational state that goes with each one. It's giving organized πŸ“‹

RFC 8349 lays down the basic building blocks for the RIB data model. This model adds on top of that so each route can have multiple next hops (aka paths), plus some extra attributes. Main character energy πŸ‘‘

Status of This Memo πŸ“

This is an Internet Standards Track document. ✨

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 7841. 🌈

Info about the current status of this document, any errata, and how to send feedback on it can be found at https://www.rfc-editor.org/info/rfc9403. πŸ”—

Copyright (c) 2023 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
   2.  Terminology and Notation
     2.1.  Tree Diagrams
     2.2.  Prefixes in Data Node Names
   3.  Design of the Model
     3.1.  Tags and Preferences
     3.2.  Repair Path
   4.  RIB Model Tree
   5.  RIB Extension YANG Module
   6.  Security Considerations
   7.  IANA Considerations
   8.  References
     8.1.  Normative References
     8.2.  Informative References
   Appendix A.  Combined Tree Diagram
   Appendix B.  ietf-rib-extension.yang example
   Acknowledgments
   Authors' Addresses

1. Introduction 🌸

Okay so this document defines a YANG data model [RFC7950] that extends the RIB data model from the ietf-routing YANG module [RFC8349] with more route attributes. It's the glow-up the RIB needed ✨

A RIB is a collection of routes with attributes that get controlled and manipulated by control plane protocols. Each RIB only holds routes from one address family [RFC8349]. Inside a protocol, routes get picked based on the metrics that protocol uses, and then the protocol installs them into the RIB. The RIB picks the preferred or active route by comparing the route preference (aka administrative distance) of the candidate routes that different protocols installed. It's a whole popularity contest, and the RIB is the judge πŸ‘‘

The module in this document extends the RIB to support more route attributes, like multiple next hops, route metrics, and administrative tags. Iconic behavior πŸ’…

The YANG modules defined and discussed in this document conform to the Network Management Datastore Architecture (NMDA) [RFC8342]. πŸ¦‹

2. Terminology and Notation πŸ“–

The following terms are defined in [RFC8342]:

  • configuration πŸ’œ
  • system state πŸ’œ
  • operational state πŸ’œ

The following terms are defined in [RFC7950]:

  • action πŸ’œ
  • augment πŸ’œ
  • container πŸ’œ
  • container with presence πŸ’œ
  • data model πŸ’œ
  • data node πŸ’œ
  • leaf πŸ’œ
  • list πŸ’œ
  • mandatory node πŸ’œ
  • module πŸ’œ
  • schema tree πŸ’œ

The following term is defined in [RFC8349], Section 5.2:

  • RIB πŸ’œ

2.1. Tree Diagrams 🌳

Tree diagrams used in this document follow the notation defined in [RFC8340]. Pretty and easy to read, periodt 🌿

2.2. Prefixes in Data Node Names 🏷️

In this document, names of data nodes, actions, and other data model objects are often used without a prefix, as long as it's clear from context which YANG module each name is defined in. Otherwise, names get prefixed with the standard prefix tied to the matching YANG module, as shown in Table 1. No guessing games here πŸ™Œ

            +========+===========================+===========+
            | Prefix | YANG Module               | Reference |
            +========+===========================+===========+
            | if     | ietf-interfaces           | [RFC8343] |
            +--------+---------------------------+-----------+
            | rt     | ietf-routing              | [RFC8349] |
            +--------+---------------------------+-----------+
            | v4ur   | ietf-ipv4-unicast-routing | [RFC8349] |
            +--------+---------------------------+-----------+
            | v6ur   | ietf-ipv6-unicast-routing | [RFC8349] |
            +--------+---------------------------+-----------+
            | inet   | ietf-inet-types           | [RFC6991] |
            +--------+---------------------------+-----------+
            | ospf   | ietf-ospf                 | [RFC9129] |
            +--------+---------------------------+-----------+
            | isis   | ietf-isis                 | [RFC9130] |
            +--------+---------------------------+-----------+

             Table 1: Prefixes and Corresponding YANG Modules

3. Design of the Model 🧁

The YANG module in this document augments the ietf-routing, ietf-ipv4-unicast-routing, and ietf-ipv6-unicast-routing YANG modules defined in [RFC8349], which give you a foundation for routing system data model development. Together with the ietf-routing YANG module and the other YANG modules defined in [RFC8349], this doc defines a generic RIB YANG data model to implement and monitor a RIB. Built different πŸ”₯

The modules in [RFC8349] also define the basic configuration and operational state for both IPv4 and IPv6 static routes. This document adds augmentations for static routes so they can support multiple next hops and more next-hop attributes. Level up unlocked πŸ†™

3.1. Tags and Preferences 🏷️

Individual route tags are supported at both the route level and the next-hop level. There's also a preference per next hop, which is used to select the most preferred reachable static route. Choosing favorites πŸ’–

The following tree snapshot shows the tag and preference entries that augment static IPv4 unicast route and IPv6 unicast route next hops. 🌲

  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
          /v4ur:simple-next-hop:
    +--rw preference?   uint32
    +--rw tag?          uint32
  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
          /v4ur:next-hop-list/v4ur:next-hop-list/v4ur:next-hop:
    +--rw preference?   uint32
    +--rw tag?          uint32
  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
          /v6ur:simple-next-hop:
    +--rw preference?   uint32
    +--rw tag?          uint32
  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
          /v6ur:next-hop-list/v6ur:next-hop-list/v6ur:next-hop:
    +--rw preference?   uint32
    +--rw tag?          uint32
  augment /rt:routing/rt:ribs/rt:rib/rt:routes/rt:route:
    +--ro metric?            uint32
    +--ro tag*               uint32
    +--ro application-tag?   uint32

3.2. Repair Path πŸ›Ÿ

The IP Fast Reroute (IPFRR) calculation by a routing protocol precomputes repair paths [RFC5714], and those repair paths get installed in the RIB. Backup plan, all set 🫢

Each route next hop in the RIB is augmented with a repair path, as shown in the following tree snapshot. πŸ¦‹

  augment /rt:routing/rt:ribs/rt:rib/rt:routes/rt:route
          /rt:next-hop/rt:next-hop-options/rt:simple-next-hop:
    +--ro repair-path
       +--ro outgoing-interface?   if:interface-state-ref
       +--ro next-hop-address?     inet:ip-address-no-zone
       +--ro metric?               uint32
  augment /rt:routing/rt:ribs/rt:rib/rt:routes/rt:route
          /rt:next-hop/rt:next-hop-options/rt:next-hop-list
          /rt:next-hop-list/rt:next-hop:
    +--ro repair-path
       +--ro outgoing-interface?   if:interface-state-ref
       +--ro next-hop-address?     inet:ip-address-no-zone
       +--ro metric?               uint32

4. RIB Model Tree 🌳

The ietf-routing.yang tree with the augmentations from this document is included in Appendix A. The meanings of the symbols can be found in [RFC8340]. Read the map before you explore πŸ—ΊοΈ

5. RIB Extension YANG Module πŸ’Ž

This YANG module references [RFC6991], [RFC8343], [RFC8349], [RFC9129], [RFC9130], and [RFC5714]. πŸ”—

<CODE BEGINS> file "ietf-rib-extension@2023-11-20.yang"
module ietf-rib-extension {
  yang-version 1.1;
  namespace "urn:ietf:params:xml:ns:yang:ietf-rib-extension";
  prefix rib-ext;

  import ietf-inet-types {
    prefix inet;
    reference
      "RFC 6991: 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)";
  }

  import ietf-ospf {
    prefix ospf;
    reference "RFC 9129: YANG Data Model for the OSPF Protocol";
  }

  import ietf-isis {
    prefix isis;
    reference "RFC 9130: YANG Data Model for the IS-IS Protocol";
  }

  organization
    "IETF RTGWG (Routing Area Working Group)";
  contact
    "WG Web:   <https://datatracker.ietf.org/wg/rtgwg/>
     WG List:  <mailto:rtgwg@ietf.org>

     Author:   Acee Lindem
               <mailto:acee.ietf@gmail.com>
     Author:   Yingzhen Qu
               <mailto:yingzhen.qu@futurewei.com>";
  description
    "This YANG module extends the RIB defined in the ietf-routing
     YANG module with additional route attributes.

     This YANG module conforms to the Network Management
     Datastore Architecture (NMDA) as described in RFC 8342.

     Copyright (c) 2023 IETF Trust and the persons identified as
     authors of the code.  All rights reserved.

     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 9403; see the
     RFC itself for full legal notices.";

  revision 2023-11-20 {
    description
      "Initial version.";
    reference
      "RFC 9403: A YANG Data Model for RIB Extensions";
  }

  /* Groupings */

Okay bestie, this is where the YANG module really comes together πŸ’– Everything below lives inside the module, so the indentation is part of the vibe (and the structure).

Here's the first chunk: the RIB statistics grouping πŸ“Š It's basically the stats dashboard for the RIB, with totals for all routes, active routes, and memory, plus a per-protocol breakdown. Yes, this is the stuff you want on your monitoring screen πŸ¦‹

     grouping rib-statistics {
       description
         "Statistics grouping used for RIB augmentation.";
       container statistics {
         config false;
         description
           "Container for RIB statistics.";
         leaf total-routes {
           type uint32;
           description
             "Total number of routes in the RIB.";
         }
         leaf total-active-routes {
           type uint32;
           description
             "Total number of active routes in the RIB.  An active
              route is the route that is preferred over other routes
              to the same destination prefix.";
         }
         leaf total-route-memory {
           type uint64;
           units "bytes";
           description
             "Total memory for all routes in the RIB.";
         }
         list protocol-statistics {
           description
             "RIB statistics for routing protocols installing
              routes in the RIB.";
           leaf protocol {
             type identityref {
               base rt:routing-protocol;
             }
             description
               "Routing protocol installing routes in the RIB.";
           }
           leaf routes {
             type uint32;
             description
               "Total number of routes in the RIB for the routing
                protocol identified by the 'protocol' entry.";
           }
           leaf active-routes {
             type uint32;
             description
               "Total number of active routes in the RIB for the
                routing protocol identified by the 'protocol' entry.
                An active route is preferred over other routes to the
                same destination prefix.";
           }
           leaf route-memory {
             type uint64;
             units "bytes";
             description
               "Total memory for all routes in the RIB for the
                routing protocol identified by the 'protocol'
                entry.";
           }
         }
       }
     }

Next up is the repair-path grouping πŸ›Ÿ This is the IP Fast Reroute (IPFRR) repair path, which is the backup route you fall back on when things break πŸ’… The reference at the bottom points you to RFC 5714, so go read that if you want the full backstory 🌸

     grouping repair-path {
       description
         "Grouping for the IP Fast Reroute (IPFRR) repair path.";
       container repair-path {
         description
           "IPFRR next-hop repair path.";
         leaf outgoing-interface {
           type if:interface-state-ref;
           description
             "Name of the outgoing interface.";
         }
         leaf next-hop-address {
           type inet:ip-address-no-zone;
           description
             "IP address of the next hop.";
         }
         leaf metric {
           type uint32;
           description
             "The metric for the repair path.  While the reroute
              repair is local and the metric is not advertised
              externally, the metric for the repair path is useful
              for troubleshooting purposes.";
         }
         reference
           "RFC 5714: IP Fast Reroute Framework";
       }
     }

Now the preference and tag augments for static routes πŸŽ€ There are four of these, one for each combo of IPv4 or IPv6 and simple-next-hop or next-hop-list. They all share the same vibe: preference picks the winner when there are multiple static routes (lower wins, and ties turn into ECMP), and tag is an opaque 32-bit value you can use for policy stuff like advertising or filtering. Same energy, four times, iconic consistency 🧚

     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/"
           + "v4ur:simple-next-hop" {
       description
         "Augment 'simple-next-hop' case in IPv4 unicast route.";
       leaf preference {
         type uint32;
         default "1";
         description
           "The preference is used to select among multiple static
            routes.  Routes with a lower next-hop preference value
            are preferred, and equal-preference routes result in
            Equal-Cost Multipath (ECMP) static routes.";
       }
       leaf tag {
         type uint32;
         default "0";
         description
           "The tag is a 32-bit opaque value associated with the
            route that can be used for policy decisions such as
            advertisement and filtering of the route.";
       }
     }

     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/"
           + "v4ur:next-hop-list/v4ur:next-hop-list/v4ur:next-hop" {
       description
         "Augment static route configuration 'next-hop-list'.";
       leaf preference {
         type uint32;
         default "1";
         description
           "The preference is used to select among multiple static
            routes.  Routes with a lower next-hop preference value
            are preferred, and equal-preference routes result in
            ECMP static routes.";
       }
       leaf tag {
         type uint32;
         default "0";
         description
           "The tag is a 32-bit opaque value associated with the
            route that can be used for policy decisions such as
            advertisement and filtering of the route.";
       }
     }

     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/"
           + "v6ur:simple-next-hop" {
       description
         "Augment 'simple-next-hop' case in IPv6 unicast route.";
       leaf preference {
         type uint32;
         default "1";
         description
           "The preference is used to select among multiple static
            routes.  Routes with a lower next-hop preference value
            are preferred, and equal-preference routes result in
            ECMP static routes.";
       }
       leaf tag {
         type uint32;
         default "0";
         description
           "The tag is a 32-bit opaque value associated with the
            route that can be used for policy decisions such as
            advertisement and filtering of the route.";
       }
     }

     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/"
           + "v6ur:next-hop-list/v6ur:next-hop-list/v6ur:next-hop" {
       description
         "Augment static route configuration 'next-hop-list'.";
       leaf preference {
         type uint32;
         default "1";
         description
           "The preference is used to select among multiple static
            routes.  Routes with a lower next-hop preference value
            are preferred, and equal-preference routes result in
            ECMP static routes.";
       }
       leaf tag {
         type uint32;
         default "0";
         description
           "The tag is a 32-bit opaque value associated with the
            route that can be used for policy decisions such as
            advertisement and filtering of the route.";
       }
     }

Next, the RIB and route augments πŸ—‚οΈ The first one bolts the statistics grouping onto each RIB. The second one adds metric, tag and application-tag to every route. The metric and tag leaves have a when check so they only apply to routes whose source protocol isn't OSPF or IS-IS, since those models already bring their own versions. The application-tag is the sneaky one: it isn't advertised implicitly, which is a big deal πŸ‘€

     augment "/rt:routing/rt:ribs/rt:rib" {
       description
         "Augment a RIB with statistics.";
       uses rib-statistics;
     }

     augment "/rt:routing/rt:ribs/rt:rib/"
           + "rt:routes/rt:route" {
       description
         "Augment a route in the RIB with common attributes.";
       leaf metric {
         when "not(derived-from("
           + "../rt:source-protocol, 'ospf:ospf')) "
           + "and not(derived-from( "
           + "../rt:source-protocol, 'isis:isis'))" {
           description
             "This augmentation is only valid for routes that don't
              have OSPF or IS-IS as the source protocol.  The YANG
              data models for OSPF and IS-IS already include a
              'metric' augmentation for routes.";
         }
         type uint32;
         description
           "The metric is a numeric value indicating the cost
            of the route from the perspective of the routing
            protocol installing the route.  In general, routes with
            a lower metric installed by the same routing protocol
            are lower cost to reach and are preferable to routes
            with a higher metric.  However, metrics from different
            routing protocols are not comparable.";
       }
       leaf-list tag {
         when "not(derived-from("
           + "../rt:source-protocol, 'ospf:ospf')) "
           + "and not(derived-from( "
           + "../rt:source-protocol, 'isis:isis'))" {
           description
             "This augmentation is only valid for routes that don't
              have OSPF or IS-IS as the source protocol.  The YANG
              data models for OSPF and IS-IS already include a 'tag'
              augmentation for routes.";
         }
         type uint32;
         description
           "A tag is a 32-bit opaque value associated with the
            route that can be used for policy decisions such as
            advertisement and filtering of the route.";
       }
       leaf application-tag {
         type uint32;
         description
           "The application-specific tag is an additional tag that
            can be used by applications that require semantics and/or
            policy different from that of the tag.  For example,
            the tag is usually automatically advertised in OSPF
            AS-External Link State Advertisements (LSAs) while this
            application-specific tag is not advertised implicitly.";
       }
     }

Last bit of the module! πŸŽ‰ These two augments hang the repair-path grouping onto the next hops in the RIB, once for the simple-next-hop case and once for each entry in a next-hop-list. Then the module closes out πŸ‘‘

     augment "/rt:routing/rt:ribs/rt:rib/"
           + "rt:routes/rt:route/rt:next-hop/rt:next-hop-options/"
           + "rt:simple-next-hop" {
       description
         "Augment 'simple-next-hop' with 'repair-path'.";
       uses repair-path;
     }

     augment "/rt:routing/rt:ribs/rt:rib/"
           + "rt:routes/rt:route/rt:next-hop/rt:next-hop-options/"
           + "rt:next-hop-list/rt:next-hop-list/rt:next-hop" {
       description
         "Augment the next hop with a repair path.";
       uses repair-path;
     }
   }
   <CODE ENDS>

6. Security Considerations πŸ”’

okay bestie, this part is serious, so we're keeping the drama but making sure it's still readable 🫢 The YANG module in this doc is a schema for data that's meant to be reached through network management protocols like NETCONF [RFC6241] or RESTCONF [RFC8040]. NETCONF's bottom layer is the secure transport layer, and the secure transport it has to support is Secure Shell (SSH) [RFC6242]. RESTCONF's bottom layer is HTTPS, and the secure transport it has to support is TLS [RFC8446] πŸ”

The Network Configuration Access Control Model (NACM) [RFC8341] is how you restrict particular NETCONF or RESTCONF users to a preset subset of the protocol operations and content that are available. It's giving bouncer at the club πŸšͺπŸ’…

Now the spicy part ⚠️ A bunch of data nodes in the ietf-rib-extension.yang module are writable, creatable, and deletable (that's config true, which is the default). These nodes can be sensitive or vulnerable in some network environments. Writing to them (for example with edit-config) without proper protection can mess with network operations, so be careful, babe πŸ™ˆ These are the subtrees and data nodes, along with why they're sensitive:

  • /v4ur:next-hop-options/v4ur:simple-next-hop/rib-ext:preference
  • /v4ur:next-hop-options/v4ur:simple-next-hop/rib-ext:tag
  • /v4ur:next-hop-options/v4ur:next-hop-list/v4ur:next-hop-list/v4ur:next-hop/rib-ext:preference
  • /v4ur:next-hop-options/v4ur:next-hop-list/v4ur:next-hop-list/v4ur:next-hop/rib-ext:tag
  • /v6ur:next-hop-options/v6ur:simple-next-hop/rib-ext:preference
  • /v6ur:next-hop-options/v6ur:simple-next-hop/rib-ext:tag
  • /v6ur:next-hop-options/v6ur:next-hop-list/v6ur:next-hop-list/v6ur:next-hop/rib-ext:preference
  • /v6ur:next-hop-options/v6ur:next-hop-list/v6ur:next-hop-list/v6ur:next-hop/rib-ext:tag
🚨 For these augmentations to ietf-routing.yang, being able to delete, add, and modify IPv4 and IPv6 static route preferences and tags would let traffic get misrouted. That's a full disaster, not a vibe πŸ’€

Some of the readable data nodes in the ietf-rib-extension.yang module can be sensitive or vulnerable too, depending on the network. So it's important to control read access (for example through get, get-config, or notifications) to them πŸ‘€ These are the subtrees and data nodes, plus their sensitivity:

  • /rt:routing/rt:ribs/rt:rib/rib-ext:statistics
  • /rt:routing/rt:ribs/rt:rib/rt:routes/rt:route/rib-ext:metric
  • /rt:routing/rt:ribs/rt:rib/rt:routes/rt:route/rib-ext:tag
  • /rt:routing/rt:ribs/rt:rib/rt:routes/rt:route/rib-ext:application-tag
  • /rt:route/rt:next-hop/rt:next-hop-options/rt:simple-next-hop/rib-ext:repair-path
  • /rt:routes/rt:route/rt:next-hop/rt:next-hop-options/rt:next-hop-list/rt:next-hop-list/rt:next-hop/rib-ext:repair-path

Exposing the RIB exposes the routing topology of the network. That can be a problem because the exposure may make other attacks easier. Network operators may also consider their topologies sensitive confidential data, so keep it locked down πŸ§šπŸ”

All the security considerations for the writable and readable data nodes defined in [RFC8349] apply to the augmentations described here too ✨

7. IANA Considerations 🌸

This document registers the following URI in the "IETF XML Registry" [RFC3688]:

URI:  urn:ietf:params:xml:ns:yang:ietf-rib-extension
Registrant Contact:  The IESG.
XML:  N/A; the requested URI is an XML namespace.

IANA has also registered the following YANG module in the "YANG Module Names" registry [RFC6020]:

Name:  ietf-rib-extension
Namespace:  urn:ietf:params:xml:ns:yang:ietf-rib-extension
Prefix:  rib-ext
Reference:  RFC 9403

8. References πŸ“š

8.1. Normative References

8.2. Informative References

Appendix A. Combined Tree Diagram ✨

okay so this appendix is the ultimate group chat recap πŸ’… It squishes all four modules into ONE giant tree: ietf-routing.yang, ietf-ipv4-unicast-routing.yang, ietf-ipv6-unicast-routing.yang, and ietf-rib-extension.yang. no cap, it's the whole picture in one place πŸ¦‹

module: ietf-routing
  +--rw routing
  +--rw router-id?                 yang:dotted-quad {router-id}?
  +--ro interfaces
  |  +--ro interface*   if:interface-ref
  +--rw control-plane-protocols
  |  +--rw control-plane-protocol* [type name]
  |     +--rw type             identityref
  |     +--rw name             string
  |     +--rw description?     string
  |     +--rw static-routes
  |        +--rw v4ur:ipv4
  |        |  +--rw v4ur:route* [destination-prefix]
  |        |     +--rw v4ur:destination-prefix    inet:ipv4-prefix
  |        |     +--rw v4ur:description?          string
  |        |     +--rw v4ur:next-hop
  |        |        +--rw (v4ur:next-hop-options)
  |        |           +--:(v4ur:simple-next-hop)
  |        |           |  +--rw v4ur:outgoing-interface?
  |        |           |  |   if:interface-ref
  |        |           |  +--rw v4ur:next-hop-address?
  |        |           |  |   inet:ipv4-address
  |        |           |  +--rw rib-ext:preference?      uint32
  |        |           |  +--rw rib-ext:tag?             uint32
  |        |           +--:(v4ur:special-next-hop)
  |        |           |  +--rw v4ur:special-next-hop?   enumeration
  |        |           +--:(v4ur:next-hop-list)
  |        |              +--rw v4ur:next-hop-list
  |        |                 +--rw v4ur:next-hop* [index]
  |        |                    +--rw v4ur:index            string
  |        |                    +--rw v4ur:outgoing-interface?
  |        |                    |   if:interface-ref
  |        |                    +--rw v4ur:next-hop-address?
  |        |                    |   inet:ipv4-address
  |        |                    +--rw rib-ext:preference?   uint32
  |        |                    +--rw rib-ext:tag?          uint32
  |        +--rw v6ur:ipv6
  |           +--rw v6ur:route* [destination-prefix]
  |              +--rw v6ur:destination-prefix    inet:ipv6-prefix
  |              +--rw v6ur:description?          string
  |              +--rw v6ur:next-hop
  |                 +--rw (v6ur:next-hop-options)
  |                    +--:(v6ur:simple-next-hop)
  |                    |  +--rw v6ur:outgoing-interface?
  |                    |  |   if:interface-ref
  |                    |  +--rw v6ur:next-hop-address?
  |                    |  |   inet:ipv6-address
  |                    |  +--rw rib-ext:preference?      uint32
  |                    |  +--rw rib-ext:tag?             uint32
  |                    +--:(v6ur:special-next-hop)
  |                    |  +--rw v6ur:special-next-hop?   enumeration
  |                    +--:(v6ur:next-hop-list)
  |                       +--rw v6ur:next-hop-list
  |                          +--rw v6ur:next-hop* [index]
  |                             +--rw v6ur:index              string
  |                             +--rw v6ur:outgoing-interface?
  |                             |   if:interface-ref
  |                             +--rw v6ur:next-hop-address?
  |                             |   inet:ipv6-address
  |                             +--rw rib-ext:preference?     uint32
  |                             +--rw rib-ext:tag?            uint32
  +--rw ribs
     +--rw rib* [name]
        +--rw name                          string
        +--rw address-family                identityref
        +--ro default-rib?                  boolean {multiple-ribs}?
        +--ro routes
        |  +--ro route* []
        |     +--ro route-preference?       route-preference
        |     +--ro next-hop
        |     |  +--ro (next-hop-options)
        |     |     +--:(simple-next-hop)
        |     |     |  +--ro outgoing-interface?
        |     |     |  |   if:interface-ref
        |     |     |  +--ro v4ur:next-hop-address?
        |     |     |  |   inet:ipv4-address
        |     |     |  +--ro v6ur:next-hop-address?
        |     |     |  |   inet:ipv6-address
        |     |     |  +--ro rib-ext:repair-path
        |     |     |     +--ro rib-ext:outgoing-interface?
        |     |     |     |   if:interface-state-ref
        |     |     |     +--ro rib-ext:next-hop-address?
        |     |     |     |   inet:ip-address-no-zone
        |     |     |     +--ro rib-ext:metric?               uint32
        |     |     +--:(special-next-hop)
        |     |     |  +--ro special-next-hop?        enumeration
        |     |     +--:(next-hop-list)
        |     |        +--ro next-hop-list
        |     |           +--ro next-hop* []
        |     |              +--ro outgoing-interface?
        |     |              |   if:interface-ref
        |     |              +--ro v4ur:address?
        |     |              |   inet:ipv4-address
        |     |              +--ro v6ur:address?
        |     |              |   inet:ipv6-address
        |     |              +--ro rib-ext:repair-path
        |     |                 +--ro rib-ext:outgoing-interface?
        |     |                 |   if:interface-state-ref
        |     |                 +--ro rib-ext:next-hop-address?
        |     |                 |   inet:ip-address-no-zone
        |     |                 +--ro rib-ext:metric?         uint32
        |     +--ro source-protocol            identityref
        |     +--ro active?                    empty
        |     +--ro last-updated?              yang:date-and-time
        |     +--ro v4ur:destination-prefix?   inet:ipv4-prefix
        |     +--ro v6ur:destination-prefix?   inet:ipv6-prefix
        |     +--ro rib-ext:metric?            uint32
        |     +--ro rib-ext:tag*               uint32
        |     +--ro rib-ext:application-tag?   uint32
        +---x active-route
        |  +---w input
        |  |  +---w v4ur:destination-address?   inet:ipv4-address
        |  |  +---w v6ur:destination-address?   inet:ipv6-address
        |  +--ro output
        |     +--ro route
        |        +--ro next-hop
        |        |  +--ro (next-hop-options)
        |        |     +--:(simple-next-hop)
        |        |     |  +--ro outgoing-interface?
        |        |     |  |   if:interface-ref
        |        |     |  +--ro v4ur:next-hop-address?
        |        |     |  |   inet:ipv4-address
        |        |     |  +--ro v6ur:next-hop-address?
        |        |     |  |   inet:ipv6-address
        |        |     +--:(special-next-hop)
        |        |     |  +--ro special-next-hop?        enumeration
        |        |     +--:(next-hop-list)
        |        |        +--ro next-hop-list
        |        |           +--ro next-hop* []
        |        |              +--ro outgoing-interface?
        |        |              |   if:interface-ref
        |        |              +--ro v4ur:next-hop-address?
        |        |              |   inet:ipv4-address
        |        |              +--ro v6ur:next-hop-address?
        |        |              |   inet:ipv6-address
        |        +--ro source-protocol            identityref
        |        +--ro active?                    empty
        |        +--ro last-updated?              yang:date-and-time
        |        +--ro v4ur:destination-prefix?   inet:ipv4-prefix
        |        +--ro v6ur:destination-prefix?   inet:ipv6-prefix
        +--rw description?                        string
        +--ro rib-ext:statistics
           +--ro rib-ext:total-routes?              uint32
           +--ro rib-ext:total-active-routes?       uint32
           +--ro rib-ext:total-route-memory?        uint64
           +--ro rib-ext:protocol-statistics* []
              +--ro rib-ext:protocol?             identityref
              +--ro rib-ext:routes?    uint32
              +--ro rib-ext:active-routes?   uint32
              +--ro rib-ext:route-memory?    uint64

Appendix B. ietf-rib-extension.yang example πŸŽ€

okay bestie, here's the XML example [W3C.REC-xml-20081126] using the RIB extension module and RFC 8349 πŸ’–

Note: '' line wrapping per [RFC8792]. πŸ™ˆ
   <routing xmlns="urn:ietf:params:xml:ns:yang:ietf-routing">
     <control-plane-protocols>
       <control-plane-protocol>
         <type>static</type>
         <name>static-routing-protocol</name>
         <static-routes>
           <ipv4 xmlns="urn:ietf:params:xml:ns:yang:\
             ietf-ipv4-unicast-routing">
             <route>
               <destination-prefix>0.0.0.0/0</destination-prefix>
               <next-hop>
                 <next-hop-address>192.0.2.2</next-hop-address>
                 <preference xmlns="urn:ietf:params:xml:ns:yang:\
                   ietf-rib-extension">30</preference>
                 <tag xmlns="urn:ietf:params:xml:ns:yang:\
                   ietf-rib-extension">99</tag>
               </next-hop>
             </route>
           </ipv4>
           <ipv6 xmlns="urn:ietf:params:xml:ns:yang:\
             ietf-ipv6-unicast-routing">
             <route>
               <destination-prefix>::/0</destination-prefix>
               <next-hop>
                <next-hop-address>2001:db8:aaaa::1111</next-hop-address>
                <preference xmlns="urn:ietf:params:xml:ns:yang:\
                  ietf-rib-extension">30</preference>
                <tag xmlns="urn:ietf:params:xml:ns:yang:\
                  ietf-rib-extension">66</tag>
               </next-hop>
             </route>
           </ipv6>
         </static-routes>
       </control-plane-protocol>
     </control-plane-protocols>
     <ribs>
       <rib>
         <name>ipv4-primary</name>
         <address-family xmlns:v4ur="urn:ietf:params:xml:ns:yang:\
           ietf-ipv4-unicast-routing">v4ur:ipv4-unicast</address-family>
         <default-rib>true</default-rib>
         <routes>
           <route>
             <destination-prefix xmlns="urn:ietf:params:xml:ns:yang:\
               ietf-ipv4-unicast-routing">0.0.0.0/0</destination-prefix>
             <next-hop>
               <next-hop-address xmlns="urn:ietf:params:xml:ns:yang:\
                 ietf-ipv4-unicast-routing">192.0.2.2</next-hop-address>
             </next-hop>
             <route-preference>5</route-preference>
             <source-protocol>static</source-protocol>
             <last-updated>2015-10-24T18:02:45+02:00</last-updated>
           </route>
           <route>
             <destination-prefix xmlns="urn:ietf:params:xml:ns:yang:\
               ietf-ipv4-unicast-routing">198.51.100.0/24\
             </destination-prefix>
             <next-hop>
               <next-hop-address xmlns="urn:ietf:params:xml:ns:yang:\
                 ietf-ipv4-unicast-routing">192.0.2.2</next-hop-address>
               <repair-path xmlns="urn:ietf:params:xml:ns:yang:\
                 ietf-rib-extension">
                 <next-hop-address>203.0.113.1</next-hop-address>
                 <metric>200</metric>
               </repair-path>
             </next-hop>
             <route-preference>120</route-preference>
             <source-protocol xmlns:rip="urn:ietf:params:xml:ns:yang:\
               ietf-rip">rip:rip</source-protocol>
             <last-updated>2015-10-24T18:02:45+02:00</last-updated>
           </route>
         </routes>
       </rib>
       <rib>
         <name>ipv6-primary</name>
         <address-family xmlns:v6ur="urn:ietf:params:xml:ns:yang:\
           ietf-ipv6-unicast-routing">v6ur:ipv6-unicast</address-family>
         <default-rib>true</default-rib>
         <routes>
           <route>
             <destination-prefix xmlns="urn:ietf:params:xml:ns:yang:\
               ietf-ipv6-unicast-routing">0::/0</destination-prefix>
             <next-hop>
               <next-hop-address xmlns="urn:ietf:params:xml:ns:yang:\
                 ietf-ipv6-unicast-routing">2001:db8:aaaa::1111\
               </next-hop-address>
             </next-hop>
             <route-preference>5</route-preference>
             <source-protocol>static</source-protocol>
             <last-updated>2015-10-24T18:02:45+02:00</last-updated>
           </route>
           <route>
             <destination-prefix xmlns="urn:ietf:params:xml:ns:yang:\
               ietf-ipv6-unicast-routing">2001:db8:bbbb::/64\
             </destination-prefix>
             <next-hop>
               <next-hop-address xmlns="urn:ietf:params:xml:ns:yang:\
                 ietf-ipv6-unicast-routing">2001:db8:aaaa::1111\
               </next-hop-address>
               <repair-path xmlns="urn:ietf:params:xml:ns:yang:\
                ietf-rib-extension">
                <next-hop-address>2001:db8:cccc::2222</next-hop-address>
                <metric>200</metric>
               </repair-path>
             </next-hop>
             <route-preference>120</route-preference>
             <source-protocol xmlns:rip="urn:ietf:params:xml:ns:yang:\
               ietf-rip">rip:rip</source-protocol>
             <last-updated>2015-10-24T18:02:45+02:00</last-updated>
           </route>
         </routes>
       </rib>
     </ribs>
   </routing>

the same example in JSON format [RFC7951] is next, and it's giving the same vibes ✨

   {
    "ietf-routing:routing": {
      "control-plane-protocols": {
        "control-plane-protocol": [
          {
            "type": "static",
            "name": "static-routing-protocol",
            "static-routes": {
              "ietf-ipv4-unicast-routing:ipv4": {
                "route": [
                  {
                    "destination-prefix": "0.0.0.0/0",
                    "next-hop": {
                      "next-hop-address": "192.0.2.2",
                      "ietf-rib-extension:preference": 30,
                      "ietf-rib-extension:tag": 99
                    }
                  }
                ]
              },
              "ietf-ipv6-unicast-routing:ipv6": {
                "route": [
                  {
                    "destination-prefix": "::/0",
                    "next-hop": {
                      "next-hop-address": "2001:db8:aaaa::1111",
                      "ietf-rib-extension:preference": 30,
                      "ietf-rib-extension:tag": 66
                    }
                  }
                ]
              }
            }
          }
        ]
      },
      "ribs": {
        "rib": [
          {
            "name": "ipv4-primary",
            "address-family": "ietf-ipv4-unicast-routing:ipv4-unicast",
            "default-rib": true,
            "routes": {
              "route": [
                {
                  "next-hop": {
                    "ietf-ipv4-unicast-routing:next-hop-address": \
                    "192.0.2.2"
                  },
                  "route-preference": 5,
                  "source-protocol": "static",
                  "last-updated": "2015-10-24T18:02:45+02:00",
                  "ietf-ipv4-unicast-routing:destination-prefix": \
                  "0.0.0.0/0"
                },
                {
                  "next-hop": {
                    "ietf-rib-extension:repair-path": {
                      "next-hop-address": "203.0.113.1",
                      "metric": 200
                    },
                    "ietf-ipv4-unicast-routing:next-hop-address": \
                    "192.0.2.2"
                  },
                  "route-preference": 120,
                  "source-protocol": "ietf-rip:rip",
                  "last-updated": "2015-10-24T18:02:45+02:00",
                  "ietf-ipv4-unicast-routing:destination-prefix": \
                  "198.51.100.0/24"
                }
              ]
            }
          },
          {
            "name": "ipv6-primary",
            "address-family": "ietf-ipv6-unicast-routing:ipv6-unicast",
            "default-rib": true,
            "routes": {
              "route": [
                {
                  "next-hop": {
                    "ietf-ipv6-unicast-routing:next-hop-address": \
                    "2001:db8:aaaa::1111"
                  },
                  "route-preference": 5,
                  "source-protocol": "static",
                  "last-updated": "2015-10-24T18:02:45+02:00",
                  "ietf-ipv6-unicast-routing:destination-prefix": "::/0"
                },
                {
                  "next-hop": {
                    "ietf-rib-extension:repair-path": {
                      "next-hop-address": "2001:db8:cccc::2222",
                      "metric": 200
                    },
                    "ietf-ipv6-unicast-routing:next-hop-address": \
                    "2001:db8:aaaa::1111"
                  },
                  "route-preference": 120,
                  "source-protocol": "ietf-rip:rip",
                  "last-updated": "2015-10-24T18:02:45+02:00",
                  "ietf-ipv6-unicast-routing:destination-prefix": \
                  "2001:db8:bbbb::/64"
                }
              ]
            }
          }
        ]
      }
    }
   }

Acknowledgments 🫢

The authors wish to thank Les Ginsberg, Krishna Deevi, and Suyoung Yoon for their helpful comments and suggestions.

The authors wish to thank Tom Petch, Rob Wilton, Chris Hopps, Martin BjΓΆrklund, Jeffrey Zhang, Γ‰ric Vyncke, Lars Eggert, and Bo Wu for their reviews and comments. πŸ’œ


Authors' Addresses πŸ’…

   Acee Lindem
   LabN Consulting, L.L.C.
   301 Midenhall Way
   Cary, NC 27513
   United States of America
   Email: acee.ietf@gmail.com
   Yingzhen Qu
   Futurewei Technologies
   2330 Central Expressway
   Santa Clara, CA 95050
   United States of America
   Email: yingzhen.qu@futurewei.com

and that's the whole RFC, bestie. iconic. 🌈✨

πŸ“¦ where this page comes from