RFC 8345

A YANG Data Model for Network Topologies

πŸ“… published March 2018, from ietf

RFC 8345: A YANG Data Model for Network Topologies πŸ¦‹

okay bestie, this is RFC 8345, "A YANG Data Model for Network Topologies," and it's giving foundational. πŸ’– It's an IETF document from March 2018, filed as a Standards Track document, with ISSN 2070-1721. It's a product of the Internet Engineering Task Force, so the IETF stream. The header doesn't list anything it obsoletes or updates, so there's no drama there. πŸ™ˆ

The authors are a whole squad: A. Clemm (Huawei), J. Medved (Cisco), R. Varga (Pantheon Technologies SRO), N. Bahadur (Bracket Computing), H. Ananthakrishnan (Packet Design), and X. Liu (Jabil). Iconic teamwork. πŸ‘‘

Abstract ✨

okay so the abstract is short but spicy: this doc defines an abstract (generic, or base) YANG data model for network/service topologies and inventories. 🧚 It's a base model, and other, more specific topology and inventory data models augment it with technology-specific details. Main character base model energy. πŸ’…

Status of This Memo 🌸

This is an Internet Standards Track document. πŸ’–

It's a product of the IETF and represents the consensus of the IETF community. It got public review and was approved for publication by the IESG (Internet Engineering Steering Group). If you want more on Internet Standards, check out Section 2 of RFC 7841. πŸ“š

For the current status, any errata, and how to send feedback, go to https://www.rfc-editor.org/info/rfc8345. πŸŽ€

Copyright (c) 2018 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 this document was published. Please review these carefully, bestie, because they explain your rights and restrictions for this document. 🫢 Code Components pulled out of this document must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty, as described in the Simplified BSD License. ⭐

Table of Contents πŸ“

1. Introduction ....................................................4
2. Key Words .......................................................8
3. Definitions and Abbreviations ...................................9
4. Model Structure Details .........................................9
   4.1. Base Network Model .........................................9
   4.2. Base Network Topology Data Model ..........................12
   4.3. Extending the Data Model ..................................13
   4.4. Discussion and Selected Design Decisions ..................14
        4.4.1. Container Structure ................................14
        4.4.2. Underlay Hierarchies and Mappings ..................14
        4.4.3. Dealing with Changes in Underlay Networks ..........15
        4.4.4. Use of Groupings ...................................15
        4.4.5. Cardinality and Directionality of Links ............16
        4.4.6. Multihoming and Link Aggregation ...................16
        4.4.7. Mapping Redundancy .................................16
        4.4.8. Typing .............................................17
        4.4.9. Representing the Same Device in Multiple Networks ..17
        4.4.10. Supporting Client-Configured and
                System-Controlled Network Topologies ..............18
        4.4.11. Identifiers of String or URI Type .................19
5. Interactions with Other YANG Modules ...........................19
6. YANG Modules ...................................................20
   6.1. Defining the Abstract Network: ietf-network ...............20
   6.2. Creating Abstract Network Topology:
        ietf-network-topology .....................................25
7. IANA Considerations ............................................32
8. Security Considerations ........................................33
9. References .....................................................35
   9.1. Normative References ......................................35
   9.2. Informative References ....................................36
Appendix A. Model Use Cases .......................................38
  A.1. Fetching Topology from a Network Element ...................38
  A.2. Modifying TE Topology Imported from an Optical Controller ..38
  A.3. Annotating Topology for Local Computation ..................39
  A.4. SDN Controller-Based Configuration of Overlays on Top of
       Underlays ..................................................39
Appendix B. Companion YANG Data Models for Implementations Not
            Compliant with NMDA ...................................39
  B.1. YANG Module for Network State ..............................40
  B.2. YANG Module for Network Topology State .....................45
Appendix C. An Example ............................................52
Acknowledgments ...................................................56
Contributors ......................................................56
Authors' Addresses ................................................57

1. Introduction 🧚

okay so this doc introduces an abstract (base) YANG [RFC7950] data model [RFC3444] for representing networks and topologies. ✨ It's split into two parts, and they're both essential vibes:

The first part is a network data model. It lets you define network hierarchies, or network stacks (networks layered on top of each other), and keep an inventory of the nodes inside a network. πŸ“¦

The second part augments that basic network model with topology information. It adds the concepts of "links" and "termination points," which describe how the nodes in a network connect to each other. πŸ”— On top of that, the data model adds vertical layering relationships between networks, and those can be augmented to cover both network inventories and network/service topologies. 🌈

It would be possible to mash both parts into one data model, but splitting them is way cleaner. πŸ’… It makes it easier to combine network topology and network inventory data models, because inventory info can be augmented separately, without worrying about topology, into the network data model. 🫢

The data model can be augmented to describe the specifics of particular kinds of networks and topologies. For example, an augmenting data model can give network nodes attributes that are specific to one network type. πŸ¦‹ Examples of augmenting models include data models for Layer 2 network topologies; Layer 3 network topologies such as unicast IGP, IS-IS [RFC1195], and OSPF [RFC2328]; traffic engineering (TE) data [RFC3209]; or any of the many transport and service topologies. πŸ’œ Info specific to particular network types gets captured in separate, technology-specific data models.

The basic data models here are generic and can be applied to lots of network and service topologies and inventories. 🌸 They let applications work with an inventory or topology of any network at a generic level, where you don't need the specifics of a particular inventory or topology type. πŸ’– And when data specific to a network type comes into play and the model gets augmented, the instantiated data still follows the same structure and is represented consistently. πŸŽ€ This also makes it easier to represent network hierarchies and the dependencies between different network components and network types. πŸ‘‘

The abstract (base) network YANG module introduced here, called "ietf-network" (Section 6.1), contains a list of abstract network nodes and defines the concept of "network hierarchy" (network stack). ⭐ Inventory and topology data models can augment the abstract network node with inventory-specific and topology-specific attributes. The network hierarchy (stack) lets any given network have one or more "supporting networks." πŸ“ The relationship between the base network data model, the inventory data models, and the topology data models is shown in Figure 1 (dotted lines in the figure denote possible augmentations to models defined in this document). πŸ™ˆ

                     +------------------------+
                     |                        |
                     | Abstract Network Model |
                     |                        |
                     +------------------------+
                                  |
                          +-------+-------+
                          |               |
                          V               V
                   +------------+  ..............
                   |  Abstract  |  : Inventory  :
                   |  Topology  |  :  Model(s)  :
                   |   Model    |  :            :
                   +------------+  ''''''''''''''
                          |
            +-------------+-------------+-------------+
            |             |             |             |
            V             V             V             V
      ............  ............  ............  ............
      :    L1    :  :    L2    :  :    L3    :  :  Service :
      : Topology :  : Topology :  : Topology :  : Topology :
      :   Model  :  :   Model  :  :   Model  :  :   Model  :
      ''''''''''''  ''''''''''''  ''''''''''''  ''''''''''''

            Figure 1: The Network Data Model Structure

The network-topology YANG module introduced here, called "ietf-network-topology" (Section 6.2), defines a generic topology data model at its most general level of abstraction. πŸ§šβ€β™€οΈ It defines a topology graph and the components it's built from: nodes, edges, and termination points. Nodes (from the "ietf-network" module) represent graph vertices, and links represent graph edges. πŸ”— Nodes also contain termination points that anchor the links. A network can contain multiple topologies, like topologies at different layers and overlay topologies, so the data model lets you capture relationships between topologies, plus dependencies between nodes and termination points across topologies. πŸ’… An example of a topology stack is shown in Figure 2.


Figure 2 is basically a three-layer cake πŸŽ‚ and I'm obsessed. The top layer is the "Service" topology πŸŽ€, and it shows how service entities relate to each other, like the service functions in a service chain. Next is the "L3" topology 🌸, which shows network elements at Layer 3 (IP). The bottom one is the "Optical" topology ✨, which shows network elements at Layer 1.

                    +---------------------------------------+
                   /            _[X1]_          "Service"  /
                  /           _/  :   \_                  /
                 /          _/     :    \_               /
                /         _/        :     \_            /
               /         /           :      \          /
              /       [X2]__________________[X3]      /
             +---------:--------------:------:-------+
                        :              :     :
                    +----:--------------:----:--------------+
                   /      :              :   :        "L3" /
                  /        :              :  :            /
                 /         :               : :           /
                /         [Y1]_____________[Y2]         /
               /           *               * *         /
              /            *              *  *        /
             +--------------*-------------*--*-------+
                             *           *   *
                    +--------*----------*----*--------------+
                   /     [Z1]_______________[Z2] "Optical" /
                  /         \_         *   _/             /
                 /            \_      *  _/              /
                /               \_   * _/               /
               /                  \ * /                /
              /                    [Z]                /
             +---------------------------------------+

               Figure 2: Topology Hierarchy (Stack) Example

Figure 2 shows the stacking in action πŸ¦‹. Service functions in the "Service" topology get mapped onto network elements in the "L3" topology, and those L3 elements then get mapped onto network elements in the "Optical" topology. Two service functions, X1 and X3, can land on one L3 network element, Y2. That could happen if both service functions live in the same Virtual Machine (VM) (or server) and share the same set of network interfaces πŸ’œ. Then the flip side: a single "L3" network element, Y2, can be mapped onto two "Optical" network elements, Z2 and Z 🧚. That could happen if one IP router plugs into multiple Reconfigurable Optical Add/Drop Multiplexers (ROADMs) in the optical domain 🌈.

Another example of a service topology stack is shown in Figure 3.

                             VPN1                       VPN2
           +---------------------+    +---------------------+
          /   [Y5]...           /    / [Z5]______[Z3]      /
         /    /  \  :          /    /  : \_       / :     /
        /    /    \  :        /    /   :   \_    /  :    /
       /    /      \  :      /    /   :      \  /   :   /
      /   [Y4]____[Y1] :    /    /   :       [Z2]   :  /
     +------:-------:---:--+    +---:---------:-----:-+
            :        :   :         :          :     :
            :         :   :       :           :     :
            :  +-------:---:-----:------------:-----:-----+
            : /       [X1]__:___:___________[X2]   :     /
            :/         / \_  : :       _____/ /   :     /
            :         /    \_ :  _____/      /   :     /
           /:        /       \: /           /   :     /
          / :       /        [X5]          /   :     /
         /   :     /       __/ \__        /   :     /
        /     :   /    ___/       \__    /   :     /
       /       : / ___/              \  /   :     /
      /        [X4]__________________[X3]..:     /
     +------------------------------------------+
                                    L3 Topology

           Figure 3: Topology Hierarchy (Stack) Example

Figure 3 shows two VPN service topologies, VPN1 and VPN2 🌸, instantiated over one common L3 topology πŸ’…. Each VPN service topology is mapped onto a subset of the nodes from that common L3 topology 🫢.

There are multiple applications for this data model, and they're honestly so cool πŸ”₯. For example, in the context of Interface to the Routing System (I2RS), nodes within the network can use the data model to capture their understanding of the overall network topology and expose it to a network controller πŸ‘‘. The controller can then use that instantiated topology data to compare and reconcile its own view of the network topology with the view of the network elements it controls ✨. Or, nodes could propagate their understanding so they compare and reconcile it among themselves, or with help from a controller πŸ¦‹. Beyond the network element and I2RS itself, a network controller might even use the data model to represent its view of the topology it controls and expose that to applications north of itself πŸ“. More use cases for the data model are described in [USECASE-REQS] πŸ’œ.

In this data model, a network is either system controlled or not πŸ’–. If a network is system controlled, it's automatically populated by the server and represents dynamically learned information that can be read from the operational state datastore 🧚. The data model can also be used to create or modify network topologies that might be tied to an inventory model or to an overlay network 🌈. Those networks are not system controlled, though. They're configured by a client πŸ’….

The data model lets a network refer to a supporting network, supporting nodes, supporting links, and so on 🫢. It also allows a network that's configured on top of a system-controlled network to be layered, which means you can set up overlay networks on top of networks that were discovered ✨. More specifically, this data model is structured so it can be implemented as part of the ephemeral datastore [RFC8342], and the requirements for that are defined in Section 3 of [RFC8242] πŸŽ€. This lets network topology data that is written, meaning configured by a client and not system controlled, refer to dynamically learned data that is controlled by the system and not configured by a client πŸ¦‹. A simple use case would be an overlay network that is supported by the dynamically discovered IP-routed network topology 🌸. When an implementation places written data for this data model in the ephemeral datastore, such a network MAY refer to another network that is system controlled πŸ’œ.

2. Key Words

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 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. πŸŽ€ Those capitalised words are special, so read them carefully πŸ€“.

3. Definitions and Abbreviations

  • Datastore: A conceptual place to store and access information. A datastore might be implemented, for example, using files, a database, flash memory locations, or combinations thereof. A datastore maps to an instantiated YANG data tree (definition from [RFC8342]). πŸ’Ύ
  • Data subtree: An instantiated data node and the data nodes that are hierarchically contained within it. 🌳
  • IGP: Interior Gateway Protocol. πŸ›£οΈ
  • IS-IS: Intermediate System to Intermediate System. 🧭
  • OSPF: Open Shortest Path First (a link-state routing protocol). πŸ—ΊοΈ
  • SDN: Software-Defined Networking. πŸ’œ
  • URI: Uniform Resource Identifier. πŸ”—
  • VM: Virtual Machine. πŸ–₯️

4. Model Structure Details ✨

4.1. Base Network Model ✨

okay so the abstract (base) network data model lives in the "ietf-network" module πŸ’… Its layout is in Figure 4, and the notation follows the syntax from [RFC8340] 🧚

module: ietf-network
  +--rw networks
     +--rw network* [network-id]
        +--rw network-id            network-id
        +--rw network-types
        +--rw supporting-network* [network-ref]
        |  +--rw network-ref    -> /networks/network/network-id
        +--rw node* [node-id]
           +--rw node-id            node-id
           +--rw supporting-node* [network-ref node-ref]
              +--rw network-ref
              |       -> ../../../supporting-network/network-ref
              +--rw node-ref       -> /networks/network/node/node-id

Figure 4: The Structure of the Abstract (Base) Network Data Model

the data model has a container holding a list of networks πŸ¦‹ Every network gets its own list entry, and you tell them apart with a network-id πŸŽ€

a network has a type, like L2, L3, OSPF, or IS-IS 🌸 and it can even have several types at once πŸ”₯ The types live under the container "network-types". In this model that container is just an augmentation target. Network-specific modules will come along later and add new data nodes for new network types under it, meaning they'll insert them below "network-types" with YANG augmentation πŸ’–

when a network is a certain type, it contains the matching data node πŸ“ Network types SHOULD always be represented using presence containers, not leafs of type "empty" πŸ’… This is what lets you show hierarchies of network subtypes in the instance data. For example, an OSPF network (which is also a Layer 3 unicast IGP network) would have a presence container "l3-unicast-igp-network" under "network-types", and that container would hold a presence container "ospf-network" ✨ You can find real examples of this pattern in [RFC8346] πŸ“š

a network can also sit inside a hierarchy of networks, stacked on top of other networks 🧱 Those are listed in "supporting-network". A supporting network is basically an underlay network 🫢

a network also has an inventory of nodes that belong to it 🌈 The nodes get their own list, and each one is identified relative to its containing network by a node-id πŸ’œ

⚠️ it's important to know that a node doesn't exist on its own. It's always part of the network that contains it 😭 If the same device or entity shows up in several networks, or at several layers of a networking stack, it gets represented by several nodes, one per network. The node is an abstraction of the device for the particular network it belongs to πŸ‘‘ If you want to say that the same entity is part of multiple topologies, you can create one "physical" network with a list of nodes, one for each device or entity. That physical network, and the nodes in it, can then be referred to as an underlay network and as nodes from the other (logical) networks and nodes, respectively πŸ¦‹ The data model lets you define more than one underlay network (and node), so you can represent layered network topologies, service topologies, and their physical instantiation all at once πŸ™ˆ

similar to a network, a node can be supported by other nodes and map onto one or more nodes in an underlay network 🌸 That's captured in "supporting-node". The result is a hierarchy of nodes that can represent device stacks, where a node at one level is supported by a set of nodes at the level below ✨ For example:

  • a "router" node might be supported by a node representing a route processor, plus separate nodes for various line cards and service modules πŸ–₯️
  • a virtual router might be supported or hosted on a physical device that has its own separate node 🧚

and so on πŸ’…

network data for a network at a particular layer can come into existence in one of two ways πŸŽ€ (1) the network data is configured by client applications. For instance, overlay networks configured by an SDN Controller application πŸ“ Or (2) the network data is automatically controlled by the system, for networks that can be discovered πŸ” A configured (overlay) network is also allowed to refer to a (discovered) underlay network 🫢

the revised datastore architecture [RFC8342] is what accounts for all of this πŸ’… For each network, the origin of its data is shown by the "origin" metadata [RFC7952] annotation (as defined in [RFC8342]). That's "intended" for data a client application configured, and "learned" for data that was discovered 🌈 Discovered network data gets filled in automatically as part of the operational state datastore πŸ€– Configured network data lives in the configuration and intended datastores, respectively πŸ“š Configured network data that's actually in effect is also reflected in the operational state datastore ✨ Data in the operational state datastore always has complete referential integrity πŸ”’ Now, if a configured data item (like a node) has a dangling reference to something that doesn't exist (like a supporting node), that configured item gets automatically removed from the operational state datastore and only shows up in the intended datastore 😭 It's then up to the client application (like an SDN Controller) to fix things and make sure the reference to the supporting resources is configured properly πŸ› οΈ

4.2. Base Network Topology Data Model πŸ—ΊοΈ

the abstract (base) network topology data model is defined in the "ietf-network-topology" module πŸ’– It builds on the network data model from the "ietf-network" module and adds links (which define how nodes connect) and termination points (which anchor the links and live inside nodes) πŸ¦‹ The structure of the network topology module is in Figure 5, and again the notation follows the syntax from [RFC8340] 🧚

module: ietf-network-topology
  augment /nw:networks/nw:network:
    +--rw link* [link-id]
       +--rw link-id            link-id
       +--rw source
       |  +--rw source-node?   -> ../../../nw:node/node-id
       |  +--rw source-tp?     leafref
       +--rw destination
       |  +--rw dest-node?   -> ../../../nw:node/node-id
       |  +--rw dest-tp?     leafref
       +--rw supporting-link* [network-ref link-ref]
          +--rw network-ref
          |       -> ../../../nw:supporting-network/network-ref
          +--rw link-ref       leafref
  augment /nw:networks/nw:network/nw:node:
    +--rw termination-point* [tp-id]
       +--rw tp-id                           tp-id
       +--rw supporting-termination-point*
               [network-ref node-ref tp-ref]
          +--rw network-ref
          |       -> ../../../nw:supporting-node/network-ref
          +--rw node-ref
          |       -> ../../../nw:supporting-node/node-ref
          +--rw tp-ref         leafref

Figure 5: The Structure of the Abstract (Base) Network Topology Data Model

a node has a list of termination points that are used to terminate links πŸ”Œ An example of a termination point might be a physical or logical port or, more generally, an interface πŸ’œ

just like a node, a termination point can be supported by an underlying termination point, which sits in the supporting node of the underlay network 🌈

a link is identified by a link-id that uniquely identifies it within a given topology 🫢 Links are point-to-point and unidirectional πŸ’… So a link has a source and a destination 🎯 Both of them reference a corresponding node, plus a termination point on that node ✨ Similar to a node, a link can map onto one or more links (terminated by the matching underlay termination points) in an underlay topology πŸ¦‹ That's captured in "supporting-link" 🌸

4.3. Extending the Data Model πŸŽ€

to derive a data model for a specific type of network, you extend the base data model πŸ’– Roughly, you introduce a new YANG module for the new network type 🧚 In that module you define a bunch of augmentations against the "ietf-network" and "ietf-network-topology" modules πŸ”₯

we start with augmentations against the "ietf-network" module 🌈 First you define a new network type, by defining a presence container that represents it πŸ“ That new type gets inserted with augmentation below the network-types container πŸ’… Then you define data nodes for any node parameters specific to that network type, and augment them into the node list ✨ Those new data nodes can be made conditional ("when") on the presence of the matching network type in the containing network πŸ™Œ If there are requirements or restrictions around network hierarchies, like a new network type needing a specific type of underlay network, you can define constraints for that and augment the supporting-network list to match πŸ—οΈ Just be careful not to go overboard with constraints πŸ™ˆ

next up are augmentations against the "ietf-network-topology" module πŸ—ΊοΈ You define data nodes for link parameters and termination point parameters that are specific to the new network type πŸ”— Those get inserted via augmentation into the link and termination-point lists, respectively 🫢 Again, the data nodes can be conditional on the presence of the matching network type in the containing network, using a corresponding "when" statement πŸ’œ

it is possible, but not required, to group data nodes for a given network type under a dedicated container πŸ“¦ Doing that adds structure, but it also makes the data node path names longer πŸ™ˆ

when a hierarchy of network types is defined, augmentations can be applied against augmenting modules in turn 🌳 The module for a more specific network type augments the module for a more general one πŸ‘‘

4.4. Discussion and Selected Design Decisions 🧠

4.4.1. Container Structure 🧺

rather than keeping lists in separate containers, the data model stays fairly flat in terms of containment πŸ₯ž The lists of nodes, links, termination points, and supporting nodes, plus supporting links and supporting termination points, aren't kept in separate containers πŸ’– So the path identifiers used to refer to specific nodes (in management operations or in constraint specifications) can stay relatively compact πŸ¦‹ The flip side is that the instance information has no separate structure that tells elements of different lists apart πŸ€·β€β™€οΈ That structure isn't semantically required, but it might give you better "human readability" in some cases πŸ₯°

4.4.2. Underlay Hierarchies and Mappings ✨

okay so bestie, we keep the mappings between networks, nodes, links, and termination points strictly generic πŸ’… That means we don't assume a termination point is an interface, and we don't assume a node is a "system" or device πŸ™ˆ The data model at this generic level just doesn't make provisions for any of that.

When you need more specifics about mappings between upper and lower layers, you put them in augmenting modules 🧚 For example, if a termination point in a particular network type maps to an interface, an augmenting module can add an augmentation to the termination point. That augmentation introduces a leaf of type interface-ref, and the leaf references the corresponding interface [RFC8343]. Same energy for nodes: if a node maps to a particular device or network element, an augmenting module can augment the node data with a leaf that references the network element πŸ’–

Links can get a little extra too πŸ¦‹ A link at one level of a hierarchy can map to multiple links at another level. A VPN topology might model VPN tunnels as links. When a VPN tunnel maps to a path made of a chain of several links, the link contains a list of those supporting links. And the reverse works as well: a link at one level can aggregate a bundle of links at another level πŸ”₯

4.4.3. Dealing with Changes in Underlay Networks 🌊

networks can churn even while other networks are layered on top of them, iykyk πŸ™ƒ When a supporting node, link, or termination point gets deleted, the supporting leafrefs in the overlay are left dangling πŸ’€ To handle that possibility, the data model uses the require-instance construct of YANG 1.1 [RFC7950].

A dangling leafref of a configured object leaves that instance without referential integrity, which basically makes it nonoperational 😭 So any corresponding object instance gets removed from the operational state datastore until the situation is resolved. That happens when either (1) the supporting object is added to the operational state datastore, or (2) the instance is reconfigured to refer to another object that is actually reflected in the operational state datastore. The instance stays part of the intended datastore though, so it isn't lost 🫢

The application maintaining the overlay is the one responsible for dealing with churn in the underlay πŸ‘‘ When a server receives a request to configure an overlay network, it SHOULD validate whether supporting nodes / links / termination points refer to nodes in the underlay that actually exist. In other words, it verifies that the nodes are reflected in the operational state datastore. Configuration requests where supporting nodes / links / termination points refer to objects that don't exist yet SHOULD be rejected πŸ™…β€β™€οΈ Later on, the application is responsible for updating the overlay when a supporting node / link / termination point gets deleted. To make that easier, an application might subscribe to updates whenever the underlay changes, for example using the mechanisms defined in [YANG-Push] ✨

4.4.4. Use of Groupings πŸŽ€

the data model uses groupings instead of just defining data nodes "inline" 🧁 Why? Because it's way easier to include the corresponding data nodes in notifications, and then the notifications don't have to respecify every data node they want to include. The trade-off is that the constraints get more complex. Constraints involving data nodes outside the grouping need to be specified together with a uses statement where the grouping is applied. This also means that constraints and XML Path Language (XPath) statements have to be written so they navigate "down" first and select entire sets of nodes, instead of being able to target individual data nodes directly πŸ€“

the topology data model includes links that are point-to-point and unidirectional. It does not directly support multipoint or bidirectional links πŸ™ˆ I know that sounds like a limitation, but keeping things this simple and generic means the model can be very easily used by applications that run graph algorithms, so it's actually a power move πŸ‘‘ Bidirectional connections can be represented as pairs of unidirectional links. Multipoint networks can be represented through pseudonodes, similar to how IS-IS does it. And if you introduce hierarchies of nodes, where nodes at one level map onto a set of other nodes at another level, and add new links for the nodes at that level, you can represent topologies with connections that aren't point-to-point 🧚

links are terminated by a single termination point, never by sets of termination points πŸ™…β€β™€οΈ So connections involving multihoming or link aggregation schemes need to be represented using multiple point-to-point links, plus a link at a higher layer that is supported by those individual links πŸ’…

4.4.7. Mapping Redundancy πŸ”

in a hierarchy of networks, you've got nodes mapping to nodes, links mapping to links, and termination points mapping to termination points. Some of that info is redundant, lowkey πŸ˜… Specifically, if you know the mapping of a link to one or more other links, and you know the termination points of each link, then the mapping information for the termination points can be derived via transitive closure. It doesn't have to be explicitly configured 🧠 That said, the data model still lets you configure this information explicitly, so applications aren't constrained in which mappings they want to configure and which ones they'd rather derive. And yes, the data model includes integrity constraints so you can validate consistency βœ…

4.4.8. Typing 🏷️

a network's network types are represented using a container that holds a data node for each of its network types. A network can encompass several types of networks at the same time, so a container is used instead of a case construct, and each network type gets its own dedicated presence container 🌈 Why not just use an empty leaf, or even simpler, skip the network container and use a leaf-list of network-type instead? Because the goal is to represent "class hierarchies" of network types, where one network type "refines" another 🀩 Containers specific to a network type are defined in the network-specific modules, augmenting the network-types container πŸ’œ

4.4.9. Representing the Same Device in Multiple Networks πŸ–₯️

okay this one is a super common ask: being able to show that the same device is part of multiple networks and topologies πŸ‘€ But the data model defines a node as relative to the network that contains it, so the same node cannot be part of multiple topologies. In lots of cases, a node is the abstraction of a particular device in a network. So to reflect that the same device is part of multiple topologies, you might go with this approach: introduce a new type of network to represent a "physical" (or "device") network, where the nodes represent devices. This network forms an underlay for the logical networks above it, and nodes of the logical network map onto nodes in the physical network 🫢

Here's the vibe, shown in Figure 6 πŸ¦‹ The figure has three networks with two nodes each. A physical network ("P" in the figure) is an inventory of two nodes, D1 and D2, each representing a device. A second network, X, has a third network, Y, as its underlay. Both X and Y also have the physical network (P) as their underlay. X1 has both Y1 and D1 as underlay nodes, while Y1 has D1 as its underlay node. Likewise, X2 has both Y2 and D2 as underlay nodes, while Y2 has D2 as its underlay node. You can easily see that X1 and Y1 are both instantiated on the same physical node (D1) πŸ‘‘

                         +---------------------+
                        /   [X1]____[X2]      /  X(Service Overlay)
                       +----:--:----:--------+
                         ..:    :..: :
                ........:     ....: : :....
         +-----:-------------:--+    :     :...
        /   [Y1]____[Y2]....:  /      :..      :
       +------|-------|-------+          :..    :...
        Y(L3) |       +---------------------:-----+ :
              |                         +----:----|-:----------+
              +------------------------/---[D1]  [D2]         /
                                      +----------------------+
                                        P (Physical Network)

Figure 6: Topology Hierarchy Example - Multiple Underlays

In the case of a physical network, nodes represent physical devices and termination points represent physical ports πŸ”Œ It's also worth noting that you can augment the data model for a physical network type, defining augmentations where nodes reference system information and termination points reference physical interfaces. That's how you build a bridge between network and device models πŸŒ‰βœ¨

4.4.10. Supporting Client-Configured and System-Controlled Network Topologies

Okay so YANG is super strict about this 🧐. Every data node has to be either configuration data ("config true") or operational data ("config false"), and never both πŸ™…β€β™€οΈ. But we still need ALL the network info, including those vertical cross-network dependencies, living in one coherent data model πŸ’–. Most of the time, topology info about a network is discovered, so the topology is basically a property of the network that gets reflected in the data model ✨. Still, some topologies need to be configurable by an application too, like overlay topologies πŸ¦‹.

The YANG data model for network topologies marks all data as "config true" πŸ’…. The difference between data that's actually configured and data that's in effect (discovered network data included) is handled by the datastores from the Network Management Datastore Architecture (NMDA) [RFC8342] 🌈. Discovered topology data gets auto-populated in the operational state datastore, i.e., <operational>. It's "system controlled" πŸ€–. Configured topology gets instantiated in a configuration datastore, e.g., <intended>. It only shows up in <operational> once it has actually taken effect πŸ™Œ.

Configured topologies usually point at an underlay topology and include layering info, like the supporting node(s) under a node, the supporting link(s) under a link, and the supporting termination point(s) under a termination point 🍰. The supporting objects must be instantiated in the operational state datastore for the dependent overlay object to show up there too 🫢. Now, if a configured data item (like a node) has a dangling reference to something that doesn't exist (like a supporting node), that item automatically gets removed from <operational> and only lives in <intended> πŸ’€. It's up to the client application to sort that out and make sure the reference to the supporting resources is configured properly πŸ› οΈ.

For each network, the origin of its data is marked using the "origin" metadata [RFC7952] annotation defined in [RFC8342] 🏷️. Generally, discovered network data has the origin "learned", and configured network data has the origin "intended" ✨.

4.4.11. Identifiers of String or URI Type

The current data model defines the identifiers of nodes, networks, links, and termination points as URIs. They could have been strings instead πŸŽ€.

Strings are easier to implement, and that's the whole case for them πŸ™ˆ. The reason we went with URIs is that a topology, node, or termination point lives in a bigger context, so it's really useful to correlate identifiers across systems 🌐. Strings are the universal data type and are easier for humans, but they kinda muddle things πŸ˜΅β€πŸ’«. What usually happens is that strings have some structure that's magically assigned, and everyone working with the data has to be told what that structure is πŸ™ƒ. A URI makes the structure explicit and attaches extra semantics: unlike a free-form string, a URI can be fed into a URI resolver, which can point to additional resources associated with it πŸ”. That matters a lot once the topology data gets integrated into a bigger, more complex system πŸ‘‘.


5. Interactions with Other YANG Modules

The data model uses data types defined in [RFC6991] πŸ’œ.

This is a protocol-independent YANG data model with topology information 🌸. It's separate from, and not linked with, the data models used to configure routing protocols or routing information. For example, that includes the "ietf-routing" YANG module [RFC8022] 🧚.

The data model obeys the requirements for ephemeral state specified in [RFC8242] ⏳. For ephemeral topology data that is system controlled, the process in charge of maintaining topology information loads information from the routing process (such as OSPF) into the operational state datastore, without relying on a configuration datastore πŸ¦‹.


6. YANG Modules

6.1. Defining the Abstract Network: ietf-network

Here comes the first module, ietf-network πŸŽ€πŸ’…

<CODE BEGINS> file "ietf-network@2018-02-26.yang"

module ietf-network {
  yang-version 1.1;
  namespace "urn:ietf:params:xml:ns:yang:ietf-network";
  prefix nw;

  import ietf-inet-types {
    prefix inet;
    reference
      "RFC 6991: Common YANG Data Types";
  }

  organization
    "IETF I2RS (Interface to the Routing System) Working Group";

  contact
    "WG Web:    <https://datatracker.ietf.org/wg/i2rs/>
     WG List:   <mailto:i2rs@ietf.org>

     Editor:    Alexander Clemm
                <mailto:ludwig@clemm.org>

     Editor:    Jan Medved
                <mailto:jmedved@cisco.com>

     Editor:    Robert Varga
                <mailto:robert.varga@pantheon.tech>

     Editor:    Nitin Bahadur
                <mailto:nitin_bahadur@yahoo.com>

     Editor:    Hariharan Ananthakrishnan
                <mailto:hari@packetdesign.com>

     Editor:    Xufeng Liu
                <mailto:xufeng.liu.ietf@gmail.com>";

  description
    "This module defines a common base data model for a collection
     of nodes in a network.  Node definitions are further used
     in network topologies and inventories.

     Copyright (c) 2018 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 Simplified 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 8345;
     see the RFC itself for full legal notices.";

  revision 2018-02-26 {
    description
      "Initial revision.";
    reference
      "RFC 8345: A YANG Data Model for Network Topologies";
  }

  typedef node-id {
    type inet:uri;
    description
      "Identifier for a node.  The precise structure of the node-id
       will be up to the implementation.  For example, some
       implementations MAY pick a URI that includes the network-id
       as part of the path.  The identifier SHOULD be chosen
       such that the same node in a real network topology will
       always be identified through the same identifier, even if
       the data model is instantiated in separate datastores.  An
       implementation MAY choose to capture semantics in the
       identifier -- for example, to indicate the type of node.";
  }
  typedef network-id {
    type inet:uri;
    description
      "Identifier for a network.  The precise structure of the
       network-id will be up to the implementation.  The identifier
       SHOULD be chosen such that the same network will always be
       identified through the same identifier, even if the data model
       is instantiated in separate datastores.  An implementation MAY
       choose to capture semantics in the identifier -- for example,
       to indicate the type of network.";
  }

  grouping network-ref {
    description
      "Contains the information necessary to reference a network --
       for example, an underlay network.";
    leaf network-ref {
      type leafref {
        path "/nw:networks/nw:network/nw:network-id";
      require-instance false;
      }
      description
        "Used to reference a network -- for example, an underlay
         network.";
    }
  }

  grouping node-ref {
    description
      "Contains the information necessary to reference a node.";
    leaf node-ref {
      type leafref {
        path "/nw:networks/nw:network[nw:network-id=current()/../"+
          "network-ref]/nw:node/nw:node-id";
        require-instance false;
      }
      description
        "Used to reference a node.
         Nodes are identified relative to the network that
         contains them.";
    }
    uses network-ref;
  }
  container networks {
    description
      "Serves as a top-level container for a list of networks.";
    list network {
      key "network-id";
      description
        "Describes a network.
         A network typically contains an inventory of nodes,
         topological information (augmented through the
         network-topology data model), and layering information.";
      leaf network-id {
        type network-id;
        description
          "Identifies a network.";
      }
      container network-types {
        description
          "Serves as an augmentation target.
           The network type is indicated through corresponding
           presence containers augmented into this container.";
      }
      list supporting-network {
        key "network-ref";
        description
          "An underlay network, used to represent layered network
           topologies.";
        leaf network-ref {
          type leafref {
            path "/nw:networks/nw:network/nw:network-id";
          require-instance false;
          }
          description
            "References the underlay network.";
        }
      }
      list node {
        key "node-id";
        description
          "The inventory of nodes of this network.";
        leaf node-id {
          type node-id;
          description
            "Uniquely identifies a node within the containing
             network.";
        }
        list supporting-node {
          key "network-ref node-ref";
          description
            "Represents another node that is in an underlay network
             and that supports this node.  Used to represent layering
             structure.";
          leaf network-ref {
            type leafref {
              path "../../../nw:supporting-network/nw:network-ref";
            require-instance false;
            }
            description
              "References the underlay network of which the
               underlay node is a part.";
          }
          leaf node-ref {
            type leafref {
              path "/nw:networks/nw:network/nw:node/nw:node-id";
            require-instance false;
            }
            description
              "References the underlay node itself.";
          }
        }
      }
    }
  }
}

<CODE ENDS>

6.2. Creating Abstract Network Topology: ietf-network-topology ✨

okay so this is where the actual topology stuff lives πŸ¦‹ the base network model we just looked at only knows about nodes, and this module adds links that connect nodes, plus termination points that links plug into on each node. it's giving main character energy, ngl πŸ’…

<CODE BEGINS> file "ietf-network-topology@2018-02-26.yang"

   module ietf-network-topology {
     yang-version 1.1;
     namespace "urn:ietf:params:xml:ns:yang:ietf-network-topology";
     prefix nt;

     import ietf-inet-types {
       prefix inet;
       reference
         "RFC 6991: Common YANG Data Types";
     }
     import ietf-network {
       prefix nw;
       reference
         "RFC 8345: A YANG Data Model for Network Topologies";
     }

     organization
       "IETF I2RS (Interface to the Routing System) Working Group";

     contact
       "WG Web:    <https://datatracker.ietf.org/wg/i2rs/>
        WG List:   <mailto:i2rs@ietf.org>

        Editor:    Alexander Clemm
                   <mailto:ludwig@clemm.org>

        Editor:    Jan Medved
                   <mailto:jmedved@cisco.com>

        Editor:    Robert Varga
                   <mailto:robert.varga@pantheon.tech>

        Editor:    Nitin Bahadur
                   <mailto:nitin_bahadur@yahoo.com>

        Editor:    Hariharan Ananthakrishnan
                   <mailto:hari@packetdesign.com>

        Editor:    Xufeng Liu
                   <mailto:xufeng.liu.ietf@gmail.com>";

     description
       "This module defines a common base model for a network topology,
        augmenting the base network data model with links to connect
        nodes, as well as termination points to terminate links
        on nodes.

        Copyright (c) 2018 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 Simplified 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 8345;
        see the RFC itself for full legal notices.";

     revision 2018-02-26 {
       description
         "Initial revision.";
       reference
         "RFC 8345: A YANG Data Model for Network Topologies";
     }

     typedef link-id {
       type inet:uri;
       description
         "An identifier for a link in a topology.  The precise
          structure of the link-id will be up to the implementation.
          The identifier SHOULD be chosen such that the same link in a
          real network topology will always be identified through the
          same identifier, even if the data model is instantiated in
          separate datastores.  An implementation MAY choose to capture
          semantics in the identifier -- for example, to indicate the
          type of link and/or the type of topology of which the link is
          a part.";
     }

     typedef tp-id {
       type inet:uri;
       description
         "An identifier for termination points on a node.  The precise
          structure of the tp-id will be up to the implementation.
          The identifier SHOULD be chosen such that the same termination
          point in a real network topology will always be identified
          through the same identifier, even if the data model is
          instantiated in separate datastores.  An implementation MAY
          choose to capture semantics in the identifier -- for example,
          to indicate the type of termination point and/or the type of
          node that contains the termination point.";
     }

     grouping link-ref {
       description
         "This grouping can be used to reference a link in a specific
          network.  Although it is not used in this module, it is
          defined here for the convenience of augmenting modules.";
       leaf link-ref {
         type leafref {
           path "/nw:networks/nw:network[nw:network-id=current()/../"+
             "network-ref]/nt:link/nt:link-id";
           require-instance false;
         }
         description
           "A type for an absolute reference to a link instance.
            (This type should not be used for relative references.
            In such a case, a relative path should be used instead.)";
       }
       uses nw:network-ref;
     }

     grouping tp-ref {
       description
         "This grouping can be used to reference a termination point
          in a specific node.  Although it is not used in this module,
          it is defined here for the convenience of augmenting
          modules.";
       leaf tp-ref {
         type leafref {
           path "/nw:networks/nw:network[nw:network-id=current()/../"+
             "network-ref]/nw:node[nw:node-id=current()/../"+
             "node-ref]/termination-point/nt:tp-id";
           require-instance false;
         }
         description
           "A type for an absolute reference to a termination point.
            (This type should not be used for relative references.
            In such a case, a relative path should be used instead.)";
       }
       uses nw:node-ref;
     }
     augment "/nw:networks/nw:network" {
       description
         "Add links to the network data model.";
       list link {
         key "link-id";
         description
           "A network link connects a local (source) node and
            a remote (destination) node via a set of the respective
            node's termination points.  It is possible to have several
            links between the same source and destination nodes.
            Likewise, a link could potentially be re-homed between
            termination points.  Therefore, in order to ensure that we
            would always know to distinguish between links, every link
            is identified by a dedicated link identifier.  Note that a
            link models a point-to-point link, not a multipoint link.";
         leaf link-id {
           type link-id;
           description
             "The identifier of a link in the topology.
              A link is specific to a topology to which it belongs.";
         }
         container source {
           description
             "This container holds the logical source of a particular
              link.";
           leaf source-node {
             type leafref {
               path "../../../nw:node/nw:node-id";
               require-instance false;
             }
             description
               "Source node identifier.  Must be in the same topology.";
           }
           leaf source-tp {
             type leafref {
               path "../../../nw:node[nw:node-id=current()/../"+
                 "source-node]/termination-point/tp-id";
               require-instance false;
             }
             description
               "This termination point is located within the source node
                and terminates the link.";
           }
         }
         container destination {
           description
             "This container holds the logical destination of a
              particular link.";
           leaf dest-node {
             type leafref {
               path "../../../nw:node/nw:node-id";
             require-instance false;
             }
             description
               "Destination node identifier.  Must be in the same
                network.";
           }
           leaf dest-tp {
             type leafref {
               path "../../../nw:node[nw:node-id=current()/../"+
                 "dest-node]/termination-point/tp-id";
               require-instance false;
             }
             description
               "This termination point is located within the
                destination node and terminates the link.";
           }
         }
         list supporting-link {
           key "network-ref link-ref";
           description
             "Identifies the link or links on which this link depends.";
           leaf network-ref {
             type leafref {
               path "../../../nw:supporting-network/nw:network-ref";
             require-instance false;
             }
             description
               "This leaf identifies in which underlay topology
                the supporting link is present.";
           }
           leaf link-ref {
             type leafref {
               path "/nw:networks/nw:network[nw:network-id=current()/"+
                 "../network-ref]/link/link-id";
               require-instance false;
             }
             description
               "This leaf identifies a link that is a part
                of this link's underlay.  Reference loops in which
                a link identifies itself as its underlay, either
                directly or transitively, are not allowed.";
           }
         }
       }
     }
     augment "/nw:networks/nw:network/nw:node" {
       description
         "Augments termination points that terminate links.
          Termination points can ultimately be mapped to interfaces.";
       list termination-point {
         key "tp-id";
         description
           "A termination point can terminate a link.
            Depending on the type of topology, a termination point
            could, for example, refer to a port or an interface.";
         leaf tp-id {
           type tp-id;
           description
             "Termination point identifier.";
         }
         list supporting-termination-point {
           key "network-ref node-ref tp-ref";
           description
             "This list identifies any termination points on which a
              given termination point depends or onto which it maps.
              Those termination points will themselves be contained
              in a supporting node.  This dependency information can be
              inferred from the dependencies between links.  Therefore,
              this item is not separately configurable.  Hence, no
              corresponding constraint needs to be articulated.
              The corresponding information is simply provided by the
              implementing system.";

           leaf network-ref {
             type leafref {
               path "../../../nw:supporting-node/nw:network-ref";
             require-instance false;
             }
             description
               "This leaf identifies in which topology the
                supporting termination point is present.";
           }
           leaf node-ref {
             type leafref {
               path "../../../nw:supporting-node/nw:node-ref";
             require-instance false;
             }
             description
               "This leaf identifies in which node the supporting
                termination point is present.";
           }
           leaf tp-ref {
             type leafref {
               path "/nw:networks/nw:network[nw:network-id=current()/"+
                 "../network-ref]/nw:node[nw:node-id=current()/../"+
                 "node-ref]/termination-point/tp-id";
               require-instance false;
             }
             description
               "Reference to the underlay node (the underlay node must
                be in a different topology).";
           }
         }
       }
     }
   }

<CODE ENDS>

7. IANA Considerations πŸ’…βœ¨

Okay bestie, IANA gets the registration paperwork πŸ“‹. This document registers four namespace URIs in the "IETF XML Registry" [RFC3688], and the requested URIs are XML namespaces, so the XML field is N/A πŸŽ€. The registrant contact is The IESG for every one of them:

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

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

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

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

This document also registers four YANG modules in the "YANG Module Names" registry [RFC6020] πŸ¦‹. Each one points back to RFC 8345 as its reference, and each has its own prefix:

Name:      ietf-network
Namespace: urn:ietf:params:xml:ns:yang:ietf-network
Prefix:    nw
Reference: RFC 8345

Name:      ietf-network-topology
Namespace: urn:ietf:params:xml:ns:yang:ietf-network-topology
Prefix:    nt
Reference: RFC 8345

Name:      ietf-network-state
Namespace: urn:ietf:params:xml:ns:yang:ietf-network-state
Prefix:    nw-s
Reference: RFC 8345

Name:      ietf-network-topology-state
Namespace: urn:ietf:params:xml:ns:yang:ietf-network-topology-state
Prefix:    nt-s
Reference: RFC 8345

8. Security Considerations πŸ”’πŸ’€

Okay, this section is serious, so let's get into it 🫢. The YANG modules in this document define a schema for data that's meant to be accessed through network management protocols like NETCONF [RFC6241] or RESTCONF [RFC8040]. For NETCONF, the lowest layer is the secure transport layer, and the mandatory-to-implement secure transport is Secure Shell (SSH) [RFC6242]. For RESTCONF, the lowest layer is HTTPS, and the mandatory-to-implement secure transport is TLS [RFC5246] πŸ”.

The NETCONF access control model [RFC8341] is how you restrict access for particular NETCONF or RESTCONF users πŸ™…β€β™€οΈ. It lets you limit them to a preconfigured subset of all the available NETCONF or RESTCONF protocol operations and content, so not everyone gets the whole buffet πŸ“.

Now the scary part 😭. The network topology and inventory created by these modules reveal information about how networks are structured, and that could be super helpful to an attacker πŸ‘€. On the privacy side, these modules don't define any personally identifiable information. Still, some node identifiers may be associated with devices that are tied to specific users, so it's not totally harmless πŸ™ˆ.

The YANG modules also define information that can be configurable in certain instances. Overlay topologies that client applications create are one example 🧩. In that case, a malicious client could introduce topologies that nobody wanted. Specifically, a malicious client could try to remove or add a node, a link, or a termination point by creating or deleting the matching elements in the node, link, or termination point lists, respectively 😀.

For a topology that is learned, the server will automatically prohibit those misconfiguration attempts, so the server has your back πŸ›‘οΈ. For a topology that is configured, meaning its origin is "intended", the bad configuration could actually take effect and show up in the operational state datastore πŸ’₯. That can disrupt the services provided over that topology. For example, the topology could get "cut", or it could be configured in a suboptimal way. That means more resources get used up in the underlay network because of routing and bandwidth utilization inefficiencies. It could also degrade service levels and possibly cause disruption of service πŸ“‰. Because of all that, it's really important that the NETCONF access control model be vigorously applied to stop unauthorized clients from misconfiguring topologies 🚨.

There are a bunch of writable, creatable, and deletable data nodes in these YANG modules (config true, which is the default). They may be sensitive or vulnerable in some network environments. Write operations (for example, edit-config) to these data nodes without proper protection can have a negative effect on network operations. Here are the subtrees and data nodes, plus how sensitive or vulnerable each one is:

In the "ietf-network" module:

  • network: A malicious client could attempt to remove or add a network in an effort to remove an overlay topology or to create an unauthorized overlay.
  • supporting network: A malicious client could attempt to disrupt the logical structure of the model, resulting in a lack of overall data integrity and making it more difficult to, for example, troubleshoot problems rooted in the layering of network topologies.
  • node: A malicious client could attempt to remove or add a node from the network, for example, in order to sabotage the topology of a network overlay.
  • supporting node: A malicious client could attempt to change the supporting node in order to sabotage the layering of an overlay.

In the "ietf-network-topology" module:

  • link: A malicious client could attempt to remove a link from a topology, add a new link, manipulate the way the link is layered over supporting links, or modify the source or destination of the link. In each case, the structure of the topology would be sabotaged, and this scenario could, for example, result in an overlay topology that is less than optimal.
  • termination point: A malicious client could attempt to remove termination points from a node, add "phantom" termination points to a node, or change the layering dependencies of termination points, again in an effort to sabotage the integrity of a topology and potentially disrupt orderly operations of an overlay.

9. References πŸ“šπŸŽ€

9.1. Normative References

Here are the normative references, the ones you absolutely need to read to understand this spec 🧠:

[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>.

[RFC3688]  Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688,
           DOI 10.17487/RFC3688, January 2004,
           <https://www.rfc-editor.org/info/rfc3688>.

[RFC5246]  Dierks, T. and E. Rescorla, "The Transport Layer Security
           (TLS) Protocol Version 1.2", RFC 5246,
           DOI 10.17487/RFC5246, August 2008,
           <https://www.rfc-editor.org/info/rfc5246>.

[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>.

[RFC6242]  Wasserman, M., "Using the NETCONF Protocol over Secure
           Shell (SSH)", RFC 6242, DOI 10.17487/RFC6242, June 2011,
           <https://www.rfc-editor.org/info/rfc6242>.

[RFC6991]  Schoenwaelder, J., Ed., "Common YANG Data Types",
           RFC 6991, DOI 10.17487/RFC6991, July 2013,
           <https://www.rfc-editor.org/info/rfc6991>.

[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>.

9.2. Informative References

And these are the informative ones 🌸. They're good background reading, not required to implement anything πŸ’œ:

[RFC1195]  Callon, R., "Use of OSI IS-IS for routing in TCP/IP and
           dual environments", RFC 1195, DOI 10.17487/RFC1195,
           December 1990, <https://www.rfc-editor.org/info/rfc1195>.

[RFC2328]  Moy, J., "OSPF Version 2", STD 54, RFC 2328,
           DOI 10.17487/RFC2328, April 1998,
           <https://www.rfc-editor.org/info/rfc2328>.

[RFC3209]  Awduche, D., Berger, L., Gan, D., Li, T., Srinivasan, V.,
           and G. Swallow, "RSVP-TE: Extensions to RSVP for LSP
           Tunnels", RFC 3209, DOI 10.17487/RFC3209, December 2001,
           <https://www.rfc-editor.org/info/rfc3209>.

[RFC3444]  Pras, A. and J. Schoenwaelder, "On the Difference between
           Information Models and Data Models", RFC 3444,
           DOI 10.17487/RFC3444, January 2003,
           <https://www.rfc-editor.org/info/rfc3444>.

[RFC7951]  Lhotka, L., "JSON Encoding of Data Modeled with YANG",
           RFC 7951, DOI 10.17487/RFC7951, August 2016,
           <https://www.rfc-editor.org/info/rfc7951>.

[RFC7952]  Lhotka, L., "Defining and Using Metadata with YANG",
           RFC 7952, DOI 10.17487/RFC7952, August 2016,
           <https://www.rfc-editor.org/info/rfc7952>.

[RFC8022]  Lhotka, L. and A. Lindem, "A YANG Data Model for Routing
           Management", RFC 8022, DOI 10.17487/RFC8022,
           November 2016, <https://www.rfc-editor.org/info/rfc8022>.

[RFC8242]  Haas, J. and S. Hares, "Interface to the Routing System
           (I2RS) Ephemeral State Requirements", RFC 8242,
           DOI 10.17487/RFC8242, September 2017,
           <https://www.rfc-editor.org/info/rfc8242>.

[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>.

[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>.

[RFC8346]  Clemm, A., Medved, J., Varga, R., Liu, X.,
           Ananthakrishnan, H., and N. Bahadur, "A YANG Data Model
           for Layer 3 Topologies", RFC 8346, DOI 10.17487/RFC8346,
           March 2018, <https://www.rfc-editor.org/info/rfc8346>.

[USECASE-REQS]
           Hares, S. and M. Chen, "Summary of I2RS Use Case
           Requirements", Work in Progress, draft-ietf-i2rs-usecase-
           reqs-summary-03, November 2016.

[YANG-Push]
           Clemm, A., Voit, E., Gonzalez Prieto, A., Tripathy, A.,
           Nilsen-Nygaard, E., Bierman, A., and B. Lengyel, "YANG
           Datastore Subscription", Work in Progress,
           draft-ietf-netconf-yang-push-15, February 2018.

Appendix A. Model Use Cases 🌈✨

A.1. Fetching Topology from a Network Element

okay so in its simplest form 🌸 a network element (like a router) learns its topology just by taking part in peering protocols (IS-IS, BGP, etc.) πŸ¦‹ That learned topology can then be exported (e.g., to a Network Management System) for external use. Usually, any network element in a domain can be queried for its topology and is expected to give back the same result ✨

it can also get a little more complex πŸ‘€ The network element may be a controller. It could be a network element with satellite or subtended devices hanging off of it, or it could be a controller in the more classical sense, meaning a special device designated to orchestrate the activities of a number of other devices (e.g., an Optical Controller) πŸ‘‘ In this case, the controller device is logically a singleton and must be queried distinctly.

It is worth noting that controllers can be built on top of other controllers to establish a topology that incorporates all of the domains within an entire network. πŸ’…

In all of the cases above, the topology learned by the network element is considered to be operational state data. That means the data is accumulated purely by the network element's interactions with other systems and is subject to change dynamically without input or consent. πŸ™ˆ

A.2. Modifying TE Topology Imported from an Optical Controller

picture this πŸŽ€ An Optical Controller presents its topology, in abstract TE terms, to a client packet controller. This customized topology (which gets merged into the client's native topology) has enough information for the path-computing client to select paths across the optical domain according to its policies. If the client determines (at any given point in time) that this imported topology doesn't cater exactly to its requirements, it may decide to request modifications to the topology. Those customization requests may include the addition or deletion of topological elements, or the modification of attributes associated with existing topological elements. From the Optical Controller's point of view, these requests translate into configuration changes to the exported abstract topology. 🧚

A.3. Annotating Topology for Local Computation

sometimes the topology a controller learns needs a little glow-up ✨ before it runs a computation algorithm on it. Imagine a path-computation application on the controller that needs to take the geographic coordinates of the nodes into account while computing paths on the learned topology. If the learned topology doesn't contain those coordinates, then these additional attributes must be configured on the corresponding topological elements. πŸ—ΊοΈ

A.4. SDN Controller-Based Configuration of Overlays on Top of Underlays

this one is giving layers πŸ₯ž An SDN Controller (for example, Open Daylight) keeps a view of the topology of the network that it controls, based on information it discovers from the network. On top of that, it provides an application where it configures and maintains an overlay topology.

The SDN Controller thus has two roles:

  • It is a client to the network.
  • It is a server to its own northbound applications and clients, e.g., an Operations Support System (OSS).

in other words, one system's client (or controller, in this case) may be another system's server (or managed system) πŸ”„

In this scenario, the SDN Controller maintains a consolidated data model of multiple layers of topology. This includes the lower layers of the network topology, built from information discovered from the network. It also includes upper layers of topology overlay, configurable by the controller's client, i.e., the OSS. To the OSS, the lower topology layers are "read-only" information, while the upper topology layers need to be read-writable. πŸ’–

Appendix B. Companion YANG Data Models for Implementations Not Compliant with NMDA ✨

okay bestie, the YANG modules in this document are built to work with implementations that support the Network Management Datastore Architecture (NMDA) as defined in [RFC8342] πŸ¦‹ But what if NMDA isn't supported? No worries πŸ™Œ The following two companion modules, "ietf-network-state" and "ietf-network-topology-state", are defined for that case, and they represent the operational state of networks and network topologies, respectively. These modules mirror the "ietf-network" and "ietf-network-topology" modules (defined in Sections 6.1 and 6.2 of this document), but in these companion modules, all data nodes are non-configurable. They represent state that comes into being by either (1) learning topology information from the network or (2) applying configuration from the mirrored modules. 🌈

The "ietf-network-state" and "ietf-network-topology-state" companion modules are redundant and SHOULD NOT be supported by implementations that support NMDA. That's why we define these modules in Appendices B.1 and B.2 (below) instead of the main body of this document. πŸ™ˆ

As the structure of both modules mirrors that of their underlying modules, the YANG tree is not depicted separately. 🌸

B.1. YANG Module for Network State

<CODE BEGINS> file "ietf-network-state@2018-02-26.yang"

module ietf-network-state {
  yang-version 1.1;
  namespace "urn:ietf:params:xml:ns:yang:ietf-network-state";
  prefix nw-s;

  import ietf-network {
    prefix nw;
    reference
      "RFC 8345: A YANG Data Model for Network Topologies";
  }

  organization
    "IETF I2RS (Interface to the Routing System) Working Group";

  contact
    "WG Web:    <https://datatracker.ietf.org/wg/i2rs/>
     WG List:   <mailto:i2rs@ietf.org>

     Editor:    Alexander Clemm
                <mailto:ludwig@clemm.org>

     Editor:    Jan Medved
                <mailto:jmedved@cisco.com>

     Editor:    Robert Varga
                <mailto:robert.varga@pantheon.tech>

     Editor:    Nitin Bahadur
                <mailto:nitin_bahadur@yahoo.com>

     Editor:    Hariharan Ananthakrishnan
                <mailto:hari@packetdesign.com>

     Editor:    Xufeng Liu
                <mailto:xufeng.liu.ietf@gmail.com>";

  description
    "This module defines a common base data model for a collection
     of nodes in a network.  Node definitions are further used
     in network topologies and inventories.  It represents
     information that either (1) is learned and automatically
     populated or (2) results from applying network information
     that has been configured per the 'ietf-network' data model,
     mirroring the corresponding data nodes in this data model.

     The data model mirrors 'ietf-network' but contains only
     read-only state data.  The data model is not needed when the
     underlying implementation infrastructure supports the Network
     Management Datastore Architecture (NMDA).

     Copyright (c) 2018 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 Simplified 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 8345;
     see the RFC itself for full legal notices.";

  revision 2018-02-26 {
    description
      "Initial revision.";
    reference
      "RFC 8345: A YANG Data Model for Network Topologies";
  }
  grouping network-ref {
    description
      "Contains the information necessary to reference a network --
       for example, an underlay network.";
    leaf network-ref {
      type leafref {
        path "/nw-s:networks/nw-s:network/nw-s:network-id";
      require-instance false;
      }
      description
        "Used to reference a network -- for example, an underlay
         network.";
    }
  }

  grouping node-ref {
    description
      "Contains the information necessary to reference a node.";
    leaf node-ref {
      type leafref {
        path "/nw-s:networks/nw-s:network[nw-s:network-id=current()"+
          "/../network-ref]/nw-s:node/nw-s:node-id";
        require-instance false;
      }
      description
        "Used to reference a node.
         Nodes are identified relative to the network that
         contains them.";
    }
    uses network-ref;
  }
  container networks {
    config false;
    description
      "Serves as a top-level container for a list of networks.";
    list network {
      key "network-id";
      description
        "Describes a network.
         A network typically contains an inventory of nodes,
         topological information (augmented through the
         network-topology data model), and layering information.";
      container network-types {
        description
          "Serves as an augmentation target.
           The network type is indicated through corresponding
           presence containers augmented into this container.";
      }
      leaf network-id {
        type nw:network-id;
        description
          "Identifies a network.";
      }
      list supporting-network {
        key "network-ref";
        description
          "An underlay network, used to represent layered network
           topologies.";
        leaf network-ref {
          type leafref {
            path "/nw-s:networks/nw-s:network/nw-s:network-id";
          require-instance false;
          }
          description
            "References the underlay network.";
        }
      }
      list node {
        key "node-id";
        description
          "The inventory of nodes of this network.";
        leaf node-id {
          type nw:node-id;
          description
            "Uniquely identifies a node within the containing
             network.";
        }
        list supporting-node {
          key "network-ref node-ref";
          description
            "Represents another node that is in an underlay network
             and that supports this node.  Used to represent layering
             structure.";
          leaf network-ref {
            type leafref {
              path "../../../nw-s:supporting-network/nw-s:network-ref";
            require-instance false;
            }
            description
              "References the underlay network of which the
               underlay node is a part.";
          }
          leaf node-ref {
            type leafref {
              path "/nw-s:networks/nw-s:network/nw-s:node/nw-s:node-id";
            require-instance false;
            }
            description
              "References the underlay node itself.";
          }
        }
      }
    }
  }
}

<CODE ENDS>

B.2. YANG Module for Network Topology State ✨

okay so B.2 is the YANG module for network topology state, and it's giving read-only realness πŸ¦‹ It's a common base data model for topology state, whether the topology was learned or came from applying config set up per the 'ietf-network-topology' model. It augments the base network state model with links that connect nodes and termination points that terminate those links on nodes 🌸

It mirrors 'ietf-network-topology' but only has read-only state data, and you don't need it at all when your implementation supports the Network Management Datastore Architecture (NMDA) πŸ’…

<CODE BEGINS> file "ietf-network-topology-state@2018-02-26.yang"

module ietf-network-topology-state {
  yang-version 1.1;
  namespace "urn:ietf:params:xml:ns:yang:ietf-network-topology-state";
  prefix nt-s;

  import ietf-network-state {
    prefix nw-s;
    reference
      "RFC 8345: A YANG Data Model for Network Topologies";
  }
  import ietf-network-topology {
    prefix nt;
    reference
      "RFC 8345: A YANG Data Model for Network Topologies";
  }

  organization
    "IETF I2RS (Interface to the Routing System) Working Group";

  contact
    "WG Web:    <https://datatracker.ietf.org/wg/i2rs/>
     WG List:   <mailto:i2rs@ietf.org>

     Editor:    Alexander Clemm
                <mailto:ludwig@clemm.org>

     Editor:    Jan Medved
                <mailto:jmedved@cisco.com>

     Editor:    Robert Varga
                <mailto:robert.varga@pantheon.tech>

     Editor:    Nitin Bahadur
                <mailto:nitin_bahadur@yahoo.com>

     Editor:    Hariharan Ananthakrishnan
                <mailto:hari@packetdesign.com>

     Editor:    Xufeng Liu
                <mailto:xufeng.liu.ietf@gmail.com>";

  description
    "This module defines a common base data model for network
     topology state, representing topology that either (1) is learned
     or (2) results from applying topology that has been configured
     per the 'ietf-network-topology' data model, mirroring the
     corresponding data nodes in this data model.  It augments the
     base network state data model with links to connect nodes, as
     well as termination points to terminate links on nodes.

     The data model mirrors 'ietf-network-topology' but contains only
     read-only state data.  The data model is not needed when the
     underlying implementation infrastructure supports the Network
     Management Datastore Architecture (NMDA).

     Copyright (c) 2018 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 Simplified 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 8345;
     see the RFC itself for full legal notices.";

  revision 2018-02-26 {
    description
      "Initial revision.";
    reference
      "RFC 8345: A YANG Data Model for Network Topologies";
  }
  grouping link-ref {
    description
      "References a link in a specific network.  Although this
       grouping is not used in this module, it is defined here for
       the convenience of augmenting modules.";
    leaf link-ref {
      type leafref {
        path "/nw-s:networks/nw-s:network[nw-s:network-id=current()"+
          "/../network-ref]/nt-s:link/nt-s:link-id";
        require-instance false;
      }
      description
        "A type for an absolute reference to a link instance.
         (This type should not be used for relative references.
         In such a case, a relative path should be used instead.)";
    }
    uses nw-s:network-ref;
  }

  grouping tp-ref {
    description
      "References a termination point in a specific node.  Although
       this grouping is not used in this module, it is defined here
       for the convenience of augmenting modules.";
    leaf tp-ref {
      type leafref {
        path "/nw-s:networks/nw-s:network[nw-s:network-id=current()"+
          "/../network-ref]/nw-s:node[nw-s:node-id=current()/../"+
          "node-ref]/nt-s:termination-point/nt-s:tp-id";
        require-instance false;
      }
      description
        "A type for an absolute reference to a termination point.
         (This type should not be used for relative references.
         In such a case, a relative path should be used instead.)";
    }
    uses nw-s:node-ref;
  }

  augment "/nw-s:networks/nw-s:network" {
    description
      "Add links to the network data model.";
    list link {
      key "link-id";
      description
        "A network link connects a local (source) node and
         a remote (destination) node via a set of the respective
         node's termination points.  It is possible to have several
         links between the same source and destination nodes.
         Likewise, a link could potentially be re-homed between
         termination points.  Therefore, in order to ensure that we
         would always know to distinguish between links, every link
         is identified by a dedicated link identifier.  Note that a
         link models a point-to-point link, not a multipoint link.";
      container source {
        description
          "This container holds the logical source of a particular
           link.";
        leaf source-node {
          type leafref {
            path "../../../nw-s:node/nw-s:node-id";
            require-instance false;
          }
          description
            "Source node identifier.  Must be in the same topology.";
        }
        leaf source-tp {
          type leafref {
            path "../../../nw-s:node[nw-s:node-id=current()/../"+
              "source-node]/termination-point/tp-id";
            require-instance false;
          }
          description
            "This termination point is located within the source node
             and terminates the link.";
        }
      }
      container destination {
        description
          "This container holds the logical destination of a
           particular link.";
        leaf dest-node {
          type leafref {
            path "../../../nw-s:node/nw-s:node-id";
          require-instance false;
          }
          description
            "Destination node identifier.  Must be in the same
             network.";
        }
        leaf dest-tp {
          type leafref {
            path "../../../nw-s:node[nw-s:node-id=current()/../"+
              "dest-node]/termination-point/tp-id";
            require-instance false;
          }
          description
            "This termination point is located within the
             destination node and terminates the link.";
        }
      }
      leaf link-id {
        type nt:link-id;
        description
          "The identifier of a link in the topology.
           A link is specific to a topology to which it belongs.";
      }
      list supporting-link {
        key "network-ref link-ref";
        description
          "Identifies the link or links on which this link depends.";
        leaf network-ref {
          type leafref {
            path "../../../nw-s:supporting-network/nw-s:network-ref";
          require-instance false;
          }
          description
            "This leaf identifies in which underlay topology
             the supporting link is present.";
        }
        leaf link-ref {
          type leafref {
            path "/nw-s:networks/nw-s:network[nw-s:network-id="+
              "current()/../network-ref]/link/link-id";
            require-instance false;
          }
          description
            "This leaf identifies a link that is a part
             of this link's underlay.  Reference loops in which
             a link identifies itself as its underlay, either
             directly or transitively, are not allowed.";
        }
      }
    }
  }
  augment "/nw-s:networks/nw-s:network/nw-s:node" {
    description
      "Augments termination points that terminate links.
       Termination points can ultimately be mapped to interfaces.";
    list termination-point {
      key "tp-id";
      description
        "A termination point can terminate a link.
         Depending on the type of topology, a termination point
         could, for example, refer to a port or an interface.";
      leaf tp-id {
        type nt:tp-id;
        description
          "Termination point identifier.";
      }
      list supporting-termination-point {
        key "network-ref node-ref tp-ref";
        description
          "This list identifies any termination points on which a
           given termination point depends or onto which it maps.
           Those termination points will themselves be contained
           in a supporting node.  This dependency information can be
           inferred from the dependencies between links.  Therefore,
           this item is not separately configurable.  Hence, no
           corresponding constraint needs to be articulated.
           The corresponding information is simply provided by the
           implementing system.";
        leaf network-ref {
          type leafref {
            path "../../../nw-s:supporting-node/nw-s:network-ref";
          require-instance false;
          }
          description
            "This leaf identifies in which topology the
             supporting termination point is present.";
        }
        leaf node-ref {
          type leafref {
            path "../../../nw-s:supporting-node/nw-s:node-ref";
          require-instance false;
          }
          description
            "This leaf identifies in which node the supporting
             termination point is present.";
        }
        leaf tp-ref {
          type leafref {
            path "/nw-s:networks/nw-s:network[nw-s:network-id="+
              "current()/../network-ref]/nw-s:node[nw-s:node-id="+
              "current()/../node-ref]/termination-point/tp-id";
            require-instance false;
          }
          description
            "Reference to the underlay node (the underlay node must
             be in a different topology).";
        }
      }
    }
  }
}

<CODE ENDS>

Appendix C. An Example

okay so this is the part where we see the whole thing come together πŸŽ€βœ¨ we're gonna look at an instance data tree in JSON encoding [RFC7951], and it's going to instantiate "ietf-network-topology" (plus "ietf-network", which "ietf-network-topology" augments) for the topology in Figure 7. bestie, the topology is giving three nodes: D1, D2, and D3 🌸

D1 has three termination points: 1-0-1, 1-2-1, and 1-3-1 πŸ’… D2 has three termination points too: 2-1-1, 2-0-1, and 2-3-1 πŸ’– D3 has two termination points: 3-1-1 and 3-2-1 πŸ¦‹

and then there are six links, two between each pair of nodes, one going each direction. literally so clean 😭🫢

                +------------+                   +------------+
                |     D1     |                   |     D2     |
               /-\          /-\                 /-\          /-\
               | | 1-0-1    | |---------------->| | 2-1-1    | |
               | |    1-2-1 | |<----------------| |    2-0-1 | |
               \-/  1-3-1   \-/                 \-/  2-3-1   \-/
                |   /----\   |                   |   /----\   |
                +---|    |---+                   +---|    |---+
                    \----/                           \----/
                     A  |                             A  |
                     |  |                             |  |
                     |  |                             |  |
                     |  |       +------------+        |  |
                     |  |       |     D3     |        |  |
                     |  |      /-\          /-\       |  |
                     |  +----->| | 3-1-1    | |-------+  |
                     +---------| |    3-2-1 | |<---------+
                               \-/          \-/
                                |            |
                                +------------+

Figure 7: A Network Topology Example 🧚

the corresponding instance data tree is in Figure 8 πŸ‘‘

{
  "ietf-network:networks": {
    "network": [
      {
        "network-types": {
        },
        "network-id": "otn-hc",
        "node": [
          {
            "node-id": "D1",
            "termination-point": [
              {
                "tp-id": "1-0-1"
              },
              {
                "tp-id": "1-2-1"
              },
              {
                "tp-id": "1-3-1"
              }
            ]
          },
          {
            "node-id": "D2",
            "termination-point": [
              {
                "tp-id": "2-0-1"
              },
              {
                "tp-id": "2-1-1"
              },
              {
                "tp-id": "2-3-1"
              }
            ]
          },
          {
            "node-id": "D3",
            "termination-point": [
              {
                "tp-id": "3-1-1"
              },
              {
                "tp-id": "3-2-1"
              }
            ]
          }
        ],
        "ietf-network-topology:link": [
          {
            "link-id": "D1,1-2-1,D2,2-1-1",
            "source": {
              "source-node": "D1",
              "source-tp": "1-2-1"
            }
            "destination": {
              "dest-node": "D2",
              "dest-tp": "2-1-1"
            }
          },
          {
            "link-id": "D2,2-1-1,D1,1-2-1",
            "source": {
              "source-node": "D2",
              "source-tp": "2-1-1"
            }
            "destination": {
              "dest-node": "D1",
              "dest-tp": "1-2-1"
            }
          },
          {
            "link-id": "D1,1-3-1,D3,3-1-1",
            "source": {
              "source-node": "D1",
              "source-tp": "1-3-1"
            }
            "destination": {
              "dest-node": "D3",
              "dest-tp": "3-1-1"
            }
          },
          {
            "link-id": "D3,3-1-1,D1,1-3-1",
            "source": {
              "source-node": "D3",
              "source-tp": "3-1-1"
            }
            "destination": {
              "dest-node": "D1",
              "dest-tp": "1-3-1"
            }
          },
          {
            "link-id": "D2,2-3-1,D3,3-2-1",
            "source": {
              "source-node": "D2",
              "source-tp": "2-3-1"
            }
            "destination": {
              "dest-node": "D3",
              "dest-tp": "3-2-1"
            }
          },
          {
            "link-id": "D3,3-2-1,D2,2-3-1",
            "source": {
              "source-node": "D3",
              "source-tp": "3-2-1"
            }
            "destination": {
              "dest-node": "D2",
              "dest-tp": "2-3-1"
            }
          }
        ]
      }
    ]
  }
}

Figure 8: Instance Data Tree πŸ’œ

Acknowledgments

we wanna shout out everyone who helped with helpful contributions, comments, and suggestions: Alia Atlas, Andy Bierman, Martin Bjorklund, Igor Bryskin, Benoit Claise, Susan Hares, Ladislav Lhotka, Carlos Pignataro, Juergen Schoenwaelder, Robert Wilton, Qin Wu, and Xian Zhang πŸ™ŒπŸŒˆ

Contributors

more people contributed to the data model in this paper than can fit in the "Authors' Addresses" section πŸ’– additional contributors include:

  • Vishnu Pavan Beeram, Juniper
  • Ken Gray, Cisco
  • Tom Nadeau, Brocade
  • Tony Tkacik
  • Kent Watsen, Juniper
  • Aleksandr Zhdankin, Cisco

Authors' Addresses

Alexander Clemm Huawei USA - Futurewei Technologies Inc. Santa Clara, CA United States of America

Email: ludwig@clemm.org, alexander.clemm@huawei.com

Jan Medved Cisco

Email: jmedved@cisco.com

Robert Varga Pantheon Technologies SRO

Email: robert.varga@pantheon.tech

Nitin Bahadur Bracket Computing

Email: nitin_bahadur@yahoo.com

Hariharan Ananthakrishnan Packet Design

Email: hari@packetdesign.com

Xufeng Liu Jabil

Email: xufeng.liu.ietf@gmail.com

πŸ“¦ where this page comes from