RFC 8530

YANG Model for Logical Network Elements

πŸ“… published March 2019, from ietf

RFC 8530: YANG Model for Logical Network Elements πŸ¦‹

Part 1 of 8 🌸

  • Who wrote it: L. Berger and C. Hopps (LabN Consulting, L.L.C.), A. Lindem (Cisco Systems), and D. Bogdanovic and X. Liu (Volta Networks) πŸ’…
  • Category: Standards Track πŸ”₯
  • ISSN: 2070-1721
  • Date: March 2019 πŸŽ€
  • Obsoletes and updates: the title block doesn't list anything it obsoletes or updates πŸ™ˆ

Abstract

okay so this doc defines a logical network element (LNE) YANG module that's NMDA-compliant (Network Management Datastore Architecture, slay πŸ’–). It's for managing the logical resource partitioning that can exist on a network device. Common industry names for that are logical systems or logical routers ✨. The YANG model here conforms with NMDA as defined in RFC 8342 🫢.


Status of This Memo

this is an Internet Standards Track document πŸ‘‘

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

info on the current status, any errata, and how to give feedback lives at https://www.rfc-editor.org/info/rfc8530 πŸ’œ


Copyright (c) 2019 IETF Trust and the persons identified as the document authors. All rights reserved. πŸŽ€

this doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they stand on the publication date. please actually read those, bestie, because they spell out your rights and restrictions πŸ™. any Code Components pulled out of this document have to include the Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty as described in that license πŸ’…


Table of Contents 🧚

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   3
  1.1.  Terminology . . . . . . . . . . . . . . . . . . . . . . .   4
2.  Overview  . . . . . . . . . . . . . . . . . . . . . . . . . .   4
3.  Logical Network Elements  . . . . . . . . . . . . . . . . . .   5
  3.1.  LNE Instantiation and Resource Assignment . . . . . . . .   6
  3.2.  LNE Management -- LNE View  . . . . . . . . . . . . . . .   7
  3.3.  LNE Management -- Host Network Device View  . . . . . . .   7
4.  Security Considerations . . . . . . . . . . . . . . . . . . .   9
5.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .  10
6.  Logical Network Element Model . . . . . . . . . . . . . . . .  10
7.  References  . . . . . . . . . . . . . . . . . . . . . . . . .  14
  7.1.  Normative References  . . . . . . . . . . . . . . . . . .  14
  7.2.  Informative References  . . . . . . . . . . . . . . . . .  15
Appendix A.  Examples . . . . . . . . . . . . . . . . . . . . . .  17
  A.1.  Example: Host-Device-Managed LNE  . . . . . . . . . . . .  17
    A.1.1.  Configuration Data  . . . . . . . . . . . . . . . . .  21
    A.1.2.  State Data  . . . . . . . . . . . . . . . . . . . . .  25
  A.2.  Example: Self-Managed LNE . . . . . . . . . . . . . . . .  33
    A.2.1.  Configuration Data  . . . . . . . . . . . . . . . . .  36
    A.2.2.  State Data  . . . . . . . . . . . . . . . . . . . . .  39
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . .  49
Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  49

1. Introduction ✨

okay bestie, this doc defines an NMDA-compliant YANG module [RFC6020] so you can create logical network elements (LNEs) on a network device 🧚. an LNE is an independently managed virtual device built out of resources it gets from the host (or parent) network device. conceptually, an LNE running on a host is like a virtual machine running on a host system πŸ’–. if you're into host-virtualization lingo, you could call the LNE the "Guest" and the box it lives in the "Host" πŸŽ€. LNEs can be built with host-virtualization tech, but that's not a requirement πŸ¦‹. the YANG model here conforms with the Network Management Datastore Architecture defined in [RFC8342] πŸ’…

this doc also defines the augmentations you need for handing host resources to a given LNE 🌈. right now the interface management model [RFC8343] is the only module that defines host resources, so this doc only has one augmentation: assigning interfaces to an LNE πŸ”₯. future modules that cover control of host device resources are expected to, where it makes sense, offer matching support for assigning those controlled resources to LNEs πŸ‘‘

since each LNE is independently managed, each one gets its own set of YANG-modeled data that's separate from the host and from other LNEs 🫢. for example, several LNEs can each have their own "Tunnel0" interface, and those won't clash or show up in the host's interface model πŸ’œ. an LNE also gets its own management interfaces, which can include independent instances of NETCONF/RESTCONF/etc servers for configuring its YANG models πŸ“. as proof of how independent it is, an implementation can totally rename assigned interfaces. so on the host an assigned interface might be "Ethernet0/1" while inside the LNE it's "eth1" 😭✨

on top of standard management interfaces, a host device implementation may let you reach LNE config and operational YANG models straight from the host system 🌸. when that's supported, the access happens through a yang-schema-mount mount point [RFC8528], and the root-level LNE YANG models sit underneath it 🧚

vendor names for an LNE include logical system, logical router, virtual switch, chassis, and fabric πŸ’…

1.1. Terminology

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. πŸ”₯

you're expected to already know YANG [RFC7950] and YANG Schema Mount [RFC8528] terms and concepts πŸ“š. this doc draws its data model graphics using YANG Tree Diagrams [RFC8340] πŸ¦‹


2. Overview πŸ’–

so in this doc we're looking at network devices that support protocols and functions from the IETF Routing Area, like routers, firewalls, and hosts 🌈. these devices can be physical or virtual. a classic router with custom hardware counts, and so does one sitting inside a server-based virtual machine doing a virtual network function (VNF) πŸ’…. each device can split its resources into LNEs, and every LNE gives you a managed logical device 🫢. vendor names for an LNE include logical system, logical router, virtual switch, chassis, and fabric πŸŽ€. each LNE can also support VPN Routing and Forwarding (VRF) and Virtual Switching Instance (VSI) functions, which we'll call Network Instances (NIs) from here on πŸ‘‘. here's how it all fits together in Figure 1 🧚

              ,'''''''''''''''''''''''''''''''''''''''''''''''.
              |      Network Device (Physical or Virtual)     |
              | .....................   ..................... |
              | :  Logical Network  :   :  Logical Network  : |
              | :      Element      :   :      Element      : |
              | :+-----+-----+-----+:   :+-----+-----+-----+: |
              | :| Net | Net | Net |:   :| Net | Net | Net |: |
              | :|Inst.|Inst.|Inst.|:   :|Inst.|Inst.|Inst.|: |
              | :+-----+-----+-----+:   :+-----+-----+-----+: |
              | :  | |   | |   | |  :   :  | |   | |   | |  : |
              | :..|.|...|.|...|.|..:   :..|.|...|.|...|.|..: |
              |    | |   | |   | |         | |   | |   | |    |
               ''''|'|'''|'|'''|'|'''''''''|'|'''|'|'''|'|'''''
                   | |   | |   | |         | |   | |   | |
                      Interfaces              Interfaces

                     Figure 1: Module Element Relationships

the LNE model is covered in Section 3, and the NI model is covered in [RFC8529] 🫢

the interface management model [RFC8343] is already around, and defining LNEs and NIs affects it πŸ”₯. this doc and [RFC8529] both define augmentations to the interface model so it can support LNEs and NIs πŸ’œ. stuff like hardware and QoS modules might need similar elements too, maybe just for LNEs, once those get defined 🌸

interfaces are a huge deal in any network device's config and operational state 😭. they usually mix raw physical interfaces, link-layer interfaces, addressing config, and logical interfaces that might not be tied to any physical one πŸ¦‹. system services and Layer 2 and Layer 3 protocols can also attach config or operational state to different interface types (not shown here, to keep it simple) 🧚. the interface management model is defined by [RFC8343] πŸŽ€. the logical-network-element module augments that existing model by adding an identifier that interfaces use to point to their associated LNE πŸ‘‘

here's the interface-related augmentation πŸ’…

    module: ietf-logical-network-element
      augment /if:interfaces/if:interface:
        +--rw bind-lne-name?   ->
             /logical-network-elements/logical-network-element/name

the interface model in [RFC8343] is built as one flat list of all interfaces, with no regard for how resources get logically assigned on the device 🌈. so the bind-lne-name leaf is what links an interface to its LNE πŸ’–. heads up: as it's defined right now, if you want an interface in both an LNE and an NI, you first assign it to the LNE. then, inside that LNE's interface model, the LNE's version of that interface gets assigned to an NI using the mechanisms in [RFC8529] ✨

3. Logical Network Elements ✨

okay so logical network elements are giving "one device, many personalities" πŸ’… Some devices can split their resources into independent logical routers and/or switches. Whether a device can do this is totally implementation specific 🫢 Systems without that ability don't need to include the logical-network-element module, no stress. In physical devices, some hardware features are shared across partitions, but control-plane (e.g., routing) protocol instances, tables, and configuration are managed separately πŸ¦‹ For example, in logical routers or VNFs, this may look like setting up multiple logical instances from a single software installation 🌸 The model lets you configure multiple instances on one device by creating a list of logical network elements, and each one gets its own configuration and operational state for its routing and switching protocols πŸ“

The LNE model can be represented as:

module: ietf-logical-network-element
  +--rw logical-network-elements
     +--rw logical-network-element* [name]
        +--rw name           string
        +--rw managed?       boolean
        +--rw description?   string
        +--mp root
  augment /if:interfaces/if:interface:
    +--rw bind-lne-name?
          -> /logical-network-elements/logical-network-element/name

  notifications:
    +---n bind-lne-name-failed
       +--ro name             -> /if:interfaces/interface/name
       +--ro bind-lne-name
       |       -> /if:interfaces/interface/lne:bind-lne-name
       +--ro error-info?      string

name identifies the logical network element πŸŽ€ managed indicates if the server providing the host network device will provide the client LNE information via the root structure πŸ‘‘ The root of an LNE's specific data is the schema mount point root. bind-lne-name is used to associate an interface with an LNE, and bind-lne-name-failed is used in certain failure cases πŸ’œ

An LNE root MUST contain at least the YANG library [RFC7895] and interface module [RFC8343]. no skipping these, bestie πŸ™ˆ

3.1. LNE Instantiation and Resource Assignment

Clients can control logical network elements using existing list operations ✨ When a list entry gets created, a new LNE is instantiated. The models mounted under an LNE root are expected to depend on the server implementation 🧚 When a list entry gets deleted, an existing LNE is destroyed. For more information, see [RFC7950], Section 7.8.6 πŸ’…

Once an LNE exists, host network device resources can be associated with it. As mentioned earlier, this document augments ietf-interfaces with the bind-lne-name leaf so interfaces can be linked to LNEs πŸ¦‹ When a bind-lne-name is set to a valid LNE name, an implementation MUST take whatever steps are internally necessary to assign the interface to the LNE, or provide an error message (defined below) saying why the assignment failed 😭 The assignment can fail while processing the set, or after asynchronous processing. In that latter case, error notification is supported via a notification πŸ”₯

On a successful interface assignment, an implementation MUST also make the resource available to the LNE by providing a system-created interface to the LNE 🫢 The name of that system-created interface is a local matter. It may be identical to the host device name, or completely different and mapped from and to the name used in the context of the host device 🌈 The system-created interface SHOULD be exposed via the LNE-specific instance of the interface model [RFC8343] πŸ’–

3.2. LNE Management -- LNE View

Each LNE instance is expected to support management functions from within the context of the LNE root 🌸 It does this via a server that presents the LNE's root as the device root. Management functions operating within an LNE are accessed through the LNE's standard management interfaces, e.g., NETCONF and SNMP πŸ“ Initial configuration, much like the initial configuration of the host device, is a local implementation matter πŸŽ€

When you access an LNE via its management interface, you get a network device representation, but its scope is limited to that specific LNE πŸ¦‹ Normal YANG/NETCONF mechanisms, together with the required YANG library [RFC7895] instance, can be used to identify the available modules. Each supported module will be presented as a top-level module πŸ’… Only LNE-associated resources will show up in resource-related modules, e.g., interfaces, hardware, and perhaps QoS. From the management perspective, there is no difference between the available LNE view (information) and a physical network device πŸ‘‘

3.3. LNE Management -- Host Network Device View

There are multiple implementation approaches a network device can use to support the logical-network-element module and multiple LNEs 🧚 Some approaches let management functions operating at the network device level access LNE configuration and operational information, while others don't. Similarly, even when LNE management from the network device is supported by the implementation, it may be prohibited by user policy πŸ™ˆ

No matter which method an implementation picks, the 'managed' boolean mentioned above indicates when LNE management from the network device context is possible ✨ When 'managed' is 'false', the LNE cannot be managed by the host system and can only be managed from within the context of the LNE, as described in Section 3.2. Attempts to access information below a root node whose associated 'managed' boolean is set to 'false' MUST result in the error message indicated below 😭 In some implementations, it may not be possible to change this value. For example, when an LNE is implemented using virtual machine and traditional hypervisor technologies, this value is likely to be restricted to 'false' πŸ’€

It is an implementation choice whether the information can be accessed and modified from within the context of the LNE, or even from the context of the host device 🌈 When the 'managed' boolean is 'true', LNE information SHALL be accessible from the context of the host device. When the associated schema-mount definition has the config leaf set to 'true', LNE information SHALL also be modifiable from the context of the host device πŸ”₯ When LNE information is available from both the host device and from within the context of the LNE, the same information MUST be made available via the root element, with paths modified as described in [RFC8528] 🫢

An implementation MAY represent an LNE's schema using either the 'inline' or the 'shared-schema' approaches defined in [RFC8528] πŸ’œ The choice is completely an implementation choice. The inline approach is anticipated to be generally used where the 'managed' boolean will always be 'false'. The 'shared-schema' approach is expected to be most useful when all LNEs share the same schema πŸ¦‹ When 'shared-schema' is used with an LNE mount point, the YANG library rooted in the LNE's mount point MUST match the associated schema defined according to the ietf-yang-schema-mount module πŸ‘‘

Beyond the two modules that will always be present for an LNE, an LNE is a network device itself, so all modules that may be present at the top-level network device MAY also be present for the LNE 🌸 The list of available modules is expected to be implementation dependent, as is the method an implementation uses to support LNEs. Appendix A provides example uses of LNEs πŸ“

4. Security Considerations πŸ”’

The YANG modules specified in this document define a schema for data that is designed to be accessed via network management protocols such as NETCONF [RFC6241] or RESTCONF [RFC8040] πŸ’… The lowest NETCONF layer is the secure transport layer, and the mandatory-to-implement secure transport is Secure Shell (SSH) [RFC6242]. The lowest RESTCONF layer is HTTPS, and the mandatory-to-implement secure transport is TLS [RFC8446] 😭

The Network Configuration Access Control Model (NACM) [RFC8341] provides the means to restrict access for particular NETCONF or RESTCONF users to a preconfigured subset of all available NETCONF or RESTCONF protocol operations and content πŸ‘‘

LNE information represents device and network configuration information 🫢 As such, its security is important, but it is fundamentally no different from any other interface or device configuration information that has already been covered in other documents such as [RFC8343], [RFC7317], and [RFC8349] πŸ’–

The vulnerable "config true" parameters and subtrees are the following:

  • /logical-network-elements/logical-network-element: This list specifies the logical network element and the related logical device configuration.
  • /logical-network-elements/logical-network-element/managed: While this leaf is contained in the previous list, it is worth particular attention, as it controls whether information under the LNE mount point is accessible by both the host device and within the LNE context. There may be extra sensitivity to this leaf in environments where an LNE is managed by a different party than the host device, and that party does not wish to share LNE information with the operator of the host device 🚨
  • /if:interfaces/if:interface/bind-lne-name: This leaf indicates the LNE instance to which an interface is assigned. Implementations should pay particular attention to when changes to this leaf are permitted, as removing an interface from an LNE can have a major impact on the LNE's operation, since it is similar to physically removing an interface from the device. Implementations can reject a reassignment using the previously described error message generation πŸ’€
Unauthorized access to any of these lists can adversely affect the security of both the local device and the network 😱 This may lead to network malfunctions, delivery of packets to inappropriate destinations, and other problems. Treat this stuff like your diary, periodt πŸ”

5. IANA Considerations 🌈

This document registers a URI in the "IETF XML Registry" [RFC3688].

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

This document registers a YANG module in the "YANG Module Names" registry [RFC6020] ✨

name:        ietf-logical-network-element
namespace:   urn:ietf:params:xml:ns:yang:ietf-logical-network-element
prefix:      lne
reference:   RFC 8530

6. Logical Network Element Model πŸŽ€

okay so the whole model is packed into one YANG module, and it's giving organized πŸ’… Here's the full thing, copy-paste ready:

 <CODE BEGINS> file "ietf-logical-network-element@2019-01-25.yang"
 module ietf-logical-network-element {
   yang-version 1.1;

   // namespace

   namespace "urn:ietf:params:xml:ns:yang:ietf-logical-network-element";
   prefix lne;

   // import some basic types

   import ietf-interfaces {
     prefix if;
     reference
       "RFC 8343: A YANG Data Model for Interface Management";
   }
   import ietf-yang-schema-mount {
     prefix yangmnt;
     reference
       "RFC 8528: YANG Schema Mount";
   }
   organization
     "IETF Routing Area (rtgwg) Working Group";
   contact
     "WG Web:   <https://datatracker.ietf.org/wg/rtgwg/>
      WG List:  <mailto:rtgwg@ietf.org>

      Author:   Lou Berger
                <mailto:lberger@labn.net>

      Author:   Christian Hopps
                <mailto:chopps@chopps.org>

      Author:   Acee Lindem
                <mailto:acee@cisco.com>

      Author:   Dean Bogdanovic
                <mailto:ivandean@gmail.com>";
   description
     "This module is used to support multiple logical network
      elements on a single physical or virtual system.

      Copyright (c) 2019 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
      (http://trustee.ietf.org/license-info).

      This version of this YANG module is part of RFC 8530; see
      the RFC itself for full legal notices.";

   revision 2019-01-25 {
     description
       "Initial revision.";
     reference
       "RFC 8530: YANG Model for Logical Network Elements";
   }

   // top level device definition statements

   container logical-network-elements {
     description
       "Allows a network device to support multiple logical
        network element (device) instances.";
     list logical-network-element {

       key "name";
       description
         "List of logical network elements.";
       leaf name {
         type string;
         description
           "Device-wide unique identifier for the
            logical network element.";
       }
       leaf managed {
         type boolean;
         default "true";
         description
           "True if the host can access LNE information
            using the root mount point.  This value
            may not be modifiable in all implementations.";
       }
       leaf description {
         type string;
         description
           "Description of the logical network element.";
       }
       container root {
         description
           "Container for mount point.";
         yangmnt:mount-point "root" {
           description
             "Root for models supported per logical
              network element.  This mount point may or may not
              be inline based on the server implementation.  It
              SHALL always contain a YANG library and interfaces
              instance.

              When the associated 'managed' leaf is 'false', any
              operation that attempts to access information below
              the root SHALL fail with an error-tag of
              'access-denied' and an error-app-tag of
              'lne-not-managed'.";
         }
       }
     }
   }

   // augment statements

   augment "/if:interfaces/if:interface" {
     description
       "Add a node for the identification of the logical network

        element associated with an interface.  Applies to
        interfaces that can be assigned per logical network
        element.

        Note that a standard error will be returned if the
        identified leafref isn't present.  If an interface
        cannot be assigned for any other reason, the operation
        SHALL fail with an error-tag of 'operation-failed' and an
        error-app-tag of 'lne-assignment-failed'.  A meaningful
        error-info that indicates the source of the assignment
        failure SHOULD also be provided.";
     leaf bind-lne-name {
       type leafref {
         path "/logical-network-elements/logical-network-element/name";
       }
       description
         "Logical network element ID to which the interface is
          bound.";
     }
   }

   // notification statements

   notification bind-lne-name-failed {
     description
       "Indicates an error in the association of an interface to an
        LNE.  Only generated after success is initially returned
        when bind-lne-name is set.";
     leaf name {
       type leafref {
         path "/if:interfaces/if:interface/if:name";
       }
       mandatory true;
       description
         "Contains the interface name associated with the
          failure.";
     }
     leaf bind-lne-name {
       type leafref {
         path "/if:interfaces/if:interface/lne:bind-lne-name";
       }
       mandatory true;
       description
         "Contains the bind-lne-name associated with the
          failure.";
     }
     leaf error-info {
       type string;
       description
         "Optionally, indicates the source of the assignment
          failure.";
     }
   }
 }

 <CODE ENDS>
the big vibe check here is the root mount point. when the managed leaf is false, anything under the root has to fail with an access-denied error. that's a rule, not a suggestion πŸ™ˆ

7. References πŸ“š

7.1. Normative References 🌸

7.2. Informative References πŸ’œ


Appendix A. Examples ✨

okay, the examples section is up next, and it's where the LNE stuff really comes to life 🧚 Let's get into it, bestie 🫢

A.1. Example: Host-Device-Managed LNE πŸŽ€

okay so this bit walks through an example of the LNE model using schema mount to handle the parent management πŸ’… an example device runs multiple LNE instances (logical routers) πŸ¦‹ and each one supports Layer 2 and Layer 3 interfaces [RFC8343], a routing information base [RFC8349], and the OSPF protocol [OSPF-YANG]. every feature has its own YANG model, and they all get combined with YANG schema mount like this 🧚 not every possible mounted module is shown here. implementations could also mount the model from [RFC8348] ✨

module: ietf-logical-network-element
  +--rw logical-network-elements
     +--rw logical-network-element* [name]
        +--rw name           string
        +--mp root
           +--ro yanglib:modules-state/
           |  +--ro module-set-id    string
           |  +--ro module* [name revision]
           |     +--ro name                yang:yang-identifier
           +--rw sys:system/
           |  +--rw contact?          string
           |  +--rw hostname?         inet:domain-name
           |  +--rw authentication {authentication}?
           |     +--rw user-authentication-order*   identityref
           |     +--rw user* [name] {local-users}?
           |        +--rw name              string
           |        +--rw password?         ianach:crypt-hash
           |        +--rw authorized-key* [name]
           |           +--rw name         string
           |           +--rw algorithm    string
           |           +--rw key-data     binary
           +--ro sys:system-state/
           |     ...
           +--rw rt:routing/
           |  +--rw router-id?                 yang:dotted-quad
           |  +--rw control-plane-protocols
           |     +--rw control-plane-protocol* [type name]
           |        +--rw ospf:ospf/
           |          +--rw areas
           |             +--rw area* [area-id]
           |                +--rw interfaces
           |                   +--rw interface* [name]
           |                      +--rw name if:interface-ref
           |                      +--rw cost?   uint16
           +--rw if:interfaces/
              +--rw interface* [name]
                 +--rw name            string
                 +--rw ip:ipv4!/
                 |  +--rw address* [ip]
                 |  ...

module: ietf-interfaces
  +--rw interfaces
     +--rw interface* [name]
        +--rw name                        string
        +--rw lne:bind-lne-name?          string
        +--ro oper-status        enumeration

module: ietf-yang-library
  +--ro modules-state
     +--ro module-set-id    string
     +--ro module* [name revision]
        +--ro name                yang:yang-identifier

module: ietf-system
  +--rw system
  |  +--rw contact?          string
  |  +--rw hostname?         inet:domain-name
  |  +--rw authentication {authentication}?
  |     +--rw user-authentication-order*   identityref
  |     +--rw user* [name] {local-users}?
  |        +--rw name              string
  |        +--rw password?         ianach:crypt-hash
  |        +--rw authorized-key* [name]
  |           +--rw name         string
  |           +--rw algorithm    string
  |           +--rw key-data     binary
  +--ro system-state
     +--ro platform
     |  +--ro os-name?      string
     |  +--ro os-release?   string

to make the schema above real, the example device sets up the following schema mount instance 🌸

"ietf-yang-schema-mount:schema-mounts": {
  "mount-point": [
    {
      "module": "ietf-logical-network-element",
      "label": "root",
      "shared-schema":  {}
    }
  ]
}

with the YANG schema mount implementation in place, an operator can create logical router instances πŸ“ an interface can be assigned to a logical router so that the logical router has permission to access that interface, and then OSPF can be enabled on that assigned interface πŸ’œ

for this implementation, a parent management session can see the schemas of both the parent hosting system and the child logical routers πŸ‘‘ on top of that, each child logical router can grant its own management sessions, and those sessions get this schema:

module: ietf-yang-library
  +--ro modules-state
     +--ro module-set-id    string
     +--ro module* [name revision]
        +--ro name                yang:yang-identifier

module: ietf-system
  +--rw system
  |  +--rw contact?          string
  |  +--rw hostname?         inet:domain-name
  |  +--rw authentication {authentication}?
  |     +--rw user-authentication-order*   identityref
  |     +--rw user* [name] {local-users}?
  |        +--rw name              string
  |        +--rw password?         ianach:crypt-hash
  |        +--rw authorized-key* [name]
  |           +--rw name         string
  |           +--rw algorithm    string
  |           +--rw key-data     binary
  +--ro system-state
     +--ro platform
        +--ro os-name?      string
        +--ro os-release?   string

module: ietf-routing
  rw-- routing
     +--rw router-id?                 yang:dotted-quad
     +--rw control-plane-protocols
        +--rw control-plane-protocol* [type name]
           +--rw ospf:ospf/
              +--rw areas
                 +--rw area* [area-id]
                    +--rw interfaces
                       +--rw interface* [name]
                          +--rw name    if:interface-ref
                          +--rw cost?   uint16

module: ietf-interfaces
  +--rw interfaces
     +--rw interface* [name]
        +--rw name                        string
        +--ro oper-status        enumeration

A.1.1. Configuration Data 🧁

the following shows an example where two customer-specific LNEs are configured ✨

{
  "ietf-logical-network-element:logical-network-elements": {
    "logical-network-element": [
      {
        "name": "cust1",
        "root": {
          "ietf-system:system": {
            "authentication": {
              "user": [
                {
                  "name": "john",
                  "password": "$0$password"
                }
              ]
            }
          },
          "ietf-routing:routing": {
            "router-id": "192.0.2.1",
            "control-plane-protocols": {
              "control-plane-protocol": [
                {
                  "type": "ietf-routing:ospf",
                  "name": "1",
                  "ietf-ospf:ospf": {
                    "af": "ipv4",
                    "areas": {
                      "area": [
                        {
                          "area-id": "203.0.113.1",
                          "interfaces": {
                            "interface": [
                              {
                                "name": "eth1",
                                "cost": 10
                              }
                            ]
                          }

                        }
                      ]
                    }
                  }
                }
              ]
            }
          },
          "ietf-interfaces:interfaces": {
            "interface": [
              {
                "name": "eth1",
                "type": "iana-if-type:ethernetCsmacd",
                "ietf-ip:ipv4": {
                  "address": [
                    {
                      "ip": "192.0.2.11",
                      "prefix-length": 24
                    }
                  ]
                },
                "ietf-ip:ipv6": {
                  "address": [
                    {
                      "ip": "2001:db8:0:2::11",
                      "prefix-length": 64
                    }
                  ]
                }
              }
            ]
          }
        }
      },
      {
        "name": "cust2",
        "root": {
          "ietf-system:system": {
            "authentication": {
              "user": [
                {
                  "name": "john",
                  "password": "$0$password"
                }
              ]
            }
          },
          "ietf-routing:routing": {

            "router-id": "192.0.2.2",
            "control-plane-protocols": {
              "control-plane-protocol": [
                {
                  "type": "ietf-routing:ospf",
                  "name": "1",
                  "ietf-ospf:ospf": {
                    "af": "ipv4",
                    "areas": {
                      "area": [
                        {
                          "area-id": "203.0.113.1",
                          "interfaces": {
                            "interface": [
                              {
                                "name": "eth1",
                                "cost": 10
                              }
                            ]
                          }
                        }
                      ]
                    }
                  }
                }
              ]
            }
          },
          "ietf-interfaces:interfaces": {
            "interface": [
              {
                "name": "eth1",
                "type": "iana-if-type:ethernetCsmacd",
                "ietf-ip:ipv4": {
                  "address": [
                    {
                      "ip": "192.0.2.11",
                      "prefix-length": 24
                    }
                  ]
                }
              }
            ]
          }
        }
      }
    ]
  },
  "ietf-interfaces:interfaces": {
    "interface": [
      {
        "name": "eth0",
        "type": "iana-if-type:ethernetCsmacd",
        "ietf-ip:ipv4": {
          "address": [
            {
              "ip": "192.0.2.10",
              "prefix-length": 24
            }
          ]
        },
        "ietf-ip:ipv6": {
          "address": [
            {
              "ip": "2001:db8:0:2::10",
              "prefix-length": 64
            }
          ]
        }
      },
      {
        "name": "cust1:eth1",
        "type": "iana-if-type:ethernetCsmacd",
        "ietf-logical-network-element:bind-lne-name": "cust1"
      },
      {
        "name": "cust2:eth1",
        "type": "iana-if-type:ethernetCsmacd",
        "ietf-logical-network-element:bind-lne-name": "cust2"
      }
    ]
  },

  "ietf-system:system": {
    "authentication": {
      "user": [
        {
          "name": "root",
          "password": "$0$password"
        }
      ]
    }
  }
}

A.1.2. State Data πŸ¦‹

the following shows possible state data associated with the above configuration data πŸ’–

{ "ietf-logical-network-element:logical-network-elements": { "logical-network-element": [ { "name": "cust1", "root": { "ietf-yang-library:modules-state": { "module-set-id": "123e4567-e89b-12d3-a456-426655440000", "module": [ { "name": "iana-if-type", "revision": "2014-05-08", "namespace": "urn:ietf:params:xml:ns:yang:iana-if-type", "conformance-type": "import" }, { "name": "ietf-inet-types", "revision": "2013-07-15", "namespace": "urn:ietf:params:xml:ns:yang:ietf-inet-types", "conformance-type": "import" }, { "name": "ietf-interfaces", "revision": "2014-05-08", "feature": [ "arbitrary-names", "pre-provisioning" ], "namespace": "urn:ietf:params:xml:ns:yang:ietf-interfaces", "conformance-type": "implement" }, { "name": "ietf-ip", "revision": "2014-06-16", "namespace": "urn:ietf:params:xml:ns:yang:ietf-ip", "conformance-type": "implement" }, { "name": "ietf-ospf", "revision": "2018-03-03", "namespace": "urn:ietf:params:xml:ns:yang:ietf-ospf", "conformance-type": "implement" }, { "name": "ietf-routing", "revision": "2018-03-13", "namespace": "urn:ietf:params:xml:ns:yang:ietf-routing", "conformance-type": "implement" }, { "name": "ietf-system", "revision": "2014-08-06", "namespace": "urn:ietf:params:xml:ns:yang:ietf-system", "conformance-type": "implement" }, { "name": "ietf-yang-library", "revision": "2016-06-21", "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-library", "conformance-type": "implement" }, { "name": "ietf-yang-types", "revision": "2013-07-15", "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-types", "conformance-type": "import" } ] }, "ietf-system:system-state": { "platform": { "os-name": "NetworkOS" } }, "ietf-routing:routing": { "router-id": "192.0.2.1", "control-plane-protocols": { "control-plane-protocol": [ { "type": "ietf-routing:ospf", "name": "1", "ietf-ospf:ospf": { "af": "ipv4", "areas": { "area": [ { "area-id": "203.0.113.1", "interfaces": { "interface": [ { "name": "eth1", "cost": 10 } ] } } ] } } } ] } }, "ietf-interfaces:interfaces": { "interface": [ { "name": "eth1", "type": "iana-if-type:ethernetCsmacd", "oper-status": "up", "phys-address": "00:01:02:A1:B1:C1", "statistics": { "discontinuity-time": "2017-06-26T12:34:56-05:00" }, "ietf-ip:ipv4": { "address": [ { "ip": "192.0.2.11", "prefix-length": 24 } ] }, "ietf-ip:ipv6": { "address": [ { "ip": "2001:db8:0:2::11", "prefix-length": 64 } ] } } ] } } }, {

"name": "cust2", "root": { "ietf-yang-library:modules-state": { "module-set-id": "123e4567-e89b-12d3-a456-426655440000", "module": [ { "name": "iana-if-type", "revision": "2014-05-08", "namespace": "urn:ietf:params:xml:ns:yang:iana-if-type", "conformance-type": "import" }, { "name": "ietf-inet-types", "revision": "2013-07-15", "namespace": "urn:ietf:params:xml:ns:yang:ietf-inet-types", "conformance-type": "import" }, { "name": "ietf-interfaces", "revision": "2014-05-08", "feature": [ "arbitrary-names", "pre-provisioning" ], "namespace": "urn:ietf:params:xml:ns:yang:ietf-interfaces", "conformance-type": "implement" }, { "name": "ietf-ip", "revision": "2014-06-16", "namespace": "urn:ietf:params:xml:ns:yang:ietf-ip", "conformance-type": "implement" }, { "name": "ietf-ospf", "revision": "2018-03-03", "namespace": "urn:ietf:params:xml:ns:yang:ietf-ospf", "conformance-type": "implement" }, { "name": "ietf-routing", "revision": "2018-03-13", "namespace": "urn:ietf:params:xml:ns:yang:ietf-routing", "conformance-type": "implement" }, {

"name": "ietf-system", "revision": "2014-08-06", "namespace": "urn:ietf:params:xml:ns:yang:ietf-system", "conformance-type": "implement" }, { "name": "ietf-yang-library", "revision": "2016-06-21", "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-library", "conformance-type": "implement" }, { "name": "ietf-yang-types", "revision": "2013-07-15", "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-types", "conformance-type": "import" } ] }, "ietf-system:system-state": { "platform": { "os-name": "NetworkOS" } }, "ietf-routing:routing": { "router-id": "192.0.2.2", "control-plane-protocols": { "control-plane-protocol": [ { "type": "ietf-routing:ospf", "name": "1", "ietf-ospf:ospf": { "af": "ipv4", "areas": { "area": [ { "area-id": "203.0.113.1", "interfaces": { "interface": [ { "name": "eth1", "cost": 10 } ] } }

] } } } ] } }, "ietf-interfaces:interfaces": { "interface": [ { "name": "eth1", "type": "iana-if-type:ethernetCsmacd", "oper-status": "up", "phys-address": "00:01:02:A1:B1:C2", "statistics": { "discontinuity-time": "2017-06-26T12:34:56-05:00" }, "ietf-ip:ipv4": { "address": [ { "ip": "192.0.2.11", "prefix-length": 24 } ] } } ] } } } ] },

"ietf-interfaces:interfaces": { "interface": [ { "name": "eth0", "type": "iana-if-type:ethernetCsmacd", "oper-status": "up", "phys-address": "00:01:02:A1:B1:C0", "statistics": { "discontinuity-time": "2017-06-26T12:34:56-05:00" }, "ietf-ip:ipv4": { "address": [ { "ip": "192.0.2.10", "prefix-length": 24

} ] }, "ietf-ip:ipv6": { "address": [ { "ip": "2001:db8:0:2::10", "prefix-length": 64 } ] } }, { "name": "cust1:eth1", "type": "iana-if-type:ethernetCsmacd", "oper-status": "up", "phys-address": "00:01:02:A1:B1:C1", "statistics": { "discontinuity-time": "2017-06-26T12:34:56-05:00" }, "ietf-logical-network-element:bind-lne-name": "cust1" }, { "name": "cust2:eth1", "type": "iana-if-type:ethernetCsmacd", "oper-status": "up", "phys-address": "00:01:02:A1:B1:C2", "statistics": { "discontinuity-time": "2017-06-26T12:34:56-05:00" }, "ietf-logical-network-element:bind-lne-name": "cust2" } ] },

"ietf-system:system-state": { "platform": { "os-name": "NetworkOS" } },

  "ietf-yang-library:modules-state": {
    "module-set-id": "123e4567-e89b-12d3-a456-426655440000",
    "module": [
      {
        "name": "iana-if-type",
        "revision": "2014-05-08",
        "namespace": "urn:ietf:params:xml:ns:yang:iana-if-type",
        "conformance-type": "import"
      },
      {
        "name": "ietf-inet-types",
        "revision": "2013-07-15",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-inet-types",
        "conformance-type": "import"
      },
      {
        "name": "ietf-interfaces",
        "revision": "2014-05-08",
        "feature": [
          "arbitrary-names",
          "pre-provisioning"
        ],
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-interfaces",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-ip",
        "revision": "2014-06-16",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-ip",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-logical-network-element",
        "revision": "2017-03-13",
        "feature": [
          "bind-lne-name"
        ],
        "namespace":
          "urn:ietf:params:xml:ns:yang:ietf-logical-network-element",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-ospf",
        "revision": "2018-03-03",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-ospf",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-routing",
        "revision": "2018-03-13",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-routing",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-system",
        "revision": "2014-08-06",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-system",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-yang-library",
        "revision": "2016-06-21",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-library",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-yang-schema-mount",
        "revision": "2017-05-16",
        "namespace":
          "urn:ietf:params:xml:ns:yang:ietf-yang-schema-mount",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-yang-types",
        "revision": "2013-07-15",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-types",
        "conformance-type": "import"
      }
    ]
  },

  "ietf-yang-schema-mount:schema-mounts": {
    "mount-point": [
      {
        "module": "ietf-logical-network-element",
        "label": "root",
        "shared-schema": {}
      }
    ]
  }
}

That wraps up the host device's state data, all tidy and complete πŸŽ€βœ¨

A.2. Example: Self-Managed LNE ✨

okay bestie, this section is all about using schema mount to give each logical router its own independent management πŸ¦‹ The example device can run multiple LNEs (logical routers), and each one gets Layer 2 and Layer 3 interfaces [RFC8343], a routing information base [RFC8349], and the OSPF protocol. Every one of those features has its own YANG model, and the YANG schema mount slays by putting them all together like this πŸ’…

module: ietf-logical-network-element
  +--rw logical-network-elements
     +--rw logical-network-element* [name]
        +--rw name           string
        +--mp root
           // The internal modules of the LNE are not visible to
           // the parent management.
           // The child manages its modules, including ietf-routing
           // and ietf-interfaces

module: ietf-interfaces
  +--rw interfaces
     +--rw interface* [name]
        +--rw name                        string
        +--rw lne:bind-lne-name?          string
        +--ro oper-status        enumeration

module: ietf-yang-library
  +--ro modules-state
     +--ro module-set-id    string
     +--ro module* [name revision]
        +--ro name                yang:yang-identifier

module: ietf-system
  +--rw system
  |  +--rw contact?          string
  |  +--rw hostname?         inet:domain-name
  |  +--rw authentication {authentication}?
  |     +--rw user-authentication-order*   identityref
  |     +--rw user* [name] {local-users}?
  |        +--rw name              string
  |        +--rw password?         ianach:crypt-hash
  |        +--rw authorized-key* [name]
  |           +--rw name         string
  |           +--rw algorithm    string
  |           +--rw key-data     binary
  +--ro system-state
     +--ro platform
     |  +--ro os-name?      string
     |  +--ro os-release?   string

To make the schema above real, the device sets up this schema mount instance 🧚

"ietf-yang-schema-mount:schema-mounts": {
  "mount-point": [
    {
      "module": "ietf-logical-network-element",
      "label": "root",
      "inline": {}
    }
  ]
}

Using the YANG schema mount implementation, an operator can create logical routers, and each one comes with its own router-specific inline modules 🌸 An interface can be assigned to a logical router, which gives that logical router permission to access the interface. Once that's done, OSPF can be enabled on the assigned interface πŸ“ Each logical router manages its own set of modules on its own, and those sets may or may not match the ones on the other logical routers.

Here's an example of the schema set running on one particular logical router πŸ’œ

module: ietf-yang-library
  +--ro modules-state
     +--ro module-set-id    string
     +--ro module* [name revision]
        +--ro name                yang:yang-identifier

module: ietf-system
  +--rw system
  |  +--rw contact?          string
  |  +--rw hostname?         inet:domain-name
  |  +--rw authentication {authentication}?
  |     +--rw user-authentication-order*   identityref
  |     +--rw user* [name] {local-users}?
  |        +--rw name              string
  |        +--rw password?         ianach:crypt-hash
  |        +--rw authorized-key* [name]
  |           +--rw name         string
  |           +--rw algorithm    string
  |           +--rw key-data     binary
  +--ro system-state
     +--ro platform
     |  +--ro os-name?      string
     |  +--ro os-release?   string

module: ietf-routing
  +--rw routing
     +--rw router-id?                 yang:dotted-quad
     +--rw control-plane-protocols
        +--rw control-plane-protocol* [type name]
           +--rw ospf:ospf/
              +--rw areas
                 +--rw area* [area-id]
                    +--rw interfaces
                       +--rw interface* [name]
                          +--rw name    if:interface-ref
                          +--rw cost?   uint16

module: ietf-interfaces
  +--rw interfaces
     +--rw interface* [name]
        +--rw name                        string
        +--ro oper-status        enumeration

A.2.1. Configuration Data

each child virtual router gets its own sessions and its own configuration data, so they don't step on each other's toes πŸ’…

A.2.1.1. Logical Network Element 'vnf1'

Here's a sample of the configuration data for the LNE named "vnf1" πŸŽ€

{
  "ietf-system:system": {
    "authentication": {
      "user": [
        {
          "name": "john",
          "password": "$0$password"
        }
      ]
    }
  },
  "ietf-routing:routing": {
    "router-id": "192.0.2.1",
    "control-plane-protocols": {
      "control-plane-protocol": [
        {
          "type": "ietf-routing:ospf",
          "name": "1",
          "ietf-ospf:ospf": {
            "af": "ipv4",
            "areas": {
              "area": [
                {
                  "area-id": "203.0.113.1",
                  "interfaces": {
                    "interface": [
                      {
                        "name": "eth1",
                        "cost": 10
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      ]
    }
  },
  "ietf-interfaces:interfaces": {
    "interface": [
      {

        "name": "eth1",
        "type": "iana-if-type:ethernetCsmacd",
        "ietf-ip:ipv4": {
          "address": [
            {
              "ip": "192.0.2.11",
              "prefix-length": 24
            }
          ]
        }
      }
    ]
  }
}

A.2.1.2. Logical Network Element 'vnf2'

And here's the config for the LNE named "vnf2" πŸ¦‹

{
  "ietf-system:system": {
    "authentication": {
      "user": [
        {
          "name": "john",
          "password": "$0$password"
        }
      ]
    }
  },
  "ietf-routing:routing": {
    "router-id": "192.0.2.2",
    "control-plane-protocols": {
      "control-plane-protocol": [
        {
          "type": "ietf-routing:ospf",
          "name": "1",
          "ietf-ospf:ospf": {
            "af": "ipv4",
            "areas": {
              "area": [
                {
                  "area-id": "203.0.113.1",
                  "interfaces": {
                    "interface": [
                      {
                        "name": "eth1",
                        "cost": 10
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      ]
    }
  },
  "ietf-interfaces:interfaces": {
    "interface": [
      {
        "name": "eth1",
        "type": "iana-if-type:ethernetCsmacd",
        "ietf-ip:ipv4": {
          "address": [
            {
              "ip": "192.0.2.11",
              "prefix-length": 24
            }
          ]
        }
      }
    ]
  }
}

A.2.2. State Data

next up is the possible state data that goes with the configuration above πŸ‘€ heads up, there are three views in total: the host device's view, plus one view for each of the LNEs 🌈

A.2.2.1. Host Device πŸ–₯️✨

okay so this is the state data for the device hosting the example LNEs πŸ’… it's giving main character energy, the host box is running the whole show πŸ‘‘

{
  "ietf-logical-network-element:logical-network-elements": {
    "logical-network-element": [
      {
        "name": "vnf1",
        "root": {
        }

      },
      {
        "name": "vnf2",
        "root": {
        }
      }
    ]
  },

  "ietf-interfaces:interfaces": {
    "interface": [
      {
        "name": "eth0",
        "type": "iana-if-type:ethernetCsmacd",
        "oper-status": "up",
        "phys-address": "00:01:02:A1:B1:C0",
        "statistics": {
          "discontinuity-time": "2017-06-26T12:34:56-05:00"
        },
        "ietf-ip:ipv4": {
          "address": [
            {
              "ip": "192.0.2.10",
              "prefix-length": 24
            }
          ]
        }
      },
      {
        "name": "vnf1:eth1",
        "type": "iana-if-type:ethernetCsmacd",
        "oper-status": "up",
        "phys-address": "00:01:02:A1:B1:C1",
        "statistics": {
          "discontinuity-time": "2017-06-26T12:34:56-05:00"
        },
        "ietf-logical-network-element:bind-lne-name": "vnf1"
      },
      {
        "name": "vnf2:eth2",
        "type": "iana-if-type:ethernetCsmacd",
        "oper-status": "up",
        "phys-address": "00:01:02:A1:B1:C2",
        "statistics": {
          "discontinuity-time": "2017-06-26T12:34:56-05:00"
        },
        "ietf-logical-network-element:bind-lne-name": "vnf2"
      }

    ]
  },

  "ietf-system:system-state": {
    "platform": {
      "os-name": "NetworkOS"
    }
  },

  "ietf-yang-library:modules-state": {
    "module-set-id": "123e4567-e89b-12d3-a456-426655440000",
    "module": [
      {
        "name": "iana-if-type",
        "revision": "2014-05-08",
        "namespace": "urn:ietf:params:xml:ns:yang:iana-if-type",
        "conformance-type": "import"
      },
      {
        "name": "ietf-inet-types",
        "revision": "2013-07-15",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-inet-types",
        "conformance-type": "import"
      },
      {
        "name": "ietf-interfaces",
        "revision": "2014-05-08",
        "feature": [
          "arbitrary-names",
          "pre-provisioning"
        ],
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-interfaces",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-ip",
        "revision": "2014-06-16",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-ip",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-logical-network-element",
        "revision": "2017-03-13",
        "feature": [
          "bind-lne-name"
        ],
        "namespace":
          "urn:ietf:params:xml:ns:yang:ietf-logical-network-element",

        "conformance-type": "implement"
      },
      {
        "name": "ietf-system",
        "revision": "2014-08-06",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-system",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-yang-library",
        "revision": "2016-06-21",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-library",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-yang-schema-mount",
        "revision": "2017-05-16",
        "namespace":
          "urn:ietf:params:xml:ns:yang:ietf-yang-schema-mount",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-yang-types",
        "revision": "2013-07-15",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-types",
        "conformance-type": "import"
      }
    ]
  },

  "ietf-yang-schema-mount:schema-mounts": {
    "mount-point": [
      {
        "module": "ietf-logical-network-element",
        "label": "root",
        "inline": {}
      }
    ]
  }
}

A.2.2.2. Logical Network Element 'vnf1' 🌸

here's the state data for the example LNE named "vnf1" πŸ¦‹ it's got its own module list, its own OSPF routing setup, and its own little interface, so it's giving independent and iconic πŸ’œ

{
  "ietf-yang-library:modules-state": {
    "module-set-id": "123e4567-e89b-12d3-a456-426655440000",
    "module": [
      {
        "name": "iana-if-type",
        "revision": "2014-05-08",
        "namespace": "urn:ietf:params:xml:ns:yang:iana-if-type",
        "conformance-type": "import"
      },
      {
        "name": "ietf-inet-types",
        "revision": "2013-07-15",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-inet-types",
        "conformance-type": "import"
      },
      {
        "name": "ietf-interfaces",
        "revision": "2014-05-08",
        "feature": [
          "arbitrary-names",
          "pre-provisioning"
        ],
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-interfaces",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-ip",
        "revision": "2014-06-16",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-ip",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-ospf",
        "revision": "2018-03-03",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-ospf",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-routing",
        "revision": "2018-03-13",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-routing",
        "conformance-type": "implement"

      },
      {
        "name": "ietf-system",
        "revision": "2014-08-06",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-system",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-yang-library",
        "revision": "2016-06-21",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-library",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-yang-types",
        "revision": "2013-07-15",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-types",
        "conformance-type": "import"
      }
    ]
  },

  "ietf-system:system-state": {
    "platform": {
      "os-name": "NetworkOS"
    }
  },

  "ietf-routing:routing": {
    "router-id": "192.0.2.1",
    "control-plane-protocols": {
      "control-plane-protocol": [
        {
          "type": "ietf-routing:ospf",
          "name": "1",
          "ietf-ospf:ospf": {
            "af": "ipv4",
            "areas": {
              "area": [
                {
                  "area-id": "203.0.113.1",
                  "interfaces": {
                    "interface": [
                      {
                        "name": "eth1",
                        "cost": 10
                      }
                    ]

                  }
                }
              ]
            }
          }
        }
      ]
    }
  },

  "ietf-interfaces:interfaces": {
    "interface": [
      {
        "name": "eth1",
        "type": "iana-if-type:ethernetCsmacd",
        "oper-status": "up",
        "phys-address": "00:01:02:A1:B1:C1",
        "statistics": {
          "discontinuity-time": "2017-06-26T12:34:56-05:00"
        },
        "ietf-ip:ipv4": {
          "address": [
            {
              "ip": "192.0.2.11",
              "prefix-length": 24
            }
          ]
        }
      }
    ]
  }
}

A.2.2.3. Logical Network Element 'vnf2' 🧚

and last but not least, the state data for the example LNE named "vnf2" 🫢 same vibe as vnf1 but with its own router-id and MAC address, because every LNE deserves its own spotlight ✨

{
  "ietf-yang-library:modules-state": {
    "module-set-id": "123e4567-e89b-12d3-a456-426655440000",
    "module": [
      {
        "name": "iana-if-type",
        "revision": "2014-05-08",
        "namespace": "urn:ietf:params:xml:ns:yang:iana-if-type",
        "conformance-type": "import"
      },
      {
        "name": "ietf-inet-types",
        "revision": "2013-07-15",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-inet-types",
        "conformance-type": "import"
      },
      {
        "name": "ietf-interfaces",
        "revision": "2014-05-08",
        "feature": [
          "arbitrary-names",
          "pre-provisioning"
        ],
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-interfaces",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-ip",
        "revision": "2014-06-16",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-ip",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-ospf",
        "revision": "2018-03-03",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-ospf",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-routing",
        "revision": "2018-03-13",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-routing",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-system",
        "revision": "2014-08-06",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-system",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-yang-library",
        "revision": "2016-06-21",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-library",
        "conformance-type": "implement"
      },
      {
        "name": "ietf-yang-types",
        "revision": "2013-07-15",
        "namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-types",
        "conformance-type": "import"
      }
    ]
  },

  "ietf-system:system-state": {
    "platform": {
      "os-name": "NetworkOS"
    }
  },

  "ietf-routing:routing": {
    "router-id": "192.0.2.2",
    "control-plane-protocols": {
      "control-plane-protocol": [
        {
          "type": "ietf-routing:ospf",
          "name": "1",
          "ietf-ospf:ospf": {
            "af": "ipv4",
            "areas": {
              "area": [
                {
                  "area-id": "203.0.113.1",
                  "interfaces": {
                    "interface": [
                      {
                        "name": "eth1",
                        "cost": 10
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      ]
    }
  },
  "ietf-interfaces:interfaces": {
    "interface": [
      {
        "name": "eth1",
        "type": "iana-if-type:ethernetCsmacd",
        "oper-status": "up",
        "phys-address": "00:01:02:A1:B1:C2",
        "statistics": {
          "discontinuity-time": "2017-06-26T12:34:56-05:00"
        },
        "ietf-ip:ipv4": {
          "address": [
            {
              "ip": "192.0.2.11",
              "prefix-length": 24
            }
          ]
        }
      }
    ]
  }
}

Acknowledgments ✨

Okay bestie, let's give a shoutout to the amazing people who made this happen 🫢 The Routing Area Yang Architecture design team was full of legends: Acee Lindem, Anees Shaikh, Christian Hopps, Dean Bogdanovic, Lou Berger, Qin Wu, Rob Shakir, Stephane Litkowski, and Yan Gang πŸ‘‘ Useful review comments also came from Martin Bjorklund, John Scudder, Dan Romascanu, and Taylor Yu πŸ’œ

This document was motivated by, and derived from, "Network Device YANG Logical Organization" [DEVICE-MODEL] 🌸 So that one gets its flowers too!

And a big thank you to Alvaro Retana for the IESG review 🌈✨


Authors' Addresses πŸ¦‹

Here's where you can find the authors, bestie πŸ’…

Lou Berger LabN Consulting, L.L.C.

Email: lberger@labn.net

Christian Hopps LabN Consulting, L.L.C.

Email: chopps@chopps.org

Acee Lindem Cisco Systems 301 Midenhall Way Cary, NC 27513 United States of America

Email: acee@cisco.com

Dean Bogdanovic Volta Networks

Email: ivandean@gmail.com

Xufeng Liu Volta Networks

Email: xufeng.liu.ietf@gmail.com πŸŽ€

πŸ“¦ where this page comes from