RFC 4741
NETCONF Configuration Protocol
NETCONF Configuration Protocol π
okay bestie, this is RFC 4741 and it's all about NETCONF, the protocol for installing, changing, and deleting the configuration on network devices π₯οΈβ¨
Here's the title block tea π«: it's from the Network Working Group, it's Request for Comments: 4741 π, and the author is R. Enns, Ed. at Juniper Networks (the "Ed." means editor). It's on the Standards Track π€οΈ and it's dated December 2006 π . The title block doesn't list anything it obsoletes or updates, so no drama there π
Status of This Memo πΈ
So this doc is an Internet standards track protocol for the whole Internet community, and it's literally asking for discussion and suggestions to make it better π«Ά If you want to know where it stands officially, check the current edition of "Internet Official Protocol Standards" (STD 1) π And the memo can be distributed with no limits π
Copyright Notice π
Copyright (C) The IETF Trust (2006). π
Abstract π¦
Okay so the big idea π‘ NETCONF (defined right here) gives you ways to install, manipulate, and delete the configuration of network devices π₯οΈπ₯ The configuration data and the protocol messages are both encoded in XML (Extensible Markup Language) πβ¨ And the actual NETCONF protocol operations are built on top of a simple Remote Procedure Call (RPC) layer π Honestly so clean π
Table of Contents π
1. Introduction ....................................................5
1.1. Protocol Overview ..........................................6
1.2. Capabilities ...............................................7
1.3. Separation of Configuration and State Data .................7
2. Transport Protocol Requirements .................................8
2.1. Connection-Oriented Operation ..............................9
2.2. Authentication, Integrity, and Confidentiality .............9
2.3. Authentication .............................................9
2.4. Mandatory Transport Protocol ..............................10
3. XML Considerations .............................................10
3.1. Namespace .................................................10
3.2. No Document Type Declarations .............................10
4. RPC Model ......................................................10
4.1. <rpc> Element .............................................10
4.2. <rpc-reply> Element .......................................12
4.3. <rpc-error> Element .......................................12
4.4. <ok> Element ..............................................16
4.5. Pipelining ................................................16
5. Configuration Model ............................................16
5.1. Configuration Datastores ..................................16
5.2. Data Modeling .............................................17
6. Subtree Filtering ..............................................17
6.1. Overview ..................................................17
6.2. Subtree Filter Components .................................18
6.2.1. Namespace Selection ................................18
6.2.2. Attribute Match Expressions ........................19
6.2.3. Containment Nodes ..................................19
6.2.4. Selection Nodes ....................................20
6.2.5. Content Match Nodes ................................20
6.3. Subtree Filter Processing .................................22
6.4. Subtree Filtering Examples ................................22
6.4.1. No Filter ..........................................22
6.4.2. Empty Filter .......................................23
6.4.3. Select the Entire <users> Subtree ..................23
6.4.4. Select All <name> Elements within the
<users> Subtree ....................................25
6.4.5. One Specific <user> Entry ..........................26
6.4.6. Specific Elements from a Specific <user> Entry .....27
6.4.7. Multiple Subtrees ..................................28
6.4.8. Elements with Attribute Naming .....................29
7. Protocol Operations ............................................31
7.1. <get-config> ..............................................31
7.2. <edit-config> .............................................34
7.3. <copy-config> .............................................39
7.4. <delete-config> ...........................................41
7.5. <lock> ....................................................42
7.6. <unlock> ..................................................44
7.7. <get> .....................................................45
7.8. <close-session> ...........................................47
7.9. <kill-session> ............................................48
8. Capabilities ...................................................49
8.1. Capabilities Exchange .....................................49
8.2. Writable-Running Capability ...............................50
8.2.1. Description ........................................50
8.2.2. Dependencies .......................................50
8.2.3. Capability Identifier ..............................50
8.2.4. New Operations .....................................51
8.2.5. Modifications to Existing Operations ...............51
8.3. Candidate Configuration Capability ........................51
8.3.1. Description ........................................51
8.3.2. Dependencies .......................................52
8.3.3. Capability Identifier ..............................52
8.3.4. New Operations .....................................52
8.3.5. Modifications to Existing Operations ...............53
8.4. Confirmed Commit Capability ...............................55
8.4.1. Description ........................................55
8.4.2. Dependencies .......................................55
8.4.3. Capability Identifier ..............................56
8.4.4. New Operations .....................................56
8.4.5. Modifications to Existing Operations ...............56
8.5. Rollback on Error Capability ..............................57
8.5.1. Description ........................................57
8.5.2. Dependencies .......................................57
8.5.3. Capability Identifier ..............................57
8.5.4. New Operations .....................................57
8.5.5. Modifications to Existing Operations ...............57
8.6. Validate Capability .......................................58
8.6.1. Description ........................................58
8.6.2. Dependencies .......................................58
8.6.3. Capability Identifier ..............................58
8.6.4. New Operations .....................................58
8.7. Distinct Startup Capability ...............................60
8.7.1. Description ........................................60
8.7.2. Dependencies .......................................60
8.7.3. Capability Identifier ..............................60
8.7.4. New Operations .....................................60
8.7.5. Modifications to Existing Operations ...............60
8.8. URL Capability ............................................61
8.8.1. Description ........................................61
8.8.2. Dependencies .......................................61
8.8.3. Capability Identifier ..............................62
8.8.4. New Operations .....................................62
8.8.5. Modifications to Existing Operations ...............62
8.9. XPath Capability ..........................................63
8.9.1. Description ........................................63
8.9.2. Dependencies .......................................63
8.9.3. Capability Identifier ..............................63
8.9.4. New Operations .....................................63
8.9.5. Modifications to Existing Operations ...............63
9. Security Considerations ........................................64
10. IANA Considerations ...........................................66
10.1. NETCONF XML Namespace ....................................66
10.2. NETCONF XML Schema .......................................66
10.3. NETCONF Capability URNs ..................................66
11. Authors and Acknowledgements ..................................68
12. References ....................................................68
12.1. Normative References .....................................68
12.2. Informative References ...................................69
Appendix A. NETCONF Error List ....................................70
Appendix B. XML Schema for NETCONF RPC and Protocol Operations ....74
Appendix C. Capability Template ...................................86
C.1. capability-name (template) ................................86
C.1.1. Overview ...........................................86
C.1.2. Dependencies .......................................86
C.1.3. Capability Identifier ..............................86
C.1.4. New Operations .....................................86
C.1.5. Modifications to Existing Operations ...............86
C.1.6. Interactions with Other Capabilities ...............86
Appendix D. Configuring Multiple Devices with NETCONF ............87
D.1. Operations on Individual Devices ..........................87
D.1.1. Acquiring the Configuration Lock ...................87
D.1.2. Loading the Update .................................88
D.1.3. Validating the Incoming Configuration ..............89
D.1.4. Checkpointing the Running Configuration ............89
D.1.5. Changing the Running Configuration .................90
D.1.6. Testing the New Configuration ......................91
D.1.7. Making the Change Permanent ........................91
D.1.8. Releasing the Configuration Lock ...................92
D.2. Operations on Multiple Devices ............................92
Appendix E. Deferred Features .....................................93
1. Introduction β¨
okay so NETCONF is basically the protocol that lets you manage a network device, pull out its configuration data, and upload and tweak new config π it gives you a full, formal API for the device, so apps can send and receive whole or partial configuration data sets. literally iconic π
NETCONF runs on a remote procedure call (RPC) vibe. a client writes an RPC in XML [1] and sends it to a server over a secure, connection-oriented session. the server answers with a reply, also in XML. both the request and the response are fully described in XML DTDs or XML schemas (or both!), so both sides know exactly which syntax rules apply to the exchange π§
the key thing about NETCONF is that the management protocol mirrors the device's native functionality really closely π«Ά that keeps implementation costs down and means you get access to new features fast. apps can also reach both the syntactic and the semantic content of the device's native user interface, which is so main character energy π
NETCONF lets a client discover which protocol extensions a server supports. these "capabilities" let the client adjust its behavior to use whatever the device is offering β¨ capability definitions can be extended 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 bestie.
NETCONF is a building block in an automated configuration system πΈ XML is the lingua franca of interchange, giving you a flexible but fully specified encoding for hierarchical content. you can pair NETCONF with XML-based transformation tech like XSLT [8] to automatically generate full and partial configurations π the system can query one or more databases for info about network topologies, links, policies, customers, and services. that data can then be transformed by one or more XSLT scripts, going from a task-oriented, vendor-independent data schema into a form specific to the vendor, product, operating system, and software release. the result gets passed to the device over NETCONF. it's giving automation perfection π₯
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 [3].
1.1. Protocol Overview
NETCONF uses a simple RPC-based mechanism so a client and a server can talk to each other π the client is usually a script or application running as part of a network manager, and the server is usually a network device. in this document, "device" and "server" mean the same thing, and "client" and "application" do too π
a NETCONF session is the logical connection between a network administrator (or network configuration app) 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 those changes show up in every session. session-specific attributes only affect the session where they were changed π
NETCONF can be split conceptually into four layers π¦
Layer Example
+-------------+ +-----------------------------+
(4) | Content | | Configuration data |
+-------------+ +-----------------------------+
| |
+-------------+ +-----------------------------+
(3) | Operations | | <get-config>, <edit-config> |
+-------------+ +-----------------------------+
| |
+-------------+ +-----------------------------+
(2) | RPC | | <rpc>, <rpc-reply> |
+-------------+ +-----------------------------+
| |
+-------------+ +-----------------------------+
(1) | Transport | | BEEP, SSH, SSL, console |
| Protocol | | |
+-------------+ +-----------------------------+
- the transport protocol layer gives you a communication path between client and server π NETCONF can sit on top of any transport protocol that offers a set of basic requirements, and Section 2 covers those.
- the RPC layer is a simple, transport-independent framing mechanism for encoding RPCs β¨ Section 4 documents this protocol.
- the operations layer defines a set of base operations, invoked as RPC methods with XML-encoded parameters π Section 7 has the full list of base operations.
- the content layer is outside the scope of this document π since the configuration data being manipulated is currently proprietary, how this content is specified depends on the NETCONF implementation. a separate effort to specify a standard data definition language and standard content is expected to happen later.
1.2. 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). these URIs should follow the guidelines in Section 8, so keep that in mind β¨
capabilities augment the device's base operations, describing both extra operations and the content allowed inside them π¦ the client can discover the server's capabilities and then use any additional operations, parameters, and content those capabilities define.
a capability definition may 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 finds out what the server supports. Section 8 also lists the 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 may define standardized capabilities, and implementations may define proprietary ones. a capability URI MUST sufficiently distinguish the naming authority so names don't collide π₯
1.3. Separation of Configuration and State Data
the info you can pull from a running system is split into two classes: configuration data and state data π§ configuration data is the writable data needed to transform a system from its initial default state into its current state. state data is everything else on the system that isn't configuration data, like read-only status info and collected statistics. when a device is doing configuration operations, a few problems pop up if state data gets mixed in:
- comparing configuration data sets gets flooded with irrelevant entries, like different statistics π
- incoming data could contain nonsensical requests, like attempts to write read-only data π
- the data sets would get big π
- archived data could hold values for read-only data items, which makes restoring archived data way more complicated π₯²
to deal with all that, NETCONF knows the difference between configuration data and state data and gives you an operation for each π
the <get-config> operation retrieves configuration data only, while the <get> operation retrieves both configuration and state data.
NETCONF is focused on the info the device needs to get into its desired running state. other important, persistent data is implementation specific. for example, user files and databases are not treated as configuration data by NETCONF π«Ά
if a local database of user authentication data is stored on the device, whether it counts as configuration data is an implementation-dependent matter π
2. Transport Protocol Requirements β¨
NETCONF uses an RPC-based communication paradigm π a client sends a series of one or more RPC request operations, and the server responds with a matching series of RPC replies.
NETCONF can be layered on any transport protocol that provides the required set of functionality π¦ it isn't tied to one particular transport. instead, it allows a mapping that defines how NETCONF is implemented over a specific 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 what NETCONF needs from the underlying transport protocol π§
2.1. Connection-Oriented Operation
NETCONF is connection-oriented, so it needs a persistent connection between peers πΈ that connection must provide reliable, sequenced data delivery.
NETCONF connections are long-lived and stick around between protocol operations π that means the client can make changes to the connection's state, and those changes last for the connection's whole lifetime. for example, authentication info set for a connection stays in effect until the connection closes π
resources the client requested from the server for a particular connection MUST be automatically released when that connection closes, which makes failure recovery simpler and more robust π₯ for example, when a client acquires a lock, the lock sticks around until it's explicitly released or the server figures out the connection has been terminated. if a connection dies while the client holds a lock, the server can run whatever recovery makes sense π«Ά the lock operation gets more love in Section 7.5.
2.2. Authentication, Integrity, and Confidentiality
NETCONF connections must provide authentication, data integrity, and confidentiality π NETCONF relies on the transport protocol for this. a NETCONF peer assumes that appropriate levels of security and confidentiality are provided independently of this document π for example, connections may be encrypted in TLS [9] or SSH [10], depending on the underlying protocol.
2.3. Authentication
NETCONF connections must be authenticated π the transport protocol is responsible for authentication. the peer assumes the connection's authentication info was validated by the underlying protocol using sufficiently trustworthy mechanisms, and that the peer's identity has been sufficiently proven π¦
one goal of NETCONF is a programmatic interface to the device that closely follows the device's native interface β¨ so it's expected that the underlying protocol uses the authentication mechanisms the device already defines. for example, a device that supports RADIUS [11] should let you use RADIUS to authenticate NETCONF sessions π§
the authentication process should result in an identity whose permissions are known to the device. those permissions MUST be enforced for the rest of the NETCONF session π π₯
2.4. Mandatory Transport Protocol
A NETCONF implementation MUST support the SSH transport protocol mapping [4]. π«Ά
3. XML Considerations β¨
okay so XML is the encoding format for NETCONF π which means complex hierarchical data gets written as text you can read, save, and edit with regular text tools AND with tools made for XML specifically π§ iconic behavior tbh.
this section covers a small number of XML-related considerations for NETCONF π
3.1. Namespace
all NETCONF protocol elements are defined in this namespace π¦
urn:ietf:params:xml:ns:netconf:base:1.0
NETCONF capability names MUST be URIs [5]. NETCONF capabilities get their own moment in Section 8 πΈ
3.2. No Document Type Declarations
Document type declarations MUST NOT appear in NETCONF content. not me putting a DOCTYPE in my NETCONF content π absolutely not
4. RPC Model π
the NETCONF protocol runs on an RPC-based communication model. NETCONF peers use <rpc> and <rpc-reply> elements to provide transport protocol-independent framing of requests and responses, so the framing doesn't care which transport you're using π¦ main character energy
4.1. <rpc> Element
the <rpc> element is how a client wraps up a NETCONF request to send to the server π
the <rpc> element has a mandatory attribute "message-id" π. it's an arbitrary string picked by whoever sends the RPC, and it'll commonly be a monotonically increasing integer. the receiver doesn't decode or interpret it. it just saves it so it can be used as the "message-id" attribute on any resulting <rpc-reply> message. like this:
<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 show up on an <rpc> element, a NETCONF peer MUST return them unmodified in the <rpc-reply> element π«Ά no edits, no drama
the name and parameters of an RPC are encoded as the contents of the <rpc> element. the RPC name is an element sitting directly inside <rpc>, and any parameters go inside that element β¨
this example invokes a method called <my-own-method>, with two parameters: <my-first-parameter> set to "14", and <another-parameter> set to "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>
this one 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>
and this one 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 gets sent back in response to an <rpc> operation π
the <rpc-reply> element has a mandatory attribute "message-id", and it's equal to the "message-id" attribute of the <rpc> it's responding to. they're a matching set π―
a NETCONF peer MUST also return any additional attributes included in the <rpc> element unmodified in the <rpc-reply> element π«Ά same energy as before, we don't change the attributes
the response name and response data are encoded as the contents of the <rpc-reply> element. the reply name is an element directly inside <rpc-reply>, and any data is encoded inside that element πΈ
for example:
the following <rpc> element invokes the NETCONF <get> method and includes an additional attribute called "user-id". heads up that "user-id" is NOT in the NETCONF namespace π. the returned <rpc-reply> element sends back the "user-id" attribute along with 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
the <rpc-error> element gets sent inside <rpc-reply> messages if an error happens while the server is processing an <rpc> request π
if a server runs into multiple errors while processing an <rpc> request, the <rpc-reply> MAY contain multiple <rpc-error> elements. BUT a server isn't required to detect or report more than one <rpc-error> element when a request has multiple errors, and it isn't required to check for particular error conditions in any specific sequence π. a server MUST return an <rpc-error> element if any error conditions occur during processing, and it SHOULD return an <rpc-error> element if any warning 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 doesn't have sufficient access rights π privacy is slay
the <rpc-error> element includes the following information:
error-type: defines the conceptual layer where the error occurred. it's an enumeration, and it's one of:- transport
- rpc
- protocol
- application
error-tag: contains a string identifying the error condition. check Appendix A for the allowed values πerror-severity: contains a string identifying the error severity, as determined by the device. it's one of:- error
- warning
error-app-tag: contains a string identifying the data-model-specific or implementation-specific error condition, if one exists. this element won't be present if no appropriate application error tag can be associated with a particular error condition π«error-path: contains the absolute XPath [2] expression that identifies the element path to the node associated with the error being reported in a particular rpc-error element. this element won't be present if no appropriate payload element can be associated with a particular error condition, OR if the 'bad-element' QString returned in the 'error-info' container is enough to identify the node associated with the error. when the XPath expression is interpreted, the set of namespace declarations are the ones in scope on the rpc-error element, including the default namespace πΊοΈerror-message: contains a string suitable for human display that describes the error condition. this element won't be present if no appropriate message is provided for a particular error condition. this element SHOULD include an xml:lang attribute as defined in [1] and discussed in [12] πerror-info: contains protocol- or data-model-specific error content. this element won't 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 π«. only in this case is it acceptable for the NETCONF peer to omit the message-id attribute in the <rpc-reply> element. (yes this is the one exception, I'm screaming π)
<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 the case of returning multiple <rpc-error> elements π
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-message xml:lang="en">
MTU value 25000 is not within range 256..9192
</error-message>
<error-info>
<top xmlns="http://example.com/schema/1.2/config">
<interface>
<name>Ethernet0/0</name>
<mtu>25000</mtu>
</interface>
</top>
</error-info>
</rpc-error>
<rpc-error>
<error-type>application</error-type>
<error-tag>invalid-value</error-tag>
<error-severity>error</error-severity>
<error-message xml:lang="en">
Invalid IP address for interface Ethernet1/0
</error-message>
<error-info>
<top xmlns="http://example.com/schema/1.2/config">
<interface xc:operation="replace">
<name>Ethernet1/0</name>
<address>
<name>1.4</name>
<prefix-length>24</prefix-length>
</address>
</interface>
</top>
</error-info>
</rpc-error>
</rpc-reply>
4.4. <ok> Element
the <ok> element gets sent in <rpc-reply> messages if no errors or warnings happened while processing an <rpc> request. it's the "all good, bestie" signal β
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 π’ it's a line, no cutting
5. Configuration Model π
NETCONF provides an initial set of operations, plus a number of capabilities that can be used to extend the base π§© and NETCONF peers exchange device capabilities when the session is initiated, as described in Section 8.1 π€ ily
5.1. Configuration Datastores β¨
okay so NETCONF says there can be one or more configuration datastores, and it lets you do configuration operations on them π A configuration datastore is the complete set of configuration data a device needs to go from its initial default state to the state you actually want it in π It does not include state data or executive commands, so those are not part of it π ββοΈ
Only the <running> configuration datastore is in the base model πΈ Extra datastores can be defined by capabilities, and those only show up on devices that advertise the capabilities. No cap, it's very clear who has what π¦
- Running: 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. π
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 NETCONF π It's assumed that the application already knows the device's data model well, and that both sides understand things like the layout, containment, keying, lookup, replacement, and management of the data. Any other constraints the data model imposes are also assumed to be known π«Ά
NETCONF carries configuration data inside a <config> element that is specific to the device's data model. The protocol treats what's inside that element as opaque data, so it doesn't poke at it π The device uses capabilities to announce which data models it implements, and the capability definition spells out the operation and constraints that the data model brings with it β¨
Devices and managers can support multiple data models, both standard and proprietary ones. Mix and match, bestie π
6. Subtree Filtering π
6.1. Overview π¦
Okay this one is so cute, XML subtree filtering lets an application pick out particular XML subtrees to include in the <rpc-reply> for a <get> or <get-config> operation π There's a small set of filters for inclusion, simple content exact-match, and selection. That's enough for some useful selection, but it's also super limited π The agent doesn't need any data-model-specific semantics while processing, so implementations can stay simple and centralized π
Conceptually, a subtree filter is made of zero or more element subtrees, and those represent the filter selection criteria. At each containment level inside a subtree, the server looks at the set of sibling nodes and works out whether that node's subtree, plus the path of elements up to the root, gets included in the filter output πΈ
Every element in a particular subtree of a filter must match nodes that are present in the server's conceptual data model, no exceptions π ββοΈ XML namespaces can be declared with 'xmlns' declarations inside the filter data model. If you do that, the declared namespace must first exactly match a namespace the server supports. Prefix values for qualified namespaces don't matter when filter elements get compared to elements in the underlying data model, so you don't have to match them π§ Only data tied to a specified namespace gets included in the filter output π
Each node in a subtree filter is an inclusive filter. Only associated nodes in the underlying data model(s) inside the specified configuration datastore on the server get selected by the filter π«Ά A node has to exactly match the namespace and hierarchy of the elements in the filter data, with one twist: the filter's absolute path name gets adjusted to start from the layer below <filter> π
Response messages only contain the subtrees the filter selected. Any selection criteria that were in the request, inside a selected subtree, are also included in the response. Some elements that are written in the filter as leaf nodes will get expanded (meaning their subtrees get included) in the filter output, so keep an eye out for that π Specific data instances won't be duplicated in the response, even if the request has multiple filter subtree expressions that select the same data π₯
6.2. Subtree Filter Components π
A subtree filter is made of XML elements and their XML attributes. There are five types of components that can show up in one:
- Namespace Selection
- Attribute Match Expressions
- Containment Nodes
- Selection Nodes
- Content Match Nodes
6.2.1. Namespace Selection π§
If namespaces are used, the filter output will only include elements from the specified namespace. A namespace counts as a match (for filter purposes) if the content of the 'xmlns' attributes is the same in the filter and in the underlying data model π Heads up: namespace selection can't be used by itself. You need at least one element in the filter for any elements to be included in the output π
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 plus any child nodes (from the underlying data model) in the 'http://example.com/schema/1.2/config' namespace get included in the filter output π¦
6.2.2. Attribute Match Expressions π
An attribute that shows up in a subtree filter is part of an "attribute match expression". Any number of XML attributes, qualified or unqualified, can be present in any type of filter node π On top of the usual selection criteria for that node, the selected data has to have matching values for every attribute listed in the node. If an element isn't defined to include a specified attribute, it 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>
In this example, the <top>, <interfaces>, and <interface> elements are containment nodes, and 'ifName' is an attribute match expression. Only 'interface' nodes in the 'http://example.com/schema/1.2/config' namespace that have an 'ifName' attribute with the value 'eth0', and that sit inside 'interfaces' nodes inside 'top' nodes, get included in the filter output π
6.2.3. Containment Nodes πΈ
Nodes that contain child elements inside a subtree filter are called "containment nodes". Each child element can be any type of node, including another containment node π§ For every containment node in a subtree filter, all 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, the <top> element is a containment node π«Ά
6.2.4. Selection Nodes π
An empty leaf node inside a filter is called a "selection node", and it represents an "explicit selection" filter on the underlying data model π₯ If there are any selection nodes in 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 π± 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 this form π
Example:
<filter type="subtree">
<top xmlns="http://example.com/schema/1.2/config">
<users/>
</top>
</filter>
In this example, the <top> element is a containment node, and the <users> element is a selection node. Only 'users' nodes in the 'http://example.com/schema/1.2/config' namespace that occur 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 contains simple content is called a "content match node" π¦ It's used to select some or all of its sibling nodes for the filter output, and it represents an exact-match filter on the leaf node's element content. These constraints apply to content match nodes:
- A content match node must not contain nested elements (i.e., it must resolve to a simpleType in the XML Schema Definition (XSD)).
- Multiple content match nodes (i.e., 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 (e.g.,
<foo></foo>) will be interpreted as a selection node (e.g.,<foo/>). - Leading and trailing whitespace characters are ignored, but any whitespace characters within a block of text characters are not ignored or modified.
If all specified sibling content match nodes in a subtree filter expression are 'true', the filter output nodes get selected like this:
- Each content match node in the sibling set is included in the filter output.
- If any containment nodes are present in the sibling set, they are processed further and included if any nested filter criteria are also met.
- If any selection nodes are present in the sibling set, then all of them are included in the filter output.
- Otherwise (i.e., 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.
If any of the sibling content match node tests are 'false', then no further filter processing happens on that sibling set, and 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, the <users> and <user> nodes are both containment nodes, and <name> is a content match node. Since no sibling nodes of <name> are specified (and therefore no containment or selection nodes), all of the sibling nodes of <name> are returned in the filter output. Only 'user' nodes in the 'http://example.com/schema/1.2/config' namespace that match the element hierarchy, and for which the <name> element is equal to 'fred', get included in the filter output π«Άβ¨
6.3. Subtree Filter Processing β¨
okay so the filter output (aka the set of selected nodes) starts out totally empty π«§
each subtree filter can hold one or more data model fragments. these are basically chunks of the data model that should get picked out, along with all their child nodes, and dropped into the filter output π
the server then checks each subtree data fragment against its internal data models. if the whole fragment matches a portion of the supported data model (starting from the root all the way down to the innermost element in the filter), then that node and everything under it goes into the result data π
the server works through each sibling set (all the nodes sharing the same parent) together, going from the root down to the leaf nodes. the root elements in the filter count as one sibling set too, as long as they're in the same namespace, even though they don't share a parent. it's giving family reunion π¨βπ©βπ§
for each sibling set, the server figures out which nodes are in the filter output (or might be), and which sibling subtrees get pruned out. it first checks what types of nodes are in the set, then handles each one by its type's rules π if any nodes in the set get selected, the whole process repeats for the sibling sets under each selected node. it keeps going until every sibling set in every subtree of the filter has been handled. main character energy, the whole way through π
6.4. Subtree Filtering Examples π§
6.4.1. No Filter
leaving the filter out of a get operation returns the entire data model. literally everything, no filter, no drama π
<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 there are no content match or selection nodes in it. and no, this is not an error π it's just a quiet little request. the filter type attribute used in these examples gets more attention 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
this filter has one selection node (<users>), so just that subtree gets selected π¦ this is the fully-populated <users> data model that shows up in most of the filter examples after this one. and ngl, in a real data model the <company-info> probably wouldn't come back with the list of users for a particular host or network π
NOTE: 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>. the <top> element and its descendents are 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>
the next filter request would give the exact same result, but only because the <users> container has just one child element (<user>) π€·ββοΈ
<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 selector node (<name>) πΈ every <name> element in the same sibling set gets selected. the manager might need to know that <name> works as an instance identifier in this data structure, but the server doesn't need that meta-data to process the request. the server just vibes and does its thing β¨
<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 in the sibling set containing <name> where the value of <name> equals "fred" gets selected. one specific user, served β¨
<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 one has two containment nodes (<users>, <user>), one content match node (<name>), and two selector nodes (<type>, <full-name>) π every <type> and <full-name> in the sibling set with <name> equal to "fred" gets selected. the <company-info> element gets left out, because the sibling set contains selection nodes. selective and iconic π
<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) π¦ three little filter groups, all in one request, no cap π«Ά
the "root" subtree filter has two containment nodes (<users>, <user>), one content match node (<name>), and one selector node (<company-info>). the subtree selection criteria is met, so just the company-info subtree for "root" gets selected π
the "fred" subtree filter has three containment nodes (<users>, <user>, <company-info>), one content match node (<name>), and one selector node (<id>). the criteria is met here too, so just the <id> element inside the company-info subtree for "fred" makes it into the filter output π
the "barney" subtree filter has three containment nodes (<users>, <user>, <company-info>), two content match nodes (<name>, <type>), and one selector node (<dept>). this time the criteria is NOT met, because user "barney" isn't a "superuser" π so the whole subtree for "barney", including its parent <user> entry, gets excluded from the filter output. bye bye barney π
<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 β¨
okay bestie, in this example the filter has one containment node (<interfaces>), one attribute match expression (ifName), and one selector node (<interface>) π
. Every <interface> subtree whose ifName attribute equals "eth0" gets selected in the filter output π¦. The filter data elements and attributes must be qualified, because an unqualified ifName attribute won't count as part of the schema/1.2 namespace π.
<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>
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 π
The NETCONF protocol gives you a small set of low-level operations to manage device configurations and pull device state info π§. The base protocol covers retrieving, configuring, copying, and deleting configuration datastores. Extra operations show up depending on what the device advertises as its capabilities πΈ.
The base protocol includes these protocol operations:
getget-configedit-configcopy-configdelete-configlockunlockclose-sessionkill-session
An operation can fail for lots of reasons, including "operation not supported" π. An initiator should not assume that any operation will always succeed, so always check the return values in an RPC reply for error responses π.
The syntax and XML encoding of the protocol operations are formally defined in the XML schema in Appendix B. The next sections describe what each protocol operation actually does β¨.
7.1. <get-config> π
Description:
Retrieve all or part of a specified configuration π.
Parameters:
- source: the name of the configuration datastore being queried, such as
<running/>. - filter: the filter element identifies the portions of the device configuration to retrieve. If this element is unspecified, the entire configuration is returned π.
- The filter element may optionally contain a
"type"attribute. This attribute tells you which filtering syntax is used inside the filter element. The default filtering mechanism in NETCONF is called subtree filtering and is described in Section 6. The value"subtree"explicitly identifies this type of filtering π¦. - If the NETCONF peer supports the
:xpathcapability (Section 8.9), the value"xpath"may be used to show that the select attribute on the filter element contains an XPath expression π.
- The filter element may optionally contain a
Positive Response:
If the device can satisfy the request, the server sends an <rpc-reply> element containing a <data> element with the results of the query π«Ά.
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>
If the configuration is available in more than one format, such as XML and text, you can use an XML namespace to say which format you want π. In the next example, the client uses a specific element (<config-text>) in a specific namespace to tell the server it wants the configuration in an alternative format π
. The server may support any number of distinct formats or views into the configuration data, and the client uses the <filter> parameter to pick between them π.
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<get-config>
<source>
<running/>
</source>
<filter type="subtree">
<!-- request a text version of the configuration -->
<config-text xmlns="http://example.com/text/1.2/config"/>
</filter>
</get-config>
</rpc>
<rpc-reply message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<data>
<config-text xmlns="http://example.com/text/1.2/config">
<!-- configuration text... -->
</config-text>
</data>
</rpc-reply>
Section 6 has more examples of subtree filtering πΈ.
7.2. <edit-config> β¨
Okay so the <edit-config> operation loads all or part of a specified configuration into the specified target configuration π. You can express the new config a few ways, like a local file, a remote file, or inline. If the target configuration 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 and should identify a local configuration file π.
The device analyzes the source and target configurations and makes the requested changes β¨. It's not a full replacement like <copy-config> π. Instead, the target gets changed based on the source's data and the operations you asked for, which is lowkey so much more precise π
.
Attributes
operation:
Elements in the <config> subtree may contain an operation attribute π¦. It tells the device where in the config to do the operation, and it MAY show up on multiple elements throughout the <config> subtree π.
If you don't specify the operation attribute, the config gets merged into the configuration datastore π§.
The operation attribute has one of these values:
merge: The config data on the element with this attribute gets merged with the config at the matching level in the datastore named by the target parameter. This is the default behavior π.replace: The config data on the element with this attribute replaces any related config in the datastore named by the target parameter. Unlike a<copy-config>operation, which replaces the entire target config, only the config actually present in the config parameter gets affected π.create: The config data on the element with this attribute gets added to the configuration if and only if it doesn't already exist on the device. If it does exist, an<rpc-error>element comes back with an<error-tag>value ofdata-existsπ.delete: The config data on the element with this attribute gets deleted from the datastore named by the target parameter π.
Parameters
target:
This is the name of the configuration datastore being edited, like <running/> or <candidate/> β¨.
default-operation:
This selects the default operation (the one described in the operation attribute) for this <edit-config> request π. The default value is "merge" π«Ά.
The default-operation parameter is optional, but if you do provide it, it must have one of these values:
merge: The config data in the<config>parameter gets merged with the config at the matching level in the target datastore. This is the default behavior πΈ.replace: The config data in the<config>parameter completely replaces the config in the target datastore. This is useful for loading previously saved config data π₯.none: The target datastore is unaffected by the config in the<config>parameter, unless and until the incoming config data uses theoperationattribute to request a different operation. If the config in the<config>parameter contains data with no matching level in the target datastore, an<rpc-error>is returned with an<error-tag>value ofdata-missing. Usingnonelets operations likedeleteavoid accidentally creating the parent hierarchy of the element being deleted π.
test-option:
The test-option element may be specified only if the device advertises the :validate capability (Section 8.6) π.
The test-option element has one of these values:
test-then-set: Run a validation test before attempting to set. If validation errors occur, don't perform the<edit-config>operation. This is the default test-option π§.set: Perform a set without running a validation test first πββοΈ.
error-option:
The error-option element has one of these values:
stop-on-error: Abort the edit-config operation on the first error. This is the default error-option π.continue-on-error: Keep processing config data even when there's an error. The error gets recorded, and a negative response is generated if any errors occur π.rollback-on-error: If an error condition happens that generates an<rpc-error>element with error severity, the server stops processing the edit-config operation and restores the specified configuration to its complete state from the start of this edit-config operation π. This option requires the server to support the:rollback-on-errorcapability described in Section 8.5 π«§.
config:
This is a hierarchy of configuration data, as defined by one of the device's data models π. The contents MUST be placed in an appropriate namespace, so the device can detect the right data model π. The contents MUST also follow the constraints of that data model, as defined by its capability definition π . Capabilities are discussed in Section 8 β¨.
Positive Response
If the device can satisfy the request, an <rpc-reply> is sent containing an <ok> element π₯°.
Negative Response
An <rpc-error> response is sent if the request can't be completed for any reason π.
Example
The <edit-config> examples in this section use a simple data model π§Έ. Multiple instances of the interface element may be present, and each instance is told apart by the name element inside it π¦.
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, where the 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> πͺ
Okay so <copy-config> 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, a new one gets created, if that's allowed π±.
If a NETCONF peer supports the :url capability (Section 8.8), the <url> element can appear 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 π. A device may also 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 π«. That one's a hard no, bestie π.
Parameters
target:
This is the name of the configuration datastore to use as the destination of the copy operation π―.
source:
This is the name of the configuration datastore to use as the source of the copy operation, or the <config> element containing the configuration subtree to copy π¦.
Positive Response
If the device can 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 can't 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@example.com:passphrase/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> ποΈ
okay so delete-config is the "bye bye, datastore" operation π . It deletes a configuration datastore, but the <running> datastore is off-limits and can never be deleted π ββοΈ.
If a NETCONF peer supports the :url capability (Section 8.8), the <url> element can show up as the <target> parameter β¨.
Parameters:
- target: the name of the configuration datastore you want gone π«§
Positive Response: if the device manages to do it, you get an <rpc-reply> that includes an <ok> element π.
Negative Response: if the request can't be completed for any reason, an <rpc-error> element goes inside the <rpc-reply> π.
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> π
the lock operation is giving "do not disturb, I'm working" π«Ά. It lets a client lock a device's configuration system so nobody messes with the changes it's making. The other threats are NETCONF clients, non-NETCONF clients (like SNMP and command line interface (CLI) scripts), and human users π. These locks are meant to be short-lived, just long enough to make a change without anyone crashing the party β¨.
An attempt to lock the configuration MUST fail if an existing session or other entity already 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 the ones requested by this session π. SNMP and CLI requests that try to modify the resource MUST fail with an appropriate error π .
The lock lasts from the moment it's acquired until either it gets released or the NETCONF session closes π°οΈ. The session can close because the client explicitly closes it, or because the server closes it implicitly, based on things like the underlying transport failing or a simple inactivity timeout π₯. What counts as those criteria depends on the implementation and the underlying transport π€·ββοΈ.
The lock operation takes a mandatory parameter, target, which names the configuration that gets locked π―. While a lock is active, any other NETCONF session is blocked from using <edit-config> on the locked configuration, and from using the locked configuration as the target of a <copy-config> operation π ββοΈ. The system also makes sure that SNMP, CLI, and other non-NETCONF management operations can't change those locked resources either π‘οΈ. If you need to force a lock held by another NETCONF session to release, the <kill-session> message (at the RPC layer) can do that π₯. How to break locks held by other entities is outside the scope of this document, so we're not covering that here π.
A lock MUST not be granted if either 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 those changes haven't been committed or rolled back.
The server MUST respond with either an <ok> element or an <rpc-error> π.
A lock gets released by the system if the session holding it is terminated for any reason π§Ή.
Parameters:
- target: the name of the configuration datastore to lock π
Positive Response: if the device can satisfy the request, you get an <rpc-reply> that contains an <ok> element π.
Negative Response: if the request can't be completed for any reason, an <rpc-error> element is included in the <rpc-reply> π.
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 instead π€. Heads up: any other entity locking even a partial piece of a target will stop 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> π
the unlock operation is how you let go of a configuration lock you grabbed earlier with the <lock> operation π«§.
An unlock operation won't succeed if any of the following conditions are 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: the name of the configuration datastore to unlock ποΈ
A NETCONF client is not permitted to unlock a configuration datastore that it didn't lock π ββοΈ. Hands off, bestie π .
Positive Response: if the device can satisfy the request, you get an <rpc-reply> that contains an <ok> element πΈ.
Negative Response: if the request can't be completed for any reason, an <rpc-error> element is included in the <rpc-reply> π.
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> π
the get operation is the "show me everything (or just this bit)" move β¨. It retrieves running configuration and device state information π§.
Parameters:
- filter: this parameter picks out the portion of the system configuration and state data you want back π―. If this parameter is empty, all the device configuration and state information comes back π.
The filter element can optionally have a 'type' attribute. That attribute tells you what kind of filtering syntax is used inside the filter element π§. The default filtering mechanism in NETCONF is called subtree filtering, and it's 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" can be used to say that the select attribute of the filter element contains an XPath expression πͺ.
Positive Response: if the device can satisfy the request, you get an <rpc-reply>, and the <data> section holds the appropriate subset π.
Negative Response: if the request can't be completed for any reason, an <rpc-error> element is included in the <rpc-reply> π.
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> π
okay so <close-session> is the polite "bye, see ya" π . It requests graceful termination of a NETCONF session π«Ά.
When a NETCONF server gets a <close-session> request, it closes the session gracefully π·. It releases any locks and resources tied to the session, and gracefully closes any associated connections too π§Ή. Any NETCONF requests that show up after a <close-session> request get ignored π.
Positive Response: if the device can satisfy the request, you get an <rpc-reply> that includes an <ok> element π.
Negative Response: if the request can't be completed for any reason, an <rpc-error> element is included in the <rpc-reply> π.
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> π₯
the kill-session operation is the dramatic one π€. It forces a NETCONF session to terminate π₯.
When a NETCONF entity gets a <kill-session> request for an open session, it aborts any operations currently in process π. It also releases any locks and resources tied to that session, and closes any associated connections π .
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 βͺ.
Otherwise, the <kill-session> operation does not roll back configuration or other device state modifications made by the entity holding the lock π.
Parameters:
- session-id: the session identifier of the NETCONF session to be terminated π. If this value is equal to the current session ID, an 'invalid-value' error is returned π ββοΈ.
Positive Response: if the device can satisfy the request, you get an <rpc-reply> that includes an <ok> element πΈ.
Negative Response: if the request can't be completed for any reason, an <rpc-error> element is included in the <rpc-reply> π.
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 β¨
okay bestie, this section is all about capabilities π, which are basically the features a client or server is like "yeah, I can do that" about. A client or a server MAY implement them. Each peer advertises what it can do during an initial capabilities exchange π«Ά. You only need to understand the capabilities you might actually use, and you MUST ignore any capability the other side sends that you don't require or don't understand. No drama, just ignore it π
You can define more with the template in Appendix C β¨. Future capability definitions may get published as standards by standards bodies, or as proprietary extensions π
A NETCONF capability is identified with a URI π¦. The base ones use URNs, following the method in RFC 3553 [6]. Capabilities defined in this document look like this:
urn:ietf:params:netconf:capability:{name}:1.0
where {name} is the name of the capability. People shorten these to :{name} in chats and emails, so the foo capability has the formal name urn:ietf:params:netconf:capability:foo:1.0 and gets called ":foo" π§. The shorthand form MUST NOT be used inside the protocol π
8.1. Capabilities Exchange
Capabilities get advertised in messages that each peer sends during session establishment π. When the NETCONF session opens, each peer (both client and server) MUST send a <hello> element with a list of its capabilities. Each peer MUST send at least the base NETCONF capability, urn:ietf:params:netconf:base:1.0 β¨
A server sending the <hello> element MUST include a <session-id> element with the session ID for this NETCONF session. A client sending the <hello> element MUST NOT include a <session-id> element π
A server receiving a <session-id> element MUST NOT continue the NETCONF session. Similarly, a client that doesn't receive a <session-id> element in the server's <hello> message MUST NOT continue the NETCONF session. In both cases, the underlying transport should be closed. Not me getting ghosted by a server π
Here's an example where a server advertises the base NETCONF capability, one NETCONF capability from 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.0
</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. Nobody waits for the other person to text first, periodt π
8.2. Writable-Running Capability
8.2.1. Description
The :writable-running capability says 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 β¨
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, says that the device supports a candidate configuration datastore πΈ This is used to hold configuration data that can be messed with without touching the device's current configuration. The candidate configuration is a full configuration data set, a little workspace for building and manipulating configuration data. You can make additions, deletions, and changes to it to construct the configuration you want. A <commit> operation can happen at any time, and it sets the device's running configuration 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 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 clearly both what the client is asking for and what the server has to do. It keeps the intentions obvious, the special cases less complicated, and the interactions between operations more straightforward. For example, the :confirmed-commit capability (Section 8.4) would make no sense as a "copy confirmed" operation π Iconic logic, honestly.
The candidate configuration may be shared among multiple sessions π― Unless a client has specific information that the candidate configuration is not shared, it must assume that other sessions may be able to modify the candidate configuration at the same time. So it is prudent for a client to lock the candidate configuration before modifying it π
A 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 a 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 instructs the device to implement the configuration data 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 π
If the system doesn't have the :candidate capability, the <commit> operation isn't available π«
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/>
</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 shouldn't be committed, the <discard-changes> operation can 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 π§Ό
8.3.5. Modifications to Existing Operations
8.3.5.1. <get-config>, <edit-config>, <copy-config>, and <validate>
The candidate configuration can be used as a source or target of any <get-config>, <edit-config>, <copy-config>, or <validate> operation, as a <source> or <target> parameter π° The <candidate> element is used to indicate the candidate configuration:
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<get-config> <!-- any NETCONF operation -->
<source>
<candidate/>
</source>
</get-config>
</rpc>
8.3.5.2. <lock> and <unlock>
The candidate configuration can be locked using the <lock> operation, with 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>
Similarly, the candidate configuration is unlocked using the <candidate> element as the <target> parameter π
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<unlock>
<target>
<candidate/>
</target>
</unlock>
</rpc>
When a client fails with outstanding changes to the candidate configuration, recovery can be a lot. To make recovery easy, any outstanding changes are discarded when the lock is released, whether that's explicitly with the <unlock> operation or implicitly from a session failure π₯²
8.4. Confirmed Commit Capability
8.4.1. Description
The :confirmed-commit capability says that the server will support the <confirmed> and <confirm-timeout> parameters for the <commit> protocol operation π See Section 8.3 for more on the <commit> operation π
A confirmed commit operation MUST be reverted if a follow-up commit (called the "confirming commit") isn't issued within 600 seconds (10 minutes) β° The timeout period can be adjusted with the <confirm-timeout> element. The confirming commit can itself include a <confirmed> parameter β¨
If the session that issued the confirmed commit is terminated for any reason before the confirm timeout expires, the server MUST restore the configuration to its state before the confirmed commit was issued. π
If the device reboots for any reason before the confirm timeout expires, the server MUST restore the configuration to its state before the confirmed commit was issued. π
If a confirming commit isn't issued, the device reverts its configuration to the state it was in before the confirmed commit was issued. Note that any commit operation, including a commit that introduces additional changes to the configuration, will serve as a confirming commit π§ So if you want to cancel a confirmed commit and revert changes without waiting for the timeout, the manager can explicitly restore the configuration to its state before the confirmed commit was issued π
For shared configurations, this feature can cause other configuration changes (for example, via other NETCONF sessions) to be inadvertently altered or removed, unless the configuration locking feature is used. In other words, the lock is obtained before the edit-config operation is started π¨ Therefore, it is strongly suggested that, to use this feature with shared configuration databases, configuration locking should also be used. Protect your configs, bestie π‘οΈ
8.4.2. Dependencies
The :confirmed-commit capability is only relevant if the :candidate capability is also supported π«Ά
8.4.3. Capability Identifier
The :confirmed-commit capability is identified by the following capability string:
urn:ietf:params:netconf:capability:confirmed-commit:1.0
8.4.4. New Operations β¨
None. π«Ά Nothing new to add here, bestie.
8.4.5. Modifications to Existing Operations π οΈ
8.4.5.1. <commit>
okay so the :confirmed-commit capability gives the <commit> operation 2 extra parameters π
confirmed: this one tells the server to perform a confirmed commit operation πconfirm-timeout: the timeout period for the confirmed commit, in seconds β°. If you don't set it, it defaults to 600 seconds, so you get 10 minutes unless you say otherwise π
Here's how it looks in the wild:
<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>
8.5. Rollback on Error Capability π
8.5.1. Description
This capability says the server will support the 'rollback-on-error' value in the <error-option> parameter for the <edit-config> operation. Main character energy π
π¨ Heads up, bestie! For shared configurations, this feature can accidentally mess with other config changes (say, ones coming from other NETCONF sessions) and wipe them out or change them. The fix is to use the configuration locking feature too, meaning you grab the lock before you start the edit-config operation. So if you're using this with shared configuration databases, it is strongly suggested that you also use configuration locking. π
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 lets the 'rollback-on-error' value go into the <error-option> parameter on the <edit-config> operation. It's giving undo button π
<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 basically checking a candidate configuration for syntax errors and semantic errors before the config gets applied to the device π§
If this capability is advertised, the device supports the <validate> protocol operation and checks at least for syntax errors. On top of that, this capability supports the test-option parameter for the <edit-config> operation, and when you provide it, the device checks at least for syntax errors too π
8.6.2. Dependencies
None.
8.6.3. Capability Identifier
The :validate capability is identified by this capability string:
urn:ietf:params:netconf:capability:validate:1.0
8.6.4. New Operations
8.6.4.1. <validate>
Description:
This protocol operation validates the contents of the specified configuration. Slay π
Parameters:
source: the name of the configuration datastore being validated, such as<candidate>, or the<config>element that holds the configuration subtree you want validated πΈ
Positive Response:
If the device can satisfy the request, you get an <rpc-reply> containing 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 π
A validate operation can fail for any of these reasons:
- Syntax errors
- Missing parameters
- References to undefined configuration data
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.7. Distinct Startup Capability π
8.7.1. Description
The device keeps separate running and startup configuration datastores, so it's a two-separate-besties situation π§ Operations that affect the running configuration will not be automatically copied to the startup configuration. To update the startup configuration to match the running configuration, an explicit <copy-config> operation from <running> to <startup> must be invoked. NETCONF protocol operations refer to the startup datastore using 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 additional values π₯
+--------------------+--------------------------+-------------------+
| Operation | Parameters | Notes |
+--------------------+--------------------------+-------------------+
| <get-config> | <source> | |
| | | |
| <copy-config> | <source> <target> | |
| | | |
| <lock> | <target> | |
| | | |
| <unlock> | <target> | |
| | | |
| <validate> | <source> | If :validate is |
| | | advertised |
+--------------------+--------------------------+-------------------+
To save the startup configuration, use the copy-config operation to copy the <running> configuration datastore to the <startup> configuration datastore πΎ
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<copy-config>
<source>
<running/>
</source>
<target>
<startup/>
</target>
</copy-config>
</rpc>
8.8. URL Capability π
8.8.1. Description
The NETCONF peer can accept the <url> element in <source> and <target> parameters. The capability is further identified by URL arguments that show which URL schemes are supported πΈ
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, assigned a comma-separated list of scheme names that tells 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 changes the <edit-config> operation so it accepts the <url> element as an alternative to the <config> parameter. If the <url> element is specified, then it should identify a local configuration file π
8.8.5.2. <copy-config>
The :url capability changes the <copy-config> operation so it accepts the <url> element as the value of the <source> and the <target> parameters π
8.8.5.3. <delete-config>
The :url capability changes the <delete-config> operation so it accepts the <url> element as the value of the <target> parameters. If this parameter contains a URL, then it should identify a local configuration file ποΈ
8.8.5.4. <validate>
The :url capability changes the <validate> operation so it accepts the <url> element as the value of the <source> parameter β
8.9. XPath Capability π§
8.9.1. Description
The XPath capability tells you the NETCONF peer supports using XPath expressions in the <filter> element. XPath is described in [2].
The XPath expression must return a node-set. π
The XPath expression is evaluated in a context where the context node is the root node, and the set of namespace declarations are those in scope on the filter element, including the default namespace. Very precise, very iconic π
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 changes the <get> and <get-config> operations so they accept the value "xpath" in the type attribute of the filter element. When the type attribute 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 returned data. The filter element itself MUST be empty in this case π
For example:
<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 type="xpath" select="top/users/user[name='fred']"/>
</get-config>
</rpc>
9. Security Considerations πβ¨
Okay bestie, first things first: this document does NOT specify an authorization scheme π , because authorization should be tied to a meta-data model or a data model. Implementors SHOULD provide a comprehensive authorization scheme with NETCONF. π«Ά
Authorization of individual users through the NETCONF server may or may not map 1:1 onto other interfaces π. Why? First, the data models might be incompatible. Second, you might want to authorize based on what the transport protocol layer already offers (TELNET, SSH, etc).
Also, operations on configurations can have unintended consequences if they aren't guarded by the global lock on the files or objects being operated on π. Picture this: a partially complete access list gets committed from a candidate configuration, and the lock owner has no idea. That could leave the device either insecure or inaccessible, if the lock on the candidate configuration doesn't also cover the <copy-config> operation when it's applied to that candidate configuration. Yikes. π
Configuration information is sensitive by its very nature π₯. Sending it in the clear, without integrity checking, leaves devices wide open to classic eavesdropping attacks. Configs often hold passwords, user names, service descriptions, and topological information, and all of that is sensitive. So this protocol should be implemented carefully, with real attention to every kind of attack you'd expect against any other management interface. π§
The protocol, therefore, must minimally support options for both confidentiality and authentication π. It's anticipated that the underlying protocol (SSH, BEEP, etc) will provide both confidentiality and authentication, as is required. It's further expected that the identity of each end of a NETCONF session will be available to the other end, so it can decide authorization for any given request. You could also easily imagine extra information, like transport and encryption methods, being made available for authorization purposes. NETCONF itself provides no means to re-authenticate, much less authenticate. All of that happens at lower layers. π
Different environments may well allow different rights before and after authentication, so an authorization model is not specified in this document π¦. When an operation isn't properly authorized, a simple "access denied" is sufficient. And note that authorization information may itself be exchanged as configuration information, which is all the more reason to make sure the connection is secure. π
That said, some operations are clearly more sensitive by nature than others π. For instance, <copy-config> to the startup or running configurations is clearly not a normal provisioning operation, whereas <edit-config> totally is. Global operations like these MUST disallow changing information that an individual isn't authorized to change. For example, say user A isn't allowed to configure an IP address on an interface, but user B has configured an IP address on an interface in the <candidate> configuration. Then user A must not be allowed to commit the <candidate> configuration. Main character energy for user B, a hard no for user A. π ββοΈ
Similarly, just because someone says "go write a configuration through the URL capability at a particular place", that doesn't mean an element should do it without proper authorization. Nice try. π
The <lock> operation shows that NETCONF is intended for use by systems that have at least some trust in the administrator π€. As specified in this document, it's possible to lock portions of a configuration that a principal might not otherwise have access to, because after all, the entire configuration is locked. π¬ To deal with this, there are two approaches. You can kill another NETCONF session programmatically from within NETCONF, if you know the session identifier of the offending session. The other way to break a lock is to provide a function within the device's native user interface. Both of these mechanisms suffer from a race condition, which might be eased by removing the offending user from an AAA server. However, that solution isn't useful in all deployment scenarios, like the ones where SSH public/private key pairs are used. ποΈ
10. IANA Considerations πΈ
10.1. NETCONF XML Namespace
This document registers a URI for the NETCONF XML namespace in the IETF XML registry [7] π.
Following the format in RFC 3688, IANA has made the following registration:
- 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 [7] π.
Following the format in RFC 3688, IANA has made the following registration:
- URI:
urn:ietf:params:xml:schema:netconf - Registrant Contact: The IESG.
- XML: Appendix B of this document.
10.3. NETCONF Capability URNs
This document creates a registry that allocates NETCONF capability identifiers π¦. Additions to the registry require IETF Standards Action.
The initial content of the registry contains the capability URNs defined in Section 8 β¨.
Following the guidelines in RFC 3553 [6], IANA assigned a NETCONF sub-namespace as follows:
- Registry name: netconf
- Specification: Section 8 of this document.
- Repository: The following table.
+--------------------+----------------------------------------------+
| Index | Capability Identifier |
+--------------------+----------------------------------------------+
| :writable-running | urn:ietf:params:netconf:capability:writable- |
| | running:1.0 |
| | |
| :candidate | urn:ietf:params:netconf:capability:candidate |
| | :1.0 |
| | |
| :confirmed-commit | urn:ietf:params:netconf:capability:confirmed |
| | -commit:1.0 |
| | |
| :rollback-on-error | urn:ietf:params:netconf:capability:rollback- |
| | on-error:1.0 |
| | |
| :validate | urn:ietf:params:netconf:capability:validate: |
| | 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 |
+--------------------+----------------------------------------------+
- Index value: The capability name.
11. Authors and Acknowledgements π
This document was written by:
- Andy Bierman
- Ken Crozier, Cisco Systems
- Rob Enns, Juniper Networks
- Ted Goddard, IceSoft
- Eliot Lear, Cisco Systems
- Phil Shafer, Juniper Networks
- Steve Waldbusser
- Margaret Wasserman, ThingMagic
The authors would like to acknowledge the members of the NETCONF working group π«Ά. In particular, they'd like to thank Wes Hardaker for his persistence and patience in helping them with security considerations. They'd also like to thank Randy Presuhn, Sharon Chisholm, Juergen Schoenwalder, Glenn Waters, David Perkins, Weijing Chen, Simon Leinen, Keith Allen, and Dave Harrington for all of their valuable advice π.
12. References π
12.1. Normative References
- [1] Sperberg-McQueen, C., Paoli, J., Maler, E., and T. Bray, "Extensible Markup Language (XML) 1.0 (Second Edition)", World Wide Web Consortium,
http://www.w3.org/TR/2000/REC-xml-20001006, October 2000. - [2] Clark, J. and S. DeRose, "XML Path Language (XPath) Version 1.0", World Wide Web Consortium Recommendation,
http://www.w3.org/TR/1999/REC-xpath-19991116, November 1999. - [3] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
- [4] Wasserman, M. and T. Goddard, "Using the NETCONF Configuration Protocol over Secure SHell (SSH)", RFC 4742, December 2006.
- [5] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, January 2005.
- [6] Mealling, M., Masinter, L., Hardie, T., and G. Klyne, "An IETF URN Sub-namespace for Registered Protocol Parameters", BCP 73, RFC 3553, June 2003.
- [7] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688, January 2004.
12.2. Informative References
- [8] Clark, J., "XSL Transformations (XSLT) Version 1.0", World Wide Web Consortium Recommendation,
http://www.w3.org/TR/1999/REC-xslt-19991116, November 1999. - [9] Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.1", RFC 4346, April 2006.
- [10] Ylonen, T. and C. Lonvick, "The Secure Shell (SSH) Protocol Architecture", RFC 4251, January 2006.
- [11] Rigney, C., Willens, S., Rubens, A., and W. Simpson, "Remote Authentication Dial In User Service (RADIUS)", RFC 2865, June 2000.
- [12] 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.
Appendix A. NETCONF Error List β¨
okay bestie, this is the full menu of everything that can go wrong in NETCONF π every error gets a Tag, an Error-type (which layers it can show up in), a Severity, its Error-info and a Description. the entries are below, exactly as written π«Ά
Tag: in-use
Error-type: protocol, application
Severity: error
Error-info: none
Description: The request requires a resource that already in use.
Tag: invalid-value
Error-type: protocol, application
Severity: error
Error-info: none
Description: The request specifies an unacceptable value for one
or more parameters.
Tag: too-big
Error-type: transport, rpc, protocol, application
Severity: error
Error-info: none
Description: The request or response (that would be generated) is too
large for the implementation to handle.
Tag: missing-attribute
Error-type: rpc, protocol, application
Severity: error
Error-info: <bad-attribute> : name of the missing attribute
<bad-element> : name of the element that should
contain the missing attribute
Description: An expected attribute is missing.
Tag: bad-attribute
Error-type: rpc, protocol, application
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
Description: An attribute value is not correct; e.g., wrong type,
out of range, pattern mismatch.
Tag: unknown-attribute
Error-type: rpc, protocol, application
Severity: error
Error-info: <bad-attribute> : name of the unexpected attribute
<bad-element> : name of the element that contains
the unexpected attribute
Description: An unexpected attribute is present.
Tag: missing-element
Error-type: rpc, protocol, application
Severity: error
Error-info: <bad-element> : name of the missing element
Description: An expected element is missing.
Tag: bad-element
Error-type: rpc, protocol, application
Severity: error
Error-info: <bad-element> : name of the element w/ bad value
Description: An element value is not correct; e.g., wrong type,
out of range, pattern mismatch.
Tag: unknown-element
Error-type: rpc, protocol, application
Severity: error
Error-info: <bad-element> : name of the unexpected element
Description: An unexpected element is present.
Tag: unknown-namespace
Error-type: rpc, protocol, application
Severity: error
Error-info: <bad-element> : name of the element that contains
the unexpected namespace
<bad-namespace> : name of the unexpected namespace
Description: An unexpected namespace is present.
Tag: access-denied
Error-type: rpc, protocol, application
Severity: error
Error-info: none
Description: Access to the requested RPC, protocol operation,
or data model is denied because authorization failed.
Tag: lock-denied
Error-type: protocol
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
Description: Access to the requested lock is denied because the
lock is currently held by another entity.
Tag: resource-denied
Error-type: transport, rpc, protocol, application
Severity: error
Error-info: none
Description: Request could not be completed because of insufficient
resources.
Tag: rollback-failed
Error-type: protocol, application
Severity: error
Error-info: none
Description: Request to rollback some configuration change (via
rollback-on-error or discard-changes operations) was
not completed for some reason.
Tag: data-exists
Error-type: application
Severity: error
Error-info: none
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.
Tag: data-missing
Error-type: application
Severity: error
Error-info: none
Description: Request could not be completed because the relevant
data model content does not exist. For example,
a 'replace' or 'delete' operation was attempted on
data that does not exist.
Tag: operation-not-supported
Error-type: rpc, protocol, application
Severity: error
Error-info: none
Description: Request could not be completed because the requested
operation is not supported by this implementation.
Tag: operation-failed
Error-type: rpc, protocol, application
Severity: error
Error-info: none
Description: Request could not be completed because the requested
operation failed for some reason not covered by
any other error condition.
Tag: partial-operation
Error-type: application
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.
Description: Some part of the requested operation failed or was
not attempted for some reason. Full cleanup has
not been performed (e.g., rollback not supported)
by the server. The error-info container is used
to identify which portions of the application
data model content for which the requested operation
has succeeded (<ok-element>), failed (<bad-element>),
or not been attempted (<noop-element>).
Appendix B. XML Schema for NETCONF RPC and Protocol Operations π
this is the XML Schema for the RPC and protocol operations, and it's gorgeous π it starts right here, between the BEGIN marker and the code, exactly as written π
BEGIN
<?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">
<!--
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:restriction>
</xs:simpleType>
<xs:simpleType name="ErrorSeverity">
<xs:restriction base="xs:string">
<xs:enumeration value="error"/>
<xs:enumeration value="warning"/>
</xs:restriction>
okay so we're still deep in the schema, and bestie, the error stuff is giving structure π every error can carry a little bundle of info, and the rpc-reply wrapper is basically the whole vibe β¨
</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:QName"
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"
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>
<!--
<rpc-reply> element
-->
<xs:complexType name="rpcReplyType">
<xs:choice>
<xs:element name="ok"/>
<xs:group ref="rpcResponse"/>
</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:group name="rpcResponse">
<xs:sequence>
<xs:element name="rpc-error" type="rpcErrorType"
minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="data" type="dataInlineType" minOccurs="0"/>
</xs:sequence>
</xs:group>
<xs:element name="rpc-reply" type="rpcReplyType"/>
<!--
Type for <test-option> parameter to <edit-config>
-->
<xs:simpleType name="testOptionType">
<xs:restriction base="xs:string">
<xs:enumeration value="test-then-set"/>
<xs:enumeration value="set"/>
</xs:restriction>
</xs:simpleType>
<!--
Type for <error-option> parameter to <edit-config>
-->
<xs:simpleType name="errorOptionType">
<xs:restriction base="xs:string">
<xs:annotation>
<xs:documentation>
Use of the rollback-on-error value requires
the :rollback-on-error capability.
</xs:documentation>
</xs:annotation>
<xs:enumeration value="stop-on-error"/>
<xs:enumeration value="continue-on-error"/>
<xs:enumeration value="rollback-on-error"/>
</xs:restriction>
</xs:simpleType>
<!--
rpcOperationType: used as a base type for all
NETCONF operations
-->
<xs:complexType name="rpcOperationType"/>
<xs:element name="rpcOperation"
type="rpcOperationType" abstract="true"/>
<!--
Type for <config> element
-->
<xs:complexType name="configInlineType">
<xs:complexContent>
<xs:extension base="xs:anyType"/>
</xs:complexContent>
</xs:complexType>
<!--
Type for <data> element
-->
<xs:complexType name="dataInlineType">
<xs:complexContent>
<xs:extension base="xs:anyType"/>
</xs:complexContent>
</xs:complexType>
<!--
Type for <filter> element
-->
<xs:simpleType name="FilterType">
<xs:restriction base="xs:string">
<xs:annotation>
<xs:documentation>
Use of the xpath value requires the :xpath capability.
</xs:documentation>
</xs:annotation>
<xs:enumeration value="subtree"/>
<xs:enumeration value="xpath"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="filterInlineType">
<xs:complexContent>
<xs:extension base="xs:anyType">
<xs:attribute name="type"
type="FilterType" default="subtree"/>
<!-- if type="xpath", the xpath expression
appears in the select element -->
<xs:attribute name="select"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!--
configuration datastore names
-->
<xs:annotation>
<xs:documentation>
The startup datastore can be used only if the :startup
capability is advertised. The candidate datastore can
be used only if the :candidate datastore is advertised.
</xs:documentation>
</xs:annotation>
<xs:complexType name="configNameType"/>
<xs:element name="config-name"
type="configNameType" abstract="true"/>
<xs:element name="startup" type="configNameType"
substitutionGroup="config-name"/>
<xs:element name="candidate" type="configNameType"
substitutionGroup="config-name"/>
<xs:element name="running" type="configNameType"
substitutionGroup="config-name"/>
<!--
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:restriction>
</xs:simpleType>
<xs:attribute name="operation"
type="editOperationType" default="merge"/>
<!--
<default-operation> element
-->
<xs:simpleType name="defaultOperationType">
<xs:restriction base="xs:string">
<xs:enumeration value="merge"/>
<xs:enumeration value="replace"/>
<xs:enumeration value="none"/>
</xs:restriction>
</xs:simpleType>
<!--
<url> element
-->
<xs:complexType name="configURIType">
<xs:annotation>
<xs:documentation>
Use of the url element requires the :url capability.
</xs:documentation>
</xs:annotation>
<xs:simpleContent>
<xs:extension base="xs:anyURI"/>
</xs:simpleContent>
</xs:complexType>
<!--
Type for <source> element (except <get-config>)
-->
<xs:complexType name="rpcOperationSourceType">
<xs:choice>
<xs:element name="config" type="configInlineType"/>
<xs:element ref="config-name"/>
<xs:element name="url" type="configURIType"/>
</xs:choice>
</xs:complexType>
<!--
Type for <source> element in <get-config>
-->
<xs:complexType name="getConfigSourceType">
<xs:choice>
<xs:element ref="config-name"/>
<xs:element name="url" type="configURIType"/>
</xs:choice>
</xs:complexType>
<!--
Type for <target> element
-->
<xs:complexType name="rpcOperationTargetType">
<xs:choice>
<xs:element ref="config-name"/>
<xs:element name="url" type="configURIType"/>
</xs:choice>
</xs:complexType>
<!--
<get-config> operation
-->
<xs:complexType name="getConfigType">
<xs:complexContent>
<xs:extension base="rpcOperationType">
<xs:sequence>
<xs:element name="source"
type="getConfigSourceType"/>
<xs:element name="filter"
type="filterInlineType" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="get-config" type="getConfigType"
substitutionGroup="rpcOperation"/>
<!--
<edit-config> operation
-->
<xs:complexType name="editConfigType">
<xs:complexContent>
<xs:extension base="rpcOperationType">
<xs:sequence>
<xs:annotation>
<xs:documentation>
Use of the test-option element requires the
:validate capability. Use of the url element
requires the :url capability.
</xs:documentation>
</xs:annotation>
<xs:element name="target"
type="rpcOperationTargetType"/>
<xs:element name="default-operation"
type="defaultOperationType"
minOccurs="0"/>
<xs:element name="test-option"
type="testOptionType"
minOccurs="0"/>
<xs:element name="error-option"
type="errorOptionType"
minOccurs="0"/>
<xs:choice>
<xs:element name="config"
type="configInlineType"/>
<xs:element name="url"
type="configURIType"/>
</xs:choice>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="edit-config" type="editConfigType"
substitutionGroup="rpcOperation"/>
<!--
<copy-config> operation
-->
<xs:complexType name="copyConfigType">
<xs:complexContent>
<xs:extension base="rpcOperationType">
<xs:sequence>
<xs:element name="target" type="rpcOperationTargetType"/>
<xs:element name="source" type="rpcOperationSourceType"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="copy-config" type="copyConfigType"
substitutionGroup="rpcOperation"/>
<!--
<delete-config> operation
-->
<xs:complexType name="deleteConfigType">
<xs:complexContent>
<xs:extension base="rpcOperationType">
<xs:sequence>
<xs:element name="target" type="rpcOperationTargetType"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="delete-config" type="deleteConfigType"
substitutionGroup="rpcOperation"/>
<!--
<get> operation
-->
<xs:complexType name="getType">
<xs:complexContent>
<xs:extension base="rpcOperationType">
<xs:sequence>
<xs:element name="filter"
type="filterInlineType" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="get" type="getType"
substitutionGroup="rpcOperation"/>
<!--
<lock> operation
-->
<xs:complexType name="lockType">
<xs:complexContent>
<xs:extension base="rpcOperationType">
<xs:sequence>
<xs:element name="target"
type="rpcOperationTargetType"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="lock" type="lockType"
substitutionGroup="rpcOperation"/>
<!--
<unlock> operation
-->
<xs:complexType name="unlockType">
<xs:complexContent>
<xs:extension base="rpcOperationType">
<xs:sequence>
<xs:element name="target" type="rpcOperationTargetType"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="unlock" type="unlockType"
substitutionGroup="rpcOperation"/>
<!--
<validate> operation
-->
<xs:complexType name="validateType">
<xs:annotation>
<xs:documentation>
The validate operation requires the :validate capability.
</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="rpcOperationType">
<xs:sequence>
<xs:element name="source" type="rpcOperationSourceType"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="validate" type="validateType"
substitutionGroup="rpcOperation"/>
<!--
<commit> operation
-->
<xs:simpleType name="confirmTimeoutType">
<xs:restriction base="xs:unsignedInt">
<xs:minInclusive value="1"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="commitType">
<xs:annotation>
<xs:documentation>
The commit operation requires the :candidate capability.
</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="rpcOperationType">
<xs:sequence>
<xs:annotation>
<xs:documentation>
Use of the confirmed and confirm-timeout elements
requires the :confirmed-commit capability.
</xs:documentation>
</xs:annotation>
<xs:element name="confirmed" minOccurs="0"/>
<xs:element name="confirm-timeout"
type="confirmTimeoutType"
minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="commit" type="commitType"
substitutionGroup="rpcOperation"/>
<!--
<discard-changes> operation
-->
<xs:complexType name="discardChangesType">
<xs:annotation>
<xs:documentation>
The discard-changes operation requires the
:candidate capability.
</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="rpcOperationType"/>
</xs:complexContent>
</xs:complexType>
<xs:element name="discard-changes"
type="discardChangesType"
substitutionGroup="rpcOperation"/>
<!--
<close-session> operation
-->
<xs:complexType name="closeSessionType">
<xs:complexContent>
<xs:extension base="rpcOperationType"/>
</xs:complexContent>
</xs:complexType>
<xs:element name="close-session" type="closeSessionType"
substitutionGroup="rpcOperation"/>
<!--
<kill-session> operation
-->
<xs:complexType name="killSessionType">
<xs:complexContent>
<xs:extension base="rpcOperationType">
<xs:sequence>
<xs:element name="session-id"
type="SessionId" minOccurs="1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="kill-session" type="killSessionType"
substitutionGroup="rpcOperation"/>
<!--
<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>
END
Appendix C. Capability Template π
C.1. capability-name (template) π
C.1.1. Overview β¨
C.1.2. Dependencies π«Ά
C.1.3. Capability Identifier π¦
The {name} capability is identified by the following capability string:
{capability uri}
C.1.4. New Operations πΈ
C.1.4.1. <op-name> π
C.1.5. Modifications to Existing Operations π§
C.1.5.1. <op-name> π
If existing operations are not modified by this capability, this section may be omitted.
C.1.6. Interactions with Other Capabilities π
If this capability does not interact with other capabilities, this section may be omitted.
Appendix D. Configuring Multiple Devices with NETCONF π
D.1. Operations on Individual Devices π₯
okay so bestie, picture this: you're about to change the config on ONE device. Main character energy, right? π The app needs to build trust that its change went in correctly and didn't mess up the device. The app (and the person using it) should feel totally confident that the change didn't wreck the network. π«Ά
Protecting each individual device is a whole process, honestly iconic β¨:
- Acquiring the configuration lock.
- Loading the update.
- Validating the incoming configuration.
- Checkpointing the running configuration.
- Changing the running configuration.
- Testing the new configuration.
- Making the change permanent (if desired).
- Releasing the configuration lock.
Okay let's go through each step, one at a time π¦
D.1.1. Acquiring the Configuration Lock π
Okay so a lock should be acquired to stop simultaneous updates from multiple sources. π If multiple sources are touching the device, the app gets hampered in both testing its change and recovering if the update fails π Grabbing a short-lived lock is a simple move that keeps other parties from sneaking in unrelated changes. Slay π
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>
D.1.2. Loading the Update π§
The configuration can be loaded onto the device without impacting the running system. Literally no disruption πΈ If the :url capability is supported and lists "file" as a supported scheme, the incoming changes can go into a local file. π
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<copy-config>
<target>
<url>file://incoming.conf</url>
</target>
<source>
<config>
<!-- place incoming configuration here -->
</config>
</source>
</copy-config>
</rpc>
If the :candidate capability is supported, the candidate configuration can be used instead. π¦
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<edit-config>
<target>
<candidate/>
</target>
<config>
<!-- place incoming configuration here -->
</config>
</edit-config>
</rpc>
Oops, if the update fails, the user file can be deleted using the<delete-config>operation, or the candidate configuration can be reverted using the<discard-changes>operation. Keep that plan handy, bestie π¨
D.1.3. Validating the Incoming Configuration π
Before the incoming configuration is applied, validating it is often useful. π Validation lets the app feel confident the change will succeed, and it makes recovery way easier if it doesn't. Smart, right? π
If the device supports the :url capability and lists "file" as a supported scheme, use the <validate> operation with the <source> parameter set to the proper user file: β¨
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<validate>
<source>
<url>file://incoming.conf</url>
</source>
</validate>
</rpc>
If the device supports the :candidate capability, some validation happens as part of loading the incoming configuration into the candidate. π«Ά For full validation, either pass the <validate> parameter during the <edit-config> step given above, or use the <validate> operation with the <source> parameter set to <candidate>. Choose your fighter π
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<validate>
<source>
<candidate/>
</source>
</validate>
</rpc>
D.1.4. 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 that checkpoint file. Safety net vibes π§Έ
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. π Okay that's the vibe for this part, bestie! π«Ά
D.1.5. Changing the Running Configuration β¨
Okay so, once the incoming configuration is safely loaded onto the device and validated, it's finally time to touch the running system. π
If the device supports the :url capability and lists "file" as a supported scheme, use the <edit-config> operation to merge the incoming configuration into the running configuration.
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<edit-config>
<target>
<running/>
</target>
<config>
<url>file://incoming.conf</url>
</config>
</edit-config>
</rpc>
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>
D.1.6. Testing the New Configuration π§ͺ
Now that the incoming configuration is merged into the running configuration, the application needs to gain trust that the change did what it was supposed to do to the device, and didn't mess anything else up. Main character energy, but make it verified. π
To build that confidence, the application can run tests of the operational state of the device. The nature of the test depends on the nature of the change, and that part is outside the scope of this document. 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). π¦
D.1.7. Making the Change Permanent π
Once the configuration change is in place and the application has enough faith that it works properly, the application should 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 that timer win, bestie. β°
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<commit/>
</rpc>
D.1.8. Releasing the Configuration Lock π
When the configuration update is complete, the lock must be released so other applications can access the configuration. Sharing is caring. π
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>
D.2. Operations on Multiple Devices π
Okay, this is where it gets spicy. When a configuration change needs updates across a bunch of devices, you have to be careful about providing the required transaction semantics. NETCONF has enough primitives to build transaction-oriented operations on top of it. Providing complete transactional semantics across multiple devices is prohibitively expensive, but you can shrink the size and number of windows for failure scenarios. π
There are two classes of multi-device operations. The first class lets the operation fail on individual devices without requiring every device to revert to its original state. The operation can be retried later, or its failure can simply be reported to the user. An example is adding an NTP server. For this class, failure avoidance and recovery focus on the individual device, which means recovering the device, reporting the failure, and perhaps scheduling another attempt. π§
The second class is the more interesting one. The operation should complete on all devices or be fully reversed, so the network either transforms into a new state or resets to its original state. For example, a change to a VPN may require updates to a number of devices. Another example is adding a class-of-service definition. Leaving the network with only some devices updated with the new definition will lead to future failures when the definition gets referenced. Not it. π
To give transactional semantics, the same steps used in single-device operations (listed above) are used, but they're performed in parallel across all devices. Configuration locks should be acquired on all target devices and kept until all devices are updated and the changes are made permanent. Configuration changes should be uploaded and validated across all devices. Checkpoints should be made on each device. Then the running configuration can be changed, tested, and made permanent. If any of these steps fail, the previous configurations can be restored on any devices where they were changed. Once the changes are either fully implemented or fully discarded, the locks on each device can be released. π
Appendix E. Deferred Features πΈ
The following features have been deferred until a future revision of this document. Future me's problem, iykyk. π
- Granular locking of configuration objects.
- Named configuration files/datastores.
- Support for multiple NETCONF channels.
- Asynchronous notifications.
- Explicit protocol support for rollback of configuration changes to prior versions.
Editor's Address π
Rob Enns
Juniper Networks
1194 North Mathilda Ave
Sunnyvale, CA 94089
US
EMail: rpe@juniper.net
Full Copyright Statement Β©οΈ
Copyright (C) The IETF Trust (2006).
This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.
This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST, AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Intellectual Property π
The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.
Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.
The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.
Acknowledgement π
Funding for the RFC Editor function is currently provided by the Internet Society.
π¦ where this page comes from
- ietf: rfc4741 2006-12
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms