RFC 6241

Network Configuration Protocol (NETCONF)

๐Ÿ“… published June 2011, from ietf

RFC 6241: Network Configuration Protocol (NETCONF) ๐ŸŽ€

Part 1 of 20 ๐Ÿ’–

Okay bestie, this is the one that gave us NETCONF! ๐Ÿฆ‹ It's an Internet Standards Track document from the IETF, published in June 2011, with ISSN 2070-1721. The editors are R. Enns (Juniper Networks), M. Bjorklund (Tail-f Systems), J. Schoenwaelder (Jacobs University) and A. Bierman (Brocade), and they're all marked as Ed. ๐Ÿซถ It obsoletes RFC 4741, and no updates are listed.


Abstract โœจ

NETCONF is the protocol here, and it's giving "manage all your network devices from one place" ๐Ÿ’… It gives you ways to install, change, and delete the configuration on network devices. The config data and the protocol messages are both encoded in XML ๐ŸŒธ The NETCONF operations are done as remote procedure calls (RPCs), and this doc obsoletes RFC 4741. Iconic ๐Ÿ‘‘

Status of This Memo ๐Ÿ“œ

So, the status: this is an Internet Standards Track document ๐Ÿ”ฅ

It's a product of the IETF, which means it reflects 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 5741 ๐Ÿ“

Info on the current status, any errata, and how to send feedback lives at http://www.rfc-editor.org/info/rfc6241 ๐Ÿงš

Copyright (c) 2011 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 (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English. ๐Ÿซถ

Table of Contents โœจ

okay bestie, here's the map of the whole spec ๐Ÿ—บ๏ธ๐Ÿ’– every section, subsection, and appendix is lined up below, so you can see exactly where everything lives ๐Ÿฆ‹

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   6
     1.1.  Terminology . . . . . . . . . . . . . . . . . . . . . . .   7
     1.2.  Protocol Overview . . . . . . . . . . . . . . . . . . . .   8
     1.3.  Capabilities  . . . . . . . . . . . . . . . . . . . . . .  10
     1.4.  Separation of Configuration and State Data  . . . . . . .  10
   2.  Transport Protocol Requirements . . . . . . . . . . . . . . .  11
     2.1.  Connection-Oriented Operation . . . . . . . . . . . . . .  11
     2.2.  Authentication, Integrity, and Confidentiality  . . . . .  12
     2.3.  Mandatory Transport Protocol  . . . . . . . . . . . . . .  12
   3.  XML Considerations  . . . . . . . . . . . . . . . . . . . . .  13
     3.1.  Namespace . . . . . . . . . . . . . . . . . . . . . . . .  13
     3.2.  Document Type Declarations  . . . . . . . . . . . . . . .  13
   4.  RPC Model . . . . . . . . . . . . . . . . . . . . . . . . . .  13
     4.1.  <rpc> Element . . . . . . . . . . . . . . . . . . . . . .  13
     4.2.  <rpc-reply> Element . . . . . . . . . . . . . . . . . . .  15
     4.3.  <rpc-error> Element . . . . . . . . . . . . . . . . . . .  16
     4.4.  <ok> Element  . . . . . . . . . . . . . . . . . . . . . .  19
     4.5.  Pipelining  . . . . . . . . . . . . . . . . . . . . . . .  19
   5.  Configuration Model . . . . . . . . . . . . . . . . . . . . .  19
     5.1.  Configuration Datastores  . . . . . . . . . . . . . . . .  19
     5.2.  Data Modeling . . . . . . . . . . . . . . . . . . . . . .  20
   6.  Subtree Filtering . . . . . . . . . . . . . . . . . . . . . .  20
     6.1.  Overview  . . . . . . . . . . . . . . . . . . . . . . . .  20
     6.2.  Subtree Filter Components . . . . . . . . . . . . . . . .  21
       6.2.1.  Namespace Selection . . . . . . . . . . . . . . . . .  21
       6.2.2.  Attribute Match Expressions . . . . . . . . . . . . .  22
       6.2.3.  Containment Nodes . . . . . . . . . . . . . . . . . .  23
       6.2.4.  Selection Nodes . . . . . . . . . . . . . . . . . . .  23
       6.2.5.  Content Match Nodes . . . . . . . . . . . . . . . . .  24
     6.3.  Subtree Filter Processing . . . . . . . . . . . . . . . .  25
     6.4.  Subtree Filtering Examples  . . . . . . . . . . . . . . .  26
       6.4.1.  No Filter . . . . . . . . . . . . . . . . . . . . . .  26
       6.4.2.  Empty Filter  . . . . . . . . . . . . . . . . . . . .  26
       6.4.3.  Select the Entire <users> Subtree . . . . . . . . . .  27
       6.4.4.  Select All <name> Elements within the <users>
               Subtree . . . . . . . . . . . . . . . . . . . . . . .  29
       6.4.5.  One Specific <user> Entry . . . . . . . . . . . . . .  30
       6.4.6.  Specific Elements from a Specific <user> Entry  . . .  31
       6.4.7.  Multiple Subtrees . . . . . . . . . . . . . . . . . .  32
       6.4.8.  Elements with Attribute Naming  . . . . . . . . . . .  33
   7.  Protocol Operations . . . . . . . . . . . . . . . . . . . . .  35
     7.1.  <get-config>  . . . . . . . . . . . . . . . . . . . . . .  35
     7.2.  <edit-config> . . . . . . . . . . . . . . . . . . . . . .  37
     7.3.  <copy-config> . . . . . . . . . . . . . . . . . . . . . .  43
     7.4.  <delete-config> . . . . . . . . . . . . . . . . . . . . .  44
     7.5.  <lock>  . . . . . . . . . . . . . . . . . . . . . . . . .  44
     7.6.  <unlock>  . . . . . . . . . . . . . . . . . . . . . . . .  47
     7.7.  <get> . . . . . . . . . . . . . . . . . . . . . . . . . .  48
     7.8.  <close-session> . . . . . . . . . . . . . . . . . . . . .  49
     7.9.  <kill-session>  . . . . . . . . . . . . . . . . . . . . .  50
   8.  Capabilities  . . . . . . . . . . . . . . . . . . . . . . . .  51
     8.1.  Capabilities Exchange . . . . . . . . . . . . . . . . . .  51
     8.2.  Writable-Running Capability . . . . . . . . . . . . . . .  53
       8.2.1.  Description . . . . . . . . . . . . . . . . . . . . .  53
       8.2.2.  Dependencies  . . . . . . . . . . . . . . . . . . . .  53
       8.2.3.  Capability Identifier . . . . . . . . . . . . . . . .  53
       8.2.4.  New Operations  . . . . . . . . . . . . . . . . . . .  53
       8.2.5.  Modifications to Existing Operations  . . . . . . . .  53
     8.3.  Candidate Configuration Capability  . . . . . . . . . . .  53
       8.3.1.  Description . . . . . . . . . . . . . . . . . . . . .  53
       8.3.2.  Dependencies  . . . . . . . . . . . . . . . . . . . .  54
       8.3.3.  Capability Identifier . . . . . . . . . . . . . . . .  54
       8.3.4.  New Operations  . . . . . . . . . . . . . . . . . . .  54
       8.3.5.  Modifications to Existing Operations  . . . . . . . .  56
     8.4.  Confirmed Commit Capability . . . . . . . . . . . . . . .  57
       8.4.1.  Description . . . . . . . . . . . . . . . . . . . . .  57
       8.4.2.  Dependencies  . . . . . . . . . . . . . . . . . . . .  58
       8.4.3.  Capability Identifier . . . . . . . . . . . . . . . .  58
       8.4.4.  New Operations  . . . . . . . . . . . . . . . . . . .  59
       8.4.5.  Modifications to Existing Operations  . . . . . . . .  60
     8.5.  Rollback-on-Error Capability  . . . . . . . . . . . . . .  61
       8.5.1.  Description . . . . . . . . . . . . . . . . . . . . .  61
       8.5.2.  Dependencies  . . . . . . . . . . . . . . . . . . . .  62
       8.5.3.  Capability Identifier . . . . . . . . . . . . . . . .  62
       8.5.4.  New Operations  . . . . . . . . . . . . . . . . . . .  62
       8.5.5.  Modifications to Existing Operations  . . . . . . . .  62
     8.6.  Validate Capability . . . . . . . . . . . . . . . . . . .  63
       8.6.1.  Description . . . . . . . . . . . . . . . . . . . . .  63
       8.6.2.  Dependencies  . . . . . . . . . . . . . . . . . . . .  63
       8.6.3.  Capability Identifier . . . . . . . . . . . . . . . .  63
       8.6.4.  New Operations  . . . . . . . . . . . . . . . . . . .  63
       8.6.5.  Modifications to Existing Operations  . . . . . . . .  64
     8.7.  Distinct Startup Capability . . . . . . . . . . . . . . .  64
       8.7.1.  Description . . . . . . . . . . . . . . . . . . . . .  64
       8.7.2.  Dependencies  . . . . . . . . . . . . . . . . . . . .  65
       8.7.3.  Capability Identifier . . . . . . . . . . . . . . . .  65
       8.7.4.  New Operations  . . . . . . . . . . . . . . . . . . .  65
       8.7.5.  Modifications to Existing Operations  . . . . . . . .  65
     8.8.  URL Capability  . . . . . . . . . . . . . . . . . . . . .  66
       8.8.1.  Description . . . . . . . . . . . . . . . . . . . . .  66
       8.8.2.  Dependencies  . . . . . . . . . . . . . . . . . . . .  66
       8.8.3.  Capability Identifier . . . . . . . . . . . . . . . .  66
       8.8.4.  New Operations  . . . . . . . . . . . . . . . . . . .  66
       8.8.5.  Modifications to Existing Operations  . . . . . . . .  66

     8.9.  XPath Capability  . . . . . . . . . . . . . . . . . . . .  67
       8.9.1.  Description . . . . . . . . . . . . . . . . . . . . .  67
       8.9.2.  Dependencies  . . . . . . . . . . . . . . . . . . . .  68
       8.9.3.  Capability Identifier . . . . . . . . . . . . . . . .  68
       8.9.4.  New Operations  . . . . . . . . . . . . . . . . . . .  68
       8.9.5.  Modifications to Existing Operations  . . . . . . . .  68
   9.  Security Considerations . . . . . . . . . . . . . . . . . . .  69
   10. IANA Considerations . . . . . . . . . . . . . . . . . . . . .  71
     10.1. NETCONF XML Namespace . . . . . . . . . . . . . . . . . .  71
     10.2. NETCONF XML Schema  . . . . . . . . . . . . . . . . . . .  71
     10.3. NETCONF YANG Module . . . . . . . . . . . . . . . . . . .  72
     10.4. NETCONF Capability URNs . . . . . . . . . . . . . . . . .  72
   11. Contributors  . . . . . . . . . . . . . . . . . . . . . . . .  73
   12. Acknowledgements  . . . . . . . . . . . . . . . . . . . . . .  73
   13. References  . . . . . . . . . . . . . . . . . . . . . . . . .  74
     13.1. Normative References  . . . . . . . . . . . . . . . . . .  74
     13.2. Informative References  . . . . . . . . . . . . . . . . .  75
   Appendix A.  NETCONF Error List . . . . . . . . . . . . . . . . .  76
   Appendix B.  XML Schema for NETCONF Messages Layer  . . . . . . .  80
   Appendix C.  YANG Module for NETCONF Protocol Operations  . . . .  85
   Appendix D.  Capability Template  . . . . . . . . . . . . . . . . 105
     D.1.  capability-name (template)  . . . . . . . . . . . . . . . 105
       D.1.1.  Overview  . . . . . . . . . . . . . . . . . . . . . . 105
       D.1.2.  Dependencies  . . . . . . . . . . . . . . . . . . . . 105
       D.1.3.  Capability Identifier . . . . . . . . . . . . . . . . 105
       D.1.4.  New Operations  . . . . . . . . . . . . . . . . . . . 105
       D.1.5.  Modifications to Existing Operations  . . . . . . . . 105
       D.1.6.  Interactions with Other Capabilities  . . . . . . . . 105
   Appendix E.  Configuring Multiple Devices with NETCONF  . . . . . 106
     E.1.  Operations on Individual Devices  . . . . . . . . . . . . 106
       E.1.1.  Acquiring the Configuration Lock  . . . . . . . . . . 106
       E.1.2.  Checkpointing the Running Configuration . . . . . . . 107
       E.1.3.  Loading and Validating the Incoming Configuration . . 108
       E.1.4.  Changing the Running Configuration  . . . . . . . . . 108
       E.1.5.  Testing the New Configuration . . . . . . . . . . . . 109
       E.1.6.  Making the Change Permanent . . . . . . . . . . . . . 109
       E.1.7.  Releasing the Configuration Lock  . . . . . . . . . . 110
     E.2.  Operations on Multiple Devices  . . . . . . . . . . . . . 111
   Appendix F.  Changes from RFC 4741  . . . . . . . . . . . . . . . 112

1. Introduction โœจ

Okay, so NETCONF is basically the cool, organized way to manage a network device ๐ŸŽ€. It gives you a simple mechanism to manage a device, grab its configuration data, upload new configuration data, and tweak it. The device exposes a full, formal API, and apps can use that API to send and receive full or partial configuration data sets. Iconic ๐Ÿ’…

NETCONF runs on a remote procedure call (RPC) paradigm ๐Ÿฆ‹. A client encodes an RPC in XML [W3C.REC-xml-20001006] and sends it to a server over a secure, connection-oriented session. The server sends back a reply, also encoded in XML. The contents of both the request and the response are fully described in XML DTDs or XML schemas (or both), so both sides know exactly what syntax rules apply to the exchange. No guesswork, bestie ๐Ÿซถ

Here's the part that's lowkey my favorite โœจ. NETCONF lets the management protocol closely mirror the device's native functionality. That keeps implementation costs down and gets you access to new features quickly. Apps can also reach both the syntactic and the semantic content of the device's native user interface. Main character energy ๐Ÿ‘‘

NETCONF also lets a client discover which protocol extensions a server supports ๐Ÿ”. These "capabilities" let the client adjust its behavior to use the features the device exposes. Capability definitions can be extended easily in a noncentralized way, and standard and non-standard capabilities can both be defined with semantic and syntactic rigor ๐Ÿ’œ. Capabilities get their own deep dive in Section 8, so stay tuned ๐Ÿงš

NETCONF is a building block in a system of automated configuration ๐ŸŒˆ. XML is the lingua franca of interchange, giving you a flexible but fully specified encoding for hierarchical content. NETCONF can team up with XML-based transformation technologies, like XSLT [W3C.REC-xslt-19991116], to automatically generate full and partial configurations. The system can query one or more databases for data about networking topologies, links, policies, customers, and services. That data can then be transformed with one or more XSLT scripts, from a task-oriented, vendor-independent data schema into something specific to the vendor, product, operating system, and software release. Finally, the resulting data gets passed to the device using NETCONF ๐Ÿ“

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119]. ๐Ÿ“–

1.1. Terminology

Let's get our vocab straight ๐Ÿ’…

  • candidate configuration datastore: A configuration datastore that can be manipulated without impacting the device's current configuration, and that can be committed to the running configuration datastore. Not all devices support a candidate configuration datastore.
  • capability: A functionality that supplements the base NETCONF specification.
  • client: Invokes protocol operations on a server. A client can also subscribe to receive notifications from a server.
  • configuration data: The set of writable data that is required to transform a system from its initial default state into its current state.
  • 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.
  • configuration datastore: The datastore holding the complete set of configuration data that is required to get a device from its initial default state into a desired operational state.
  • message: A protocol element sent over a session. Messages are well-formed XML documents.
  • notification: A server-initiated message indicating that a certain event has been recognized by the server.
  • protocol operation: A specific remote procedure call, as used within the NETCONF protocol.
  • remote procedure call (RPC): Realized by exchanging <rpc> and <rpc-reply> messages.
  • running configuration datastore: A configuration datastore holding the complete configuration currently active on the device. The running configuration datastore always exists.
  • server: Executes protocol operations invoked by a client. A server can also send notifications to a client.
  • session: Client and server exchange messages using a secure, connection-oriented session.
  • startup configuration datastore: The configuration datastore holding the configuration loaded by the device when it boots. It is only present on devices that separate the startup configuration datastore from the running configuration datastore.
  • state data: The additional data on a system that is not configuration data, such as read-only status information and collected statistics.
  • user: The authenticated identity of the client. The authenticated identity of a client is commonly referred to as the NETCONF username.

1.2. Protocol Overview

NETCONF uses a simple RPC-based mechanism to make client-server communication work ๐Ÿฆ‹. The client can be a script or application, usually running as part of a network manager. The server is usually a network device. In this document, "device" and "server" mean the same thing, and so do "client" and "application" ๐Ÿซถ

A NETCONF session is the logical connection between a network administrator (or network configuration application) and a network device ๐Ÿ’–. A device MUST support at least one NETCONF session and SHOULD support multiple sessions. Global configuration attributes can be changed during any authorized session, and the effects are visible in all sessions. Session-specific attributes only affect the session in which they were changed. Lowkey iconic design ๐ŸŒธ

NETCONF can be conceptually split into four layers, as shown in Figure 1 โœจ

         Layer                 Example
    +-------------+      +-----------------+      +----------------+
(4) |   Content   |      |  Configuration  |      |  Notification  |
    |             |      |      data       |      |      data      |
    +-------------+      +-----------------+      +----------------+
           |                       |                      |
    +-------------+      +-----------------+              |
(3) | Operations  |      |  <edit-config>  |              |
    |             |      |                 |              |
    +-------------+      +-----------------+              |
           |                       |                      |
    +-------------+      +-----------------+      +----------------+
(2) |  Messages   |      |     <rpc>,      |      | <notification> |
    |             |      |   <rpc-reply>   |      |                |
    +-------------+      +-----------------+      +----------------+
           |                       |                      |
    +-------------+      +-----------------------------------------+
(1) |   Secure    |      |  SSH, TLS, BEEP/TLS, SOAP/HTTP/TLS, ... |
    |  Transport  |      |                                         |
    +-------------+      +-----------------------------------------+

                  Figure 1: NETCONF Protocol Layers

(1) The Secure Transport layer is the communication path between the client and server ๐Ÿ”. NETCONF can be layered over any transport protocol that provides a set of basic requirements. Section 2 talks through those requirements.

(2) The Messages layer gives you a simple, transport-independent framing mechanism for encoding RPCs and notifications ๐Ÿ“ฆ. Section 4 documents the RPC messages, and [RFC5717] documents notifications.

(3) The Operations layer defines a set of base protocol operations, invoked as RPC methods with XML-encoded parameters ๐Ÿงš. Section 7 has the full list of base protocol operations.

(4) The Content layer is outside the scope of this document ๐Ÿ™ˆ. Separate efforts to standardize NETCONF data models are expected to happen.

The YANG data modeling language [RFC6020] was developed for specifying NETCONF data models and protocol operations. It covers the Operations and Content layers of Figure 1 ๐Ÿ’œ

1.3. Capabilities

A NETCONF capability is a set of functionality that supplements the base NETCONF specification ๐ŸŒˆ. Each capability is identified by a uniform resource identifier (URI) [RFC3986].

Capabilities augment the base operations of the device. They describe extra operations and the content allowed inside those operations ๐Ÿ’–. The client can discover the server's capabilities and then use any additional operations, parameters, and content those capabilities define.

A capability definition might name one or more dependent capabilities. To support a capability, the server MUST support any capabilities it depends on ๐Ÿ”—.

Section 8 defines the capabilities exchange, which is how the client discovers the server's capabilities. Section 8 also lists the set of capabilities defined in this document ๐Ÿ“œ

Additional capabilities can be defined at any time in external documents, so the set can keep growing over time ๐ŸŒฑ. Standards bodies can define standardized capabilities, and implementations can define proprietary ones. A capability URI MUST sufficiently distinguish the naming authority to avoid naming collisions ๐ŸŽ€

1.4. Separation of Configuration and State Data

Information you can pull from a running system falls into two classes: configuration data and state data ๐Ÿ“. Configuration data is the set of writable data required to transform a system from its initial default state into its current state. State data is the additional data on a system that isn't configuration data, like read-only status information and collected statistics. When a device is doing configuration operations, a few problems pop up if state data gets included:

  • Comparisons of configuration data sets would be dominated by irrelevant entries, such as different statistics ๐Ÿ™„.
  • Incoming data could contain nonsensical requests, such as attempts to write read-only data ๐Ÿ’€.
  • The data sets would be large ๐Ÿ“ฆ.
  • Archived data could contain values for read-only data items, which complicates the processing needed to restore archived data ๐Ÿ˜ญ.

To deal with these issues, NETCONF recognizes the difference between configuration data and state data, and it provides operations for each. The <get-config> operation retrieves configuration data only, while the <get> operation retrieves both configuration and state data โœจ

NETCONF focuses on the information needed to get the device into its desired running state ๐ŸŽฏ. Including other important, persistent data is implementation specific. For example, user files and databases are not treated as configuration data by NETCONF.

For example, if a local database of user authentication data is stored on the device, it's an implementation-dependent matter whether it gets included in configuration data ๐Ÿงš

2. Transport Protocol Requirements ๐Ÿš€

okay so NETCONF runs on an RPC-based vibe ๐Ÿ’…. A client sends a series of one or more RPC request messages, and the server answers with a matching series of RPC reply messages.

NETCONF can be layered on any transport protocol that gives it the functionality it needs ๐Ÿฆ‹. It's not married to one specific transport. Instead, there's a mapping that explains how it gets implemented over a given protocol.

The transport protocol MUST provide a mechanism to indicate the session type (client or server) to the NETCONF protocol layer ๐ŸŽ€.

This section breaks down exactly what NETCONF needs from the transport underneath it ๐Ÿงš.

2.1. Connection-Oriented Operation

NETCONF is connection-oriented, so it needs a persistent connection between peers ๐Ÿ”—. This connection MUST provide reliable, sequenced data delivery. NETCONF connections are long-lived, sticking around between protocol operations โœจ.

Resources requested from the server for a particular connection MUST be automatically released when that connection closes, which makes failure recovery simpler and more robust ๐Ÿซถ. Like, say a client grabs a lock. That lock stays put until the client explicitly releases it or the server determines the connection has been terminated. If the connection drops while the client is holding a lock, the server can perform any appropriate recovery ๐Ÿ˜ญ. The <lock> operation is talked about more in Section 7.5 ๐Ÿ’œ.

2.2. Authentication, Integrity, and Confidentiality

NETCONF connections MUST provide authentication, data integrity, confidentiality, and replay protection. NETCONF depends on the transport protocol for this capability ๐Ÿ”. A NETCONF peer assumes that appropriate levels of security and confidentiality are provided independently of this document. For example, connections could be encrypted using Transport Layer Security (TLS) [RFC5246] or Secure Shell (SSH) [RFC4251], depending on the underlying protocol.

NETCONF connections MUST be authenticated. The transport protocol is responsible for authenticating the server to the client and the client to the server ๐Ÿ™ˆ. A NETCONF peer assumes that the connection's authentication information has been validated by the underlying transport protocol using sufficiently trustworthy mechanisms, and that the peer's identity has been sufficiently proven.

One goal of NETCONF is to give you a programmatic interface to the device that closely follows what the device's native interface can do ๐Ÿ“. So it's expected that the underlying protocol uses the existing authentication mechanisms already on the device. For example, a NETCONF server on a device that supports RADIUS [RFC2865] might let you use RADIUS to authenticate NETCONF sessions. Iconic, right? ๐Ÿ‘‘

The authentication process MUST result in an authenticated client identity whose permissions are known to the server. This authenticated identity is commonly called the NETCONF username ๐Ÿงพ. The username is a string of characters that match the "Char" production from Section 2.2 of [W3C.REC-xml-20001006]. The algorithm used to derive the username is specific to the transport protocol, and also specific to the authentication mechanism that the transport protocol uses. The transport protocol MUST provide a username to be used by the other NETCONF layers.

The access permissions of a given client, identified by its NETCONF username, are part of the configuration of the NETCONF server. These permissions MUST be enforced during the remainder of the NETCONF session ๐Ÿ”’. How access control gets configured is outside the scope of this document, so that's a different story ๐Ÿ’….

2.3. Mandatory Transport Protocol

A NETCONF implementation MUST support the SSH transport protocol mapping [RFC6242]. Non-negotiable, bestie ๐Ÿซถ.

3. XML Considerations ๐ŸŒธ

XML is the encoding format for NETCONF ๐Ÿ’–. It lets complex hierarchical data show up in a text format you can read, save, and manipulate with regular text tools and XML-specific tools alike.

All NETCONF messages MUST be well-formed XML, encoded in UTF-8 [RFC3629]. If a peer receives an <rpc> message that is not well-formed XML or is not encoded in UTF-8, it SHOULD reply with a "malformed-message" error. If a reply cannot be sent for any reason, the server MUST terminate the session ๐Ÿšซ. A NETCONF message MAY begin with an XML declaration (see Section 2.8 of [W3C.REC-xml-20001006]) โœจ.

This section covers a small number of XML-related considerations for NETCONF ๐Ÿงš.

3.1. Namespace

All NETCONF protocol elements are defined in the following namespace ๐ŸŽ€:

   urn:ietf:params:xml:ns:netconf:base:1.0

NETCONF capability names MUST be URIs [RFC3986]. NETCONF capabilities are discussed in Section 8 ๐Ÿฆ‹.

3.2. Document Type Declarations

Document type declarations (see Section 2.8 of [W3C.REC-xml-20001006]) MUST NOT appear in NETCONF content. No DOCTYPE drama allowed ๐Ÿ™…โ€โ™€๏ธ๐Ÿ’€.

4. RPC Model ๐Ÿง

The NETCONF protocol uses an RPC-based communication model. NETCONF peers use <rpc> and <rpc-reply> elements to provide transport-protocol-independent framing of NETCONF requests and responses ๐Ÿ’œ.

The syntax and XML encoding of the Messages-layer RPCs are formally defined in the XML schema in Appendix B ๐Ÿ“œ.

4.1. <rpc> Element

The <rpc> element is used to enclose a NETCONF request sent from the client to the server ๐Ÿ“ฎ.

The <rpc> element has a mandatory attribute "message-id", which is a string chosen by the sender of the RPC that will commonly encode a monotonically increasing integer. The receiver doesn't decode or interpret this string. It just saves it to use as a "message-id" attribute in any resulting <rpc-reply> message ๐Ÿง . The sender MUST ensure that the "message-id" value is normalized according to the XML attribute value normalization rules defined in [W3C.REC-xml-20001006] if the sender wants the string returned unmodified. For example:

    <rpc message-id="101"
         xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
      <some-method>
        <!-- method parameters here... -->
      </some-method>
    </rpc>

If additional attributes are present in an <rpc> element, a NETCONF peer MUST return them unmodified in the <rpc-reply> element. This includes any "xmlns" attributes ๐Ÿซถ.

The name and parameters of an RPC are encoded as the contents of the <rpc> element. The name of the RPC is an element directly inside the <rpc> element, and any parameters are encoded inside that element ๐Ÿ’….

The following example invokes a method called <my-own-method>, which has two parameters, <my-first-parameter>, with a value of "14", and <another-parameter>, with a value of "fred" ๐ŸŒˆ:

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <my-own-method xmlns="http://example.net/me/my-own/1.0">
      <my-first-parameter>14</my-first-parameter>
      <another-parameter>fred</another-parameter>
    </my-own-method>
  </rpc>

The following example invokes a <rock-the-house> method with a <zip-code> parameter of "27606-0100" ๐Ÿ”ฅ:

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <rock-the-house xmlns="http://example.net/rock/1.0">
      <zip-code>27606-0100</zip-code>
    </rock-the-house>
  </rpc>

The following example invokes the NETCONF <get> method with no parameters ๐Ÿงš:

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <get/>
  </rpc>

4.2. <rpc-reply> Element

The <rpc-reply> message is sent in response to an <rpc> message ๐Ÿ’Œ.

The <rpc-reply> element has a mandatory attribute "message-id", which is equal to the "message-id" attribute of the <rpc> it's responding to ๐ŸŽฏ.

A NETCONF server MUST also return any additional attributes included in the <rpc> element unmodified in the <rpc-reply> element ๐Ÿซถ.

The response data is encoded as one or more child elements of the <rpc-reply> element ๐Ÿ’.

For example:

The following <rpc> element invokes the NETCONF <get> method and includes an additional attribute called "user-id". Note that the "user-id" attribute is not in the NETCONF namespace. The returned <rpc-reply> element returns the "user-id" attribute, as well as the requested content ๐Ÿ™ˆ:

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
       xmlns:ex="http://example.net/content/1.0"
       ex:user-id="fred">
    <get/>
  </rpc>

  <rpc-reply message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
       xmlns:ex="http://example.net/content/1.0"
       ex:user-id="fred">
    <data>
      <!-- contents here... -->
    </data>
  </rpc-reply>

4.3. <rpc-error> Element โœจ

okay so the <rpc-error> element is what gets sent back inside an <rpc-reply> when something goes wrong while the server is handling an <rpc> request ๐Ÿ™ˆ

If the server runs into multiple errors while processing one <rpc> request, the <rpc-reply> MAY contain multiple <rpc-error> elements. ngl though, a server is not required to detect or report more than one <rpc-error> element if a request contains multiple errors ๐Ÿ’€ It also doesn't have to check for particular error conditions in any specific sequence. But this part is the big one: a server MUST return an <rpc-error> element if any error conditions occur during processing ๐Ÿ˜ค

A server MUST NOT return application-level- or data-model-specific error information in an <rpc-error> element for which the client does not have sufficient access rights ๐Ÿ”’ privacy is so important, bestie.

The <rpc-error> element includes the following information:

  • error-type: defines the conceptual layer where the error occurred. It's an enumeration with one of these values:
    • transport (layer: Secure Transport)
    • rpc (layer: Messages)
    • protocol (layer: Operations)
    • application (layer: Content)
  • error-tag: contains a string identifying the error condition. See Appendix A for the allowed values ๐ŸŽ€
  • error-severity: contains a string identifying the error severity, as determined by the device. One of:
    • error
    • warning

Note that there are no <error-tag> values defined in this document that use the "warning" enumeration. That one is reserved for future use ๐ŸŒธ

  • error-app-tag: contains a string identifying the data-model-specific or implementation-specific error condition, if one exists. This element will not be present if no appropriate application error-tag can be associated with a particular error condition. If a data-model-specific and an implementation-specific error-app-tag both exist, then the data-model-specific value MUST be used by the server. so the data-model one wins, always ๐Ÿ‘‘
  • error-path: contains the absolute XPath [W3C.REC-xpath-19991116] expression identifying the element path to the node that is associated with the error being reported in a particular <rpc-error> element. This element will not be present if no appropriate payload element or datastore node can be associated with a particular error condition.

The XPath expression is interpreted in the following context:

  • The set of namespace declarations are those in scope on the <rpc-error> element.
  • The set of variable bindings is empty.
  • The function library is the core function library.

The context node depends on the node associated with the error being reported:

  • If a payload element can be associated with the error, the context node is the rpc request's document node (i.e., the <rpc> element).
  • Otherwise, the context node is the root of all data models, i.e., the node that has the top-level nodes from all data models as children.
  • error-message: contains a string suitable for human display that describes the error condition. This element will not be present if no appropriate message is provided for a particular error condition. This element SHOULD include an "xml:lang" attribute as defined in [W3C.REC-xml-20001006] and discussed in [RFC3470]. translations are a whole vibe ๐ŸŒ
  • error-info: contains protocol- or data-model-specific error content. This element will not be present if no such error content is provided for a particular error condition. The list in Appendix A defines any mandatory error-info content for each error. After any protocol-mandated content, a data model definition MAY mandate that certain application-layer error information be included in the error-info container. An implementation MAY include additional elements to provide extended and/or implementation-specific debugging information ๐Ÿงš

Appendix A enumerates the standard NETCONF errors. go check it out, it's giving reference material ๐Ÿ“š

Example: an error is returned if an <rpc> element is received without a "message-id" attribute. Note that only in this case is it acceptable for the NETCONF peer to omit the "message-id" attribute in the <rpc-reply> element. so specific, I'm obsessed ๐Ÿ˜ญ

<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get-config>
    <source>
      <running/>
    </source>
  </get-config>
</rpc>

<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <rpc-error>
    <error-type>rpc</error-type>
    <error-tag>missing-attribute</error-tag>
    <error-severity>error</error-severity>
    <error-info>
      <bad-attribute>message-id</bad-attribute>
      <bad-element>rpc</bad-element>
    </error-info>
  </rpc-error>
</rpc-reply>

The following <rpc-reply> shows what it looks like when the server returns multiple <rpc-error> elements. This one is a big moment ๐Ÿฆ‹

Note that the data models used in the examples in this section use the <name> element to tell apart multiple instances of the <interface> element ๐Ÿง

<rpc-reply message-id="101"
  xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
  xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
  <rpc-error>
    <error-type>application</error-type>
    <error-tag>invalid-value</error-tag>
    <error-severity>error</error-severity>
    <error-path xmlns:t="http://example.com/schema/1.2/config">
      /t:top/t:interface[t:name="Ethernet0/0"]/t:mtu
    </error-path>
    <error-message xml:lang="en">
      MTU value 25000 is not within range 256..9192
    </error-message>
  </rpc-error>
  <rpc-error>
    <error-type>application</error-type>
    <error-tag>invalid-value</error-tag>
    <error-severity>error</error-severity>
    <error-path xmlns:t="http://example.com/schema/1.2/config">
      /t:top/t:interface[t:name="Ethernet1/0"]/t:address/t:name
    </error-path>
    <error-message xml:lang="en">
      Invalid IP address for interface Ethernet1/0
    </error-message>
  </rpc-error>
</rpc-reply>

4.4. <ok> Element ๐Ÿซถ

The <ok> element is sent in <rpc-reply> messages when no errors or warnings occurred during processing of an <rpc> request and no data was returned from the operation. it's the "all good, no notes" response ๐Ÿ’– For example:

<rpc-reply message-id="101"
           xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

4.5. Pipelining ๐Ÿš€

NETCONF <rpc> requests MUST be processed serially by the managed device. Additional <rpc> requests MAY be sent before previous ones have been completed. The managed device MUST send responses only in the order the requests were received. so the queue is strict but you can totally stack requests ๐Ÿฅž

5. Configuration Model ๐ŸŽ€

NETCONF gives you an initial set of operations plus a bunch of capabilities that can be used to extend that base. NETCONF peers exchange device capabilities when the session is initiated, as described in Section 8.1 โœจ

5.1. Configuration Datastores ๐Ÿ—‚๏ธ

NETCONF defines the existence of one or more configuration datastores and allows configuration operations on them. A configuration datastore is defined as the complete set of configuration data that is required to get a device from its initial default state into a desired operational state. The configuration datastore does not include state data or executive commands, so no sneaking those in ๐Ÿ™…โ€โ™€๏ธ

The running configuration datastore holds the complete configuration currently active on the network device. Only one configuration datastore of this type exists on the device, and it is always present. NETCONF protocol operations refer to this datastore using the <running> element ๐ŸŒˆ

Only the <running> configuration datastore is present in the base model. Additional configuration datastores MAY be defined by capabilities. Such configuration datastores are available only on devices that advertise the capabilities ๐Ÿงš

The capabilities in Sections 8.3 and 8.7 define the <candidate> and <startup> configuration datastores, respectively ๐Ÿ’œ

5.2. Data Modeling ๐Ÿ“

Data modeling and content issues are outside the scope of the NETCONF protocol. The assumption is that the device's data model is well-known to the application and that both parties are aware of issues such as the layout, containment, keying, lookup, replacement, and management of the data, as well as any other constraints imposed by the data model. it's giving "we all agreed on the schema beforehand" energy ๐Ÿค

NETCONF carries configuration data inside the <config> element that is specific to the device's data model. The protocol treats the contents of that element as opaque data. The device uses capabilities to announce the set of data models that the device implements. The capability definition details the operation and constraints imposed by the data model ๐Ÿ”

Devices and managers can support multiple data models, including both standard and proprietary data models ๐ŸŒธ

6. Subtree Filtering ๐Ÿฆ‹

6.1. Overview ๐ŸŒท

XML subtree filtering is a mechanism that lets an application select particular XML subtrees to include in the <rpc-reply> for a <get> or <get-config> operation. A small set of filters for inclusion, simple content exact-match, and selection is provided. That makes for some useful but also very limited selection mechanisms, honestly kinda iconic in its simplicity ๐Ÿ’… The server does not need to use any data-model-specific semantics during processing, which allows for simple and centralized implementation strategies.

Conceptually, a subtree filter is made up of zero or more element subtrees, which represent the filter selection criteria. At each containment level within a subtree, the set of sibling nodes is logically processed by the server to determine whether its subtree and the path of elements to the root are included in the filter output ๐Ÿงฉ

Each node specified in a subtree filter represents an inclusive filter. Only associated nodes in the underlying data model(s) within the specified datastore on the server are selected by the filter. A node is selected if it matches the selection criteria and hierarchy of elements given in the filter data, except that the filter absolute path name is adjusted to start from the layer below <filter> โœจ

Response messages contain only the subtrees selected by the filter. Any selection criteria that were present in the request, within a particular selected subtree, are also included in the response. Note that some elements expressed in the filter as leaf nodes will be expanded (i.e., subtrees included) in the filter output ๐ŸŒฟ Specific data instances are not duplicated in the response in the event that the request contains multiple filter subtree expressions that select the same data. no double-dipping, bestie ๐Ÿ™…โ€โ™€๏ธ

6.2. Subtree Filter Components ๐Ÿง

A subtree filter is made up of XML elements and their XML attributes. There are five types of components that can be present in a subtree filter:

  • Namespace Selection
  • Attribute Match Expressions
  • Containment Nodes
  • Selection Nodes
  • Content Match Nodes

6.2.1. Namespace Selection โœจ

okay so a namespace counts as a match (for filter purposes) when the XML namespace on a node inside the <filter> element is the same as the one in the underlying data model ๐Ÿ’… that's the whole vibe. BUT namespace selection can't work alone ๐Ÿ™ˆ at least one element MUST be specified in the filter if you want any elements to show up in the filter output.

there's also a wildcard thing for subtree filtering ๐Ÿฆ‹ if an element inside the <filter> element isn't qualified by a namespace (like xmlns=""), the server MUST evaluate all the XML namespaces it supports when it processes that subtree filter node. this wildcard isn't applicable to XML attributes, so don't try it there ๐Ÿ˜ญ

and prefix values for qualified namespaces don't matter when you're comparing filter elements to the underlying data model ๐ŸŒธ

Example:

  <filter type="subtree">
    <top xmlns="http://example.com/schema/1.2/config"/>
  </filter>

in this example, the <top> element is a selection node ๐ŸŽ€ and only this node (in the "http://example.com/schema/1.2/config" namespace) plus any child nodes from the underlying data model get included in the filter output โœจ

6.2.2. Attribute Match Expressions

an attribute inside a subtree filter is part of an "attribute match expression" ๐Ÿ’œ any number of XML attributes (qualified or unqualified) MAY be present in any type of filter node. on top of the usual selection criteria for that node, the selected data MUST have matching values for every attribute specified in the node. and if an element isn't defined to include a specified attribute, it just doesn't get selected in the filter output ๐Ÿ™ˆ

Example:

  <filter type="subtree">
    <t:top xmlns:t="http://example.com/schema/1.2/config">
      <t:interfaces>
        <t:interface t:ifName="eth0"/>
      </t:interfaces>
    </t:top>
  </filter>

so here <top> and <interfaces> are containment nodes ๐Ÿงš <interface> is a selection node, and "ifName" is the attribute match expression ๐Ÿ”ฅ only "interface" nodes in the "http://example.com/schema/1.2/config" namespace that have an "ifName" attribute set to "eth0" and sit inside "interfaces" nodes within "top" nodes make it into the filter output. main character energy ๐Ÿ‘‘

6.2.3. Containment Nodes

nodes that hold child elements inside a subtree filter are called "containment nodes" ๐Ÿ“ each child can be any type of node, including another containment node. for every containment node in a subtree filter, all the data model instances that exactly match the specified namespaces, element hierarchy, and attribute match expressions get included in the filter output โœจ

Example:

  <filter type="subtree">
    <top xmlns="http://example.com/schema/1.2/config">
      <users/>
    </top>
  </filter>

in this example, <top> is a containment node ๐Ÿ’–

6.2.4. Selection Nodes

an empty leaf node inside a filter is called a "selection node" ๐ŸŽฏ it stands for an "explicit selection" filter on the underlying data model. if there are any selection nodes among a set of sibling nodes, the filter selects the specified subtree(s) and stops automatically selecting the whole set of sibling nodes in the underlying data model. honestly iconic ๐Ÿ‘‘

an empty leaf node can be written with an empty tag (like <foo/>) or with explicit start and end tags (like <foo> </foo>) ๐ŸŒˆ any whitespace characters are ignored in that second form, so don't stress about it ๐Ÿซถ

Example:

  <filter type="subtree">
    <top xmlns="http://example.com/schema/1.2/config">
      <users/>
    </top>
  </filter>

so <top> is a containment node and <users> is a selection node ๐ŸŽ€ only "users" nodes in the "http://example.com/schema/1.2/config" namespace that show up inside a <top> element which is the root of the configuration datastore get included in the filter output ๐Ÿงš

6.2.5. Content Match Nodes

a leaf node that holds simple content is called a "content match node" ๐Ÿ’… it's used to select some or all of its sibling nodes for filter output, and it's an exact-match filter on the leaf node's element content. here are the rules, bestie:

  • A content match node MUST NOT contain nested elements.
  • Multiple content match nodes (that is, sibling nodes) are logically combined in an "AND" expression.
  • Filtering of mixed content is not supported.
  • Filtering of list content is not supported.
  • Filtering of whitespace-only content is not supported.
  • A content match node MUST contain non-whitespace characters. An empty element (like <foo></foo>) will be interpreted as a selection node (like <foo/>) ๐Ÿ™ˆ
  • Leading and trailing whitespace characters are ignored, but any whitespace characters within a block of text are not ignored or modified.

if every sibling content match node in a subtree filter expression comes back "true", then the filter output nodes get selected like this:

  • Each content match node in the sibling set is included in the filter output.
  • If there are any containment nodes in the sibling set, they get processed further and included if any nested filter criteria are also met.
  • If there are any selection nodes in the sibling set, all of them are included in the filter output.
  • If any sibling nodes of a selection node are instance identifier components for a conceptual data structure (like a list key leaf), they MAY also be included in the filter output.
  • Otherwise (that is, there are no selection or containment nodes in the filter sibling set), all the nodes defined at this level in the underlying data model (and their subtrees, if any) are returned in the filter output โœจ

and if any of the sibling content match node tests are "false", no further filter processing happens on that sibling set ๐Ÿ˜ญ none of the sibling subtrees get selected by the filter, including the content match node(s).

Example:

  <filter type="subtree">
    <top xmlns="http://example.com/schema/1.2/config">
      <users>
        <user>
          <name>fred</name>
        </user>
      </users>
    </top>
  </filter>

in this example, <users> and <user> are both containment nodes, and <name> is a content match node ๐ŸŒธ since no sibling nodes of <name> are specified (so there are no containment or selection nodes), all of <name>'s sibling nodes get returned in the filter output. only "user" nodes in the "http://example.com/schema/1.2/config" namespace that match the element hierarchy, and where the <name> element equals "fred", end up in the filter output ๐Ÿ’–

6.3. Subtree Filter Processing

the filter output (the set of selected nodes) starts out empty ๐Ÿซง

each subtree filter can contain one or more data model fragments ๐Ÿงฉ these represent the parts of the data model that will be selected (with all their child nodes) in the filter output.

the server compares each subtree data fragment to the internal data models it supports. if the entire subtree data-fragment filter (from the root down to the innermost element specified in the filter) exactly matches a matching portion of the supported data model, then that node and all its children get included in the result data ๐ŸŽ€

the server processes all nodes with the same parent node (a sibling set) together, starting at the root and working down to the leaf nodes ๐ŸŒณ the root elements in the filter count as being in the same sibling set (as long as they're in the same namespace), even though they don't share a common parent ๐Ÿ’…

for each sibling set, the server works out which nodes are included (or potentially included) in the filter output, and which sibling subtrees get excluded (pruned) ๐Ÿช“ it first figures out which types of nodes are present in the sibling set, then processes the nodes according to the rules for their type. if any nodes in the sibling set are selected, the same process gets applied recursively to the sibling sets of each selected node. the algorithm keeps going until all sibling sets in all subtrees specified in the filter have been processed ๐Ÿ” slay.

6.4. Subtree Filtering Examples

6.4.1. No Filter

leaving out the filter on the <get> operation returns the entire data model ๐ŸŒˆ

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <get/>
  </rpc>

  <rpc-reply message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <data>
      <!-- ... entire set of data returned ... -->
    </data>
  </rpc-reply>

6.4.2. Empty Filter

an empty filter selects nothing, because no content match or selection nodes are present ๐Ÿ™ˆ and that is NOT an error, just a quiet little nothing ๐Ÿซง the <filter> element's "type" attribute used in these examples gets talked about more in Section 7.1 ๐Ÿ’œ

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <get>
      <filter type="subtree">
      </filter>
    </get>
  </rpc>
  <rpc-reply message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <data>
    </data>
  </rpc-reply>

6.4.3. Select the Entire <users> Subtree โœจ

Okay bestie, this filter only has one selection node (<users>), so the whole <users> subtree gets selected and that's the entire vibe ๐Ÿ’… This example is basically the fully loaded <users> data model that shows up in most of the filter examples coming next ๐Ÿซถ Real talk though: in an actual data model, <company-info> probably wouldn't come back with the list of users for a particular host or network ๐Ÿ™ˆ

๐Ÿ“ Quick note, bestie: all the filtering and configuration examples in this document live in the namespace "http://example.com/schema/1.2/config". The root element of that namespace is <top>, and the <top> element and everything under it is just an example configuration data model, nothing more ๐ŸŒธ
<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get-config>
    <source>
      <running/>
    </source>
    <filter type="subtree">
      <top xmlns="http://example.com/schema/1.2/config">
        <users/>
      </top>
    </filter>
  </get-config>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <data>
    <top xmlns="http://example.com/schema/1.2/config">
      <users>
        <user>
          <name>root</name>
          <type>superuser</type>
          <full-name>Charlie Root</full-name>
          <company-info>
            <dept>1</dept>
            <id>1</id>
          </company-info>
        </user>
        <user>
          <name>fred</name>
          <type>admin</type>
          <full-name>Fred Flintstone</full-name>
          <company-info>
            <dept>2</dept>
            <id>2</id>
          </company-info>
        </user>
        <user>
          <name>barney</name>
          <type>admin</type>
          <full-name>Barney Rubble</full-name>
          <company-info>
            <dept>2</dept>
            <id>3</id>
          </company-info>
        </user>
      </users>
    </top>
  </data>
</rpc-reply>

This next filter request would give the exact same result ๐Ÿงš but only because the container <users> defines one child element (<user>), so it's not a fluke, it's just how the data is shaped.

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get-config>
    <source>
      <running/>
    </source>
    <filter type="subtree">
      <top xmlns="http://example.com/schema/1.2/config">
        <users>
          <user/>
        </users>
      </top>
    </filter>
  </get-config>
</rpc>

6.4.4. Select All <name> Elements within the <users> Subtree ๐Ÿ’–

This filter has two containment nodes (<users>, <user>) and one selection node (<name>). Every instance of <name> in the same sibling set gets selected in the output ๐ŸŽ€ The client might need to know that <name> works as an instance identifier in this particular data structure, but the server doesn't need that meta-data to process the request. The server just does its thing, no cap ๐Ÿ’…

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get-config>
    <source>
      <running/>
    </source>
    <filter type="subtree">
      <top xmlns="http://example.com/schema/1.2/config">
        <users>
          <user>
            <name/>
          </user>
        </users>
      </top>
    </filter>
  </get-config>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <data>
    <top xmlns="http://example.com/schema/1.2/config">
      <users>
        <user>
          <name>root</name>
        </user>
        <user>
          <name>fred</name>
        </user>
        <user>
          <name>barney</name>
        </user>
      </users>
    </top>
  </data>
</rpc-reply>

6.4.5. One Specific <user> Entry ๐Ÿฆ‹

This filter has two containment nodes (<users>, <user>) and one content match node (<name>). Every instance of the sibling set containing <name> where the value of <name> equals "fred" gets selected in the output. Main character energy for Fred, literally ๐Ÿ‘‘

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get-config>
    <source>
      <running/>
    </source>
    <filter type="subtree">
      <top xmlns="http://example.com/schema/1.2/config">
        <users>
          <user>
            <name>fred</name>
          </user>
        </users>
      </top>
    </filter>
  </get-config>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <data>
    <top xmlns="http://example.com/schema/1.2/config">
      <users>
        <user>
          <name>fred</name>
          <type>admin</type>
          <full-name>Fred Flintstone</full-name>
          <company-info>
            <dept>2</dept>
            <id>2</id>
          </company-info>
        </user>
      </users>
    </top>
  </data>
</rpc-reply>

6.4.6. Specific Elements from a Specific <user> Entry ๐ŸŒธ

This filter has two containment nodes (<users>, <user>), one content match node (<name>), and two selection nodes (<type>, <full-name>). Every instance of <type> and <full-name> in the same sibling set containing <name> where the value of <name> equals "fred" gets selected in the output. Now the detail that matters: <company-info> is not included, because that sibling set has selection nodes in it, so only what you asked for comes back ๐Ÿ’…

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get-config>
    <source>
      <running/>
    </source>
    <filter type="subtree">
      <top xmlns="http://example.com/schema/1.2/config">
        <users>
          <user>
            <name>fred</name>
            <type/>
            <full-name/>
          </user>
        </users>
      </top>
    </filter>
  </get-config>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <data>
    <top xmlns="http://example.com/schema/1.2/config">
      <users>
        <user>
          <name>fred</name>
          <type>admin</type>
          <full-name>Fred Flintstone</full-name>
        </user>
      </users>
    </top>
  </data>
</rpc-reply>

6.4.7. Multiple Subtrees ๐ŸŒˆ

This filter has three subtrees (name=root, fred, barney), and each one gets judged on its own ๐Ÿ‘‘

The "root" subtree filter has two containment nodes (<users>, <user>), one content match node (<name>), and one selection node (<company-info>). The subtree selection criteria are met, so just the company-info subtree for "root" shows up in the output ๐ŸŽ€

The "fred" subtree filter has three containment nodes (<users>, <user>, <company-info>), one content match node (<name>), and one selection node (<id>). The subtree selection criteria are met, so just the <id> element inside the company-info subtree for "fred" gets selected ๐Ÿซถ

The "barney" subtree filter has three containment nodes (<users>, <user>, <company-info>), two content match nodes (<name>, <type>), and one selection node (<dept>). The subtree selection criteria are not met, because user "barney" isn't a "superuser", so the entire subtree for "barney" (including its parent <user> entry) gets left out of the output ๐Ÿ’€

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get-config>
    <source>
      <running/>
    </source>
    <filter type="subtree">
      <top xmlns="http://example.com/schema/1.2/config">
        <users>
          <user>
            <name>root</name>
            <company-info/>
          </user>
          <user>
            <name>fred</name>
            <company-info>
              <id/>
            </company-info>
          </user>
          <user>
            <name>barney</name>
            <type>superuser</type>
            <company-info>
              <dept/>
            </company-info>
          </user>

        </users>
      </top>
    </filter>
  </get-config>
</rpc>

<rpc-reply message-id="101"
           xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <data>
    <top xmlns="http://example.com/schema/1.2/config">
      <users>
        <user>
          <name>root</name>
          <company-info>
            <dept>1</dept>
            <id>1</id>
          </company-info>
        </user>
        <user>
          <name>fred</name>
          <company-info>
            <id>2</id>
          </company-info>
        </user>
      </users>
    </top>
  </data>
</rpc-reply>

6.4.8. Elements with Attribute Naming ๐Ÿฆ‹

In this example, the filter has one containment node (<interfaces>), one attribute match expression ("ifName"), and one selection node (<interface>). Every instance of the <interface> subtree with an "ifName" attribute equal to "eth0" gets selected in the output โœจ The filter data elements and attributes are qualified here, because the "ifName" attribute won't be considered part of the "schema/1.2" namespace if it's unqualified. So the prefixes matter, iykyk ๐Ÿ’…

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get>
    <filter type="subtree">
      <t:top xmlns:t="http://example.com/schema/1.2/stats">
        <t:interfaces>
          <t:interface t:ifName="eth0"/>
        </t:interfaces>
      </t:top>
    </filter>
  </get>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <data>
    <t:top xmlns:t="http://example.com/schema/1.2/stats">
      <t:interfaces>
        <t:interface t:ifName="eth0">
          <t:ifInOctets>45621</t:ifInOctets>
          <t:ifOutOctets>774344</t:ifOutOctets>
        </t:interface>
      </t:interfaces>
    </t:top>
  </data>
</rpc-reply>

Now plot twist ๐Ÿ™ˆ If "ifName" were a child node instead of an attribute, then the following request would produce similar results.

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get>
    <filter type="subtree">
      <top xmlns="http://example.com/schema/1.2/stats">
        <interfaces>
          <interface>
            <ifName>eth0</ifName>
          </interface>
        </interfaces>
      </top>
    </filter>
  </get>
</rpc>

7. Protocol Operations โœจ

NETCONF gives you a small, cute set of low-level operations ๐ŸŽ€ to manage device configs and grab device state info. The base protocol covers retrieving, configuring, copying, and deleting configuration datastores. Extra ops show up depending on what the device advertises in its capabilities ๐Ÿ’…

The base protocol includes these protocol operations:

  • get
  • get-config
  • edit-config
  • copy-config
  • delete-config
  • lock
  • unlock
  • close-session
  • kill-session

okay, real talk: any protocol operation can fail, and "operation not supported" is one of the ways it can happen ๐Ÿ™ˆ So an initiator SHOULD NOT assume an operation will always succeed. And you SHOULD check the return values in any RPC reply for error responses. Don't skip this part, bestie ๐Ÿ˜ญ

The syntax and XML encoding of these operations are formally defined in the YANG module in Appendix C. The sections below describe what each operation actually does ๐Ÿฆ‹


7.1. <get-config> ๐ŸŒธ

Description: Retrieve all or part of a specified configuration datastore.

Parameters:

  • source: The name of the configuration datastore being queried, such as <running/>.
  • filter: This parameter picks out the portions of the device configuration datastore you want back. If it isn't present, the entire configuration is returned ๐Ÿ’–

The <filter> element MAY optionally contain a "type" attribute. That attribute tells you what filtering syntax is used inside the <filter> element. The default filtering mechanism in NETCONF is subtree filtering, which is described in Section 6, and the value "subtree" explicitly identifies it ๐Ÿงš

If the NETCONF peer supports the :xpath capability (Section 8.9), the value "xpath" MAY be used to say that the "select" attribute on the <filter> element holds an XPath expression. Slay ๐Ÿ‘‘

Positive Response: If the device can satisfy the request, the server sends back an <rpc-reply> element containing a <data> element with the query results โœจ

Negative Response: An <rpc-error> element is included in the <rpc-reply> if the request can't be completed for any reason ๐Ÿ’€

Example: To retrieve the entire <users> subtree:

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get-config>
    <source>
      <running/>
    </source>
    <filter type="subtree">
      <top xmlns="http://example.com/schema/1.2/config">
        <users/>
      </top>
    </filter>
  </get-config>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <data>
    <top xmlns="http://example.com/schema/1.2/config">
      <users>
        <user>
          <name>root</name>
          <type>superuser</type>
          <full-name>Charlie Root</full-name>
          <company-info>
            <dept>1</dept>
            <id>1</id>
          </company-info>
        </user>
        <!-- additional <user> elements appear here... -->
      </users>
    </top>
  </data>
</rpc-reply>

Section 6 has more subtree filtering examples if you want to keep going ๐Ÿซถ

Heads up: the <users> example above is the whole vibe for subtree filtering, so if the filter feels confusing, come back to this one ๐Ÿ“

7.2. <edit-config> ๐Ÿ’…

Description:

okay so the <edit-config> operation loads all or part of a specified configuration into the specified target configuration datastore ๐ŸŽ€ the new configuration can be expressed a few different ways, like from a local file, a remote file, or inline โœจ and if the target configuration datastore doesn't exist yet? it gets created ๐ŸŒธ

If a NETCONF peer supports the :url capability (Section 8.8), the <url> element can appear instead of the <config> parameter ๐Ÿ”—

The device analyzes the source and target configurations and performs the requested changes ๐Ÿงš the target configuration is not necessarily replaced, the way it is with the <copy-config> message ๐Ÿ’€ instead, the target configuration gets changed according to the source's data and the requested operations ๐Ÿ’–

If the <edit-config> operation contains multiple sub-operations that apply to the same conceptual node in the underlying data model, then the result of the operation is undefined (i.e., outside the scope of the NETCONF protocol) ๐Ÿ™ˆ that's a whole vibe, and it's outside NETCONF's lane ๐Ÿ˜ญ

Attributes:

operation: Elements in the <config> subtree MAY contain an "operation" attribute, which belongs to the NETCONF namespace defined in Section 3.1. The attribute identifies the point in the configuration to perform the operation and MAY appear on multiple elements throughout the <config> subtree ๐Ÿฆ‹

If the "operation" attribute is not specified, the configuration is merged into the configuration datastore ๐Ÿ“

The "operation" attribute has one of the following values:

  • merge: The configuration data identified by the element containing this attribute is merged with the configuration at the corresponding level in the configuration datastore identified by the <target> parameter. This is the default behavior ๐Ÿ’œ
  • replace: The configuration data identified by the element containing this attribute replaces any related configuration in the configuration datastore identified by the <target> parameter. If no such configuration data exists in the configuration datastore, it is created. Unlike a <copy-config> operation, which replaces the entire target configuration, only the configuration actually present in the <config> parameter is affected โœจ
  • create: The configuration data identified by the element containing this attribute is added to the configuration if and only if the configuration data does not already exist in the configuration datastore. If the configuration data exists, an <rpc-error> element is returned with an <error-tag> value of "data-exists" ๐Ÿ™…โ€โ™€๏ธ
  • delete: The configuration data identified by the element containing this attribute is deleted from the configuration if and only if the configuration data currently exists in the configuration datastore. If the configuration data does not exist, an <rpc-error> element is returned with an <error-tag> value of "data-missing" ๐Ÿ—‘๏ธ
  • remove: The configuration data identified by the element containing this attribute is deleted from the configuration if the configuration data currently exists in the configuration datastore. If the configuration data does not exist, the "remove" operation is silently ignored by the server ๐Ÿคซ

Parameters:

target: Name of the configuration datastore being edited, such as <running/> or <candidate/> ๐ŸŽฏ

default-operation: Selects the default operation (as described in the "operation" attribute) for this <edit-config> request. The default value for the <default-operation> parameter is "merge" ๐Ÿซถ

The <default-operation> parameter is optional, but if provided, it has one of the following values:

  • merge: The configuration data in the <config> parameter is merged with the configuration at the corresponding level in the target datastore. This is the default behavior ๐Ÿ’–
  • replace: The configuration data in the <config> parameter completely replaces the configuration in the target datastore. This is useful for loading previously saved configuration data ๐Ÿ“ฆ
  • none: The target datastore is unaffected by the configuration in the <config> parameter, unless and until the incoming configuration data uses the "operation" attribute to request a different operation. If the configuration in the <config> parameter contains data for which there is not a corresponding level in the target datastore, an <rpc-error> is returned with an <error-tag> value of data-missing. Using "none" allows operations like "delete" to avoid unintentionally creating the parent hierarchy of the element to be deleted ๐Ÿง 

test-option: The <test-option> element MAY be specified only if the device advertises the :validate:1.1 capability (Section 8.6) ๐Ÿงช

The <test-option> element has one of the following values:

  • test-then-set: Perform a validation test before attempting to set. If validation errors occur, do not perform the <edit-config> operation. This is the default test-option ๐Ÿ›ก๏ธ
  • set: Perform a set without a validation test first ๐Ÿƒโ€โ™€๏ธ
  • test-only: Perform only the validation test, without attempting to set ๐Ÿ‘€

error-option: The <error-option> element has one of the following values:

  • stop-on-error: Abort the <edit-config> operation on first error. This is the default error-option ๐Ÿ›‘
  • continue-on-error: Continue to process configuration data on error; error is recorded, and negative response is generated if any errors occur ๐Ÿณ๏ธ
  • rollback-on-error: If an error condition occurs such that an error severity <rpc-error> element is generated, the server will stop processing the <edit-config> operation and restore the specified configuration to its complete state at the start of this <edit-config> operation. This option requires the server to support the :rollback-on-error capability described in Section 8.5 โช

config: A hierarchy of configuration data as defined by one of the device's data models. The contents MUST be placed in an appropriate namespace, to allow the device to detect the appropriate data model, and the contents MUST follow the constraints of that data model, as defined by its capability definition. Capabilities are discussed in Section 8 ๐Ÿ“š

Positive Response: If the device was able to satisfy the request, an <rpc-reply> is sent containing an <ok> element ๐Ÿฅณ

Negative Response: An <rpc-error> response is sent if the request cannot be completed for any reason ๐Ÿ˜ฌ

Example: The <edit-config> examples in this section utilize a simple data model, in which multiple instances of the <interface> element can be present, and an instance is distinguished by the <name> element within each <interface> element ๐ŸŒˆ

Set the MTU to 1500 on an interface named "Ethernet0/0" in the running configuration ๐Ÿ’…

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <edit-config>
    <target>
      <running/>
    </target>
    <config>
      <top xmlns="http://example.com/schema/1.2/config">
        <interface>
          <name>Ethernet0/0</name>
          <mtu>1500</mtu>
        </interface>
      </top>
    </config>
  </edit-config>
</rpc>
<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

Add an interface named "Ethernet0/0" to the running configuration, replacing any previous interface with that name ๐Ÿ”„

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <edit-config>
    <target>
      <running/>
    </target>
    <config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
      <top xmlns="http://example.com/schema/1.2/config">
        <interface xc:operation="replace">
          <name>Ethernet0/0</name>
          <mtu>1500</mtu>
          <address>
            <name>192.0.2.4</name>
            <prefix-length>24</prefix-length>
          </address>
        </interface>
      </top>
    </config>
  </edit-config>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

Delete the configuration for an interface named "Ethernet0/0" from the running configuration ๐Ÿ—‘๏ธโœจ

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <edit-config>
    <target>
      <running/>
    </target>
    <default-operation>none</default-operation>
    <config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
      <top xmlns="http://example.com/schema/1.2/config">
        <interface xc:operation="delete">
          <name>Ethernet0/0</name>

        </interface>
      </top>
    </config>
  </edit-config>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

Delete interface 192.0.2.4 from an OSPF area (other interfaces configured in the same area are unaffected) ๐Ÿฆ‹

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <edit-config>
    <target>
      <running/>
    </target>
    <default-operation>none</default-operation>
    <config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
      <top xmlns="http://example.com/schema/1.2/config">
        <protocols>
          <ospf>
            <area>
              <name>0.0.0.0</name>
              <interfaces>
                <interface xc:operation="delete">
                  <name>192.0.2.4</name>
                </interface>
              </interfaces>
            </area>
          </ospf>
        </protocols>
      </top>
    </config>
  </edit-config>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

7.3. <copy-config>

Description: Okay so <copy-config> is the ultimate glow-up move ๐Ÿ’… It creates or replaces an entire configuration datastore using the contents of another complete configuration datastore ๐ŸŽ€. If the target datastore already exists, it gets overwritten ๐Ÿ˜ญ. If it doesn't exist yet, a brand new one gets created, as long as that's allowed โœจ.

If a NETCONF peer supports the :url capability (Section 8.8), the <url> element can show up as the <source> or <target> parameter ๐Ÿฆ‹.

Even if a device advertises the :writable-running capability, it MAY choose not to support the <running/> configuration datastore as the <target> parameter of a <copy-config> operation ๐Ÿ™ˆ. It also MAY choose not to support remote-to-remote copy operations, where both the <source> and <target> parameters use the <url> element ๐ŸŒธ. If the <source> and <target> parameters identify the same URL or configuration datastore, an error MUST be returned with an error-tag containing "invalid-value" ๐Ÿ’€.

Parameters:

  • target: Name of the configuration datastore to use as the destination of the <copy-config> operation.
  • source: Name of the configuration datastore to use as the source of the <copy-config> operation, or the <config> element containing the complete configuration to copy.

Positive Response: If the device was able to satisfy the request, an <rpc-reply> is sent that includes an <ok> element ๐Ÿซถ.

Negative Response: An <rpc-error> element is included within the <rpc-reply> if the request cannot be completed for any reason.

Example:

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <copy-config>
    <target>
      <running/>
    </target>
    <source>
      <url>https://user:password@example.com/cfg/new.txt</url>
    </source>
  </copy-config>
</rpc>
<rpc-reply message-id="101"
    xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

7.4. <delete-config>

Description: Time to clear the slate ๐Ÿงน <delete-config> deletes a configuration datastore. The <running> configuration datastore cannot be deleted, so don't even try ๐Ÿ™…โ€โ™€๏ธ.

If a NETCONF peer supports the :url capability (Section 8.8), the <url> element can appear as the <target> parameter ๐Ÿฆ‹.

Parameters:

  • target: Name of the configuration datastore to delete.

Positive Response: If the device was able to satisfy the request, an <rpc-reply> is sent that includes an <ok> element ๐Ÿซถ.

Negative Response: An <rpc-error> element is included within the <rpc-reply> if the request cannot be completed for any reason.

Example:

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <delete-config>
    <target>
      <startup/>
    </target>
  </delete-config>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

7.5. <lock>

Description: The <lock> operation lets the client lock the entire configuration datastore system of a device ๐Ÿ”’. These locks are meant to be short-lived, so a client can make a change without worrying about interference from other NETCONF clients, non-NETCONF clients (e.g., SNMP and command line interface (CLI) scripts), and human users ๐Ÿ‘€.

An attempt to lock the configuration datastore MUST fail if an existing session or other entity holds a lock on any portion of the lock target ๐Ÿšซ.

When the lock is acquired, the server MUST prevent any changes to the locked resource other than those requested by this session. SNMP and CLI requests to modify the resource MUST fail with an appropriate error ๐Ÿ™…โ€โ™€๏ธ.

The duration of the lock starts when the lock is acquired and lasts until either the lock is released or the NETCONF session closes. The session can be closed explicitly by the client, or implicitly by the server based on criteria such as failure of the underlying transport, simple inactivity timeout, or detection of abusive behavior on the part of the client โณ. These criteria depend on the implementation and the underlying transport ๐Ÿง .

The <lock> operation takes a mandatory parameter, <target>. The <target> parameter names the configuration datastore that will be locked ๐ŸŽฏ. When a lock is active, using the <edit-config> operation on the locked configuration datastore and using the locked configuration as a target of the <copy-config> operation will be disallowed by any other NETCONF session ๐Ÿšง. On top of that, the system will make sure these locked configuration resources aren't modified by other non-NETCONF management operations such as SNMP and CLI ๐Ÿ›ก๏ธ. The <kill-session> operation can be used to force the release of a lock owned by another NETCONF session. Defining how to break locks held by other entities is beyond the scope of this document ๐Ÿคทโ€โ™€๏ธ.

A lock MUST NOT be granted if any of the following conditions is true:

  • A lock is already held by any NETCONF session or another entity.
  • The target configuration is <candidate>, it has already been modified, and these changes have not been committed or rolled back.
  • The target configuration is <running>, and another NETCONF session has an ongoing confirmed commit (Section 8.4).

The server MUST respond with either an <ok> element or an <rpc-error> ๐Ÿ’ฌ.

A lock will be released by the system if the session holding the lock is terminated for any reason ๐ŸŒˆ.

Parameters:

  • target: Name of the configuration datastore to lock.

Positive Response: If the device was able to satisfy the request, an <rpc-reply> is sent that contains an <ok> element ๐Ÿซถ.

Negative Response: An <rpc-error> element is included in the <rpc-reply> if the request cannot be completed for any reason.

If the lock is already held, the <error-tag> element will be "lock-denied" and the <error-info> element will include the <session-id> of the lock owner ๐Ÿ˜ค. If the lock is held by a non-NETCONF entity, a <session-id> of 0 (zero) is included ๐Ÿค–. Note that any other entity performing a lock on even a partial piece of a target will prevent a NETCONF lock (which is global) from being obtained on that target ๐Ÿ“ข.

Example: The following example shows a successful acquisition of a lock ๐ŸŽ‰.

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <lock>
    <target>
      <running/>
    </target>
  </lock>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/> <!-- lock succeeded -->
</rpc-reply>

Example: The following example shows a failed attempt to acquire a lock when the lock is already in use ๐Ÿฅฒ.

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <lock>
    <target>
      <running/>
    </target>
  </lock>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <rpc-error> <!-- lock failed -->
    <error-type>protocol</error-type>
    <error-tag>lock-denied</error-tag>
    <error-severity>error</error-severity>
    <error-message>
      Lock failed, lock is already held
    </error-message>
    <error-info>
      <session-id>454</session-id>
      <!-- lock is held by NETCONF session 454 -->
    </error-info>
  </rpc-error>
</rpc-reply>

7.6. <unlock>

Description: The <unlock> operation releases a configuration lock that was previously obtained with the <lock> operation ๐Ÿ”“.

An <unlock> operation will not succeed if either of the following conditions is true:

  • The specified lock is not currently active.
  • The session issuing the <unlock> operation is not the same session that obtained the lock.

The server MUST respond with either an <ok> element or an <rpc-error> ๐Ÿ’ฌ.

Parameters:

  • target: Name of the configuration datastore to unlock.

A NETCONF client is not permitted to unlock a configuration datastore that it did not lock ๐Ÿšท.

Positive Response: If the device was able to satisfy the request, an <rpc-reply> is sent that contains an <ok> element ๐Ÿซถ.

Negative Response: An <rpc-error> element is included in the <rpc-reply> if the request cannot be completed for any reason.

Example:

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <unlock>
    <target>
     <running/>
    </target>
  </unlock>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

7.7. <get>

Description: This one's all about retrieving running configuration and device state information ๐Ÿ‘€โœจ.

Parameters:

  • filter: This parameter specifies the portion of the system configuration and state data to retrieve. If this parameter is not present, all the device configuration and state information is returned ๐Ÿงบ.

The <filter> element MAY optionally contain a "type" attribute. This attribute indicates the type of filtering syntax used within the <filter> element. The default filtering mechanism in NETCONF is referred to as subtree filtering and is described in Section 6. The value "subtree" explicitly identifies this type of filtering ๐ŸŒณ.

If the NETCONF peer supports the :xpath capability (Section 8.9), the value "xpath" MAY be used to indicate that the "select" attribute of the <filter> element contains an XPath expression ๐Ÿงญ.

Positive Response: If the device was able to satisfy the request, an <rpc-reply> is sent. The <data> section contains the appropriate subset ๐Ÿซถ.

Negative Response: An <rpc-error> element is included in the <rpc-reply> if the request cannot be completed for any reason.

Example:

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get>
    <filter type="subtree">
      <top xmlns="http://example.com/schema/1.2/stats">
        <interfaces>
          <interface>
            <ifName>eth0</ifName>
          </interface>
        </interfaces>
      </top>
    </filter>
  </get>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <data>
    <top xmlns="http://example.com/schema/1.2/stats">
      <interfaces>
        <interface>
          <ifName>eth0</ifName>
          <ifInOctets>45621</ifInOctets>
          <ifOutOctets>774344</ifOutOctets>
        </interface>
      </interfaces>
    </top>
  </data>
</rpc-reply>

7.8. <close-session> ๐Ÿ’…

Description: Request graceful termination of a NETCONF session ๐Ÿซถ

Okay so when a NETCONF server gets a <close-session> request, it gracefully closes the session, no drama ๐Ÿฆ‹ It releases any locks and resources tied to that session and closes any connections that go with it. And anything NETCONF-y that shows up after a <close-session> request just gets ignored. Periodt ๐Ÿ’€

Positive Response: If the device could handle the request, you get an <rpc-reply> with an <ok> element inside ๐ŸŽ€

Negative Response: If the request can't be completed for any reason, the <rpc-reply> includes an <rpc-error> element instead ๐Ÿ˜ญ

Example:

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <close-session/>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

7.9. <kill-session> โšก

Description: Force the termination of a NETCONF session ๐Ÿ’ฅ

Bestie, this one is the aggressive sibling of <close-session> ๐Ÿ˜ค When a NETCONF entity gets a <kill-session> request for an open session, it aborts whatever operations are currently in process, releases any locks and resources tied to that session, and closes any associated connections. Yikes ๐Ÿ™ˆ

If a NETCONF server gets a <kill-session> request while it's processing a confirmed commit (Section 8.4), it MUST restore the configuration to its state from before the confirmed commit was issued. That's a must, not a maybe ๐Ÿ”ฅ

Otherwise, the <kill-session> operation does NOT roll back configuration or other device state changes made by the entity that was holding the lock. So be careful, it's not a magic undo button ๐Ÿ’…

Parameters:

  • session-id: The session identifier of the NETCONF session you want to terminate ๐Ÿฆ‹ If this value is equal to the current session ID, you get an "invalid-value" error. Don't kill yourself, sis ๐Ÿ’€

Positive Response: If the device could handle the request, you get an <rpc-reply> with an <ok> element inside ๐ŸŽ€

Negative Response: If the request can't be completed for any reason, the <rpc-reply> includes an <rpc-error> element instead ๐Ÿ˜ญ

Example:

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <kill-session>
    <session-id>4</session-id>
  </kill-session>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

8. Capabilities โœจ

This section defines a set of capabilities that a client or a server MAY implement ๐ŸŒธ Each peer advertises its capabilities by sending them during an initial capabilities exchange. Each peer only needs to understand the capabilities it might actually use, and it MUST ignore any capability received from the other peer that it doesn't require or doesn't understand. Main character energy, but make it efficient ๐Ÿ’…

Additional capabilities can be defined using the template in Appendix D. Future capability definitions can be published as standards by standards bodies, or published as proprietary extensions ๐ŸŒˆ

A NETCONF capability is identified with a URI ๐Ÿฆ‹ The base capabilities are defined using URNs following the method described in RFC 3553 [RFC3553]. Capabilities defined in this document have the following format:

urn:ietf:params:netconf:capability:{name}:1.x

Where {name} is the name of the capability. People often refer to capabilities in discussions and email using the shorthand :{name}, or :{name}:{version} if the capability exists in multiple versions ๐Ÿ’ฌ For example, the foo capability would have the formal name "urn:ietf:params:netconf:capability:foo:1.0" and be called :foo. The shorthand form MUST NOT be used inside the protocol. Shorthand is for the group chat, not the wire ๐Ÿ™ˆ

8.1. Capabilities Exchange

Capabilities are advertised in messages sent by each peer during session establishment ๐Ÿค When the NETCONF session opens, each peer (both client and server) MUST send a <hello> element containing a list of that peer's capabilities. Each peer MUST send at least the base NETCONF capability, "urn:ietf:params:netconf:base:1.1". A peer MAY include capabilities for previous NETCONF versions, to show that it supports multiple protocol versions. Versatile queen ๐Ÿ‘‘

Both NETCONF peers MUST verify that the other peer has advertised a common protocol version. When comparing protocol version capability URIs, only the base part is used, in case any parameters are encoded at the end of the URI string. If there's no protocol version capability in common, the NETCONF peer MUST NOT continue the session. If more than one protocol version URI in common is present, then the highest numbered (most recent) protocol version MUST be used by both peers. Newest version wins, always โœจ

A server sending the <hello> element MUST include a <session-id> element containing the session ID for this NETCONF session. A client sending the <hello> element MUST NOT include a <session-id> element. Roles, but make them legible ๐ŸŽ€

A server that receives a <hello> message with a <session-id> element MUST terminate the NETCONF session. Similarly, a client that doesn't receive a <session-id> element in the server's <hello> message MUST terminate the NETCONF session (without first sending a <close-session>). Not me getting ghosted by a server with no session ID ๐Ÿ˜ญ

In the following example, a server advertises the base NETCONF capability, one NETCONF capability defined in the base NETCONF document, and one implementation-specific capability ๐Ÿงš

<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <capabilities>
    <capability>
      urn:ietf:params:netconf:base:1.1
    </capability>
    <capability>
      urn:ietf:params:netconf:capability:startup:1.0
    </capability>
    <capability>
      http://example.net/router/2.3/myfeature
    </capability>
  </capabilities>
  <session-id>4</session-id>
</hello>

Each peer sends its <hello> element simultaneously as soon as the connection is open. A peer MUST NOT wait to receive the capability set from the other side before sending its own set. No waiting around, we're all sending at once ๐Ÿฆ‹

8.2. Writable-Running Capability ๐Ÿ“

8.2.1. Description

The :writable-running capability indicates that the device supports direct writes to the <running> configuration datastore. In other words, the device supports <edit-config> and <copy-config> operations where the <running> configuration is the target. Direct access, no cap ๐Ÿ’…

8.2.2. Dependencies

None.

8.2.3. Capability Identifier

The :writable-running capability is identified by the following capability string:

urn:ietf:params:netconf:capability:writable-running:1.0

8.2.4. New Operations

None.

8.2.5. Modifications to Existing Operations

8.2.5.1. <edit-config>

The :writable-running capability modifies the <edit-config> operation so it accepts the <running> element as a <target> ๐ŸŽฏ

8.2.5.2. <copy-config>

The :writable-running capability modifies the <copy-config> operation so it accepts the <running> element as a <target> ๐ŸŽฏ

8.3. Candidate Configuration Capability ๐Ÿง

8.3.1. Description

The candidate configuration capability, :candidate, indicates that the device supports a candidate configuration datastore. This is used to hold configuration data that can be manipulated without impacting the device's current configuration ๐Ÿซง The candidate configuration is a full configuration data set that serves as a workspace for creating and manipulating configuration data. Additions, deletions, and changes can all be made to this data to build the configuration you actually want. A <commit> operation MAY be performed at any time, and that causes the device's running configuration to be set to the value of the candidate configuration โœจ

The <commit> operation effectively sets the running configuration to the current contents of the candidate configuration. It could technically be modeled as a simple copy, but it's its own distinct operation for a bunch of reasons ๐Ÿง  Keeping high-level concepts as first-class operations lets developers see more clearly both what the client is requesting and what the server has to do. It keeps intentions obvious, special cases less complex, and interactions between operations more straightforward. For example, the :confirmed-commit:1.1 capability (Section 8.4) would make no sense as a "copy confirmed" operation ๐Ÿ™ƒ

The candidate configuration can be shared among multiple sessions. Unless a client has specific information that the candidate configuration is not shared, it MUST assume that other sessions are able to modify the candidate configuration at the same time. So it's smart for a client to lock the candidate configuration before modifying it ๐Ÿ”’

The client can discard any uncommitted changes to the candidate configuration by executing the <discard-changes> operation. This operation reverts the contents of the candidate configuration to the contents of the running configuration ๐Ÿ”„

8.3.2. Dependencies

None.

8.3.3. Capability Identifier

The :candidate capability is identified by the following capability string:

urn:ietf:params:netconf:capability:candidate:1.0

8.3.4. New Operations

8.3.4.1. <commit>

Description:

When the candidate configuration's content is complete, the configuration data can be committed. That publishes the data set to the rest of the device and asks the device to conform to the behavior described in the new configuration ๐Ÿš€

To commit the candidate configuration as the device's new current configuration, use the <commit> operation.

The <commit> operation tells the device to implement the configuration data contained in the candidate configuration. If the device can't commit all of the changes in the candidate configuration datastore, then the running configuration MUST remain unchanged. If the device does succeed in committing, the running configuration MUST be updated with the contents of the candidate configuration. All or nothing, bestie ๐Ÿ’ฏ

If the running or candidate configuration is currently locked by a different session, the <commit> operation MUST fail with an <error-tag> value of "in-use" ๐Ÿ” Someone else has the mic, so wait your turn.

If the system does not have the :candidate capability, the <commit> operation is not available ๐Ÿ™…

Positive Response:

If the device could handle the request, you get an <rpc-reply> that contains an <ok> element ๐ŸŽ€

Negative Response:

If the request can't be completed for any reason, the <rpc-reply> includes an <rpc-error> element instead ๐Ÿ˜ญ

Example:

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <commit/>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

8.3.4.2. <discard-changes>

If the client decides the candidate configuration is not going to be committed, the <discard-changes> operation can be used to revert the candidate configuration to the current running configuration ๐Ÿงน

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <discard-changes/>
</rpc>

This operation discards any uncommitted changes by resetting the candidate configuration with the content of the running configuration. Clean slate, iykyk ๐Ÿซง

8.3.5. Modifications to Existing Operations

8.3.5.1. <get-config>, <edit-config>, <copy-config>, and <validate> โœจ

okay so the candidate configuration can be a source or target for any <get-config>, <edit-config>, <copy-config>, or <validate> operation, as a <source> or <target> parameter ๐Ÿ’… the <candidate> element is how you tell the server you mean the candidate ๐ŸŽ€

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <get-config>
      <source>
        <candidate/>
      </source>
    </get-config>
  </rpc>

8.3.5.2. <lock> and <unlock> ๐Ÿ”

you can lock the candidate configuration with the <lock> operation, using the <candidate> element as the <target> parameter ๐Ÿซถ

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <lock>
      <target>
        <candidate/>
      </target>
    </lock>
  </rpc>

and to unlock it, it's the same vibe, just with <unlock> instead ๐Ÿ”“

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <unlock>
      <target>
        <candidate/>
      </target>
    </unlock>
  </rpc>
๐Ÿ˜ญ recovery can be a whole mess when a client fails with outstanding changes to the candidate configuration. so the fix is that any outstanding changes get discarded when the lock is released, whether that's explicitly with <unlock> or implicitly because the session failed. clean slate, no drama ๐Ÿงน

8.4. Confirmed Commit Capability ๐Ÿฆ‹

8.4.1. Description ๐Ÿ’–

the :confirmed-commit:1.1 capability means the server supports the <cancel-commit> operation, plus the <confirmed>, <confirm-timeout>, <persist>, and <persist-id> parameters for <commit>. for more on <commit>, check Section 8.3 ๐ŸŒธ

now the big one. a confirmed <commit> MUST be reverted if a confirming commit isn't issued within the timeout period (600 seconds by default, aka 10 minutes โฐ). the confirming commit is just a <commit> without the <confirmed> parameter. you can change the timeout with <confirm-timeout>. if you send another confirmed <commit> before the timer runs out, the timer resets to the new value (600 seconds by default). both the confirming commit and a follow-up confirmed <commit> MAY bring in additional changes to the configuration โœจ

if you don't include the <persist> element, then any follow-up commit and the confirming commit MUST be issued on the same session that issued the confirmed commit ๐Ÿง  if you DO give <persist> in the confirmed <commit>, a follow-up commit and the confirming commit can happen on any session, and they MUST include a <persist-id> element whose value matches the value you gave in <persist> ๐Ÿ”‘

if the server also advertises the :startup capability, you need a <copy-config> from running to startup to save the changes to startup too ๐Ÿ’พ

if the session that issued the confirmed commit gets terminated for any reason before the confirm timeout expires, the server MUST restore the configuration to how it was before the confirmed commit was issued, unless that confirmed commit also had a <persist> element ๐Ÿซ 

same energy for reboots. if the device reboots for any reason before the confirm timeout expires, the server MUST restore the configuration to its state from before the confirmed commit ๐Ÿ”„

if no confirming commit shows up, the device reverts its configuration to the state it had before the confirmed commit. if you don't want to wait for the timeout, the client can cancel the confirmed commit and revert right away by using the <cancel-commit> operation ๐Ÿƒโ€โ™€๏ธ

โš ๏ธ for shared configurations, this feature can accidentally alter or remove other configuration changes (for example, ones made via other NETCONF sessions), unless you use the configuration locking feature (meaning you obtain the lock before you start the <edit-config> operation). so it is strongly suggested that if you're using this with shared configuration datastores, configuration locking SHOULD also be used ๐Ÿ™ˆ

version 1.0 of this capability was defined in [RFC4741]. version 1.1 is defined in this document and extends 1.0 by adding a new operation, <cancel-commit>, and two new optional parameters, <persist> and <persist-id> ๐ŸŽ€ for backwards compatibility with old clients, servers conforming to this specification MAY advertise version 1.0 in addition to version 1.1 ๐Ÿ‘‘

8.4.2. Dependencies ๐Ÿงฉ

the :confirmed-commit:1.1 capability is only relevant if the :candidate capability is also supported ๐Ÿ’…

8.4.3. Capability Identifier ๐Ÿชช

the :confirmed-commit:1.1 capability is identified by this capability string:

   urn:ietf:params:netconf:capability:confirmed-commit:1.1

8.4.4. New Operations ๐Ÿ†•

8.4.4.1. <cancel-commit> ๐Ÿ›‘

Description:

cancels an ongoing confirmed commit. if the <persist-id> parameter isn't given, the <cancel-commit> operation MUST be issued on the same session that issued the confirmed commit ๐Ÿซถ

Parameters:

persist-id:

cancels a persistent confirmed commit. the value MUST be equal to the value given in the <persist> parameter to the <commit> operation. if the value doesn't match, the operation fails with an "invalid-value" error ๐Ÿšซ

Positive Response:

if the device was able to satisfy the request, an <rpc-reply> is sent that contains an <ok> element โœ…

Negative Response:

an <rpc-error> element is included in the <rpc-reply> if the request can't be completed for any reason ๐Ÿ’€

Example:

   <rpc message-id="101"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <commit>
       <confirmed/>
     </commit>
   </rpc>

   <rpc-reply message-id="101"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <ok/>
   </rpc-reply>

   <rpc message-id="102"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <cancel-commit/>
   </rpc>
   <rpc-reply message-id="102"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <ok/>
   </rpc-reply>

8.4.5. Modifications to Existing Operations โœ๏ธ

8.4.5.1. <commit> ๐Ÿ’ซ

the :confirmed-commit:1.1 capability allows 4 additional parameters on the <commit> operation ๐ŸŽ‰

Parameters:

confirmed:

performs a confirmed <commit> operation ๐Ÿ”’

confirm-timeout:

timeout period for the confirmed commit, in seconds. if you don't specify it, the confirm timeout defaults to 600 seconds โณ

persist:

makes the confirmed commit survive a session termination, and sets a token on the ongoing confirmed commit ๐Ÿท๏ธ

persist-id:

used to issue a follow-up confirmed commit or a confirming commit from any session, using the token from the previous <commit> operation ๐Ÿช„

Example:

   <rpc message-id="101"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <commit>
       <confirmed/>
       <confirm-timeout>120</confirm-timeout>
     </commit>
   </rpc>

   <rpc-reply message-id="101"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <ok/>
   </rpc-reply>

Example:

   <!-- start a persistent confirmed-commit -->
   <rpc message-id="101"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <commit>
       <confirmed/>
       <persist>IQ,d4668</persist>
     </commit>
   </rpc>

   <rpc-reply message-id="101"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <ok/>
   </rpc-reply>

   <!-- confirm the persistent confirmed-commit,
        possibly from another session -->
   <rpc message-id="102"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <commit>
       <persist-id>IQ,d4668</persist-id>
     </commit>
   </rpc>

   <rpc-reply message-id="102"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <ok/>
   </rpc-reply>

8.5. Rollback-on-Error Capability ๐Ÿช„

8.5.1. Description ๐Ÿ“

this capability means the server supports the "rollback-on-error" value in the <error-option> parameter to the <edit-config> operation ๐Ÿ’…

โš ๏ธ for shared configurations, this feature can accidentally alter or remove other configuration changes (for example, ones made via other NETCONF sessions), unless you use the configuration locking feature (meaning the lock is obtained before the <edit-config> operation starts). so it is strongly suggested that if you're using this with shared configuration datastores, configuration locking also be used ๐Ÿ™ˆ

8.5.2. Dependencies ๐Ÿงฉ

None.

8.5.3. Capability Identifier ๐Ÿชช

the :rollback-on-error capability is identified by this capability string:

   urn:ietf:params:netconf:capability:rollback-on-error:1.0

8.5.4. New Operations ๐Ÿ†•

None.

8.5.5. Modifications to Existing Operations โœ๏ธ

8.5.5.1. <edit-config> ๐ŸŒˆ

the :rollback-on-error capability allows the "rollback-on-error" value for the <error-option> parameter on the <edit-config> operation ๐ŸŽ€

   <rpc message-id="101"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <edit-config>
       <target>
         <running/>
       </target>
       <error-option>rollback-on-error</error-option>
       <config>
         <top xmlns="http://example.com/schema/1.2/config">
           <interface>
             <name>Ethernet0/0</name>
             <mtu>100000</mtu>
           </interface>
         </top>
       </config>
     </edit-config>
   </rpc>

   <rpc-reply message-id="101"
        xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <ok/>
   </rpc-reply>

8.6. Validate Capability ๐Ÿ”

8.6.1. Description ๐Ÿ’ญ

validation is checking a complete configuration for syntactical and semantic errors before you apply it to the device ๐Ÿง

if this capability is advertised, the device supports the <validate> protocol operation and checks at least for syntax errors. it also supports the <test-option> parameter to the <edit-config> operation and, when that's provided, checks at least for syntax errors too โœจ

version 1.0 of this capability was defined in [RFC4741]. version 1.1 is defined in this document and extends 1.0 by adding a new value, "test-only", to the <test-option> parameter of the <edit-config> operation ๐Ÿฆ‹ for backwards compatibility with old clients, servers conforming to this specification MAY advertise version 1.0 in addition to version 1.1 ๐Ÿ’œ

8.6.2. Dependencies ๐Ÿงฉ

None.

8.6.3. Capability Identifier ๐Ÿชช

the :validate:1.1 capability is identified by this capability string:

   urn:ietf:params:netconf:capability:validate:1.1

8.6.4. New Operations ๐Ÿ†•

8.6.4.1. <validate> ๐Ÿ’…

okay so <validate> is the operation that checks whether the contents of a configuration are actually valid โœจ

Description: this operation checks that the contents of the specified configuration are valid ๐ŸŽ€

Parameters:

  • source: the name of the configuration datastore to validate, like <candidate>, or the <config> element that holds the complete configuration you want checked ๐Ÿงš

Positive Response: if the device can handle the request, you get back an <rpc-reply> with an <ok> element inside ๐Ÿซถ

Negative Response: if the request can't be completed for any reason, the <rpc-reply> includes an <rpc-error> element ๐Ÿ’€. a <validate> can fail for a bunch of reasons, like syntax errors, missing parameters, references to configuration data that doesn't exist, or any other rule broken by the underlying data model ๐Ÿ˜ญ

Example:

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <validate>
    <source>
      <candidate/>
    </source>
  </validate>
</rpc>

<rpc-reply message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok/>
</rpc-reply>

8.6.5. Modifications to Existing Operations ๐ŸŒธ

8.6.5.1. <edit-config> ๐Ÿฆ‹

okay this one is lowkey simple: the :validate:1.1 capability lets <edit-config> accept the <test-option> parameter ๐Ÿ“

8.7. Distinct Startup Capability ๐Ÿ‘‘

8.7.1. Description โœจ

so the device keeps running and startup configuration datastores separate, which is iconic ๐Ÿ’–. the startup config gets loaded when the device boots up ๐ŸŒˆ. changes you make to the running config do NOT automatically get copied over to startup ๐Ÿ’€. if you want startup to match what's currently running, you send an explicit <copy-config> from <running> to <startup> ๐ŸŽ€. NETCONF operations reach the startup datastore through the <startup> element ๐Ÿงš

8.7.2. Dependencies ๐Ÿซถ

None.

8.7.3. Capability Identifier ๐Ÿ’…

The :startup capability is identified by this capability string:

urn:ietf:params:netconf:capability:startup:1.0

8.7.4. New Operations โœจ

None.

8.7.5. Modifications to Existing Operations ๐Ÿฆ‹

8.7.5.1. General ๐ŸŒธ

the :startup capability adds the <startup/> configuration datastore to the arguments of several NETCONF operations ๐Ÿ‘‘. the server MUST support the following extra values:

+--------------------+--------------------------+-------------------+
| Operation          | Parameters               | Notes             |
+--------------------+--------------------------+-------------------+
| <get-config>       | <source>                 |                   |
|                    |                          |                   |
| <copy-config>      | <source> <target>        |                   |
|                    |                          |                   |
| <lock>             | <target>                 |                   |
|                    |                          |                   |
| <unlock>           | <target>                 |                   |
|                    |                          |                   |
| <validate>         | <source>                 | If :validate:1.1  |
|                    |                          | is advertised     |
|                    |                          |                   |
| <delete-config>    | <target>                 | Resets the device |
|                    |                          | to its factory    |
|                    |                          | defaults          |
+--------------------+--------------------------+-------------------+

if you want to save the startup config, just use <copy-config> to copy the <running> datastore into the <startup> datastore ๐Ÿ”ฅ

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <copy-config>
    <target>
      <startup/>
    </target>
    <source>
      <running/>
    </source>
  </copy-config>
</rpc>

8.8. URL Capability ๐ŸŒˆ

8.8.1. Description ๐Ÿงš

the NETCONF peer can accept the <url> element inside <source> and <target> parameters, which is giving flexibility ๐Ÿ’–. the capability also comes with URL arguments that list the URL schemes it supports ๐ŸŽ€

8.8.2. Dependencies ๐Ÿซถ

None.

8.8.3. Capability Identifier โœจ

The :url capability is identified by this capability string:

urn:ietf:params:netconf:capability:url:1.0?scheme={name,...}

the :url capability URI MUST contain a "scheme" argument, and that argument gets a comma-separated list of scheme names telling you which schemes the NETCONF peer supports ๐Ÿฆ‹. for example:

urn:ietf:params:netconf:capability:url:1.0?scheme=http,ftp,file

8.8.4. New Operations ๐ŸŒธ

None.

8.8.5. Modifications to Existing Operations ๐Ÿ‘‘

8.8.5.1. <edit-config> ๐Ÿ’…

the :url capability lets <edit-config> take a <url> element instead of the <config> parameter ๐Ÿ“

the file that the URL points to holds the configuration data hierarchy you want to change. it's encoded in XML under the <config> element in the "urn:ietf:params:xml:ns:netconf:base:1.0" namespace ๐Ÿงš

8.8.5.2. <copy-config> ๐Ÿซถ

the :url capability lets <copy-config> accept a <url> element as the value of both the <source> and <target> parameters ๐Ÿ”ฅ

the file behind the URL holds the complete datastore. it's encoded in XML under the <config> element in the "urn:ietf:params:xml:ns:netconf:base:1.0" namespace ๐Ÿ’–

8.8.5.3. <delete-config> ๐ŸŒˆ

the :url capability lets <delete-config> accept a <url> element as the value of the <target> parameter ๐ŸŽ€

8.8.5.4. <validate> โœจ

the :url capability lets <validate> accept a <url> element as the value of the <source> parameter ๐Ÿฆ‹


8.9. XPath Capability ๐Ÿ’œ

8.9.1. Description ๐ŸŒธ

the XPath capability means the NETCONF peer can use XPath expressions inside the <filter> element ๐Ÿ‘‘. XPath is described in [W3C.REC-xpath-19991116].

the data model used in the XPath expression is the same one used in XPath 1.0 [W3C.REC-xpath-19991116], plus the same extension for root node children that XSLT 1.0 uses ([W3C.REC-xslt-19991116], Section 3.1). basically, the root node MAY have any number of element nodes as its children ๐Ÿงš

the XPath expression gets evaluated in this context:

  • The set of namespace declarations is the ones in scope on the <filter> element.
  • The set of variable bindings is defined by the data model. If no such variable bindings are defined, the set is empty.
  • The function library is the core function library, plus any functions the data model defines.
  • The context node is the root node.

the XPath expression MUST return a node set. if it doesn't return a node set, the operation fails with an "invalid-value" error ๐Ÿ’€

the response message holds the subtrees picked out by the filter expression ๐Ÿ“. for each subtree, the path from the data model root node down to that subtree is included, along with any elements or attributes needed to uniquely identify it. specific data instances don't get duplicated in the response ๐Ÿซถ

8.9.2. Dependencies ๐ŸŒˆ

None.

8.9.3. Capability Identifier ๐Ÿ’–

The :xpath capability is identified by this capability string:

urn:ietf:params:netconf:capability:xpath:1.0

8.9.4. New Operations ๐ŸŽ€

None.

8.9.5. Modifications to Existing Operations ๐Ÿฆ‹

8.9.5.1. <get-config> and <get> โœจ

the :xpath capability lets <get> and <get-config> accept the value "xpath" in the "type" attribute of the <filter> element ๐Ÿ‘‘. when "type" is set to "xpath", a "select" attribute MUST be present on the <filter> element. the "select" attribute gets treated as an XPath expression and used to filter the data that comes back ๐Ÿ”ฅ. the <filter> element itself MUST be empty in this case ๐Ÿ’…

the XPath result for the select expression MUST be a node-set. every node in that node-set MUST correspond to a node in the underlying data model. to identify each node properly, these encoding rules apply ๐Ÿงš:

  • All ancestor nodes of the result node MUST be encoded first, so the <data> element in the reply only contains fully specified subtrees, according to the underlying data model.
  • If any sibling or ancestor nodes of the result node are needed to identify a particular instance within a conceptual data structure, then those nodes MUST also be encoded in the response.

here's an example, bestie ๐Ÿซถ:

<rpc message-id="101"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <get-config>
    <source>
      <running/>
    </source>
    <!-- get the user named fred -->
    <filter xmlns:t="http://example.com/schema/1.2/config"
            type="xpath"
            select="/t:top/t:users/t:user[t:name='fred']"/>
   </get-config>
</rpc>

<rpc-reply message-id="101"
           xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <data>
    <top xmlns="http://example.com/schema/1.2/config">
      <users>
        <user>
          <name>fred</name>
          <company-info>
            <id>2</id>
          </company-info>
        </user>
      </users>
    </top>
  </data>
</rpc-reply>

9. Security Considerations ๐Ÿ”โœจ

okay bestie, this is the serious section, so grab your thinking cap ๐Ÿง ๐Ÿ’…. This section covers security for the base NETCONF message layer and the base operations. Security for the NETCONF transports lives in the transport docs, and security for the content NETCONF moves around lives in the docs that define the data models ๐ŸŽ€.

This doc doesn't define an authorization scheme ๐Ÿ™ˆ because that's probably going to be tied to a meta-data model or a data model. Implementors SHOULD provide a comprehensive authorization scheme with NETCONF ๐Ÿ’œ.

Authorizing individual users through the NETCONF server might not line up 1:1 with other interfaces, and it might. Two reasons: the data models could be incompatible, and it could be nice to authorize based on what the Secure Transport layer offers (like SSH, BEEP, etc.) ๐Ÿฆ‹.

Also, operations on configurations could have unintended consequences if they aren't guarded by the global lock on the files or objects being touched. Picture this: the running configuration isn't locked, so a half-finished access list gets committed from the candidate configuration, and the owner of the candidate's lock has no clue ๐Ÿ˜ญ. The device ends up either insecure or totally inaccessible. Yikes ๐Ÿ’€.

Configuration info is sensitive by nature ๐Ÿ™€. If it's sent in the clear with no integrity checking, devices are wide open to classic eavesdropping and false data injection attacks. Configs often hold passwords, user names, service descriptions, and topology info, all of which are sensitive ๐Ÿ”ฅ. So this protocol SHOULD be implemented carefully, with attention to every kind of attack you'd expect against any other management interface ๐Ÿ›ก๏ธ.

The protocol MUST minimally support options for both confidentiality and authentication. That's non-negotiable ๐Ÿšจ.

Here's the good news: the underlying protocol (SSH, BEEP, etc.) is expected to provide both confidentiality and authentication, as needed ๐Ÿซถ. Each end of a NETCONF session is also expected to know the other end's identity so it can decide what that party is allowed to do with any given request ๐Ÿ‘‘. You could even imagine extra info, like transport and encryption methods, feeding into authorization too โœจ. NETCONF itself has no way to re-authenticate, let alone authenticate. All of that happens at lower layers ๐Ÿงš.

Different environments might allow different rights before and after authentication, so this document doesn't specify an authorization model ๐ŸŒˆ. When an operation isn't properly authorized, a plain "access denied" is enough ๐Ÿ™…โ€โ™€๏ธ. Also, authorization info can travel as configuration info, which is all the more reason to lock down the connection ๐Ÿ”’๐Ÿ’–.

That said, some operations are obviously more sensitive than others ๐Ÿ‘€. For example, <copy-config> to the startup or running configurations is clearly not a normal provisioning move, whereas <edit-config> totally is ๐Ÿ“. Global operations like that MUST disallow changing information that an individual isn't authorized to change ๐Ÿšซ. Say user A isn't allowed to configure an IP address on an interface, but user B has set one on an interface in the <candidate> configuration. User A MUST NOT be allowed to commit the <candidate> configuration ๐Ÿ˜ค.

Similarly, just because someone says "go write a configuration through the URL capability at a particular place," that doesn't mean the element will do it without proper authorization ๐Ÿ™ˆ.

The <lock> operation shows that NETCONF is meant for systems where the administrator is at least somewhat trusted ๐Ÿค. As specified here, you can lock parts of a configuration that a principal otherwise couldn't access, because the entire configuration gets locked ๐Ÿ˜ฌ. There are two ways to deal with that. You can kill another NETCONF session programmatically from inside NETCONF if you know the session identifier of the offending session ๐Ÿ”ช. Or you can provide a function in the device's native user interface to break the lock โœจ. Both of these have a race condition that could be eased by removing the offending user from an Authentication, Authorization, and Accounting (AAA) server. But that fix isn't useful in every deployment, like the ones using SSH public/private key pairs ๐Ÿ”‘.


10. IANA Considerations ๐Ÿ“‹๐Ÿ’…

10.1. NETCONF XML Namespace

This document registers a URI for the NETCONF XML namespace in the IETF XML registry [RFC3688] ๐ŸŽ€.

IANA has updated the following URI to reference this document:

URI: urn:ietf:params:xml:ns:netconf:base:1.0

Registrant Contact: The IESG.

XML: N/A, the requested URI is an XML namespace.

10.2. NETCONF XML Schema

This document registers a URI for the NETCONF XML schema in the IETF XML registry [RFC3688] ๐Ÿ“.

IANA has updated the following URI to reference this document:

URI: urn:ietf:params:xml:schema:netconf
Registrant Contact: The IESG.

XML: Appendix B of this document.

10.3. NETCONF YANG Module

This document registers a YANG module in the YANG Module Names registry [RFC6020] ๐Ÿฆ‹.

  name:        ietf-netconf
  namespace:   urn:ietf:params:xml:ns:netconf:base:1.0
  prefix:      nc
  reference:   RFC 6241

10.4. NETCONF Capability URNs

IANA has created and now maintains a registry called "Network Configuration Protocol (NETCONF) Capability URNs," which hands out NETCONF capability identifiers ๐Ÿ—‚๏ธ. Additions to the registry require IETF Standards Action ๐Ÿ›๏ธ.

IANA has updated the allocations of the following capabilities to reference this document:

   Index
      Capability Identifier
   ------------------------

   :writable-running
      urn:ietf:params:netconf:capability:writable-running:1.0

   :candidate
      urn:ietf:params:netconf:capability:candidate:1.0

   :rollback-on-error
      urn:ietf:params:netconf:capability:rollback-on-error:1.0

   :startup
      urn:ietf:params:netconf:capability:startup:1.0

   :url
      urn:ietf:params:netconf:capability:url:1.0

   :xpath
      urn:ietf:params:netconf:capability:xpath:1.0

IANA has added the following capabilities to the registry:

   Index
      Capability Identifier
   ------------------------

   :base:1.1
      urn:ietf:params:netconf:base:1.1

   :confirmed-commit:1.1
      urn:ietf:params:netconf:capability:confirmed-commit:1.1

   :validate:1.1
      urn:ietf:params:netconf:capability:validate:1.1

11. Contributors ๐Ÿซถ

In addition to the editors, this document was also written by:

  • Ken Crozier, Cisco Systems ๐Ÿ’–
  • Ted Goddard, IceSoft ๐ŸŒธ
  • Eliot Lear, Cisco Systems โญ
  • Phil Shafer, Juniper Networks ๐Ÿฆ‹
  • Steve Waldbusser ๐Ÿงš
  • Margaret Wasserman, Painless Security, LLC ๐Ÿ‘‘

12. Acknowledgements ๐Ÿ’œ

The authors want to thank the members of the NETCONF working group ๐Ÿฅฐ. Special shoutout to Wes Hardaker, who was persistent and patient in helping with the security considerations ๐Ÿ™Œ. Thank you also to Randy Presuhn, Sharon Chisholm, Glenn Waters, David Perkins, Weijing Chen, Simon Leinen, Keith Allen, Dave Harrington, Ladislav Lhotka, Tom Petch, and Kent Watsen for all of their valuable advice ๐ŸŽ€โœจ.


13. References ๐Ÿ“š

13.1. Normative References

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC3553]  Mealling, M., Masinter, L., Hardie, T., and G. Klyne, "An
           IETF URN Sub-namespace for Registered Protocol
           Parameters", BCP 73, RFC 3553, June 2003.

[RFC3629]  Yergeau, F., "UTF-8, a transformation format of ISO
           10646", STD 63, RFC 3629, November 2003.

[RFC3688]  Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688,
           January 2004.

[RFC3986]  Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
           Resource Identifier (URI): Generic Syntax", STD 66,
           RFC 3986, January 2005.

[RFC5717]  Lengyel, B. and M. Bjorklund, "Partial Lock Remote
           Procedure Call (RPC) for NETCONF", RFC 5717,
           December 2009.

[RFC6020]  Bjorklund, M., "YANG - A Data Modeling Language for the
           Network Configuration Protocol (NETCONF)", RFC 6020,
           October 2010.

[RFC6021]  Schoenwaelder, J., "Common YANG Data Types", RFC 6021,
           October 2010.

[RFC6242]  Wasserman, M., "Using the NETCONF Configuration Protocol
           over Secure Shell (SSH)", RFC 6242, June 2011.

[W3C.REC-xml-20001006]
           Sperberg-McQueen, C., Bray, T., Paoli, J., and E. Maler,
           "Extensible Markup Language (XML) 1.0 (Second Edition)",
           World Wide Web Consortium REC-xml-20001006, October 2000,
           <http://www.w3.org/TR/2000/REC-xml-20001006>.

[W3C.REC-xpath-19991116]
           DeRose, S. and J. Clark, "XML Path Language (XPath)
           Version 1.0", World Wide Web Consortium
           Recommendation REC-xpath-19991116, November 1999,
           <http://www.w3.org/TR/1999/REC-xpath-19991116>.

13.2. Informative References

[RFC2865]  Rigney, C., Willens, S., Rubens, A., and W. Simpson,
           "Remote Authentication Dial In User Service (RADIUS)",
           RFC 2865, June 2000.

[RFC3470]  Hollenbeck, S., Rose, M., and L. Masinter, "Guidelines for
           the Use of Extensible Markup Language (XML)
           within IETF Protocols", BCP 70, RFC 3470, January 2003.

[RFC4251]  Ylonen, T. and C. Lonvick, "The Secure Shell (SSH)
           Protocol Architecture", RFC 4251, January 2006.

[RFC4741]  Enns, R., "NETCONF Configuration Protocol", RFC 4741,
           December 2006.

[RFC5246]  Dierks, T. and E. Rescorla, "The Transport Layer Security
           (TLS) Protocol Version 1.2", RFC 5246, August 2008.

[W3C.REC-xslt-19991116]
           Clark, J., "XSL Transformations (XSLT) Version 1.0", World
           Wide Web Consortium Recommendation REC-xslt-19991116,
           November 1999,
           <http://www.w3.org/TR/1999/REC-xslt-19991116>.

Appendix A. NETCONF Error List ๐Ÿ’…โœจ

This section is normative, bestie. ๐Ÿ“œ It's the official cheat sheet of every error-tag, plus which error-type and error-severity each one comes with, and any mandatory error-info that has to tag along. Every error here has error-severity set to error, so none of these are just warnings. ๐Ÿ™ˆ

in-use ๐Ÿ”’

error-tag:      in-use
error-type:     protocol, application
error-severity: error
error-info:     none

The request needs a resource that's already being used by something else. Someone's already got it. ๐Ÿ˜ค

invalid-value ๐Ÿ™…โ€โ™€๏ธ

error-tag:      invalid-value
error-type:     protocol, application
error-severity: error
error-info:     none

The request gives an unacceptable value for one or more parameters. The vibe is "that value is just not it." ๐Ÿ’€

too-big ๐Ÿ˜

error-tag:      too-big
error-type:     transport, rpc, protocol, application
error-severity: error
error-info:     none

The request, or the response that would be generated, is too large for the implementation to handle. It's literally too much for it to hold. ๐Ÿ˜ญ

missing-attribute ๐Ÿซฅ

error-tag:      missing-attribute
error-type:     rpc, protocol, application
error-severity: error
error-info:     <bad-attribute> : name of the missing attribute
                <bad-element> : name of the element that is supposed
                  to contain the missing attribute

An attribute that was expected is just gone. The error-info tells you which attribute went missing and which element was supposed to be holding it. ๐Ÿ•ต๏ธโ€โ™€๏ธ

bad-attribute ๐Ÿ™ƒ

error-tag:      bad-attribute
error-type:     rpc, protocol, application
error-severity: error
error-info:     <bad-attribute> : name of the attribute w/ bad value
                <bad-element> : name of the element that contains
                  the attribute with the bad value

The attribute is there, but its value isn't right. Think wrong type, out of range, or a pattern that doesn't match. The error-info names both the attribute and the element holding it. ๐ŸŽ€

unknown-attribute ๐Ÿ‘ฝ

error-tag:      unknown-attribute
error-type:     rpc, protocol, application
error-severity: error
error-info:     <bad-attribute> : name of the unexpected attribute
                <bad-element> : name of the element that contains
                  the unexpected attribute

An attribute showed up that nobody asked for. Who invited it? ๐Ÿ™„ The error-info points to the attribute and to the element that's carrying it.

missing-element ๐Ÿงฉ

error-tag:      missing-element
error-type:     protocol, application
error-severity: error
error-info:     <bad-element> : name of the missing element

An element that was expected isn't there. It ghosted the request. ๐Ÿ‘ป

bad-element ๐Ÿ’ข

error-tag:      bad-element
error-type:     protocol, application
error-severity: error
error-info:     <bad-element> : name of the element w/ bad value

The element is present, but its value is wrong. Wrong type, out of range, or a pattern mismatch, same as the attribute version but for elements. ๐Ÿซ 

unknown-element ๐Ÿ›ธ

error-tag:      unknown-element
error-type:     protocol, application
error-severity: error
error-info:     <bad-element> : name of the unexpected element

An element showed up that doesn't belong there at all. Not in the vibe, not in the plan. ๐Ÿšซ

unknown-namespace ๐Ÿ—บ๏ธ

error-tag:      unknown-namespace
error-type:     protocol, application
error-severity: error
error-info:     <bad-element> : name of the element that contains
                  the unexpected namespace
                <bad-namespace> : name of the unexpected namespace

An unexpected namespace is hanging around. The error-info calls out both the element holding it and the namespace itself. The wrong address label, basically. ๐Ÿ“ญ

access-denied ๐Ÿšช

error-tag:      access-denied
error-type:     protocol, application
error-severity: error
error-info:     none

The request can't go through because authorization failed. Access to the protocol operation or the data model has been denied. Not your VIP section, bestie. ๐Ÿ”

lock-denied ๐Ÿ”

error-tag:      lock-denied
error-type:     protocol
error-severity: error
error-info:     <session-id> : session ID of session holding the
                  requested lock, or zero to indicate a non-NETCONF
                  entity holds the lock

You can't get the lock because another entity is already holding it. The error-info either gives the session ID of the session holding the lock, or a zero if the lock is being held by something that isn't a NETCONF entity. Somebody got there first. ๐Ÿƒโ€โ™€๏ธ๐Ÿ’จ

resource-denied ๐Ÿชซ

error-tag:      resource-denied
error-type:     transport, rpc, protocol, application
error-severity: error
error-info:     none

The request couldn't be finished because there just isn't enough in the tank. Not enough resources, so it's a no. ๐Ÿ˜ฉ

rollback-failed โช

error-tag:      rollback-failed
error-type:     protocol, application
error-severity: error
error-info:     none

The attempt to roll back a configuration change didn't finish, whether that came from rollback-on-error or from a <discard-changes> operation. For some reason the undo didn't land. ๐Ÿ˜ฌ

data-exists ๐Ÿ“ฆ

error-tag:      data-exists
error-type:     application
error-severity: error
error-info:     none

The request couldn't be completed because the data model content it wanted to add is already there. For example, someone tried a "create" on data that already exists. Dรฉjร  vu, but make it an error. ๐Ÿ”

data-missing ๐Ÿซฅ

error-tag:      data-missing
error-type:     application
error-severity: error
error-info:     none

The request couldn't be completed because the data model content it targeted doesn't exist. For example, someone tried a "delete" on data that isn't there. You can't unfollow someone who never followed you. ๐Ÿคทโ€โ™€๏ธ

operation-not-supported ๐Ÿšซ

error-tag:      operation-not-supported
error-type:     protocol, application
error-severity: error
error-info:     none

The requested operation isn't supported by this implementation. It's just not on the menu here. ๐Ÿฝ๏ธ

operation-failed ๐Ÿ’ฅ

error-tag:      operation-failed
error-type:     rpc, protocol, application
error-severity: error
error-info:     none

The requested operation failed for some reason that doesn't fit any of the other error conditions. It's the catch-all, the "idk what happened but it didn't work" error. ๐ŸŒ€

partial-operation ๐Ÿงƒ

error-tag:      partial-operation
error-type:     application
error-severity: error
error-info:     <ok-element> : identifies an element in the data
                  model for which the requested operation has been
                  completed for that node and all its child nodes.
                  This element can appear zero or more times in the
                  <error-info> container.

                <err-element> : identifies an element in the data
                  model for which the requested operation has failed
                  for that node and all its child nodes.
                  This element can appear zero or more times in the
                  <error-info> container.

                <noop-element> : identifies an element in the data
                  model for which the requested operation was not
                  attempted for that node and all its child nodes.
                  This element can appear zero or more times in the
                  <error-info> container.

Okay, this one is a little messy, so listen up. ๐Ÿ‘‚ This error-tag is obsolete, and servers following this document SHOULD NOT send it. ๐Ÿ›‘ Still, here's the idea: some part of the operation went wrong, or never got attempted at all. The server didn't do a full cleanup, so something like rollback wasn't in play. To sort out which bits went where, the error-info container uses three kinds of elements. <ok-element> marks the parts of the application data model where the operation worked, <bad-element> marks the parts where it failed, and <noop-element> marks the parts where it was never tried. ๐Ÿงฉโœจ

error-tag:      partial-operation

Heads up, this one's been retired. ๐Ÿชฆ

malformed-message ๐Ÿ

error-tag:      malformed-message
error-type:     rpc
error-severity: error
error-info:     none

A message couldn't be handled because it didn't parse correctly. For example, it's not well-formed XML, or it uses an invalid character set. The message is just broken, and the server can't read it at all. ๐Ÿ˜ตโ€๐Ÿ’ซ

This error-tag is new in :base:1.1, and it MUST NOT be sent to old clients. ๐Ÿ™…โ€โ™€๏ธ Old clients wouldn't know what to do with it, so keep it away from them. ๐Ÿซถ

Appendix B. XML Schema for NETCONF Messages Layer โœจ

This section is normative, so this is the official XML schema for the messages layer, the part that defines what hello, rpc, and rpc-reply are allowed to look like ๐ŸŽ€. Everything in here is a spec, so it's all important.

<CODE BEGINS> file "netconf.xsd"

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
           targetNamespace="urn:ietf:params:xml:ns:netconf:base:1.0"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified"
           xml:lang="en"
           version="1.1">

  <xs:annotation>
    <xs:documentation>
      This schema defines the syntax for the NETCONF Messages layer
      messages 'hello', 'rpc', and 'rpc-reply'.
    </xs:documentation>
  </xs:annotation>

  <!--
     import standard XML definitions
    -->
  <xs:import namespace="http://www.w3.org/XML/1998/namespace"
             schemaLocation="http://www.w3.org/2001/xml.xsd">
    <xs:annotation>
      <xs:documentation>
        This import accesses the xml: attribute groups for the
        xml:lang as declared on the error-message element.
      </xs:documentation>
    </xs:annotation>
  </xs:import>
  <!--
     message-id attribute
    -->

  <xs:simpleType name="messageIdType">
    <xs:restriction base="xs:string">
      <xs:maxLength value="4095"/>
    </xs:restriction>
  </xs:simpleType>
  <!--
     Types used for session-id
    -->
  <xs:simpleType name="SessionId">
    <xs:restriction base="xs:unsignedInt">
      <xs:minInclusive value="1"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="SessionIdOrZero">
    <xs:restriction base="xs:unsignedInt"/>
  </xs:simpleType>
  <!--
     <rpc> element
    -->
  <xs:complexType name="rpcType">
    <xs:sequence>
      <xs:element ref="rpcOperation"/>
    </xs:sequence>
    <xs:attribute name="message-id" type="messageIdType"
                  use="required"/>
    <!--
       Arbitrary attributes can be supplied with <rpc> element.
      -->
    <xs:anyAttribute processContents="lax"/>
  </xs:complexType>
  <xs:element name="rpc" type="rpcType"/>
  <!--
     data types and elements used to construct rpc-errors
    -->
  <xs:simpleType name="ErrorType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="transport"/>
      <xs:enumeration value="rpc"/>
      <xs:enumeration value="protocol"/>
      <xs:enumeration value="application"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="ErrorTag">
    <xs:restriction base="xs:string">
      <xs:enumeration value="in-use"/>
      <xs:enumeration value="invalid-value"/>
      <xs:enumeration value="too-big"/>
      <xs:enumeration value="missing-attribute"/>
      <xs:enumeration value="bad-attribute"/>
      <xs:enumeration value="unknown-attribute"/>
      <xs:enumeration value="missing-element"/>
      <xs:enumeration value="bad-element"/>
      <xs:enumeration value="unknown-element"/>
      <xs:enumeration value="unknown-namespace"/>
      <xs:enumeration value="access-denied"/>
      <xs:enumeration value="lock-denied"/>
      <xs:enumeration value="resource-denied"/>
      <xs:enumeration value="rollback-failed"/>
      <xs:enumeration value="data-exists"/>
      <xs:enumeration value="data-missing"/>
      <xs:enumeration value="operation-not-supported"/>
      <xs:enumeration value="operation-failed"/>
      <xs:enumeration value="partial-operation"/>
      <xs:enumeration value="malformed-message"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="ErrorSeverity">
    <xs:restriction base="xs:string">
      <xs:enumeration value="error"/>
      <xs:enumeration value="warning"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="errorInfoType">
    <xs:sequence>
      <xs:choice>
        <xs:element name="session-id" type="SessionIdOrZero"/>
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
          <xs:sequence>
            <xs:element name="bad-attribute" type="xs:QName"
                        minOccurs="0" maxOccurs="1"/>
            <xs:element name="bad-element" type="xs:QName"
                        minOccurs="0" maxOccurs="1"/>
            <xs:element name="ok-element" type="xs:QName"
                        minOccurs="0" maxOccurs="1"/>
            <xs:element name="err-element" type="xs:QName"
                        minOccurs="0" maxOccurs="1"/>
            <xs:element name="noop-element" type="xs:QName"
                        minOccurs="0" maxOccurs="1"/>
            <xs:element name="bad-namespace" type="xs:string"
                        minOccurs="0" maxOccurs="1"/>
          </xs:sequence>
        </xs:sequence>
      </xs:choice>
      <!-- elements from any other namespace are also allowed
           to follow the NETCONF elements -->
      <xs:any namespace="##other" processContents="lax"

              minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="rpcErrorType">
    <xs:sequence>
      <xs:element name="error-type" type="ErrorType"/>
      <xs:element name="error-tag" type="ErrorTag"/>
      <xs:element name="error-severity" type="ErrorSeverity"/>
      <xs:element name="error-app-tag" type="xs:string"
                  minOccurs="0"/>
      <xs:element name="error-path" type="xs:string" minOccurs="0"/>
      <xs:element name="error-message" minOccurs="0">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="xs:string">
              <xs:attribute ref="xml:lang" use="optional"/>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
      <xs:element name="error-info" type="errorInfoType"
                  minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <!--
     operation attribute used in <edit-config>
    -->
  <xs:simpleType name="editOperationType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="merge"/>
      <xs:enumeration value="replace"/>
      <xs:enumeration value="create"/>
      <xs:enumeration value="delete"/>
      <xs:enumeration value="remove"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:attribute name="operation" type="editOperationType"/>
  <!--
     <rpc-reply> element
    -->
  <xs:complexType name="rpcReplyType">
    <xs:choice>
      <xs:element name="ok"/>
      <xs:sequence>
        <xs:element ref="rpc-error"
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="rpcResponse"
                    minOccurs="0" maxOccurs="unbounded"/>

      </xs:sequence>
    </xs:choice>
    <xs:attribute name="message-id" type="messageIdType"
                  use="optional"/>
    <!--
       Any attributes supplied with <rpc> element must be returned
       on <rpc-reply>.
      -->
    <xs:anyAttribute processContents="lax"/>
  </xs:complexType>
  <xs:element name="rpc-reply" type="rpcReplyType"/>
  <!--
     <rpc-error> element
       -->
  <xs:element name="rpc-error" type="rpcErrorType"/>
  <!--
     rpcOperationType: used as a base type for all
     NETCONF operations
    -->
  <xs:complexType name="rpcOperationType"/>
  <xs:element name="rpcOperation" type="rpcOperationType"
              abstract="true"/>
  <!--
     rpcResponseType: used as a base type for all
     NETCONF responses
    -->
  <xs:complexType name="rpcResponseType"/>
  <xs:element name="rpcResponse" type="rpcResponseType"
              abstract="true"/>
  <!--
     <hello> element
    -->
  <xs:element name="hello">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="capabilities">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="capability" type="xs:anyURI"
                          maxOccurs="unbounded"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="session-id" type="SessionId"
                    minOccurs="0"/>

      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

<CODE ENDS>

Appendix C. YANG Module for NETCONF Protocol Operations โœจ

This section is normative too, and it's the YANG side of the protocol operations ๐Ÿ’…. The ietf-netconf module pulls in its typedefs from [RFC6021], so that's where the shared building blocks come from ๐Ÿงš.

<CODE BEGINS> file "ietf-netconf@2011-06-01.yang"

module ietf-netconf {

  // the namespace for NETCONF XML definitions is unchanged
  // from RFC 4741, which this document replaces
  namespace "urn:ietf:params:xml:ns:netconf:base:1.0";

  prefix nc;

  import ietf-inet-types {
    prefix inet;
  }

  organization
    "IETF NETCONF (Network Configuration) Working Group";

  contact
    "WG Web:   <http://tools.ietf.org/wg/netconf/>
     WG List:  <netconf@ietf.org>

     WG Chair: Bert Wijnen
               <bertietf@bwijnen.net>

     WG Chair: Mehmet Ersue
               <mehmet.ersue@nsn.com>

     Editor:   Martin Bjorklund
               <mbj@tail-f.com>

     Editor:   Juergen Schoenwaelder
               <j.schoenwaelder@jacobs-university.de>

     Editor:   Andy Bierman
               <andy.bierman@brocade.com>";

  description
    "NETCONF Protocol Data Types and Protocol Operations.

     Copyright (c) 2011 IETF Trust and the persons identified as
     the document authors.  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 6241; see
     the RFC itself for full legal notices.";
  revision 2011-06-01 {
    description
      "Initial revision";
    reference
      "RFC 6241: Network Configuration Protocol";
  }

  extension get-filter-element-attributes {
    description
      "If this extension is present within an 'anyxml'
       statement named 'filter', which must be conceptually
       defined within the RPC input section for the <get>
       and <get-config> protocol operations, then the
       following unqualified XML attribute is supported
       within the <filter> element, within a <get> or
       <get-config> protocol operation:

         type : optional attribute with allowed
                value strings 'subtree' and 'xpath'.
                If missing, the default value is 'subtree'.

       If the 'xpath' feature is supported, then the
       following unqualified XML attribute is
       also supported:

         select: optional attribute containing a
                 string representing an XPath expression.
                 The 'type' attribute must be equal to 'xpath'
                 if this attribute is present.";
  }

  // NETCONF capabilities defined as features
  feature writable-running {

    description
      "NETCONF :writable-running capability;
       If the server advertises the :writable-running
       capability for a session, then this feature must
       also be enabled for that session.  Otherwise,
       this feature must not be enabled.";
    reference "RFC 6241, Section 8.2";
  }

feature candidate { description "NETCONF :candidate capability; If the server advertises the :candidate capability for a session, then this feature must also be enabled for that session. Otherwise, this feature must not be enabled."; reference "RFC 6241, Section 8.3"; }

feature confirmed-commit { if-feature candidate; description "NETCONF :confirmed-commit:1.1 capability; If the server advertises the :confirmed-commit:1.1 capability for a session, then this feature must also be enabled for that session. Otherwise, this feature must not be enabled.";

reference "RFC 6241, Section 8.4"; }

feature rollback-on-error { description "NETCONF :rollback-on-error capability; If the server advertises the :rollback-on-error capability for a session, then this feature must also be enabled for that session. Otherwise, this feature must not be enabled."; reference "RFC 6241, Section 8.5"; }

feature validate { description "NETCONF :validate:1.1 capability; If the server advertises the :validate:1.1 capability for a session, then this feature must also be enabled for that session. Otherwise, this feature must not be enabled.";

reference "RFC 6241, Section 8.6"; }

feature startup { description "NETCONF :startup capability; If the server advertises the :startup capability for a session, then this feature must also be enabled for that session. Otherwise, this feature must not be enabled."; reference "RFC 6241, Section 8.7"; }

feature url { description "NETCONF :url capability; If the server advertises the :url capability for a session, then this feature must also be enabled for that session. Otherwise, this feature must not be enabled."; reference "RFC 6241, Section 8.8"; }

feature xpath { description "NETCONF :xpath capability; If the server advertises the :xpath capability for a session, then this feature must also be enabled for that session. Otherwise, this feature must not be enabled."; reference "RFC 6241, Section 8.9"; }

// NETCONF Simple Types

typedef session-id-type { type uint32 { range "1..max"; } description "NETCONF Session Id"; }

typedef session-id-or-zero-type { type uint32; description "NETCONF Session Id or Zero to indicate none"; } typedef error-tag-type { type enumeration { enum in-use { description "The request requires a resource that already is in use."; } enum invalid-value { description "The request specifies an unacceptable value for one or more parameters."; } enum too-big { description "The request or response (that would be generated) is too large for the implementation to handle."; } enum missing-attribute { description "An expected attribute is missing."; } enum bad-attribute { description "An attribute value is not correct; e.g., wrong type, out of range, pattern mismatch."; } enum unknown-attribute { description "An unexpected attribute is present."; } enum missing-element { description "An expected element is missing."; } enum bad-element { description "An element value is not correct; e.g., wrong type, out of range, pattern mismatch."; } enum unknown-element { description "An unexpected element is present."; } enum unknown-namespace { description "An unexpected namespace is present."; } enum access-denied {

description "Access to the requested protocol operation or data model is denied because authorization failed."; } enum lock-denied { description "Access to the requested lock is denied because the lock is currently held by another entity."; } enum resource-denied { description "Request could not be completed because of insufficient resources."; } enum rollback-failed { description "Request to roll back some configuration change (via rollback-on-error or <discard-changes> operations) was not completed for some reason.";

} enum data-exists { description "Request could not be completed because the relevant data model content already exists. For example, a 'create' operation was attempted on data that already exists."; } enum data-missing { description "Request could not be completed because the relevant data model content does not exist. For example, a 'delete' operation was attempted on data that does not exist."; } enum operation-not-supported { description "Request could not be completed because the requested operation is not supported by this implementation."; } enum operation-failed { description "Request could not be completed because the requested operation failed for some reason not covered by any other error condition."; } enum partial-operation { description

"This error-tag is obsolete, and SHOULD NOT be sent by servers conforming to this document."; } enum malformed-message { description "A message could not be handled because it failed to be parsed correctly. For example, the message is not well-formed XML or it uses an invalid character set."; } } description "NETCONF Error Tag"; reference "RFC 6241, Appendix A"; }

typedef error-severity-type { type enumeration { enum error { description "Error severity"; } enum warning { description "Warning severity"; } } description "NETCONF Error Severity"; reference "RFC 6241, Section 4.3"; }

typedef edit-operation-type { type enumeration { enum merge { description "The configuration data identified by the element containing this attribute is merged with the configuration at the corresponding level in the configuration datastore identified by the target parameter."; } enum replace { description "The configuration data identified by the element containing this attribute replaces any related configuration in the configuration datastore identified by the target parameter. If no such configuration data exists in the configuration datastore, it is created. Unlike a <copy-config> operation, which replaces the entire target configuration, only the configuration actually present in the config parameter is affected.";

} enum create { description "The configuration data identified by the element containing this attribute is added to the configuration if and only if the configuration data does not already exist in the configuration datastore. If the configuration data exists, an <rpc-error> element is returned with an <error-tag> value of 'data-exists'."; } enum delete { description "The configuration data identified by the element containing this attribute is deleted from the configuration if and only if the configuration data currently exists in the configuration datastore. If the configuration data does not exist, an <rpc-error> element is returned with an <error-tag> value of 'data-missing'."; } enum remove { description "The configuration data identified by the element containing this attribute is deleted from the configuration if the configuration data currently exists in the configuration datastore. If the configuration data does not exist, the 'remove' operation is silently ignored by the server."; } } default "merge"; description "NETCONF 'operation' attribute values"; reference "RFC 6241, Section 7.2"; }

// NETCONF Standard Protocol Operations

rpc get-config { description "Retrieve all or part of a specified configuration.";

reference "RFC 6241, Section 7.1";

input { container source { description

"Particular configuration to retrieve.";

choice config-source { mandatory true; description "The configuration to retrieve."; leaf candidate { if-feature candidate; type empty; description "The candidate configuration is the config source."; } leaf running { type empty; description "The running configuration is the config source."; } leaf startup { if-feature startup; type empty; description "The startup configuration is the config source. This is optional-to-implement on the server because not all servers will support filtering for this datastore."; } } }

anyxml filter { description "Subtree or XPath filter to use."; nc:get-filter-element-attributes; } }

output { anyxml data { description "Copy of the source datastore subset that matched the filter criteria (if any). An empty data container indicates that the request did not produce any results."; } } }

rpc edit-config { description

"The <edit-config> operation loads all or part of a specified configuration to the specified target configuration.";

reference "RFC 6241, Section 7.2";

input { container target { description "Particular configuration to edit.";

choice config-target { mandatory true; description "The configuration target.";

leaf candidate { if-feature candidate; type empty; description "The candidate configuration is the config target."; } leaf running { if-feature writable-running; type empty; description "The running configuration is the config source."; } } }

okay bestie, we're still in the Appendix C YANG module, and this part is all about the edit options and the rpc operations that come after them. so the default-operation leaf is where the server gets its starting vibe ๐ŸŽ€

        leaf default-operation {
          type enumeration {
            enum merge {
              description
                "The default operation is merge.";
            }
            enum replace {
              description
                "The default operation is replace.";
            }
            enum none {
              description
                "There is no default operation.";
            }
          }
          default "merge";
          description
            "The default operation to use.";

        }

        leaf test-option {
          if-feature validate;
          type enumeration {
            enum test-then-set {
              description
                "The server will test and then set if no errors.";
            }
            enum set {
              description
                "The server will set without a test first.";
            }

            enum test-only {
              description
                "The server will only test and not set, even
                 if there are no errors.";
            }
          }
          default "test-then-set";
          description
            "The test option to use.";
        }

        leaf error-option {
          type enumeration {
            enum stop-on-error {
              description
                "The server will stop on errors.";
            }
            enum continue-on-error {
              description
                "The server may continue on errors.";
            }
            enum rollback-on-error {
              description
                "The server will roll back on errors.
                 This value can only be used if the 'rollback-on-error'
                 feature is supported.";
            }
          }
          default "stop-on-error";
          description
            "The error option to use.";
        }

        choice edit-content {

          mandatory true;
          description
            "The content for the edit operation.";

          anyxml config {
            description
              "Inline Config content.";
          }
          leaf url {
            if-feature url;
            type inet:uri;
            description
              "URL-based config content.";
          }
        }
      }
    }

so default-operation defaults to merge โœจ, and test-option (only around if the validate feature is on ๐Ÿ‘€) defaults to test-then-set. error-option defaults to stop-on-error, and the rollback one only works if the rollback-on-error feature is supported ๐Ÿ’€. the edit-content choice is mandatory, so you have to pick inline config or a url ๐Ÿซถ

next up is copy-config, the operation that creates or replaces a whole configuration datastore using the contents of another complete one. it's giving big energy ๐Ÿ’…

    rpc copy-config {
      description
        "Create or replace an entire configuration datastore with the
         contents of another complete configuration datastore.";

      reference "RFC 6241, Section 7.3";

      input {
        container target {
          description
            "Particular configuration to copy to.";

          choice config-target {
            mandatory true;
            description
              "The configuration target of the copy operation.";

            leaf candidate {
              if-feature candidate;
              type empty;
              description
                "The candidate configuration is the config target.";
            }
            leaf running {
              if-feature writable-running;
              type empty;
              description
                "The running configuration is the config target.
                 This is optional-to-implement on the server.";
            }
            leaf startup {
              if-feature startup;
              type empty;
              description
                "The startup configuration is the config target.";
            }
            leaf url {
              if-feature url;
              type inet:uri;
              description
                "The URL-based configuration is the config target.";
            }
          }
        }

        container source {
          description
            "Particular configuration to copy from.";

          choice config-source {
            mandatory true;
            description
              "The configuration source for the copy operation.";

            leaf candidate {
              if-feature candidate;
              type empty;
              description
                "The candidate configuration is the config source.";
            }
            leaf running {
              type empty;
              description
                "The running configuration is the config source.";
            }
            leaf startup {
              if-feature startup;
              type empty;
              description
                "The startup configuration is the config source.";
            }
            leaf url {
              if-feature url;
              type inet:uri;
              description
                "The URL-based configuration is the config source.";
            }
            anyxml config {

              description
                "Inline Config content: <config> element.  Represents
                 an entire configuration datastore, not
                 a subset of the running datastore.";
            }
          }
        }
      }
    }

so the target and the source each get their own choice, and both are mandatory ๐Ÿฆ‹ the running target is the odd one out: it's gated by writable-running, and the description says it's optional-to-implement on the server, so not every server is going to have it ๐Ÿ™ˆ the source side also takes an inline <config> element, and that one represents a whole datastore, not just a slice of running ๐ŸŒธ

delete-config is the one that deletes a configuration datastore. the target can only be startup or a url here, so no candidate or running ๐Ÿ˜ญ

    rpc delete-config {
      description
        "Delete a configuration datastore.";

      reference "RFC 6241, Section 7.4";

      input {
        container target {
          description
            "Particular configuration to delete.";

          choice config-target {
            mandatory true;
            description
              "The configuration target to delete.";

            leaf startup {
              if-feature startup;
              type empty;
              description
                "The startup configuration is the config target.";
            }
            leaf url {
              if-feature url;
              type inet:uri;
              description
                "The URL-based configuration is the config target.";
            }
          }
        }
      }
    }

then we get lock and unlock, which are basically bouncers at the door ๐Ÿงš lock lets the client lock the configuration system of a device, and unlock releases a lock that was previously taken with lock ๐Ÿ”ฅ both take a target that can be candidate, running, or startup, and each one is its own rpc.

    rpc lock {
      description
        "The lock operation allows the client to lock the configuration
         system of a device.";

      reference "RFC 6241, Section 7.5";

      input {
        container target {
          description
            "Particular configuration to lock.";

          choice config-target {
            mandatory true;
            description
              "The configuration target to lock.";

            leaf candidate {
              if-feature candidate;
              type empty;
              description
                "The candidate configuration is the config target.";
            }
            leaf running {
              type empty;
              description
                "The running configuration is the config target.";
            }
            leaf startup {
              if-feature startup;
              type empty;
              description
                "The startup configuration is the config target.";
            }
          }
        }
      }
    }

    rpc unlock {
      description
        "The unlock operation is used to release a configuration lock,
         previously obtained with the 'lock' operation.";

      reference "RFC 6241, Section 7.6";

      input {
        container target {
          description
            "Particular configuration to unlock.";

          choice config-target {
            mandatory true;
            description
              "The configuration target to unlock.";

            leaf candidate {
              if-feature candidate;
              type empty;
              description
                "The candidate configuration is the config target.";
            }
            leaf running {
              type empty;
              description
                "The running configuration is the config target.";
            }
            leaf startup {
              if-feature startup;
              type empty;
              description
                "The startup configuration is the config target.";
            }
          }
        }
      }
    }

next is get, which retrieves running configuration and device state information. it takes an optional filter and hands back a data blob, and an empty data container means the request didn't match anything ๐Ÿ“

    rpc get {
      description
        "Retrieve running configuration and device state information.";

      reference "RFC 6241, Section 7.7";

      input {
        anyxml filter {
          description
            "This parameter specifies the portion of the system
             configuration and state data to retrieve.";
          nc:get-filter-element-attributes;
        }
      }

      output {
        anyxml data {
          description
            "Copy of the running datastore subset and/or state
             data that matched the filter criteria (if any).
             An empty data container indicates that the request did not
             produce any results.";
        }

      }
    }

and then the session-ending ones. close-session is the polite goodbye ๐Ÿ‘‹ asking for a graceful termination of a NETCONF session ๐ŸŒˆ kill-session is the rude one ๐Ÿ’€ it forces a session to end, and it needs a mandatory session-id of type session-id-type to know who's getting kicked.

    rpc close-session {
      description
        "Request graceful termination of a NETCONF session.";

      reference "RFC 6241, Section 7.8";
    }

    rpc kill-session {
      description
        "Force the termination of a NETCONF session.";

      reference "RFC 6241, Section 7.9";

      input {
        leaf session-id {
          type session-id-type;
          mandatory true;
          description
            "Particular session to kill.";
        }
      }
    }

now the commit stuff, which is honestly my favourite part ๐Ÿฅน commit is gated by the candidate feature, and it's how the candidate config becomes the device's new current config. it has three extra leaves for the confirmed commit flow, all gated by confirmed-commit: confirmed asks for one, confirm-timeout sets how long it waits (in seconds, default 600, aka 10 minutes โฐ), and persist plus persist-id make a confirmed commit stick around even if the session drops ๐Ÿซ  the persist value is a token that you have to hand back in persist-id, and if they don't match you get an invalid-value error. the description even says the token should be a random string, so no, "password123" is not the vibe ๐Ÿ™…โ€โ™€๏ธ

    rpc commit {
      if-feature candidate;

      description
        "Commit the candidate configuration as the device's new
         current configuration.";

      reference "RFC 6241, Section 8.3.4.1";

      input {
        leaf confirmed {
          if-feature confirmed-commit;
          type empty;
          description
            "Requests a confirmed commit.";
          reference "RFC 6241, Section 8.3.4.1";
        }

        leaf confirm-timeout {
          if-feature confirmed-commit;
          type uint32 {
            range "1..max";

          }
          units "seconds";
          default "600";   // 10 minutes
          description
            "The timeout interval for a confirmed commit.";
          reference "RFC 6241, Section 8.3.4.1";
        }

        leaf persist {
          if-feature confirmed-commit;
          type string;
          description
            "This parameter is used to make a confirmed commit
             persistent.  A persistent confirmed commit is not aborted
             if the NETCONF session terminates.  The only way to abort
             a persistent confirmed commit is to let the timer expire,
             or to use the <cancel-commit> operation.

             The value of this parameter is a token that must be given
             in the 'persist-id' parameter of <commit> or
             <cancel-commit> operations in order to confirm or cancel
             the persistent confirmed commit.

             The token should be a random string.";
          reference "RFC 6241, Section 8.3.4.1";
        }

        leaf persist-id {
          if-feature confirmed-commit;
          type string;
          description
            "This parameter is given in order to commit a persistent
             confirmed commit.  The value must be equal to the value
             given in the 'persist' parameter to the <commit> operation.
             If it does not match, the operation fails with an
            'invalid-value' error.";
          reference "RFC 6241, Section 8.3.4.1";
        }

      }
    }

discard-changes is basically the undo button for your candidate config: it reverts the candidate back to the current running config, and it's also gated by candidate โœจ

    rpc discard-changes {
      if-feature candidate;

      description
        "Revert the candidate configuration to the current
         running configuration.";

      reference "RFC 6241, Section 8.3.4.2";
    }

last one in this chunk is cancel-commit, which cancels an ongoing confirmed commit ๐Ÿฆ‹ if the confirmed commit is persistent, you have to pass persist-id, and it has to match the persist value, otherwise nothing happens, bestie ๐Ÿซถ

    rpc cancel-commit {
      if-feature confirmed-commit;
      description
        "This operation is used to cancel an ongoing confirmed commit.
         If the confirmed commit is persistent, the parameter
         'persist-id' must be given, and it must match the value of the
         'persist' parameter.";
      reference "RFC 6241, Section 8.4.4.1";
      input {
        leaf persist-id {
          type string;
          description
            "This parameter is given in order to cancel a persistent
             confirmed commit.  The value must be equal to the value
             given in the 'persist' parameter to the <commit> operation.
             If it does not match, the operation fails with an
            'invalid-value' error.";
        }
      }
    }

    rpc validate {
      if-feature validate;

      description
        "Validates the contents of the specified configuration.";

      reference "RFC 6241, Section 8.6.4.1";

      input {
        container source {
          description
            "Particular configuration to validate.";

          choice config-source {
            mandatory true;
            description
              "The configuration source to validate.";

            leaf candidate {
              if-feature candidate;
              type empty;
              description
                "The candidate configuration is the config source.";

            }
            leaf running {
              type empty;
              description
                "The running configuration is the config source.";
            }
            leaf startup {
              if-feature startup;
              type empty;
              description
                "The startup configuration is the config source.";
            }
            leaf url {
              if-feature url;
              type inet:uri;
              description
                "The URL-based configuration is the config source.";
            }
            anyxml config {
              description
                "Inline Config content: <config> element.  Represents
                 an entire configuration datastore, not
                 a subset of the running datastore.";
            }
          }
        }
      }
    }

  }

  <CODE ENDS>

Appendix D. Capability Template ๐ŸŽ€

okay so this section is non-normative ๐Ÿ’…, which means it's a template you can use to define protocol capabilities, not a rulebook. YANG data models usually don't need to define protocol capabilities at all, because using YANG already gets you a capability that announces the data model and any optional parts of it (called features in YANG-speak) โœจ. The capabilities template is for the times YANG just isn't powerful enough, like handling parameterized features, or when you're working with a totally different data modeling language ๐Ÿงš.

D.1. capability-name (template) ๐Ÿ’–

D.1.1. Overview

D.1.2. Dependencies

D.1.3. Capability Identifier

The {name} capability is identified by the following capability string:

      {capability uri}

D.1.4. New Operations

D.1.4.1. <op-name>

D.1.5. Modifications to Existing Operations

D.1.5.1. <op-name>

If existing operations are not modified by this capability, this section may be omitted ๐Ÿ™ˆ.

D.1.6. Interactions with Other Capabilities

If this capability does not interact with other capabilities, this section may be omitted ๐ŸŒธ.


Appendix E. Configuring Multiple Devices with NETCONF ๐Ÿฆ‹

This section is non-normative ๐Ÿซถ.

E.1. Operations on Individual Devices

Okay, picture this: you're about to push a config change to one single device. Bestie, the work involved is no joke ๐Ÿ˜ญ. Before the app can trust its change, it has to be sure the change actually went in correctly and that it didn't mess with how the device runs. The application (and the person using the application) should feel confident that their change hasn't damaged the network ๐Ÿ”ฅ.

Protecting each individual device takes a few steps:

  • Acquiring the configuration lock.
  • Checkpointing the running configuration.
  • Loading and validating the incoming configuration.
  • Changing the running configuration.
  • Testing the new configuration.
  • Making the change permanent (if desired).
  • Releasing the configuration lock.

Let's dig into each step ๐Ÿ‘€.

E.1.1. Acquiring the Configuration Lock

A lock should be acquired to prevent simultaneous updates from multiple sources ๐Ÿ”’. If multiple sources are affecting the device, the application gets hampered in both testing its change and recovering if the update fails ๐Ÿ’€. Grabbing a short-lived lock is a simple defense that keeps other parties from sneaking in unrelated changes ๐Ÿงš.

The lock can be acquired using the <lock> operation.

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <lock>
      <target>
        <running/>
      </target>
    </lock>
  </rpc>

If the :candidate capability is supported, the candidate configuration should be locked.

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <lock>
      <target>
        <candidate/>
      </target>
    </lock>
  </rpc>

E.1.2. Checkpointing the Running Configuration

The running configuration can be saved into a local file as a checkpoint before loading the new configuration ๐Ÿ“ธ. If the update fails, the configuration can be restored by reloading the checkpoint file, so you're never left stranded ๐Ÿ“.

The checkpoint file can be created using the <copy-config> operation.

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <copy-config>
      <target>
        <url>file://checkpoint.conf</url>
      </target>
      <source>
        <running/>
      </source>
    </copy-config>
  </rpc>

To restore the checkpoint file, reverse the <source> and <target> parameters ๐Ÿ”„.

E.1.3. Loading and Validating the Incoming Configuration

If the :candidate capability is supported, the configuration can be loaded onto the device without impacting the running system ๐Ÿ™Œ.

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <edit-config>
      <target>
        <candidate/>
      </target>
      <config>
        <!-- place incoming configuration changes here -->
      </config>
    </edit-config>
  </rpc>

If the device supports the :validate:1.1 capability, it will by default validate the incoming configuration when it is loaded into the candidate โœ…. To avoid this validation, pass the <test-option> parameter with the value "set". Full validation can be requested with the <validate> operation.

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <validate>
      <source>
        <candidate/>
      </source>
    </validate>
  </rpc>

E.1.4. Changing the Running Configuration

When the incoming configuration has been safely loaded onto the device and validated, it's finally ready to impact the running system ๐Ÿš€.

If the device supports the :candidate capability, use the <commit> operation to set the running configuration to the candidate configuration. Use the <confirmed> parameter to allow automatic reversion to the original configuration if connectivity to the device fails ๐Ÿ›Ÿ.

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <commit>
      <confirmed/>
      <confirm-timeout>120</confirm-timeout>
    </commit>
  </rpc>

If the candidate is not supported by the device, the incoming configuration change is loaded directly into running ๐Ÿƒ.

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <edit-config>
      <target>
        <running/>
      </target>
      <config>
        <!-- place incoming configuration changes here -->
      </config>
    </edit-config>
  </rpc>

E.1.5. Testing the New Configuration

Now that the incoming configuration has been merged into the running configuration, the application needs to gain trust that the change affected the device the way it was intended, without hurting it ๐Ÿงช. The nature of the test depends on the nature of the change and is outside the scope of this document, so no spoilers here ๐Ÿคซ.

To gain this confidence, the application can run tests of the device's operational state ๐Ÿ”. Such tests may include reachability from the system running the application (using ping), changes in reachability to the rest of the network (by comparing the device's routing table), or inspection of the particular change (looking for operational evidence of the BGP peer that was just added). It's giving thorough energy ๐Ÿ˜Œ.

E.1.6. Making the Change Permanent

When the configuration change is in place and the application has enough faith in it working properly, the application is expected to make the change permanent ๐Ÿ’Ž.

If the device supports the :startup capability, the current configuration can be saved to the startup configuration by using the startup configuration as the target of the <copy-config> operation.

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <copy-config>
      <target>
        <startup/>
      </target>
      <source>
        <running/>
      </source>
    </copy-config>
  </rpc>

If the device supports the :candidate capability and a confirmed commit was requested, the confirming commit must be sent before the timeout expires โฐ. Don't let it slip, bestie ๐Ÿ˜ญ.

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <commit/>
  </rpc>

E.1.7. Releasing the Configuration Lock

When the configuration update is complete, the lock must be released, so other applications can access the configuration again ๐Ÿ”“.

Use the <unlock> operation to release the configuration lock.

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <unlock>
      <target>
        <running/>
      </target>
    </unlock>
  </rpc>

If the :candidate capability is supported, the candidate configuration should be unlocked.

  <rpc message-id="101"
       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <unlock>
      <target>
        <candidate/>
      </target>
    </unlock>
  </rpc>

E.2. Operations on Multiple Devices โœจ

okay bestie, this one is about doing changes across a whole pile of devices at once ๐Ÿซถ and the big vibe is: transactions are expensive, so we make the windows for things going wrong smaller instead of pretending we can make them perfect ๐Ÿ’…

NETCONF gives you enough building blocks to make transaction-style operations out of, and full transactional semantics across multiple devices is prohibitively expensive ๐Ÿ˜ญ so the goal is just to shrink the size and number of failure windows ๐Ÿฆ‹

There are two classes of multi-device operations, and they're very different:

Class one is the chill one ๐ŸŒธ the operation is allowed to fail on individual devices, and the other devices do NOT have to roll back to where they started. The failure can be retried later or just reported to the user. An NTP server being added is a good example. Here the focus is on each individual device: recovering it, reporting what went wrong, and maybe scheduling another try ๐Ÿ’–

Class two is the iconic, high-stakes one ๐Ÿ‘‘ the operation has to complete on every device or be fully reversed. The network either moves into the new state or goes back to the original one, no in-between. A VPN change can touch a bunch of devices, and so can adding a class-of-service definition. If only some devices get the new definition, things break later when something references it ๐Ÿ’€

To get transactional behaviour, you take the same steps from the single-device section and run them in parallel across all the devices ๐Ÿ”ฅ Configuration locks get acquired on all target devices and held until every device is updated and the changes are made permanent ๐Ÿ”’ Configuration changes get uploaded and validated across all devices, and checkpoints get made on each device ๐Ÿงš Then the running configuration can be changed, tested, and made permanent โœจ If any step fails, the previous configurations can be restored on whichever devices were already changed ๐Ÿซถ And once the changes are either fully in or fully thrown out, the locks on each device can be released ๐ŸŽ€


Appendix F. Changes from RFC 4741 ๐ŸŒˆ

okay this is the glow-up list, aka everything that changed since RFC 4741 ๐Ÿ’… This section lists the major changes between this document and RFC 4741 โœจ

  • Added the "malformed-message" error-tag. ๐Ÿ“
  • Added "remove" enumeration value to the "operation" attribute. ๐ŸŒธ
  • Obsoleted the "partial-operation" error-tag enumeration value. ๐Ÿ’€
  • Added <persist> and <persist-id> parameters to the <commit> operation. ๐Ÿ’–
  • Updated the base protocol URI and clarified the <hello> message exchange to select and identify the base protocol version in use for a particular session. ๐Ÿฆ‹
  • Added a YANG module to model the operations and removed the operation layer from the XSD. ๐Ÿงš
  • Clarified lock behavior for the candidate datastore. ๐Ÿ”’
  • Clarified the error response server requirements for the "delete" enumeration value of the "operation" attribute. ๐Ÿ™ˆ
  • Added a namespace wildcarding mechanism for subtree filtering. ๐Ÿ’œ
  • Added a "test-only" value for the <test-option> parameter to the <edit-config> operation. ๐Ÿซถ
  • Added a <cancel-commit> operation. ๐Ÿ‘‘
  • Introduced a NETCONF username and a requirement for transport protocols to explain how a username is derived. ๐Ÿ”ฅ

Authors' Addresses ๐ŸŽ€

Rob Enns (editor) Juniper Networks

EMail: rob.enns@gmail.com

Martin Bjorklund (editor) Tail-f Systems

EMail: mbj@tail-f.com

Juergen Schoenwaelder (editor) Jacobs University

EMail: j.schoenwaelder@jacobs-university.de

Andy Bierman (editor) Brocade

EMail: andy.bierman@brocade.com

๐Ÿ“ฆ where this page comes from