RFC 6241
Network Configuration Protocol (NETCONF)
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 Notice ๐
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:
getget-configedit-configcopy-configdelete-configlockunlockclose-sessionkill-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
- ietf: rfc6241 2011-06
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms