7-2 YANG モデル — 機器が名乗るモデルを取り出して読む
csr1000v 17.3 の hello と yang-library が名乗る YANG モデルを get-schema で取り出し、ietf-interfaces・OpenConfig・Cisco native の 3 系統で同じ Loopback0 を読み書きします。
1. 前節の振り返りと本節の内容
前節 7-1 NETCONF / RESTCONF は、csr1000v 17.03.08a の設定と状態を、NETCONF(SSH の TCP 830)と RESTCONF(HTTPS)で WSL (Windows Subsystem for Linux) 上のプログラムから読み書きしました。
7-1 の末尾(§14)は、次のことを本節へ渡しています。NETCONF の XML の名前空間、RESTCONF の URL と JSON のメンバ名に、ietf-interfaces や Cisco-IOS-XE-native といった YANG のモジュールの名前が現れたこと。hello に 520 本の capability が並び、yang-library が module-set-id を返したこと。7-1 はこれらが何を定めているかには立ち入らず、NETCONF と RESTCONF が運ぶデータの形を決める YANG のデータモデルを次節で扱うこと、IETF が定めるモデルと OpenConfig のモデルが中心で、名前だけが出てきたモジュールが何を定めているかもそこで扱うことを予告しました。本節は、この予告を同じ順で次の場所で受けます。
| 7-1 §14 の予告 | 本節での受け方 | 場所 |
|---|---|---|
| 名前空間・URL・JSON のメンバ名に現れたモジュールの名前 | モジュールの本文の module 文(名前)・namespace 文・prefix 文を機器から取り出し、それぞれが XML・JSON・URL・エラーの文言のどこに現れるかを対応づける | §6・§7 |
| hello の 520 本の capability | 520 本 = module= を持つ 507 本 + 持たない 13 本。507 本は module=・revision=・features=・deviations= の組み合わせで、機器が名乗るモジュール(yang-library では実装する 454 本と、定義を借りるだけの 53 本)の名前を示し、そのうち 497 本は revision= で版も示す(10 本は revision= を持たない) | §4.1 |
| yang-library の module-set-id | NETCONF 側と RESTCONF 側の yang-library を並べ、module-set-id の値の差と、モジュールの集合の差を別々の事実として示す。値が違う理由は本節でも確かめていない | §4.3・§4.4 |
| これらが何を定めているか | capability・<schemas>・yang-library が名乗るのはモジュールの名前と版まで。本文(YANG で書いた定義)は get-schema で機器から取り出す | §4・§5 |
| IETF のモデルと OpenConfig のモデル | IETF の ietf-interfaces・ietf-ip と、OpenConfig の openconfig-interfaces を、機器が返した本文と pyang の木で読む。同じ Loopback0 を Cisco の native モデルと合わせた 3 系統で読み書きする | §6・§8・§9 |
| 名前だけが出てきたモジュールの中身 | ietf-interfaces・ietf-ip・iana-if-type・openconfig-interfaces・Cisco-IOS-XE-native(とサブモジュール Cisco-IOS-XE-interfaces)・Cisco の deviation のモジュールの本文 | §5〜§11 |
7-1 は本文の中でも、いくつかの論点を 7-2 に送っていました。本節はそれらを次の場所で受けます(最後の §10.3 の行は、送られた論点ではなく、本節が参照する 7-1 の観測です)。
| 7-1 の箇所 | 7-1 が送ったもの | 本節での受け方 | 場所 |
|---|---|---|---|
| §1 | 7-1 はモデルの名前が XML の名前空間・JSON のメンバ名・URL に現れるところまで。モデルの中身は 7-2、状態を購読する仕組み(notification・subscribe)は 7-3 | 本節はモデルの中身を扱う。notification は capability とモジュールの名前だけを挙げ、7-3 へ送る | §2・§14 |
| §5.1 | 520 本の capability の中身は 7-2 の範囲。一覧に載っていることは、その機能が使える証拠にならない | 520 本の内訳。本節も、capability や yang-library に載っていることを使える証拠にはせず、使えたことは読み書きの応答で示す | §4・§9〜§11 |
| §7.1 | interfaces と interfaces-state がモデルの中でどう分かれているかは 7-2 の範囲 | ietf-interfaces の本文の config false の container interfaces-state と、interfaces の 2 つの list | §6.4 |
| §9.3 | error-message の中の if: は、モジュール名(ietf-interfaces:)とは違う短い書き方で、何を表す書き方かは 7-2 で扱う | ietf-interfaces の本文の prefix if; の値。同じ機器のエラーの文言は、OpenConfig の節点を openconfig-interfaces の prefix の oc-if: で書いた | §6.1・§10 |
| §9.7・§12 | NETCONF と RESTCONF で module-set-id が違い、理由は確かめていない。yang-library の中身は 7-2 の範囲 | 2 つの yang-library の集合の差を並べる。値が違う理由は本節でも確かめていない | §4.3・§4.4・§12 |
| §10.3 | candidate を有効にすると、hello の module-set-id と ietf-netconf の features が書き換わった | 本節は running だけで撮った。module= の名前と版の集合が同じまま(features は変わった)値が変わった例として参照する | §4.4 |
第 7 章は全 6 節で、本節はその 2 つ目の節です。
本節は出典に基づく部分と、本ラボの実測に基づく部分を分けて書きます。
| 層 | どこ | 何を根拠にしているか |
|---|---|---|
| 出典層 | §2 と、§4〜§12・§14 の引用の段落 | RFC 6020(YANG 1.0)を主に、RFC 7950(YANG 1.1)・RFC 6022・RFC 7895・RFC 7223・RFC 7277・RFC 6991・RFC 8340・RFC 7951・RFC 8040・RFC 6241、後継の版の RFC 8343・RFC 8344・RFC 8525(名前と版の違いの確認だけ)、OpenConfig の style guide、Cisco の Programmability Configuration Guide, Cisco IOS XE Amsterdam 17.3.x の NETCONF・RESTCONF・Model-Driven Telemetry の章 |
| 実測層 | §3〜§11 の機器の出力(hello・<rpc-reply>・HTTP の応答・CLI の show) | CML 上の csr1000v 17.03.08a 1 台と、WSL 上のクライアント(Python の paramiko と curl)。同じ構成で 1 回撮影したもの |
| 実測層(参考) | §4.3・§4.4・§4.5・§12 と図 7-2-module-set-id | 7-1 の撮影(7-1 §5.1・§9.4・§9.7・§10.3)と、本ラボの前に同じ構成で行った準備段階の試行(probe)。値が同じだったことの比較と、7-1 の観測の参照だけに使う |
| 実測層(機器が返した本文) | §5〜§11 の YANG の本文の抜粋 | 機器が get-schema で返した本文(応答の CDATA の中身を取り出したもの)。「機器が get-schema で返した本文(名前@版)」と断って載せる |
| ツール側の観測 | §4・§6・§8・§11 の木 | 機器が返した本文を、WSL の pyang 2.7.1 で描いた木。機器の出力ではない |
| 確かめていないこと | §12 | — |
以下に貼る実機出力は改変していません。長い出力から一部を抜き出した箇所には …(省略) を置きました。プロンプトとコマンドを 1 行にまとめた表記(CSR1# show … と WSL $ curl … の形)は本節の組み立てで、取得の記録ではコマンドが見出しの行として別に残っています。curl の -K - は、資格情報を 1 行の設定として標準入力から渡す指定で(7-1 §8.1)、資格情報の値はどこにも載せていません。NETCONF は、WSL が送ったバイト列(wire)と、応答から chunk の見出しを外した XML を載せます(7-1 §6 の chunked framing)。
時刻は CSR1 の機器の時計(UTC)で、show clock と HTTP の応答の Date: ヘッダで書きます。
2. YANG — データの形を書く言語
YANG は、NETCONF が扱う設定と状態のデータ・RPC (Remote Procedure Call)・通知の形を書くためのデータモデリング言語 (Data Modeling Language) です。Cisco の 17.3 の設定ガイドの NETCONF の章は、YANG の名前を次のように展開しています。
Cisco IOS XE supports the Yet Another Next Generation (YANG) data modeling language.
RFC 6020 は YANG を次のように定義しています。
YANG is a data modeling language used to model configuration and state data manipulated by the Network Configuration Protocol (NETCONF), NETCONF remote procedure calls, and NETCONF notifications.
YANG で書いたデータは、名前を持つ節点 (node) の木です。各節点は値か、子の節点の集合のどちらかを持ちます。
YANG models the hierarchical organization of data as a tree in which each node has a name, and either a value or a set of child nodes.
定義の単位はモジュール (module) で、1 つのモジュールが 1 つのデータモデルを定めます。
The module is the base unit of definition in YANG. A module defines a single data model.
モジュールは、他のモジュールの定義を取り込み(import)、サブモジュール (submodule) の中身を含めます(include)。他のモジュールが定めた木に節点を足すこと(augment)もできます。
YANG structures data models into modules and submodules. A module can import data from other external modules, and include data from submodules. The hierarchy can be augmented, allowing one module to add data nodes to the hierarchy defined in another module.
1 台の機器は複数のモジュールを実装でき、同じデータを別々のモジュールで見せることもできます。§8〜§9 では、同じ Loopback0 を IETF・OpenConfig・Cisco native の 3 つのモジュールで読み書きできました(機器の中で 1 つのデータを共有しているかは撮っていません。§9)。
A NETCONF server may implement a number of modules, allowing multiple views of the same data, or multiple views of disjoint subsections of the device’s data.
2.1 YANG 1.0 と YANG 1.1
YANG には RFC 6020 の版(YANG version 1。以下 YANG 1.0)と、RFC 7950 の版(YANG 1.1)があります。RFC 7950 は YANG 1.1 を保守版と位置づけ、RFC 6020 を廃止していません。
YANG version 1.1 is a maintenance release of the YANG language, addressing ambiguities and defects in the original specification [RFC6020].
Note that this document does not obsolete RFC 6020 [RFC6020].
Cisco の 17.3 のガイドの NETCONF の章は、YANG でのモデル化を RFC 6020 に基づくと書いています。
YANG is used to model each protocol based on RFC 6020.
本ラボで機器から取り出した 52 本の本文は、すべて YANG 1.0 でした(§5.2)。以下の YANG の文の説明は RFC 6020 に拠り、1.1 で変わった点は必要な箇所で添えます。
2.2 YANG の主な文
YANG の本文は「文」(statement) の入れ子で書きます。§4〜§11 に出てくる文は以下のとおりです(出典層。定義は RFC 6020 の各節)。
| 文 | 何を定めるか | 場所 |
|---|---|---|
module / submodule / belongs-to / include | モジュールの名前。サブモジュールは 1 つのモジュールの一部で、属するモジュールを belongs-to で示し、モジュールが include で含める | §6.1・§8.2 |
namespace | モジュールの XML の名前空間(URI) | §6.1・§7 |
prefix | モジュールとその名前空間に結び付く接頭辞 | §6.1・§7 |
import | 他のモジュールの定義を使えるようにする。使う側がその場の接頭辞を付ける | §6.1 |
revision | 版の履歴。日付(YYYY-MM-DD)で書く | §4・§5 |
container | 子の節点をまとめる節点。値を持たない | §6.3 |
list / key | 要素の並び。各要素は key の leaf の値で区別する | §6.3・§8 |
leaf / type | 値を 1 つ持つ節点と、その型(boolean・uint16・string・enumeration など) | §6.3・§10 |
identity / identityref | 名前だけを持つ識別子と、それを値にとる型 | §6.2・§7 |
leafref | 別の leaf の値を指す型 | §8.1 |
config | 設定(true)か状態(false)か | §6.4・§10 |
augment | 他のモジュールの木に節点を足す | §6.5・§7 |
grouping / uses | 節点のまとまりを定義し、使う場所に写す | §8.1 |
feature / if-feature | モジュールの一部を、機器が選べる任意の機能にする | §6.2・§11.3 |
deviation / deviate | 機器がモジュールどおりに実装していない所を示す | §11 |
次の文は、名前と 1 行の定義だけを置きます。どれも機器が get-schema で返した本文に現れます(choice は ietf-ip の本文と §6.5 の木、rpc get-schema は ietf-netconf-monitoring の本文、notification yang-library-change は ietf-yang-library の本文、must と when は Cisco-IOS-XE-native の本文)。§5 の get-schema は、この rpc get-schema で定められた操作の呼び出しです。それ以外の、これらの文が効く読み書き(選択肢の切り替え・制約の検査・get-schema 以外の操作の呼び出し・通知の購読)は、本ラボでは試していません。
| 文 | 1 行の定義 |
|---|---|
choice / case | いくつかの選択肢のうち 1 つだけが有効になる節点と、その選択肢。スキーマの木にだけ現れ、データには現れない |
must | XPath の式で、有効なデータの制約を書く |
when | 条件を満たすときだけ、その節点を有効にする |
rpc | 操作の定義 |
notification | 通知の定義(購読の仕組みは 7-3) |
2.3 木の記法 — RFC 8340
YANG のモデルの構造は、木の図 (tree diagram) で簡略に示せます。RFC 8340 は木の記法を定め、木は pyang などのツールで自動的に描けると書いています。
Such diagrams are used to provide a simplified graphical representation of a data model and can be automatically generated via tools such as “pyang” [PYANG].
以下の木は、機器が get-schema で返した本文(§5)を WSL の pyang 2.7.1 に読ませて描いたもので、機器の出力ではありません(ツール側の観測)。-p は探索先を足す指定で、pyang は既定でほかの場所(venv に同梱の module・ホームの下の yang/modules・環境変数 YANG_MODPATH の dir・カレント dir)も探します。本ラボは本文を置いた dir を -p yang で渡し、同梱の module とホームの下を空の dir に差し替え、YANG_MODPATH を外し、カレント dir には .yang のファイルを置かずに実行しました。そのうえで、pyang が読んだファイル(-V の表示)がすべて yang/ の下であることを確かめています。
木の各行の記号は RFC 8340 §2.6 が定めています。節点の名前の前の記号(flags)と、後ろの記号(opts)の定義は以下のとおりです。
<flags> is one of: rw for configuration data nodes and choice nodes ro for non-configuration data nodes and choice nodes, output parameters to rpcs and actions, and notification parameters -w for input parameters to rpcs and actions -u for uses of a grouping -x for rpcs and actions -n for notifications mp for nodes containing a “mount-point” extension statement
<opts> is one of: ? for an optional leaf, choice, anydata, or anyxml ! for a presence container * for a leaf-list or list [<keys>] for a list’s keys / for a top-level data node in a mounted module @ for a top-level data node of a module identified in a mount point parent reference
以下の木に出てくる記号を日本語で並べると、次のとおりです(出典層)。
| 記号 | 意味 |
|---|---|
rw | 設定のデータの節点(config true)。書き込みの権限を表す記号ではない |
ro | 設定でないデータの節点(状態のデータ) |
? | 任意の leaf |
! | presence container |
* | list か leaf-list |
[name] | list の key |
{if-mib}? | その節点が依る feature |
-> ../config/name | leafref が指す先の path |
ip: などの接頭辞 | 別のモジュールから augment された節点。接頭辞は、節点を定めたモジュールの prefix |
{if-mib}? と -> と接頭辞の定めは以下のとおりです。
<if-features> is the list of features this node depends on, printed within curly brackets and a question mark “{…}?”
If the type is a leafref, the type is printed as either (1) “-> TARGET”, where TARGET is the leafref path, with prefixes removed if possible or (2) “leafref”.
If the node is augmented into the tree from another module, its name is printed as <prefix>:<name>, where <prefix> is the prefix defined in the module where the node is defined.
3. 本ラボの構成
本ラボは 7-1 と同じトポロジと管理の作りで(読み書きの対象の Loopback0 のアドレスだけ 10.7.2.1/32 に変えました)、CML 上の csr1000v 1 台(CSR1)と、管理用のスイッチ(mgmt-sw)・外部接続(ext)の 3 ノードです。クライアントは WSL で、NETCONF は Python の paramiko で SSH の netconf サブシステムを開いて送受し、RESTCONF は curl で送りました(7-1 §5・§8 と同じ作り)。pyang 2.7.1 は、機器の撮影の後に WSL の手元で動かしています。
| ノード | IF | アドレス | 用途 |
|---|---|---|---|
| CSR1 | Gi1(vrf Mgmt-vrf) | 172.16.1.241/24 | 管理アドレス。CLI の SSH(TCP 22)・NETCONF(TCP 830)・RESTCONF(TCP 443) |
| CSR1 | Mgmt-vrf の既定経路 | 0.0.0.0/0 → 172.16.1.1 | WSL への戻り |
| CSR1 | Loopback0 | 10.7.2.1/32(起動時の description は initial) | 3 系統で読み書きする資源 |
CSR1 の版は 17.03.08a で、§15 の Cisco の設定ガイド(17.3.x)と同じ系列です。
CSR1# show version
Cisco IOS XE Software, Version 17.03.08a
Cisco IOS Software [Amsterdam], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 17.3.8a, RELEASE SOFTWARE (fc3)
…(省略)
cisco CSR1000V (VXE) processor (revision VXE) with 1104920K/3075K bytes of memory.
…(省略)起動時の設定(day0)の Loopback0 は以下のとおりです。
CSR1# show running-config interface Loopback0
Building configuration...
Current configuration : 85 bytes
!
interface Loopback0
description initial
ip address 10.7.2.1 255.255.255.255
endNETCONF と RESTCONF の有効化は、7-1 §4.2 と同じ 6 行を 1 回の configure で投入しました。
configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
CSR1(config)#aaa new-model
CSR1(config)#aaa authentication login default local
CSR1(config)#aaa authorization exec default local
CSR1(config)#netconf-yang
CSR1(config)#ip http secure-server
Failed to generate persistent self-signed certificate.
Secure server will use temporary self-signed certificate.
CSR1(config)#restconf
CSR1(config)#end
CSR1#拒否を示す行(% で始まる行)はありません。
投入の後の待ち方も 7-1 §4.3 と同じで、show netconf-yang datastores を show clock で挟んで繰り返し撮り、応答がエラーでなくなるのを待ちました。1 回目(18:07:13.229 の show clock の後)と 2 回目(18:07:29.567 の後)は % Error: Currently unable to process request で、3 回目に running のデータストアが返りました。
CSR1# show clock
*18:07:46.519 UTC Wed Sep 30 2026
CSR1# show netconf-yang datastores
Datastore Name : running
CSR1# show clock
*18:07:51.422 UTC Wed Sep 30 2026CSR1# show netconf-yang status
netconf-yang: enabled
netconf-yang ssh port: 830
netconf-yang candidate-datastore: disabled撮影は段階(Phase)に分け、1 本の取得スクリプトで続けて撮りました。値を拒む要求(Phase E)と deviation・feature の書き込み(Phase F)は、他の段階を巻き添えにしないよう最後に置いています。
| Phase | 内容 | 本文 |
|---|---|---|
| 0 | 版・day0 の Loopback0・有効化・準備完了の関門 | §3 |
| A | hello・module-set-id(同じ時間の窓の 3 経路)・yang-library(NETCONF と RESTCONF)・module のエントリ・<schemas>・RESTCONF の schema 資源 | §4・§5.4 |
| B | get-schema。存在しない名前と機器に無い版の 2 本を先に撮り、その後で本文を 52 本取り出す | §5 |
| C | 同じ Loopback0 を 3 系統(RESTCONF の GET・NETCONF の <get-config>)と CLI で読む | §7・§8 |
| D | 1 つの系統で description を書き、3 系統と CLI で読む(3 回) | §9 |
| E | 値を拒む要求(RESTCONF 6 種・NETCONF 3 種)と、前後の読み | §10 |
| F | deviation で外された節点への書き込みと、if-feature の付いた leaf の書き込みと削除 | §11 |
| Z | 撮影の後の状態 | —(本文では使っていない) |
4. 機器が名乗るモデル — hello・schemas・yang-library
機器は、自分が持つモデル(実装するものと、定義を借りるだけのもの)を 3 つの場所で名乗りました。NETCONF の hello の capability、ietf-netconf-monitoring の <schemas>、ietf-yang-library(yang-library)です。どれもモジュールの名前と版を名乗る一覧で、モジュールの本文は入っていません。本文は §5 の get-schema で取り出します。
4.1 hello の capability — 520 本 = 507 本 + 13 本
CSR1 の hello は以下のとおりです(Phase A の最初の NETCONF セッション。session-id は 25)。
<?xml version="1.0" encoding="UTF-8"?>
<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:base:1.1</capability>
<capability>urn:ietf:params:netconf:capability:writable-running:1.0</capability>
<capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability>
<capability>urn:ietf:params:netconf:capability:validate:1.0</capability>
<capability>urn:ietf:params:netconf:capability:validate:1.1</capability>
<capability>urn:ietf:params:netconf:capability:xpath:1.0</capability>
<capability>urn:ietf:params:netconf:capability:notification:1.0</capability>
<capability>urn:ietf:params:netconf:capability:interleave:1.0</capability>
<capability>urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=explicit&also-supported=report-all-tagged,report-all</capability>
<capability>urn:ietf:params:netconf:capability:yang-library:1.0?revision=2016-06-21&module-set-id=9a21a4b66ce28c110b54d5a052486d1f</capability>
<capability>http://tail-f.com/ns/netconf/actions/1.0</capability>
…(省略)
<capability>http://cisco.com/ns/yang/Cisco-IOS-XE-native?module=Cisco-IOS-XE-native&revision=2020-07-04&deviations=Cisco-IOS-XE-cdp-deviation,Cisco-IOS-XE-dialer-deviation,Cisco-IOS-XE-nd-deviation,Cisco-IOS-XE-policy-deviation,Cisco-IOS-XE-sanet-deviation</capability>
…(省略)
<capability>http://openconfig.net/yang/interfaces?module=openconfig-interfaces&revision=2018-01-05&deviations=cisco-xe-openconfig-if-ip-deviation,cisco-xe-openconfig-interfaces-deviation,cisco-xe-routing-openconfig-vlan-deviation</capability>
…(省略)
<capability>urn:ietf:params:xml:ns:netconf:base:1.0?module=ietf-netconf&revision=2011-06-01&features=writable-running,rollback-on-error,validate,xpath</capability>
…(省略)
<capability>urn:ietf:params:xml:ns:yang:iana-if-type?module=iana-if-type&revision=2014-05-08</capability>
…(省略)
<capability>urn:ietf:params:xml:ns:yang:ietf-event-notifications?module=ietf-event-notifications&revision=2016-10-27&features=json,configured-subscriptions&deviations=cisco-xe-ietf-event-notifications-deviation,cisco-xe-ietf-yang-push-deviation</capability>
…(省略)
<capability>urn:ietf:params:xml:ns:yang:ietf-interfaces?module=ietf-interfaces&revision=2014-05-08&features=pre-provisioning,if-mib,arbitrary-names&deviations=cisco-xe-ietf-ip-deviation</capability>
<capability>urn:ietf:params:xml:ns:yang:ietf-interfaces-ext?module=ietf-interfaces-ext</capability>
<capability>urn:ietf:params:xml:ns:yang:ietf-ip?module=ietf-ip&revision=2014-06-16&features=ipv6-privacy-autoconf,ipv4-non-contiguous-netmasks&deviations=cisco-xe-ietf-ip-deviation</capability>
…(省略)
<capability>urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults?module=ietf-netconf-with-defaults&revision=2011-06-01</capability>
…(省略)
<capability>urn:ietf:params:xml:ns:yang:ietf-yang-push?module=ietf-yang-push&revision=2016-10-28&features=on-change&deviations=cisco-xe-ietf-yang-push-deviation</capability>
…(省略)
<capability>
urn:ietf:params:netconf:capability:notification:1.1
</capability>
</capabilities>
<session-id>25</session-id></hello>]]>]]><capability> の要素を数えると 520 本でした。各 capability の中身の実体参照(& は &)を戻し、module= を含むかで分けると、含むものが 507 本、含まないものが 13 本です。507 本のうち 497 本は revision= で版も名乗り、10 本(ietf-interfaces-ext・ATM-FORUM-TC-MIB など)は revision= を持ちませんでした。yang-library でも、この 10 本の revision は空です。
module= を持つ 507 本は、RFC 6020(YANG 1.0)が定めるモジュールの名乗り方です。RFC 6020 §5.6.4 は、YANG のモジュールの名前空間の URI を hello の capability として名乗ると定めています。
The namespace URI MUST be advertised as a capability in the NETCONF <hello> message to indicate support for the YANG module by a NETCONF server.
URI の本体がモジュールの名前空間で、module= がモジュールの名前です。
Module namespaces are encoded as the base URI in the capability string, and the module name is encoded as the “module” parameter to the base URI.
revision=・features=・deviations= の意味は次のとおりです。
Where “revision-date” is the revision of the module (see Section 7.1.9) that the NETCONF server implements, “module-name” is the name of module as it appears in the “module” statement (see Section 7.1), “namespace-uri” is the namespace URI for the module as it appears in the “namespace” statement (see Section 7.1.3), “feature” is the name of an optional feature implemented by the device (see Section 7.18.1), and “deviation” is the name of a module defining device deviations (see Section 7.18.3).
上の hello の ietf-interfaces の行を分けると、以下のとおりです。
| 部分 | 値 | RFC 6020 §5.6.4 での意味 |
|---|---|---|
| URI の本体 | urn:ietf:params:xml:ns:yang:ietf-interfaces | モジュールの namespace 文の値 |
module= | ietf-interfaces | モジュールの module 文の名前 |
revision= | 2014-05-08 | 機器が実装するモジュールの版 |
features= | pre-provisioning,if-mib,arbitrary-names | 機器が実装する任意の機能(feature)の名前 |
deviations= | cisco-xe-ietf-ip-deviation | このモジュールからの外れ方(deviation)を定めるモジュール |
ietf-ip の行(module=ietf-ip)にも deviations=cisco-xe-ietf-ip-deviation が付いていて、1 つの deviation のモジュールが 2 つのモジュールの行に挙がっています。openconfig-interfaces の行は deviation のモジュールを 3 つ、Cisco-IOS-XE-native の行は 5 つ挙げています。deviation の中身は §11 で扱います。
RFC 6020 §5.6.4.1 は、機器が実装するモジュールをすべての版について名乗ることを求めています。
A server MUST advertise all revisions of all modules it implements.
hello の module= の 507 本は、NETCONF 側の yang-library(§4.4)の 507 件と名前で一致し、revision=・features=・deviations= の値も yang-library の revision・feature・deviation と食い違いはありませんでした。ただし、本機の 507 本の中には、yang-library の conformance-type が import(定義を借りるだけで実装はしない)のモジュール 53 本も含まれていました(§4.4)。hello に並んだモジュールがすべて implement というわけではありません。
module= を持たない 13 本は、NETCONF の機能の capability です。扱う場所は以下のとおりです。
| capability | 扱う場所 |
|---|---|
base:1.0・base:1.1 | 7-1 §5・§6(hello と framing) |
writable-running:1.0 | 7-1 §10.3(candidate を有効にすると消えた) |
yang-library:1.0?revision=2016-06-21&module-set-id=… | §4.3 |
notification:1.0・notification:1.1 | 名前だけ(購読の仕組みは 7-3) |
rollback-on-error:1.0・validate:1.0・validate:1.1・xpath:1.0・interleave:1.0・with-defaults:1.0?…・http://tail-f.com/ns/netconf/actions/1.0 | 名前だけ(本ラボでは使っていない。§12) |
7-1 §5.1 と同じく、capability の一覧に載っていることは、その機能が使える証拠にはなりません。
4.2 <schemas> — 543 件 = 507 + 36
2 つ目の名乗り方は、RFC 6022 の ietf-netconf-monitoring の <schemas> です。RFC 6022 は、NETCONF のクライアントがサーバの対応するモデルを見つける方法と、それを取り出す <get-schema> の操作を定めています。
This document also defines methods for NETCONF clients to discover data models supported by a NETCONF server and defines a new NETCONF <get-schema> operation to retrieve them.
Cisco の 17.3 のガイドの NETCONF の章も、対応するモデルは ietf-netconf-monitoring のモデルで見つけ、各モデルの版は capability の応答に示されると書いています。
Supported models are discovered using the ietf-netconf-monitoring model.
Revision dates for each model are shown in the capabilities response.
<schemas> は、サーバが対応する schema の一覧です。list の key は identifier・version・format の 3 つで、get-schema の入力にもこの 3 つを使います。
The list of supported schema for the NETCONF server.
The elements identifier, version, and format are used as a key in the schema list.
These are used in the <get-schema> operation.
identifier はモジュールかサブモジュールの名前で、サブモジュールの項目の namespace は、そのサブモジュールが属するモジュールの namespace です。
For YANG data models, the identifier is the name of the module or submodule.
If the list entry describes a submodule, this field contains the namespace of the module to which the submodule belongs.";
一覧の応答に本文は入りません。
The schema itself (i.e., schema content) is not returned in the response.
本ラボは、Phase A の NETCONF のセッションで、<get> に <schemas/> を選ぶフィルタを入れて送りました。
#262
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="102">
<get><filter type="subtree"><netconf-state xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"><schemas/></netconf-state></filter></get>
</rpc>
##応答は 1 行の XML で、<schema> の要素は 543 件でした。format は全件 yang、location は全件 NETCONF です。543 件の identifier を、§4.4 の NETCONF 側の yang-library のモジュールの名前(507)と、サブモジュールの名前(<submodule> の名前の異なりで 36)に当てると、507 + 36 でちょうど分かれました。
サブモジュールの項目も載っています。応答の中の Cisco-IOS-XE-interfaces と ietf-interfaces の項目は以下のとおりで、サブモジュールの Cisco-IOS-XE-interfaces の namespace は、属するモジュール(Cisco-IOS-XE-native)の namespace でした。
<schema><identifier>Cisco-IOS-XE-interfaces</identifier><version>2020-07-02</version><format>yang</format><namespace>http://cisco.com/ns/yang/Cisco-IOS-XE-native</namespace><location>NETCONF</location></schema><schema><identifier>ietf-interfaces</identifier><version>2014-05-08</version><format>yang</format><namespace>urn:ietf:params:xml:ns:yang:ietf-interfaces</namespace><location>NETCONF</location></schema>
location の NETCONF は、その schema を get-schema で機器から取り出せることを示す値です。
The optional <location> element contains a URI, which can be used to retrieve the schema by another protocol such as ftp [RFC0959] or http(s) [RFC2616] [RFC2818], or the special value ‘NETCONF’, which means that the schema can be retrieved from the device via the <get-schema> operation.
4.3 yang-library の capability と module-set-id
3 つ目の名乗り方は yang-library です。§4.1 の 13 本の 1 つ、yang-library:1.0 の capability は、YANG 1.1 で足された名乗り方です。RFC 7950 は、YANG 1.1 のモジュールを hello の capability としてではなく、ietf-yang-library で名乗ると書いています。
A server advertises support for YANG 1.1 modules by using ietf-yang-library [RFC7895] instead of listing them as capabilities in the <hello> message.
hello の yang-library の capability の module-set-id= は、yang-library の leaf の module-set-id と同じ値だと定められています。
The parameter “module-set-id” has the same value as the leaf “/modules-state/module-set-id” from “ietf-yang-library”. This parameter MUST be present.
revision= は、サーバが実装する ietf-yang-library の版です。本機の hello は revision=2016-06-21 で、RFC 7895 が載せる ietf-yang-library の revision 文と同じ日付です。
The parameter “revision” has the same value as the revision date of the “ietf-yang-library” module implemented by the server. This parameter MUST be present.
revision 2016-06-21 { description “Initial revision.”;
本機は、YANG 1.0 の名乗り方(module= を持つ 507 本)と、yang-library の capability の両方を hello に載せていました。hello に YANG 1.1 のモジュールが無いかどうかは確かめていません(本文の yang-version を確かめたのは get-schema で取り出した 52 本だけです。§12)。
yang-library の中身は RFC 7895 が定めています。RFC 7895 は YANG library を、サーバが使うすべての YANG のモジュールの情報を示すものとしています。本機の yang-library は RFC 7895 の版(2016-06-21)で、RFC 7895 は後継の RFC 8525 で廃止されています。
This document describes a YANG library that provides information about all the YANG modules used by a network management server (e.g., a Network Configuration Protocol (NETCONF) server).
This document obsoletes RFC 7895.
module-set-id は、その機器の現在のモジュールとサブモジュールの集合を表す、実装に依存した識別子です。
This mandatory leaf contains a unique implementation-specific identifier representing the current set of modules and submodules on a specific server.
集合が変われば値は必ず変わりますが、同じ集合が常に同じ値になる要件はありません。
The value of this leaf MUST change whenever the set of modules and submodules in the YANG library changes.
There is no requirement that the same set always results in the same “module- set-id” value.
2 つ目の引用の module- set-id は、原典のテキストの行末のハイフンで折り返された語を、取得したテキストのまま写したものです。RFC 7895 は、この値の用途を、一覧を一度取ってキャッシュし、値が変わった時だけ取り直すことだとしています。
This leaf allows a client to fetch the module list once, cache it, and only refetch it if the value of this leaf has been changed.
本ラボは、NETCONF と RESTCONF の module-set-id を、show clock で挟んだ同じ時間の窓の中で 3 経路から読みました。順序は show clock → hello → NETCONF の <get> → RESTCONF の GET → show clock です。
CSR1# show clock
*18:08:16.584 UTC Wed Sep 30 2026hello の yang-library の capability の値は、§4.1 の hello の 14 行目のとおり module-set-id=9a21a4b66ce28c110b54d5a052486d1f でした。同じセッションで <get> に module-set-id だけを選ぶフィルタを入れて送ると、同じ値が返りました。
#262
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
<get><filter type="subtree"><modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library"><module-set-id/></modules-state></filter></get>
</rpc>
##<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101"><data><modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library"><module-set-id>9a21a4b66ce28c110b54d5a052486d1f</module-set-id></modules-state></data></rpc-reply>続けて RESTCONF で同じ leaf を読むと、別の値が返りました。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-yang-library:modules-state/module-set-id
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:19 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"ietf-yang-library:module-set-id": "bcaa2bd1b7330ff7474931011ae702be"
}CSR1# show clock
*18:08:19.765 UTC Wed Sep 30 20262 つの show clock の差は 3.181 秒(18:08:16.584 から 18:08:19.765)で、この窓の中で NETCONF の 2 経路(hello と <get>)は 9a21a4b66ce28c110b54d5a052486d1f、RESTCONF は bcaa2bd1b7330ff7474931011ae702be を返しました。7-1 の撮影(7-1 §5.1 の hello と §9.7 の RESTCONF)と、本ラボの前に行った準備段階の試行(probe)でも、NETCONF 側と RESTCONF 側はそれぞれ同じ 2 つの値でした。3 回とも同じ値だった理由と、2 つの値が違う理由は確かめていません(§12)。
4.4 yang-library の全体 — 2 つの口で 507 本ずつ
続けて、yang-library の全体(modules-state)を NETCONF の <get> と RESTCONF の GET で読みました。NETCONF 側の応答は改行の無い 1 行の XML なので、RESTCONF 側の JSON の一部を示します。
WSL $ curl -sS -i -k --max-time 180 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-yang-library:modules-state
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:26 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"ietf-yang-library:modules-state": {
"module-set-id": "bcaa2bd1b7330ff7474931011ae702be",
"module": [
{
"name": "ATM-FORUM-TC-MIB",
"revision": "",
"schema": "https://172.16.1.241:443/restconf/tailf/modules/ATM-FORUM-TC-MIB",
"namespace": "urn:ietf:params:xml:ns:yang:smiv2:ATM-FORUM-TC-MIB",
"conformance-type": "import"
},
…(省略)
{
"name": "ietf-restconf",
"revision": "2017-01-26",
"schema": "https://172.16.1.241:443/restconf/tailf/modules/ietf-restconf/2017-01-26",
"namespace": "urn:ietf:params:xml:ns:yang:ietf-restconf",
"conformance-type": "implement"
},
…(省略)
{
"name": "ietf-yang-patch",
"revision": "2017-02-22",
"schema": "https://172.16.1.241:443/restconf/tailf/modules/ietf-yang-patch/2017-02-22",
"namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-patch",
"conformance-type": "implement"
},
…(省略)
]
}
}yang-library の構造は、機器が get-schema で返した ietf-yang-library の本文(ietf-yang-library@2016-06-21)を pyang 2.7.1 で描いた、次の木(ツール側の観測)のとおりです。コマンドは pyang -V --no-path-recurse -p yang -f tree --tree-path /modules-state yang/ietf-yang-library@2016-06-21.yang で、--tree-path で modules-state の下だけを描いています(本文の notification yang-library-change は、この木には出していません)。module の list の key は name と revision の 2 つです。
module: ietf-yang-library
+--ro modules-state
+--ro module-set-id string
+--ro module* [name revision]
+--ro name yang:yang-identifier
+--ro revision union
+--ro schema? inet:uri
+--ro namespace inet:uri
+--ro feature* yang:yang-identifier
+--ro deviation* [name revision]
| +--ro name yang:yang-identifier
| +--ro revision union
+--ro conformance-type enumeration
+--ro submodule* [name revision]
+--ro name yang:yang-identifier
+--ro revision union
+--ro schema? inet:uriRFC 7895 も、module の list の key を name と revision の 2 つとしています。
list module { key “name revision”; description “Each entry represents one revision of one module currently supported by the server.”;
conformance-type の 2 つの値は次のとおりです。implement はそのモジュールの、プロトコルで触れる対象を実装していること、import は再利用する定義を取り込むだけで、触れる対象は実装していないことを意味します。
leaf conformance-type { type enumeration { enum implement { description “Indicates that the server implements one or more protocol-accessible objects defined in the YANG module identified in this entry.
enum import { description “Indicates that the server imports reusable definitions from the specified revision of the module but does not implement any protocol-accessible objects from this revision.
2 つの応答をそれぞれ数えると、以下のとおりでした。数え方は、NETCONF 側は XML として、RESTCONF 側は JSON として読み、module の要素を 1 件ずつ集めたものです。
| 項目 | NETCONF 側(<get>) | RESTCONF 側(GET) |
|---|---|---|
| module の数 | 507 | 507 |
| conformance-type | implement 454・import 53 | implement 454・import 53 |
| 片側だけのモジュール | ietf-netconf・ietf-netconf-with-defaults | ietf-restconf・ietf-yang-patch |
| 両方に在るモジュール | 505 | 505 |
共通の 505 件の schema の頭 | http://localhost:9938 | https://172.16.1.241:443 |
| module-set-id | 9a21a4b66ce28c110b54d5a052486d1f | bcaa2bd1b7330ff7474931011ae702be |
共通の 505 件は、2 つの応答をモジュールの名前で突き合わせ、revision・conformance-type・namespace・feature・deviation・submodule(名前と版)・schema を 1 件ずつ比べました。schema 以外の 6 項目は 505 件とも一致し、schema だけが 505 件とも違いました。違うのは URL の scheme と host の部分で、その後の path(/restconf/tailf/modules/ 以降)は 505 件とも同じです。サブモジュールの要素も schema の URL を持ち、サブモジュールを持つ 12 本では、その URL も同じく scheme と host の部分だけが違いました。NETCONF 側の全体は 18:08:19.765 と 18:08:24.494 の show clock の間に、RESTCONF 側の全体は 18:08:24.494 と 18:08:27.353 の間に撮りました。
ここまでで、2 つのことが別々に観測されています。
- module-set-id の値は、NETCONF 側と RESTCONF 側で違った(§4.3)
- モジュールの集合も違った。片側だけのモジュールが 2 本ずつあり、共通の 505 件も
schemaの URL が違った
集合の差が値の差の理由であるかは確かめていません。共通の 505 件にも schema の違いがあるので、値に効いた項目を片側だけの 4 本に絞れません。7-1 §10.3 では、candidate を有効にして再起動した後、module= の名前と版の集合は同じまま、ietf-netconf の行の features と、module= を持たない capability(candidate・confirmed-commit が加わり、writable-running が消えた)が変わり、hello の module-set-id も変わっていました(7-1 の実測)。RFC 7895 §2.1.1 が定めているのは、集合が変われば値が変わること(MUST)までで、同じ集合が同じ値になる要件は置いていません(§4.3)。機器が値をどう計算しているかは確かめていません。
RESTCONF 側にだけ載っていた ietf-yang-patch は、yang-library にモジュールの名前と版が載っていたという事実までです。本ラボは YANG-Patch を使っておらず、使えるかは確かめていません(§12)。
4.5 module のエントリを 1 つずつ読む
RESTCONF では、yang-library の module の list の要素を 1 つだけ読めます。key が 2 つ(name と revision)の list の要素の URL は、module=ietf-interfaces,2014-05-08 のように、= の後に key の値を key 文の順でカンマ区切りで並べます。key が 1 つの場合の規則は 7-1 §8.5 で見たとおりで、RFC 8040 §3.5.3 は、list の要素の識別子の構文を §3.5.3.1 の ABNF の list-instance の規則で表すとし、その規則は key が複数でも = を置きます。
The “list-instance” Augmented Backus-Naur Form (ABNF) [RFC5234] rule defined in Section 3.5.3.1 represents the syntax of a list instance identifier.
list-instance = api-identifier “=” key-value *(”,” key-value)
Each key leaf value except the last one is followed by a comma character.
ietf-interfaces のエントリは以下のとおりです。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-yang-library:modules-state/module=ietf-interfaces,2014-05-08
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:29 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"ietf-yang-library:module": {
"name": "ietf-interfaces",
"revision": "2014-05-08",
"schema": "https://172.16.1.241:443/restconf/tailf/modules/ietf-interfaces/2014-05-08",
"namespace": "urn:ietf:params:xml:ns:yang:ietf-interfaces",
"feature": ["arbitrary-names", "if-mib", "pre-provisioning"],
"deviation": [
{
"name": "cisco-xe-ietf-ip-deviation",
"revision": "2016-08-10"
}
],
"conformance-type": "implement"
}
}feature は 3 つ、deviation は cisco-xe-ietf-ip-deviation(2016-08-10)の 1 つで、hello の features=・deviations= と同じ名前が並んでいます。schema の URL は §5.4 で使います。
openconfig-interfaces のエントリは、deviation のモジュールを 3 つ挙げていました。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-yang-library:modules-state/module=openconfig-interfaces,2018-01-05
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:29 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"ietf-yang-library:module": {
"name": "openconfig-interfaces",
"revision": "2018-01-05",
"schema": "https://172.16.1.241:443/restconf/tailf/modules/openconfig-interfaces/2018-01-05",
"namespace": "http://openconfig.net/yang/interfaces",
"deviation": [
{
"name": "cisco-xe-openconfig-if-ip-deviation",
"revision": "2017-03-04"
},
{
"name": "cisco-xe-openconfig-interfaces-deviation",
"revision": "2018-08-21"
},
{
"name": "cisco-xe-routing-openconfig-vlan-deviation",
"revision": "2018-12-12"
}
],
"conformance-type": "implement"
}
}Cisco-IOS-XE-native のエントリは、deviation のモジュールを 5 つ、サブモジュールを 7 つ挙げていました。サブモジュールの Cisco-IOS-XE-interfaces は §8.2 で本文を読みます。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-yang-library:modules-state/module=Cisco-IOS-XE-native,2020-07-04
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:29 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"ietf-yang-library:module": {
"name": "Cisco-IOS-XE-native",
"revision": "2020-07-04",
"schema": "https://172.16.1.241:443/restconf/tailf/modules/Cisco-IOS-XE-native/2020-07-04",
"namespace": "http://cisco.com/ns/yang/Cisco-IOS-XE-native",
"deviation": [
{
"name": "Cisco-IOS-XE-cdp-deviation",
"revision": "2019-07-23"
},
{
"name": "Cisco-IOS-XE-dialer-deviation",
"revision": "2020-07-01"
},
{
"name": "Cisco-IOS-XE-nd-deviation",
"revision": ""
},
{
"name": "Cisco-IOS-XE-policy-deviation",
"revision": "2020-07-01"
},
{
"name": "Cisco-IOS-XE-sanet-deviation",
"revision": "2020-07-01"
}
],
"conformance-type": "implement",
"submodule": [
{
"name": "Cisco-IOS-XE-interfaces",
"revision": "2020-07-02",
"schema": "https://172.16.1.241:443/restconf/tailf/modules/Cisco-IOS-XE-interfaces/2020-07-02"
},
…(省略)
]
}
}RFC 7895 は、モジュールが使うサブモジュールの名前と版を示すことを求めています。
submodule list: The name and revision of each submodule used by the module MUST be identified.
NETCONF 側にだけ在った ietf-netconf のエントリを RESTCONF で読むと、404 Not Found でした。本文は 0 バイト(Content-Length: 0)です。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-yang-library:modules-state/module=ietf-netconf,2011-06-01
HTTP/1.1 404 Not Found
Server: openresty
Date: Wed, 30 Sep 2026 18:08:29 GMT
Content-Type: text/html
Content-Length: 0
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cacheRFC 8040 §4.3 は、存在しない実体を読む要求に 404 を返すと定めています。
If a retrieval request for a data resource represents an instance that does not exist, then an error response containing a “404 Not Found” status-line MUST be returned by the server. The error-tag value “invalid-value” is used in this case.
本機の 404 には、error-tag を含む本文はありませんでした(7-1 §9.4 の 404 と同じ形)。
RESTCONF 側にだけ在った ietf-restconf のエントリは、200 OK で返りました。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-yang-library:modules-state/module=ietf-restconf,2017-01-26
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:30 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"ietf-yang-library:module": {
"name": "ietf-restconf",
"revision": "2017-01-26",
"schema": "https://172.16.1.241:443/restconf/tailf/modules/ietf-restconf/2017-01-26",
"namespace": "urn:ietf:params:xml:ns:yang:ietf-restconf",
"conformance-type": "implement"
}
}RFC 8040 §10.1 は、ietf-restconf には実装する protocol-accessible objects が無く、実装するモジュールから import されていれば yang-library に載りうる、と書いています。本機は RESTCONF 側の yang-library に、ietf-restconf を implement で載せていました。上の RFC 7895 の implement の定義と本機の値は並べるだけで、判定はしていません。
Note that there are no protocol-accessible objects in the “ietf-restconf” module to implement, but it is possible that a server will list the “ietf-restconf” module in the YANG library if it is imported (directly or indirectly) by an implemented module.
5. モデルの本文を取り出す — get-schema
5.1 get-schema の要求と応答
RFC 6022 の <get-schema> は、NETCONF のサーバから schema を取り出す操作です。
This operation is used to retrieve a schema from the NETCONF server.
入力は <schemas> の key と同じ 3 つで、identifier は必須、version と format は省略でき、format の既定は yang です。
Identifier for the schema list entry. Mandatory parameter.
Version of the schema requested. Optional parameter.
The data modeling language of the schema. Default value is ‘yang’ when not specified. Optional parameter.
Cisco の 17.3 のガイドも、get-schema でモデルを機器から取り出せると書いています。
Data models are available for optional download from a device using the get-schema RPC.
本ラボは、Phase B の NETCONF のセッション(session-id 45)で、ietf-interfaces の 2014-05-08 の版を要求しました。
#293
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
<get-schema xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"><identifier>ietf-interfaces</identifier><version>2014-05-08</version><format>yang</format></get-schema>
</rpc>
##応答の <data> の中身は、XML の要素ではなく、<![CDATA[ から ]]> までの区間(XML の CDATA セクション)に包まれた YANG の本文でした。先頭と末尾は以下のとおりです(chunk の見出しを外した XML)。
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101"><data xmlns='urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring'><![CDATA[module ietf-interfaces {
namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
prefix if;
import ietf-yang-types {
prefix yang;
}
…(省略)
reference
"RFC 2863: The Interfaces Group MIB - ifOutErrors";
}
}
}
}
}
]]></data>
</rpc-reply>この応答は、wire では 4 つの chunk に分かれて届きました。chunk の長さは 4286・8192・8192・3791 バイトで、最後は ## の行で終わります。chunk の見出しの位置は YANG の文の区切りとは関係がなく、2 つ目の見出し #8192 は configurati と on の間に、3 つ目は su と bsystem の間に入っていました。
#4286
<?xml version="1.0" encoding="UTF-8"?>
…(省略)
If a client tries to create configurati
#8192
on for a
system-controlled interface that is not present in the
…(省略)
su
#8192
bsystem, then this node is not present.";
…(省略)
other
#3791
times as indicated by the value of
…(省略)
}
}
]]></data>
</rpc-reply>
##chunked framing の読み方は 7-1 §6 のとおりで、見出しを外してつなぐと上の XML になります。
5.2 import と include を辿る — 52 本
1 つのモジュールの本文は、他のモジュールを import し、サブモジュールを include します。ietf-interfaces の本文は、上の先頭のとおり import ietf-yang-types を持っています。本ラボは、次の 17 本を起点にして、本文の import と include に出てくる名前を get-schema で順に取り出しました。
| 起点 | 本数 |
|---|---|
| ietf-interfaces・ietf-ip・iana-if-type・openconfig-interfaces・openconfig-if-ip | 5 |
| Cisco の deviation のモジュール(cisco-xe-openconfig-interfaces-deviation・cisco-xe-openconfig-if-ip-deviation・cisco-xe-ietf-ip-deviation・cisco-xe-routing-openconfig-vlan-deviation) | 4 |
| ietf-yang-library・ietf-netconf-monitoring | 2 |
Cisco-IOS-XE-native と、hello の native の行の deviations= に挙がった 5 本 | 6 |
取り出した本文は 52 本で、本文が返らなかったものは 0 本、本数の上限で打ち切ったものも 0 本でした。52 本の最初の文を数えると、module が 43 本、submodule が 9 本です。
52 本の yang-version は、yang-version "1"; を書いたものが 10 本、yang-version の文を持たないものが 42 本でした。openconfig-interfaces の本文は、先頭に yang-version "1"; を書いています(機器が get-schema で返した本文 openconfig-interfaces@2018-01-05 の先頭)。
module openconfig-interfaces {
yang-version "1";
// namespace
namespace "http://openconfig.net/yang/interfaces";
prefix "oc-if";
…(省略)RFC 6020 では yang-version の文は省略でき、書くなら値は “1” です。RFC 7950 は、この文を持たないモジュールと “1” のモジュールを、どちらも YANG version 1 のものとしています。したがって 52 本はすべて YANG 1.0 です。
The optional “yang-version” statement specifies which version of the YANG language was used in developing the module. The statement’s argument is a string. If present, it MUST contain the value “1”, which is the current YANG version and the default value.
A module or submodule that doesn’t contain the “yang-version” statement, or one that contains the value “1”, is developed for YANG version 1, defined in [RFC6020].
Cisco の 17.3 のガイドは、Cisco の YANG のモデルを GitHub の公開リポジトリの vendor/cisco の下で見られると案内しています。
To access Cisco YANG models in a developer-friendly way, clone the GitHub repository, and navigate to the vendor/cisco subdirectory.
Models for various releases of IOS-XE, IOS-XR, and NX-OS platforms are available here.
本ラボは、機器が返した 52 本のうち 12 本を、公開リポジトリ YangModels/yang の vendor/cisco/xe/1731(commit 0e28ed86)の同じ名前のファイルと比べました(残りの 40 本は比べていません)。12 本のうち、バイト単位で一致したのは次の 10 本です。
- ietf-interfaces・ietf-ip・iana-if-type
- openconfig-interfaces・openconfig-if-ip
- cisco-xe-openconfig-interfaces-deviation・cisco-xe-openconfig-if-ip-deviation・cisco-xe-ietf-ip-deviation
- ietf-yang-library・ietf-netconf-monitoring
Cisco-IOS-XE-native は、機器の版が 2020-07-04、公開リポジトリの版が 2020-07-01 で、行単位で比べると公開版だけに在る行が 2 行・機器だけに在る行が 19 行の、計 21 行が違いました(取得の時に付けた見出しの 3 行を除く)。サブモジュールの Cisco-IOS-XE-interfaces は、機器が 2020-07-02、公開リポジトリが 2020-07-01 で、同じく 2 行と 48 行の、計 50 行が違いました。この 2 本は、機器が返した本文を正とします。
5.3 存在しない名前と、機器に無い版
get-schema で存在しない名前(no-such-module-7-2)を要求すると、<rpc-error> が返りました。error-tag は invalid-value です。
#267
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
<get-schema xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"><identifier>no-such-module-7-2</identifier><format>yang</format></get-schema>
</rpc>
##<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101"><rpc-error>
<error-type>application</error-type>
<error-tag>invalid-value</error-tag>
<error-severity>error</error-severity>
<error-path xmlns:ncm="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
/nc:rpc/ncm:get-schema
</error-path><error-message xml:lang="en">/get-schema/identifier: inconsistent value</error-message><error-info><bad-element>get-schema</bad-element>
</error-info>
</rpc-error>
</rpc-reply>RFC 6022 §3.1 は、要求した schema が無い場合の error-tag を invalid-value と定めています。
If the requested schema does not exist, the <error-tag> is ‘invalid-value’.
ietf-interfaces を、機器が名乗る 2014-05-08 ではない版(2018-02-20)で要求しても、同じ invalid-value と同じ文言 /get-schema/identifier: inconsistent value が返りました。
#293
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="102">
<get-schema xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"><identifier>ietf-interfaces</identifier><version>2018-02-20</version><format>yang</format></get-schema>
</rpc>
##<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="102"><rpc-error>
<error-type>application</error-type>
<error-tag>invalid-value</error-tag>
<error-severity>error</error-severity>
<error-path xmlns:ncm="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
/nc:rpc/ncm:get-schema
</error-path><error-message xml:lang="en">/get-schema/identifier: inconsistent value</error-message><error-info><bad-element>get-schema</bad-element>
</error-info>
</rpc-error>
</rpc-reply>2014-05-08 は RFC 7223 が載せる ietf-interfaces の revision 文の日付で、2018-02-20 は後継の RFC 8343 の ietf-interfaces の revision 文の日付です。本機が名乗る ietf-interfaces は RFC 7223 の版で、2018-02-20 の版は取り出せませんでした。
revision 2014-05-08 { description “Initial revision.”;
後継の RFC 8343 は RFC 7223 を廃止しています。
This document obsoletes RFC 7223.
5.4 RESTCONF の schema 資源 — 406 と 200
RESTCONF には、YANG の本文を GET で取る「schema 資源」があります。RFC 8040 は、schema 資源の表現のメディアタイプを application/yang としています。
schema resource: a resource that is used by the client to retrieve a YANG schema with the GET method. It has a representation with the media type “application/yang”.
手順は 2 段で、yang-library の schema の leaf から URL を得て、その URL から本文を取ります。
Next, the client needs to retrieve the actual YANG schema.
RFC 8040 §3.7 は、本文の取得への対応をサーバの任意としています。対応する場合は、yang-library のモジュールのエントリに schema の leaf が要ります。URL の構造は定めていません。
The server can optionally support the retrieval of the YANG modules it uses.
If retrieval is supported, then the “schema” leaf MUST be present in the associated “module” list entry, defined in [RFC7895].
Note that there is no required structure for this URL.
RFC 7895 の schema の leaf は、取得に使える URL がある時だけ在るとされています。
This leaf will only be present if there is a URL available for retrieval of the schema for this entry.";
本ラボは、§4.5 の ietf-interfaces のエントリの schema の値(https://172.16.1.241:443/restconf/tailf/modules/ietf-interfaces/2014-05-08)の path を、Accept を 8 通りに変えて GET しました。Accept: application/yang の応答は 406 Not Acceptable でした。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang' https://172.16.1.241/restconf/tailf/modules/ietf-interfaces/2014-05-08
HTTP/1.1 406 Not Acceptable
Server: openresty
Date: Wed, 30 Sep 2026 18:08:30 GMT
Content-Type: application/yang-data+xml
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Vary: Accept-Encoding
Pragma: no-cache
<errors xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
<error>
<error-message>No acceptable mime-type supported. Got: application/yang ; Should be one of: application/yang-data+xml, application/yang-data+json, application/vnd.yang.collection+xml, application/vnd.yang.collection+json, application/yang-patch+xml, application/yang-patch+json.</error-message>
<error-tag>invalid-value</error-tag>
<error-type>application</error-type>
</error>
</errors>406 の本文が受け付ける型として挙げた 6 つと、Accept を付けない GET(curl の既定の Accept: */*)の 7 本は、どれも 200 OK で、Content-Type は application/yang でした。そのうち application/yang-data+xml の応答の先頭は以下のとおりです。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+xml' https://172.16.1.241/restconf/tailf/modules/ietf-interfaces/2014-05-08
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:31 GMT
Content-Type: application/yang
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
module ietf-interfaces {
namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
prefix if;
…(省略)Accept を付けない GET の応答の先頭も同じ形です。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - https://172.16.1.241/restconf/tailf/modules/ietf-interfaces/2014-05-08
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:31 GMT
Content-Type: application/yang
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
module ietf-interfaces {
namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
prefix if;
…(省略)8 通りの結果をまとめると、以下のとおりです。
| 要求の Accept | ステータス | 応答の Content-Type | 本文 |
|---|---|---|---|
application/yang | 406 Not Acceptable | application/yang-data+xml | <errors>(error-tag は invalid-value) |
application/yang-data+xml | 200 OK | application/yang | get-schema の本文とバイト一致 |
application/yang-data+json | 200 OK | application/yang | 同上 |
application/vnd.yang.collection+xml | 200 OK | application/yang | 同上 |
application/vnd.yang.collection+json | 200 OK | application/yang | 同上 |
application/yang-patch+xml | 200 OK | application/yang | 同上 |
application/yang-patch+json | 200 OK | application/yang | 同上 |
なし(curl の既定 */*) | 200 OK | application/yang | 同上 |
RFC 8040 §1.1.5 が schema 資源の表現に定めるメディアタイプは application/yang で、本機はその型を Accept で求めた GET に 406 を返し、他の型を求めた GET と Accept を付けない GET には application/yang の本文を返しました。RFC 8040 §3.7 は取得への対応そのものを任意とし、RFC 7895 は schema の leaf を取得に使える URL がある時だけ在るものとしています。RFC 8040 §3.7 の例は、schema 資源の GET に Accept: application/yang を付け、200 OK と Content-Type: application/yang の応答を示しています。本機が 406 を返したのと同じ Accept です。RFC 8040 の中で 406 を返す場合を定めた文は §5.2 にあり、求められた出力の符号化をサーバが支えない時に 406 を返すと定めています。この文は XML と JSON の符号化についての節の文で、schema 資源(application/yang)に当てはまるかは判定していません。
If the server does not support any of the requested output encodings for a request, then it MUST return an error response with a “406 Not Acceptable” status-line.
RFC の文・例と本機の応答は並べるだけで、406 を規定に照らした判定はしていません。406 を返した理由も確かめていません(§12)。以降の YANG の本文の抜粋は、get-schema で取り出したものです。
6. ietf-interfaces の本文を読む
6.1 module・namespace・prefix・import
機器が get-schema で返した本文(ietf-interfaces@2014-05-08)の先頭は以下のとおりです。
module ietf-interfaces {
namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
prefix if;
import ietf-yang-types {
prefix yang;
}
…(省略)module 文は、モジュールの名前を定め、そのモジュールに属する文をまとめます。
The “module” statement defines the module’s name, and groups all statements that belong to the module together.
namespace 文は、モジュールが定める識別子を修飾する XML の名前空間を定めます。NETCONF のクライアントとサーバは、データを XML で書くときにこの名前空間を使います。
The “namespace” statement defines the XML namespace that all identifiers defined by the module are qualified by, with the exception of data node identifiers defined inside a grouping (see Section 7.12 for details). The argument to the “namespace” statement is the URI of the namespace.
A NETCONF client or server uses the namespace during XML encoding of data.
prefix 文は、モジュールとその名前空間に結び付く接頭辞を定めます。ietf-interfaces の接頭辞は if です。
The “prefix” statement is used to define the prefix associated with the module and its namespace.
7-1 §9.3 で error-message の中に現れた if: は、この prefix if; の値です。根拠は、機器が返した ietf-interfaces の本文の prefix if; と、同じ機器の応答の中の次の書き方です。
| 機器の応答 | 接頭辞の現れ方 | 場所 |
|---|---|---|
| RESTCONF の XML の応答 | xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces" を宣言 | §7 |
| RESTCONF のエラーの文言 | ietf-interfaces の節点は /if:interfaces/if:interface[if:name='Loopback0']、openconfig-interfaces の節点は /oc-if:interfaces/oc-if:interface[oc-if:name='Loopback0']、ietf-ip が足した節点は ip:ipv4/ip:mtu | §10・§11 |
NETCONF の error-path | xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces" を宣言し、if:interfaces/if:interface[if:name='Loopback0']/if:enabled と書く | §10 |
oc-if は openconfig-interfaces の本文の prefix "oc-if";、ip は ietf-ip の本文の prefix ip; の値です(§8.1・§6.5)。機器の応答に現れた接頭辞は、どれも節点を定めたモジュールの prefix 文の値でした。一方、YANG の本文の中で別のモジュールの定義を指す時の接頭辞は、その本文の import 文の中の prefix で決まり、相手のモジュールの prefix 文と同じとは限りません。機器が返した openconfig-interfaces の本文は、ietf-interfaces を import ietf-interfaces { prefix ietf-if; } と取り込み、base ietf-if:interface-type; と指しています(11 行目・313 行目)。
RFC 6020 は、モジュールの中の prefix を、そのモジュールが import されるときに使う接頭辞とし、XML や XPath で接頭辞を使うサーバは、衝突が無ければモジュールが定めた接頭辞を使うべき(SHOULD)としています。RFC 7950 は同じ所を「使うよう勧められる接頭辞」(suggested) と書き換えました。接頭辞の選び方は仕様で固定されているわけではなく、本機は各モジュールの prefix 文の値を使っていた、というのが本ラボの観測です。
When used inside the “module” statement, the “prefix” statement defines the prefix to be used when this module is imported. To improve readability of the NETCONF XML, a NETCONF client or server that generates XML or XPath that use prefixes SHOULD use the prefix defined by the module, unless there is a conflict.
When used inside the “module” statement, the “prefix” statement defines the prefix suggested to be used when this module is imported. To improve readability of the NETCONF XML, a NETCONF client or server that generates XML or XPath that uses prefixes SHOULD use the prefix defined by the module as the XML namespace prefix, unless there is a conflict.
一方、JSON のメンバ名と URL に付くのは、接頭辞ではなくモジュールの名前(ietf-interfaces:)でした(7-1 §8.4、本節 §7)。
import 文は、他のモジュールの定義を使えるようにします。import の中の prefix は、import する側のモジュールの中だけで効く接頭辞です。ietf-interfaces は ietf-yang-types を yang という接頭辞で import し、状態の統計の型に yang:counter64 のように使っています(§6.4 の木)。
The “import” statement makes definitions from one module available inside another module or submodule.
The mandatory “prefix” substatement assigns a prefix for the imported module that is scoped to the importing module or submodule. Multiple “import” statements may be specified to import from different modules.
6.2 identity と feature
ietf-interfaces は、インタフェースの種類の基になる identity を 1 つ定め、任意の機能を 3 つの feature で定めています。
…(省略)
identity interface-type {
description
"Base identity from which specific interface types are
derived.";
}
…(省略)
feature arbitrary-names {
description
"This feature indicates that the device allows user-controlled
interfaces to be named arbitrarily.";
}
feature pre-provisioning {
description
"This feature indicates that the device supports
pre-provisioning of interface configuration, i.e., it is
possible to configure an interface whose physical interface
hardware is not present on the device.";
}
feature if-mib {
description
"This feature indicates that the device implements
the IF-MIB.";
reference
"RFC 2863: The Interfaces Group MIB";
}
…(省略)identity は、名前と意味と存在だけを持つ、大域で一意な識別子です。他の identity を基 (base) にして派生させることができます。
The “identity” statement is used to define a new globally unique, abstract, and untyped identity. Its only purpose is to denote its name, semantics, and existence. An identity can either be defined from scratch or derived from a base identity.
The “base” statement, which is optional, takes as an argument a string that is the name of an existing identity, from which the new identity is derived. If no “base” statement is present, the identity is defined from scratch.
インタフェースの具体的な種類は、別のモジュールの iana-if-type が、ietf-interfaces の interface-type を基にした identity として定めています。機器が get-schema で返した本文(iana-if-type@2014-05-08)では、iana-interface-type の base が if:interface-type で、Loopback の種類の softwareLoopback の base が iana-interface-type です。
module iana-if-type {
namespace "urn:ietf:params:xml:ns:yang:iana-if-type";
prefix ianaift;
import ietf-interfaces {
prefix if;
}
…(省略)
identity iana-interface-type {
base if:interface-type;
description
"This identity is used as a base for all interface types
defined in the 'ifType definitions' registry.";
}
…(省略)
identity softwareLoopback {
base iana-interface-type;
}
…(省略)iana-if-type の本文も ietf-interfaces を if という接頭辞で import し、base if:interface-type; と書いています。iana-if-type 自身の接頭辞は ianaift です。
feature は、モジュールの一部を、機器が支えるかどうかで有効・無効が決まる任意の部分にする仕組みです。feature に依る定義には if-feature 文を付けます。
YANG supports this conditional mechanism using a construct called “feature”. Features give the modeler a mechanism for making portions of the module conditional in a manner that is controlled by the device.
Features are defined using the “feature” statement. Definitions in the module that are conditional to the feature are noted by the “if-feature” statement with the name of the feature as its argument.
§4.1 の hello と §4.5 の yang-library のとおり、本機は ietf-interfaces の 3 つの feature(arbitrary-names・if-mib・pre-provisioning)をすべて名乗っていました。feature を名乗らない機器での振る舞いは、本ラボでは撮っていません(§11.3・§12)。
6.3 container・list・key・leaf・type
設定の側の木は、container interfaces の下の list interface で、key は name です。
…(省略)
container interfaces {
description
"Interface configuration parameters.";
list interface {
key "name";
…(省略)
leaf type {
type identityref {
base interface-type;
}
mandatory true;
…(省略)
leaf enabled {
type boolean;
default "true";
…(省略)
leaf link-up-down-trap-enable {
if-feature if-mib;
type enumeration {
enum enabled {
value 1;
}
enum disabled {
value 2;
}
}
description
"Controls whether linkUp/linkDown SNMP notifications
should be generated for this interface.
If this node is not configured, the value 'enabled' is
operationally used by the server for interfaces that do
not operate on top of any other interface (i.e., there are
no 'lower-layer-if' entries), and 'disabled' otherwise.";
reference
"RFC 2863: The Interfaces Group MIB -
ifLinkUpDownTrapEnable";
}
…(省略)container は子の節点をまとめる節点で、値を持ちません。list は要素の並びで、各要素は key の leaf の値で区別されます。
A container node is used to group related nodes in a subtree. A container has only child nodes and no value.
A list defines a sequence of list entries. Each entry is like a structure or a record instance, and is uniquely identified by the values of its key leafs.
設定を表す list には key が必須です。
The “key” statement, which MUST be present if the list represents configuration, and MAY be present otherwise, takes as an argument a string that specifies a space-separated list of leaf identifiers of this list.
leaf は 1 つの値を持つ節点です。leaf type の型は identityref で、base は §6.2 の interface-type です。leaf enabled は boolean で、既定は true です。leaf link-up-down-trap-enable は enumeration で、if-feature if-mib; が付いているので、if-mib の feature を支える機器でだけ有効な節点です。
A leaf node contains simple data like an integer or a string. It has exactly one value of a particular type and no child nodes.
identityref の値に入れられるのは、base から派生した identity で、さらにそのサーバが支えるモジュールで定めた identity に限られます。
Valid values for an identityref are any identities derived from the identityref’s base identity. On a particular server, the valid values are further restricted to the set of identities defined in the modules supported by the server.
6.4 config false — interfaces-state
状態の側は、別の container interfaces-state で、config false; が付いています。if-index の leaf にも if-feature if-mib; が付いています。
…(省略)
container interfaces-state {
config false;
description
"Data nodes for the operational state of interfaces.";
…(省略)
leaf if-index {
if-feature if-mib;
type int32 {
range "1..2147483647";
}
mandatory true;
…(省略)RFC 7223 は、設定のインタフェースの list と、すべてのインタフェースの運用状態の list を分けています。
There is one list of configured interfaces ("/interfaces/interface"), and a separate list for the operational state of all interfaces ("/interfaces-state/interface").
config false を付けた節点は状態のデータで、<get> では返り、<get-config> では返りません。config false の節点の下に config true の節点は置けません。
When a node is tagged with “config false”, its subhierarchy is flagged as state data, to be reported using NETCONF’s <get> operation, not the <get-config> operation.
If a node has “config” set to “false”, no node underneath it can have “config” set to “true”.
機器が返した本文(ietf-interfaces と、それが import する ietf-yang-types の 2 本)を pyang 2.7.1 で描いた木(ツール側の観測)は、以下のとおりです。コマンドは pyang -V --no-path-recurse -p yang -f tree yang/ietf-interfaces@2014-05-08.yang です。
module: ietf-interfaces
+--rw interfaces
| +--rw interface* [name]
| +--rw name string
| +--rw description? string
| +--rw type identityref
| +--rw enabled? boolean
| +--rw link-up-down-trap-enable? enumeration {if-mib}?
+--ro interfaces-state
+--ro interface* [name]
+--ro name string
+--ro type identityref
+--ro admin-status enumeration {if-mib}?
+--ro oper-status enumeration
+--ro last-change? yang:date-and-time
+--ro if-index int32 {if-mib}?
+--ro phys-address? yang:phys-address
+--ro higher-layer-if* interface-state-ref
+--ro lower-layer-if* interface-state-ref
+--ro speed? yang:gauge64
+--ro statistics
+--ro discontinuity-time yang:date-and-time
+--ro in-octets? yang:counter64
+--ro in-unicast-pkts? yang:counter64
+--ro in-broadcast-pkts? yang:counter64
+--ro in-multicast-pkts? yang:counter64
+--ro in-discards? yang:counter32
+--ro in-errors? yang:counter32
+--ro in-unknown-protos? yang:counter32
+--ro out-octets? yang:counter64
+--ro out-unicast-pkts? yang:counter64
+--ro out-broadcast-pkts? yang:counter64
+--ro out-multicast-pkts? yang:counter64
+--ro out-discards? yang:counter32
+--ro out-errors? yang:counter32pyang が読んだファイルは、次の 2 本だけでした(-V の表示)。
yang/ietf-interfaces@2014-05-08.yang
yang/ietf-yang-types@2013-07-15.yang木の読み方は §2.3 の表のとおりです。+--rw interfaces の下が設定、+--ro interfaces-state の下が状態です。interface* [name] は key が name の list、description? は任意の leaf、link-up-down-trap-enable? と if-index の {if-mib}? は、その節点が if-mib の feature に依ることを示しています。状態の統計の型は、yang:counter64 と yang:counter32 です(yang は ietf-yang-types の import の接頭辞)。
6.5 augment — ietf-ip
IP アドレスの節点は、ietf-interfaces には無く、別のモジュールの ietf-ip が augment で足しています。機器が get-schema で返した本文(ietf-ip@2014-06-16)は以下のとおりです。
module ietf-ip {
namespace "urn:ietf:params:xml:ns:yang:ietf-ip";
prefix ip;
import ietf-interfaces {
prefix if;
}
…(省略)
augment "/if:interfaces/if:interface" {
description
"Parameters for configuring IP on interfaces.
If an interface is not capable of running IP, the server
must not allow the client to configure these parameters.";
container ipv4 {
presence
"Enables IPv4 unless the 'enabled' leaf
(which defaults to 'true') is set to 'false'";
description
"Parameters for the IPv4 address family.";
…(省略)ietf-ip の接頭辞は ip で、ietf-interfaces を if という接頭辞で import し、augment "/if:interfaces/if:interface" で ietf-interfaces の interface の list に container ipv4 を足しています。RFC 6020 は augment を、他のモジュールの木に節点を足す仕組みとしています。
YANG allows a module to insert additional nodes into data models, including both the current module (and its submodules) or an external module.
The “augment” statement allows a module or submodule to add to the schema tree defined in an external module, or the current module and its submodules, and to add to the nodes from a grouping in a “uses” statement. The argument is a string that identifies a node in the schema tree. This node is called the augment’s target node. The target node MUST be either a container, list, choice, case, input, output, or notification node.
RFC 7277 は、ietf-ip が ietf-interfaces の interface と interface-state の list を augment すると書いています。
This document defines the YANG module “ietf-ip”, which augments the “interface” and “interface-state” lists defined in the “ietf-interfaces” module [RFC7223] with IP-specific data nodes, and also adds IP-specific state data.
RFC 7277 は、後継の RFC 8344 に置き換えられています。本機が載せる ietf-ip は、RFC 7277 の版(2014-06-16)です。
This document obsoletes RFC 7277.
ietf-interfaces と ietf-ip を合わせて pyang 2.7.1 で描いた木(ツール側の観測。deviation は当てていない。以下 T2a)の、設定の側は以下のとおりです。コマンドは pyang -V --no-path-recurse -p yang -f tree yang/ietf-interfaces@2014-05-08.yang yang/ietf-ip@2014-06-16.yang です。
module: ietf-interfaces
+--rw interfaces
| +--rw interface* [name]
| +--rw name string
| +--rw description? string
| +--rw type identityref
| +--rw enabled? boolean
| +--rw link-up-down-trap-enable? enumeration {if-mib}?
| +--rw ip:ipv4!
| | +--rw ip:enabled? boolean
| | +--rw ip:forwarding? boolean
| | +--rw ip:mtu? uint16
| | +--rw ip:address* [ip]
| | | +--rw ip:ip inet:ipv4-address-no-zone
| | | +--rw (ip:subnet)
| | | +--:(ip:prefix-length)
| | | | +--rw ip:prefix-length? uint8
| | | +--:(ip:netmask)
| | | +--rw ip:netmask? yang:dotted-quad {ipv4-non-contiguous-netmasks}?
| | +--rw ip:neighbor* [ip]
| | +--rw ip:ip inet:ipv4-address-no-zone
| | +--rw ip:link-layer-address yang:phys-address
| +--rw ip:ipv6!
| +--rw ip:enabled? boolean
| +--rw ip:forwarding? boolean
| +--rw ip:mtu? uint32
| +--rw ip:address* [ip]
| | +--rw ip:ip inet:ipv6-address-no-zone
| | +--rw ip:prefix-length uint8
| +--rw ip:neighbor* [ip]
| | +--rw ip:ip inet:ipv6-address-no-zone
| | +--rw ip:link-layer-address yang:phys-address
| +--rw ip:dup-addr-detect-transmits? uint32
| +--rw ip:autoconf
| +--rw ip:create-global-addresses? boolean
| +--rw ip:create-temporary-addresses? boolean {ipv6-privacy-autoconf}?
| +--rw ip:temporary-valid-lifetime? uint32 {ipv6-privacy-autoconf}?
| +--rw ip:temporary-preferred-lifetime? uint32 {ipv6-privacy-autoconf}?
…(省略)augment で足された節点は、ietf-ip の接頭辞 ip: を付けて描かれています(§2.3 の RFC 8340 §2.6)。ip:ipv4! の ! は presence container の印です。(ip:subnet) の行は ietf-ip の本文の choice subnet にあたります。
同じ 2 本に、機器が hello の deviations= に挙げた cisco-xe-ietf-ip-deviation を当てて描いた木(以下 T2b)の、設定の側は以下のとおりです。コマンドは pyang -V --no-path-recurse -p yang -f tree --deviation-module yang/cisco-xe-ietf-ip-deviation@2016-08-10.yang yang/ietf-interfaces@2014-05-08.yang yang/ietf-ip@2014-06-16.yang です。
module: ietf-interfaces
+--rw interfaces
| +--rw interface* [name]
| +--rw name string
| +--rw description? string
| +--rw type identityref
| +--rw enabled? boolean
| +--rw link-up-down-trap-enable? enumeration {if-mib}?
| +--rw ip:ipv4!
| | +--rw ip:address* [ip]
| | +--rw ip:ip inet:ipv4-address-no-zone
| | +--rw (ip:subnet)
| | +--:(ip:prefix-length)
| | | +--rw ip:prefix-length? uint8
| | +--:(ip:netmask)
| | +--rw ip:netmask? yang:dotted-quad {ipv4-non-contiguous-netmasks}?
| +--rw ip:ipv6!
| +--rw ip:address* [ip]
| +--rw ip:ip inet:ipv6-address-no-zone
| +--rw ip:prefix-length uint8
…(省略)T2a の ip:ipv4! の下にあった ip:enabled?・ip:forwarding?・ip:mtu?・ip:neighbor* が、T2b では消えています。deviation の本文と、機器が返した応答は §11 で扱います。
7. 名前が XML・JSON・URL に現れるまで
7-1 §8.4 は、RESTCONF の URL の最初の節点と、親とモジュールが変わる節点にモジュール名とコロンを付ける RFC 8040 の規則と、JSON の最上位のメンバと、親と名前空間が変わるメンバにモジュール名を付ける RFC 7951 の規則を引きました。付く名前は、YANG の本文の module 文・namespace 文・prefix 文から来ます。以下、同じ Loopback0 の応答でその対応を示します。
RESTCONF の GET で、ietf-interfaces の Loopback0 を JSON で読んだ応答は以下のとおりです(Phase C。description は day0 の initial のまま)。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:47 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"ietf-interfaces:interface": {
"name": "Loopback0",
"description": "initial",
"type": "iana-if-type:softwareLoopback",
"enabled": true,
"ietf-ip:ipv4": {
"address": [
{
"ip": "10.7.2.1",
"netmask": "255.255.255.255"
}
]
},
"ietf-ip:ipv6": {
}
}
}"ietf-interfaces:interface" の値は、{ で始まるオブジェクトでした(中の address の list は [ で始まる配列)。RFC 7951 §5.4 は、list の実体を名前と配列の組で表すと定めています。RFC 8040 の例も、URL で list の 1 件を指した要求の本文(§4.5 の PUT)と応答(§5.3.2 の GET)を、配列で書いています。RFC 8040 §5.2 は JSON の符号化を RFC 7951 に委ねていて、本機の形は RFC 7951 §5.4 の表し方(配列)と違います(7-1 §8.5・§9.2 と同じ観測)。本ラボが §9 で ietf に PATCH で送った本文もオブジェクトの形で、機器は 204 No Content を返しました。機器がこの形を使う理由は確かめていません。
A list instance is encoded as a name/array pair, and the array elements are JSON objects.
同じ URL を XML で読んだ応答は以下のとおりです。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+xml' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:47 GMT
Content-Type: application/yang-data+xml
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
<interface xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces" xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<name>Loopback0</name>
<description>initial</description>
<type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:softwareLoopback</type>
<enabled>true</enabled>
<ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
<address>
<ip>10.7.2.1</ip>
<netmask>255.255.255.255</netmask>
</address>
</ipv4>
<ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
</ipv6>
</interface>NETCONF の <get-config> で同じ要素を読むと、XML の名前空間は RESTCONF の XML と同じでした。
#324
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
<get-config><source><running/></source><filter type="subtree"><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>Loopback0</name></interface></interfaces></filter></get-config>
</rpc>
##<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101"><data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>Loopback0</name><description>initial</description><type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:softwareLoopback</type><enabled>true</enabled><ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"><address><ip>10.7.2.1</ip><netmask>255.255.255.255</netmask></address></ipv4><ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"></ipv6></interface></interfaces></data></rpc-reply>同じ ipv4 の節点が、書く場所によって別の名前で現れました。
| 書く場所 | 付く名前 | 本ラボの例 | 名前の出どころ |
|---|---|---|---|
| YANG の本文・pyang の木・機器のエラーの文言 | 接頭辞 | ip:ipv4(木)・if:interface(エラーの文言) | 節点を定めたモジュールの prefix 文(本文の中で別のモジュールを指す時は、その本文の import 文の prefix) |
| JSON のメンバ名 | モジュールの名前 | "ietf-ip:ipv4"・"ietf-interfaces:interface" | module 文 |
| RESTCONF の URL | モジュールの名前 | /restconf/data/ietf-interfaces:interfaces/interface=Loopback0 | module 文 |
| XML | 名前空間の URI | <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"> | namespace 文 |
JSON の "ietf-ip:ipv4" と XML の <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"> は、augment で足した節点が、augment を書いたモジュール(ietf-ip)の名前空間に属することの現れです。足される側(ietf-interfaces)の名前空間ではありません。
All data nodes defined in the “augment” statement are defined as XML elements in the XML namespace of the module where the “augment” is specified.
RFC 7951 §4 の名前空間付きのメンバ名は、節点を定めたモジュールの名前とコロンを付けた形です。同じ節の例も、親が別のモジュールで定められているのでモジュール名が付く、と説明しています。
o namespace-qualified - the data node identifier is prefixed with the name of the module in which the data node is defined, separated from the data node identifier by the colon character (":").
The name of the “bar” leaf is prefixed with the namespace identifier because its parent is defined in a different module.
type の値の書き方も、JSON と XML で違いました。JSON は "iana-if-type:softwareLoopback"(モジュールの名前)で、XML は xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type" を宣言したうえで ianaift:softwareLoopback(iana-if-type の prefix 文の値)でした。RFC 7951 §6.8 は、identity が leaf と別のモジュールで定められているときは、値にモジュール名を付けることを求めています。
If the identity is defined in a module other than the leaf node containing the identityref value, the namespace-qualified form (Section 4) MUST be used.
The namespace identifier “iana-if-type” must be present in this case because the “ethernetCsmacd” identity is not defined in the same module as the “type” leaf.
XML では、identityref の値は identity の修飾名(XML の名前空間の規則による名前)で書きます。本ラボの応答は ianaift: の接頭辞付きの形でした。RFC 6020 §9.10.3 は、接頭辞の無い値も定めていて、その場合は値を含む要素で有効な既定の名前空間の identity を指します。
An identityref is encoded as the referred identity’s qualified name as defined in [XML-NAMES]. If the prefix is not present, the namespace of the identityref is the default namespace in effect on the element that contains the identityref value.
JSON の値の型にも、YANG の型が現れました。"enabled": true は boolean、"name": "Loopback0" は string です。状態の側を読むと、数値の書き方が型ごとに違いました。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces-state/interface=Loopback0
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:47 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"ietf-interfaces:interface": {
"name": "Loopback0",
"type": "iana-if-type:softwareLoopback",
"admin-status": "up",
"oper-status": "up",
"last-change": "2026-09-30T18:07:37.89+00:00",
"if-index": 4,
"phys-address": "00:1e:49:74:14:00",
"speed": "8000000000",
"statistics": {
"discontinuity-time": "2026-09-30T18:05:36+00:00",
"in-octets": "0",
"in-unicast-pkts": "0",
"in-broadcast-pkts": "0",
"in-multicast-pkts": "0",
"in-discards": 0,
"in-errors": 0,
"in-unknown-protos": 0,
"out-octets": "0",
"out-unicast-pkts": "0",
"out-broadcast-pkts": "0",
"out-multicast-pkts": "0",
"out-discards": 0,
"out-errors": 0
}
}
}"if-index": 4(int32)と "in-discards": 0(yang:counter32)は JSON の数値で、"in-octets": "0"(yang:counter64)は JSON の文字列です。if-index は §6.4 の木で {if-mib}? が付いていた leaf です。RFC 7951 §6.1 は、32 ビット以下の整数を JSON の数値、64 ビットの整数を JSON の文字列で表すと定めています。
A value of the “int8”, “int16”, “int32”, “uint8”, “uint16”, or “uint32” type is represented as a JSON number.
A value of the “int64”, “uint64”, or “decimal64” type is represented as a JSON string whose content is the lexical representation of the corresponding YANG type as specified in Sections 9.2.1 and 9.3.1 of [RFC7950].
counter64 の基の型は uint64 です。RFC 6991 の ietf-yang-types は、counter64 を次のように定めています(機器が get-schema で返した ietf-yang-types@2013-07-15 の本文も type uint64; です)。
typedef counter64 { type uint64; description “The counter64 type represents a non-negative integer that monotonically increases until it reaches a maximum value of 2^64-1 (18446744073709551615 decimal), when it wraps around and starts increasing again from zero.
Loopback0 の応答の "ietf-ip:ipv6" の値は中身の無いオブジェクトで、XML でも中身の無い <ipv6> の要素でした。ietf-ip が足した ipv6 の container が中身を持たずに現れたもので、何を意味するかは確かめていません(§12)。
8. 同じ Loopback0 を 3 系統で読む
同じ Loopback0 は、ietf-interfaces(IETF)のほかに、openconfig-interfaces(OpenConfig)と Cisco-IOS-XE-native(Cisco native)の 2 つのモデルでも読めました。§2 の RFC 6020 §4.2.1 が書く、複数のモジュールで見せる形にあたります(機器の中で 1 つのデータを共有しているかは撮っていません。§9)。
8.1 OpenConfig — config と state
OpenConfig は、運用者 (operator) の集まりが定めた規約に沿って YANG のモジュールを書いています。モジュール名の openconfig は OpenConfig が出したモジュールであることを示し、接頭辞は oc- で始めます。
This document describes conventions adopted in the OpenConfig operator group when writing YANG modules.
The ‘openconfig’ prefix indicates that the module is originated by the OpenConfig operator group.
Module prefixes should be of the form
oc-xxx[-yyy]
openconfig-interfaces の名前は openconfig-interfaces、接頭辞は oc-if です(§5.2 の本文の先頭の prefix "oc-if";)。
RESTCONF の GET で openconfig-interfaces の Loopback0 を読んだ応答は以下のとおりです。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/openconfig-interfaces:interfaces/interface=Loopback0
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:47 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"openconfig-interfaces:interface": {
"name": "Loopback0",
"config": {
"name": "Loopback0",
"type": "iana-if-type:softwareLoopback",
"description": "initial",
"enabled": true
},
"state": {
"name": "Loopback0",
"type": "iana-if-type:softwareLoopback",
"description": "initial",
"enabled": true,
"ifindex": 4,
"admin-status": "UP",
"oper-status": "UP",
…(省略)
},
"subinterfaces": {
"subinterface": [
{
"index": 0,
"config": {
"index": 0,
"description": "initial",
"enabled": true
},
…(省略)
"openconfig-if-ip:ipv4": {
"addresses": {
"address": [
{
"ip": "10.7.2.1",
"config": {
"ip": "10.7.2.1",
"prefix-length": 32
},
…(省略)ietf-interfaces と違い、OpenConfig の Loopback0 は config と state の 2 つの container を持ち、IP アドレスは subinterfaces の下の "openconfig-if-ip:ipv4" にありました。state の oper-status は "UP"(大文字)で、ietf-interfaces の状態の "up"(§7)と違います。どちらも各モジュールの本文が定める enumeration の値です(openconfig-interfaces の本文の 463 行目は enum UP {、ietf-interfaces の本文の 348 行目は enum up {)。応答の中に loopback-mode の節点はありませんでした。同じ応答には、deviation の対象ではない mtu もありません。応答に無いことだけでは deviation と結び付けられないので、deviation は本文と書き込みの応答で扱います(§11)。
OpenConfig の style guide は、設定に加えて運用状態をモデルにすることを重んじ、各部分木に config と state という名前の container を置く規約を採っています。
OpenConfig has adopted a structural convention for YANG models that emphasizes the importance of modeling operational state (i.e., monitoring and telemetry data), in addition to configuration data.
At a high level, this convention uses specially named
configandstatecontainers, in every subtree to explicitly indicate configuration and operational state data.
機器が get-schema で返した本文(openconfig-interfaces@2018-01-05)で、interface の list を定める所は以下のとおりです。
…(省略)
grouping interface-phys-config {
description
"Configuration data for physical interfaces";
…(省略)
leaf mtu {
type uint16;
…(省略)
leaf loopback-mode {
type boolean;
default false;
…(省略)
uses interface-common-config;
}
…(省略)
list interface {
key "name";
description
"The list of named interfaces on the device.";
leaf name {
type leafref {
path "../config/name";
}
…(省略)
container config {
description
"Configurable items at the global, physical interface
level";
uses interface-phys-config;
}
container state {
config false;
description
"Operational state data at the global interface level";
uses interface-phys-config;
uses interface-common-state;
uses interface-counters-state;
}
…(省略)container config は uses interface-phys-config; で grouping を使い、container state は config false; を付けたうえで、同じ uses interface-phys-config; に加えて状態の grouping を使っています。grouping は再利用する節点のまとまりの定義で、それだけではスキーマの木に節点を作りません。uses は grouping の節点を、その場所に写します。
Groups of nodes can be assembled into reusable collections using the “grouping” statement.
The “grouping” statement is not a data definition statement and, as such, does not define any nodes in the schema tree.
The effect of a “uses” reference to a grouping is that the nodes defined by the grouping are copied into the current schema tree, and then updated according to the “refine” and “augment” statements.
style guide の付録の例も、state の container が config と state の両方の grouping を uses で含む形です。
uses rsvp-graceful-restart-config; uses rsvp-graceful-restart-state;
list の key の leaf name は、型が leafref で、path "../config/name"; で config の中の name を指しています。leafref は、データの木の中の特定の leaf を指す型です。style guide は、list の key をこの形にすることを求めています。
The leafref type is used to reference a particular leaf instance in the data tree. The “path” substatement (Section 9.9.2) selects a set of leaf instances, and the leafref value space is the set of values of these leaf instances.
Hence, the list key leaf nodes should be of type
leafrefwith apathpointing to the corresponding “actual” leaf in the config or state container.
The node acting as the key of the
listMUST be of typeleafrefas specified elsewhere in this guide.
openconfig-interfaces と openconfig-if-ip・openconfig-vlan を合わせて pyang 2.7.1 で描いた木(ツール側の観測。deviation は当てていない。以下 T3a)の先頭は以下のとおりです。コマンドは pyang -V --no-path-recurse -p yang -f tree yang/openconfig-interfaces@2018-01-05.yang yang/openconfig-if-ip@2018-01-05.yang yang/openconfig-vlan@2016-05-26.yang です。
module: openconfig-interfaces
+--rw interfaces
+--rw interface* [name]
+--rw name -> ../config/name
+--rw config
| +--rw name? string
| +--rw type identityref
| +--rw mtu? uint16
| +--rw loopback-mode? boolean
| +--rw description? string
| +--rw enabled? boolean
| +--rw oc-vlan:tpid? identityref
+--ro state
| +--ro name? string
| +--ro type identityref
| +--ro mtu? uint16
| +--ro loopback-mode? boolean
| +--ro description? string
| +--ro enabled? boolean
| +--ro ifindex? uint32
| +--ro admin-status enumeration
| +--ro oper-status enumeration
| +--ro last-change? oc-types:timeticks64
…(省略)+--rw name -> ../config/name が key の leafref で、+--rw config の下と +--ro state の下に、同じ name・type・mtu・loopback-mode・description・enabled が並んでいます。uses で写した grouping の節点は、木では展開して描かれます。
Nodes within a used grouping are normally expanded as if the nodes were defined at the location of the “uses” statement.
config の下の節点は rw、state の下の節点は ro です。state には、ifindex・admin-status・oper-status などの状態の節点が加わっています。
XML の応答の名前空間は、openconfig-interfaces の namespace でした。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+xml' https://172.16.1.241/restconf/data/openconfig-interfaces:interfaces/interface=Loopback0
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:48 GMT
Content-Type: application/yang-data+xml
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
<interface xmlns="http://openconfig.net/yang/interfaces" xmlns:oc-if="http://openconfig.net/yang/interfaces">
<name>Loopback0</name>
<config>
<name>Loopback0</name>
<type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:softwareLoopback</type>
<description>initial</description>
<enabled>true</enabled>
</config>
…(省略)OpenConfig のモデルは、特定のベンダに寄らない形を目指しています。本ラボは Cisco の 1 台だけで撮ったので、他のベンダの機器で同じ形が読めるかは確かめていません(§12)。
OpenConfig models are vendor-neutral and intended to express an operationally complete set of features.
8.2 Cisco native — サブモジュールの list Loopback
Cisco-IOS-XE-native の URL では、Loopback0 は /restconf/data/Cisco-IOS-XE-native:native/interface/Loopback=0 です。RESTCONF の GET の応答は以下のとおりです。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/Cisco-IOS-XE-native:native/interface/Loopback=0
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:47 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"Cisco-IOS-XE-native:Loopback": {
"name": 0,
"description": "initial",
"ip": {
"address": {
"primary": {
"address": "10.7.2.1",
"mask": "255.255.255.255"
}
}
}
}
}XML では以下のとおりです。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+xml' https://172.16.1.241/restconf/data/Cisco-IOS-XE-native:native/interface/Loopback=0
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:47 GMT
Content-Type: application/yang-data+xml
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
<Loopback xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native" xmlns:ios="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
<name>0</name>
<description>initial</description>
<ip>
<address>
<primary>
<address>10.7.2.1</address>
<mask>255.255.255.255</mask>
</primary>
</address>
</ip>
</Loopback>native の key の "name" は、JSON の数値 0 でした。ietf-interfaces と openconfig-interfaces の key が文字列 "Loopback0" だったのと違い、Loopback の番号だけが key です。
Loopback の list は、Cisco-IOS-XE-native のモジュールの本文には無く、サブモジュールにあります。機器が get-schema で返した本文(Cisco-IOS-XE-native@2020-07-04)の先頭は以下のとおりで、7 つのサブモジュールを include しています(§4.5 の yang-library のエントリの submodule の 7 本と同じ名前)。
module Cisco-IOS-XE-native {
namespace "http://cisco.com/ns/yang/Cisco-IOS-XE-native";
prefix ios;
…(省略)
include Cisco-IOS-XE-parser;
include Cisco-IOS-XE-license;
include Cisco-IOS-XE-line;
include Cisco-IOS-XE-logging;
include Cisco-IOS-XE-ip;
include Cisco-IOS-XE-ipv6;
include Cisco-IOS-XE-interfaces;
…(省略)サブモジュールの本文(Cisco-IOS-XE-interfaces@2020-07-02)は、belongs-to Cisco-IOS-XE-native で属するモジュールを示し、その中に list Loopback があります。key の leaf name の型は uint32 で、範囲は 0..2147483647 です。
submodule Cisco-IOS-XE-interfaces {
belongs-to Cisco-IOS-XE-native {
prefix ios;
}
…(省略)
list Loopback {
description
"Loopback interface";
key "name";
leaf name {
type uint32 {
range "0..2147483647";
}
}
uses interface-common-grouping;
}
…(省略)include したサブモジュールの中身は、モジュールの木に入ります。サブモジュールに分けても、外からは 1 つのモジュールに見えます。
When a module includes a submodule, it incorporates the contents of the submodule into the node hierarchy of the module.
A module may be divided into submodules, based on the needs of the module owner. The external view remains that of a single module, regardless of the presence or size of its submodules.
The “belongs-to” statement specifies the module to which the submodule belongs. The argument is an identifier that is the name of the module.
RFC 7951 §4 は、サブモジュールで定めた節点のメンバ名に、属するモジュールの名前を使うと定めています。応答の "Cisco-IOS-XE-native:Loopback" はこの形でした。key の "name": 0 は JSON の数値で、uint32 を JSON の数値で表すとする RFC 7951 §6.1 の定め(§7)と一致します。
If a data node is defined in a submodule, then the namespace-qualified member name uses the name of the main module to which the submodule belongs.
native の Loopback の木は載せていません。native の 1 本を pyang 2.7.1 に渡すと(pyang -V --no-path-recurse -p yang -f tree --tree-path /native/interface/Loopback yang/Cisco-IOS-XE-native@2020-07-04.yang)、pyang は import と include をたどって 13 本を読み、木を出力したうえで exit 1(error 2 件)で終わりました。エラーで終わった木は、本節では使いません。error の 2 行は、どちらも機器が返した Cisco-IOS-XE-ip(2020-07-01)の本文の 3538 行目と 3546 行目の path に対するもので、その path の中の Cisco-IOS-XE-native:interface が見つからない、という内容です。この path は、Cisco-IOS-XE-ip の本文の grouping の中の leaf Tunnel(3534・3542 行目)に在り、pyang はその grouping を native の本文の 2269 行目の uses config-ip-grouping; の位置として示しました。原因は確かめていません。示せるのは、上のサブモジュールの本文の list Loopback の定義までです。native を augment する他のモジュールや、native の deviation を当てた形は描いていません(§12)。
8.3 CLI と、3 系統の比べ
同じ時点の CLI の Loopback0 は以下のとおりです。
CSR1# show running-config interface Loopback0
Building configuration...
Current configuration : 85 bytes
!
interface Loopback0
description initial
ip address 10.7.2.1 255.255.255.255
end3 系統の違いを並べると、以下のとおりです(値はどれも Phase C の応答)。
| 項目 | IETF(ietf-interfaces) | OpenConfig(openconfig-interfaces) | Cisco native(Cisco-IOS-XE-native) |
|---|---|---|---|
| RESTCONF の URL | …/ietf-interfaces:interfaces/interface=Loopback0 | …/openconfig-interfaces:interfaces/interface=Loopback0 | …/Cisco-IOS-XE-native:native/interface/Loopback=0 |
| JSON の最上位のメンバ | "ietf-interfaces:interface" | "openconfig-interfaces:interface" | "Cisco-IOS-XE-native:Loopback" |
| key の値(JSON) | "Loopback0"(string) | "Loopback0"(leafref → string) | 0(uint32) |
| XML の名前空間 | urn:ietf:params:xml:ns:yang:ietf-interfaces | http://openconfig.net/yang/interfaces | http://cisco.com/ns/yang/Cisco-IOS-XE-native |
| 設定と状態 | 本機の 2014-05-08 の版では別の container(interfaces と interfaces-state) | 同じ要素の中の config と state | 本ラボは設定の側だけを読んだ |
| IP アドレスの置き場所 | ietf-ip の augment の ipv4(netmask) | subinterfaces の下の openconfig-if-ip の ipv4(prefix-length 32) | ip/address/primary(mask) |
9. 1 つの系統で書いて、3 つの系統で読む
Phase D では、Loopback0 の description を、1 回ごとに 1 つの系統だけで書き、3 系統と CLI で読み直しました。書いた順は ① OpenConfig(RESTCONF の PATCH)→ ② Cisco native(NETCONF の <edit-config>)→ ③ IETF(RESTCONF の PATCH)です。上の図の表は、行が時点(初期・①・②・③)、列が読み手(ietf・native・OpenConfig の config・CLI)です。
9.1 ① OpenConfig に PATCH
openconfig-interfaces の …/interface=Loopback0/config に description set-by-openconfig を PATCH すると、204 No Content が返りました。
WSL $ curl -sS -i -k --max-time 60 -X PATCH -K - -H 'Accept: application/yang-data+json' -H 'Content-Type: application/yang-data+json' --data-binary '{"openconfig-interfaces:config": {"description": "set-by-openconfig"}}' https://172.16.1.241/restconf/data/openconfig-interfaces:interfaces/interface=Loopback0/config
HTTP/1.1 204 No Content
Server: openresty
Date: Wed, 30 Sep 2026 18:08:51 GMT
Content-Type: text/html
Content-Length: 0
Connection: keep-alive
Last-Modified: Wed, 30 Sep 2026 18:08:51 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Etag: "1790-791731-545939"
Pragma: no-cache続く GET で読むと、ietf-interfaces と native の description も set-by-openconfig でした。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:51 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"ietf-interfaces:interface": {
"name": "Loopback0",
"description": "set-by-openconfig",
…(省略)WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/Cisco-IOS-XE-native:native/interface/Loopback=0
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:52 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"Cisco-IOS-XE-native:Loopback": {
"name": 0,
"description": "set-by-openconfig",
…(省略)WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/openconfig-interfaces:interfaces/interface=Loopback0/config
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:52 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"openconfig-interfaces:config": {
"name": "Loopback0",
"type": "iana-if-type:softwareLoopback",
"description": "set-by-openconfig",
"enabled": true
}
}CLI の running-config にも同じ値が現れました。
CSR1# show running-config interface Loopback0
Building configuration...
Current configuration : 95 bytes
!
interface Loopback0
description set-by-openconfig
ip address 10.7.2.1 255.255.255.255
end9.2 ② native に edit-config
NETCONF で、Cisco-IOS-XE-native の Loopback 0 の description を set-by-native にする <edit-config>(target は running)を送ると、<ok/> が返りました。
#357
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
<edit-config><target><running/></target><config><native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native"><interface><Loopback><name>0</name><description>set-by-native</description></Loopback></interface></native></config></edit-config>
</rpc>
##<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101"><ok/></rpc-reply>同じセッションの <get-config> で 3 系統を読むと、どれも set-by-native でした。native・OpenConfig・ietf-interfaces の順に以下のとおりです。
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="102"><data><native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native"><interface><Loopback><name>0</name><description>set-by-native</description><ip><address><primary><address>10.7.2.1</address><mask>255.255.255.255</mask></primary></address></ip><logging><event><link-status/></event></logging></Loopback></interface></native></data></rpc-reply><?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="103"><data><interfaces xmlns="http://openconfig.net/yang/interfaces"><interface><name>Loopback0</name><config><name>Loopback0</name><type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:softwareLoopback</type><description>set-by-native</description><enabled>true</enabled></config></interface></interfaces></data></rpc-reply><?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="104"><data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>Loopback0</name><description>set-by-native</description><type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:softwareLoopback</type><enabled>true</enabled><ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"><address><ip>10.7.2.1</ip><netmask>255.255.255.255</netmask></address></ipv4><ipv6 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip"></ipv6></interface></interfaces></data></rpc-reply>CLI の running-config も set-by-native でした。
CSR1# show running-config interface Loopback0
Building configuration...
Current configuration : 91 bytes
!
interface Loopback0
description set-by-native
ip address 10.7.2.1 255.255.255.255
end9.3 ③ ietf-interfaces に PATCH
最後に、ietf-interfaces の …/interface=Loopback0 に description set-by-ietf を PATCH すると、204 No Content が返りました。
WSL $ curl -sS -i -k --max-time 60 -X PATCH -K - -H 'Accept: application/yang-data+json' -H 'Content-Type: application/yang-data+json' --data-binary '{"ietf-interfaces:interface": {"name": "Loopback0", "description": "set-by-ietf"}}' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0
HTTP/1.1 204 No Content
Server: openresty
Date: Wed, 30 Sep 2026 18:08:58 GMT
Content-Type: text/html
Content-Length: 0
Connection: keep-alive
Last-Modified: Wed, 30 Sep 2026 18:08:58 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Etag: "1790-791738-79197"
Pragma: no-cache続く GET で読んだ native と OpenConfig の config、CLI の running-config は、どれも set-by-ietf でした。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/Cisco-IOS-XE-native:native/interface/Loopback=0
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:58 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"Cisco-IOS-XE-native:Loopback": {
"name": 0,
"description": "set-by-ietf",
…(省略)WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/openconfig-interfaces:interfaces/interface=Loopback0/config
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:08:58 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"openconfig-interfaces:config": {
"name": "Loopback0",
"type": "iana-if-type:softwareLoopback",
"description": "set-by-ietf",
"enabled": true
}
}CSR1# show running-config interface Loopback0
Building configuration...
Current configuration : 89 bytes
!
interface Loopback0
description set-by-ietf
ip address 10.7.2.1 255.255.255.255
end撮った 3 回の範囲で、どの系統で書いた description も、他の 2 系統の読みと CLI の running-config に同じ値で現れました。Cisco の 17.3 のガイドは、モデルに基づくインタフェースが、既存の CLI・Syslog・SNMP のインタフェースと相互に働くと書いています。
In Cisco IOS XE, model-based interfaces interoperate with existing device CLI, Syslog, and SNMP interfaces.
3 系統の間で値がどう受け渡されているかという機器の中の仕組みは、本ラボでは撮っていません。
10. モデルが値を拒む
Phase E では、モデルに合わない値を RESTCONF の PATCH で 6 種、NETCONF の <edit-config> で 3 種送りました。その前と後に、CLI の running-config と、RESTCONF の GET を撮っています。前の CLI は以下のとおりです。
CSR1# show running-config interface Loopback0
Building configuration...
Current configuration : 89 bytes
!
interface Loopback0
description set-by-ietf
ip address 10.7.2.1 255.255.255.255
end10.1 RESTCONF の 6 種
ietf-interfaces の enabled(boolean)に "maybe" を送った応答は以下のとおりです。
WSL $ curl -sS -i -k --max-time 60 -X PATCH -K - -H 'Accept: application/yang-data+json' -H 'Content-Type: application/yang-data+json' --data-binary '{"ietf-interfaces:interface": {"name": "Loopback0", "enabled": "maybe"}}' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0
HTTP/1.1 400 Bad Request
Server: openresty
Date: Wed, 30 Sep 2026 18:09:03 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Vary: Accept-Encoding
Pragma: no-cache
{
"errors": {
"error": [
{
"error-message": "invalid value for: enabled in /if:interfaces/if:interface[if:name='Loopback0']/if:enabled: \"maybe\" is not a valid value.",
"error-path": "/ietf-interfaces:interfaces/interface=Loopback0",
"error-tag": "malformed-message",
"error-type": "application"
}
]
}
}openconfig-interfaces の mtu(uint16)に 70000 を送った応答は以下のとおりです。
WSL $ curl -sS -i -k --max-time 60 -X PATCH -K - -H 'Accept: application/yang-data+json' -H 'Content-Type: application/yang-data+json' --data-binary '{"openconfig-interfaces:config": {"mtu": 70000}}' https://172.16.1.241/restconf/data/openconfig-interfaces:interfaces/interface=Loopback0/config
HTTP/1.1 400 Bad Request
Server: openresty
Date: Wed, 30 Sep 2026 18:09:03 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Vary: Accept-Encoding
Pragma: no-cache
{
"errors": {
"error": [
{
"error-message": "invalid value for: mtu in /oc-if:interfaces/oc-if:interface[oc-if:name='Loopback0']/oc-if:config/oc-if:mtu: \"70000\" is not a valid value.",
"error-path": "/openconfig-interfaces:interfaces/interface=Loopback0/config",
"error-tag": "malformed-message",
"error-type": "application"
}
]
}
}URL は Loopback0 のまま、本文の key を Loopback1 にした応答は以下のとおりです。
WSL $ curl -sS -i -k --max-time 60 -X PATCH -K - -H 'Accept: application/yang-data+json' -H 'Content-Type: application/yang-data+json' --data-binary '{"ietf-interfaces:interface": {"name": "Loopback1", "description": "key-mismatch"}}' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0
HTTP/1.1 400 Bad Request
Server: openresty
Date: Wed, 30 Sep 2026 18:09:04 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Vary: Accept-Encoding
Pragma: no-cache
{
"errors": {
"error": [
{
"error-message": "/if:interfaces/interface{Loopback0}/name: inconsistent value: Key leaf given twice with different value",
"error-path": "/ietf-interfaces:interfaces/interface=Loopback0",
"error-tag": "invalid-value",
"error-type": "application"
}
]
}
}モデルに無い leaf(no-such-leaf)を送った応答は以下のとおりです。
WSL $ curl -sS -i -k --max-time 60 -X PATCH -K - -H 'Accept: application/yang-data+json' -H 'Content-Type: application/yang-data+json' --data-binary '{"ietf-interfaces:interface": {"name": "Loopback0", "no-such-leaf": "x"}}' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0
HTTP/1.1 400 Bad Request
Server: openresty
Date: Wed, 30 Sep 2026 18:09:04 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Vary: Accept-Encoding
Pragma: no-cache
{
"errors": {
"error": [
{
"error-message": "unknown element: no-such-leaf in /if:interfaces/if:interface[if:name='Loopback0']/if:no-such-leaf",
"error-path": "/ietf-interfaces:interfaces/interface=Loopback0",
"error-tag": "malformed-message",
"error-type": "application"
}
]
}
}type に、iana-if-type に無い identity(iana-if-type:noSuchType)を送った応答は以下のとおりです。
WSL $ curl -sS -i -k --max-time 60 -X PATCH -K - -H 'Accept: application/yang-data+json' -H 'Content-Type: application/yang-data+json' --data-binary '{"ietf-interfaces:interface": {"name": "Loopback0", "type": "iana-if-type:noSuchType"}}' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0
HTTP/1.1 400 Bad Request
Server: openresty
Date: Wed, 30 Sep 2026 18:09:04 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Vary: Accept-Encoding
Pragma: no-cache
{
"errors": {
"error": [
{
"error-message": "invalid value for: type in /if:interfaces/if:interface[if:name='Loopback0']/if:type: \"iana-if-type:noSuchType\" is not a valid value.",
"error-path": "/ietf-interfaces:interfaces/interface=Loopback0",
"error-tag": "malformed-message",
"error-type": "application"
}
]
}
}openconfig-interfaces の state(config false)に description を送った応答は以下のとおりです。
WSL $ curl -sS -i -k --max-time 60 -X PATCH -K - -H 'Accept: application/yang-data+json' -H 'Content-Type: application/yang-data+json' --data-binary '{"openconfig-interfaces:state": {"description": "to-state"}}' https://172.16.1.241/restconf/data/openconfig-interfaces:interfaces/interface=Loopback0/state
HTTP/1.1 400 Bad Request
Server: openresty
Date: Wed, 30 Sep 2026 18:09:04 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Vary: Accept-Encoding
Pragma: no-cache
{
"errors": {
"error": [
{
"error-message": "object is not writable: /oc-if:interfaces/oc-if:interface[oc-if:name='Loopback0']/oc-if:state",
"error-path": "/openconfig-interfaces:interfaces/interface=Loopback0/state",
"error-tag": "malformed-message",
"error-type": "application"
}
]
}
}10.2 NETCONF の 3 種
NETCONF でも、boolean・uint16 の範囲・config false の 3 種を送りました。ietf-interfaces の enabled に maybe を送った要求と応答は以下のとおりです。
#335
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
<edit-config><target><running/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>Loopback0</name><enabled>maybe</enabled></interface></interfaces></config></edit-config>
</rpc>
##<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101"><rpc-error>
<error-type>application</error-type>
<error-tag>invalid-value</error-tag>
<error-severity>error</error-severity>
<error-path xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
/nc:rpc/nc:edit-config/nc:config/if:interfaces/if:interface[if:name='Loopback0']/if:enabled
</error-path><error-message xml:lang="en">"maybe" is not a valid value.</error-message><error-info><bad-element>enabled</bad-element>
</error-info>
</rpc-error>
</rpc-reply>openconfig-interfaces の mtu に 70000 を送った要求と応答は以下のとおりです。
#338
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="102">
<edit-config><target><running/></target><config><interfaces xmlns="http://openconfig.net/yang/interfaces"><interface><name>Loopback0</name><config><mtu>70000</mtu></config></interface></interfaces></config></edit-config>
</rpc>
##<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="102"><rpc-error>
<error-type>application</error-type>
<error-tag>invalid-value</error-tag>
<error-severity>error</error-severity>
<error-path xmlns:oc-if="http://openconfig.net/yang/interfaces" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
/nc:rpc/nc:edit-config/nc:config/oc-if:interfaces/oc-if:interface[oc-if:name='Loopback0']/oc-if:config/oc-if:mtu
</error-path><error-message xml:lang="en">"70000" is not a valid value.</error-message><error-info><bad-element>mtu</bad-element>
</error-info>
</rpc-error>
</rpc-reply>openconfig-interfaces の state に description を送った要求と応答は以下のとおりです。
#355
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="103">
<edit-config><target><running/></target><config><interfaces xmlns="http://openconfig.net/yang/interfaces"><interface><name>Loopback0</name><state><description>to-state</description></state></interface></interfaces></config></edit-config>
</rpc>
##<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="103"><rpc-error>
<error-type>application</error-type>
<error-tag>unknown-element</error-tag>
<error-severity>error</error-severity>
<error-app-tag>not-writable</error-app-tag>
<error-path xmlns:oc-if="http://openconfig.net/yang/interfaces" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
/nc:rpc/nc:edit-config/nc:config/oc-if:interfaces/oc-if:interface[oc-if:name='Loopback0']/oc-if:state
</error-path><error-message xml:lang="en">object is not writable</error-message><error-info><bad-element>state</bad-element>
</error-info>
</rpc-error>
</rpc-reply>10.3 応答の並べ
9 本の応答を並べると、以下のとおりです。
| 要求 | RESTCONF(HTTP のステータス / error-tag / error-message が含む文言) | NETCONF(error-tag / bad-element) |
|---|---|---|
ietf の enabled に "maybe"(boolean) | 400 / malformed-message / "maybe" is not a valid value | invalid-value / enabled |
OpenConfig の mtu に 70000(uint16) | 400 / malformed-message / "70000" is not a valid value | invalid-value / mtu |
| key の不一致(URL は Loopback0・本文は Loopback1) | 400 / invalid-value / Key leaf given twice with different value | —(撮っていない) |
| 未知の leaf | 400 / malformed-message / unknown element: no-such-leaf | —(撮っていない) |
identity に無い値 iana-if-type:noSuchType | 400 / malformed-message / "iana-if-type:noSuchType" is not a valid value | —(撮っていない) |
OpenConfig の state(config false)に書く | 400 / malformed-message / object is not writable | unknown-element / state(error-message は object is not writable) |
9 本の要求の前と後で、次の 3 つは変わっていませんでした。running が変わらなかったと言えるのは、この 3 つで確かめた範囲です。
- CLI の
show running-config interface Loopback0は、前と後で同じだった - ietf-interfaces の Loopback0 の GET は、前と後で
Date:の行を除いて同じだった - ietf-interfaces の Loopback1 の GET は、前も後も
404 Not Foundだった(key の不一致の要求の後も、Loopback1 は GET で見えなかった)
CSR1# show running-config interface Loopback0
Building configuration...
Current configuration : 89 bytes
!
interface Loopback0
description set-by-ietf
ip address 10.7.2.1 255.255.255.255
endWSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback1
HTTP/1.1 404 Not Found
Server: openresty
Date: Wed, 30 Sep 2026 18:09:03 GMT
Content-Type: text/html
Content-Length: 0
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cacheWSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback1
HTTP/1.1 404 Not Found
Server: openresty
Date: Wed, 30 Sep 2026 18:09:07 GMT
Content-Type: text/html
Content-Length: 0
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache10.4 出典との対応
値が拒まれた理由のうち、型の定めは YANG の RFC にあります。boolean の値は小文字の true か false で、uint16 は 0 から 65535 までの整数です。
The lexical representation of a boolean value is a string with a value of “true” or “false”. These values MUST be in lowercase.
uint16 represents integer values between 0 and 65535, inclusively.
identityref に入れられるのは base から派生した identity で、サーバが支えるモジュールで定めたものに限られます(§6.3 の RFC 6020 §9.10.2)。config false の節点は <edit-config> で送れません。RESTCONF でも、設定かどうかは YANG の config 文で決まります。
If “config” is “false”, the definition represents state data. Data nodes representing state data will be part of the reply to a <get>, but not to a <get-config> request, and cannot be sent in a <copy-config> or <edit-config> request.
The classification of data as configuration data or non-configuration data is derived from the YANG “config” statement.
RESTCONF の PATCH の本文の key は、URL の key と同じでなければなりません。この文は error-tag を名指ししておらず、本機は invalid-value を返しました。
If the target resource represents a YANG list instance, then the key leaf values, in message-body representation, MUST be the same as the key leaf values in the request URI. The PATCH method MUST NOT be used to change the key leaf values for a data resource instance.
NETCONF の invalid-value は、YANG の RFC の §8.3.1 の定めと一致します。§8.3.1 は、leaf の値が型の制約(range などを含む)に合わないとき、<rpc-error> の error-tag を invalid-value にすることを求めています。RFC 7950 の文は以下のとおりで、RFC 6020 §8.3.1 にも同じ趣旨の文があります。
If a leaf data value does not match the type constraints for the leaf, including those defined in the type’s “range”, “length”, and “pattern” properties, the server MUST reply with an “invalid-value” <error-tag> in the <rpc-error>, and with the error-app-tag (Section 7.5.4.2) and error-message (Section 7.5.4.1) associated with the constraint, if any exist.
YANG の RFC のこれらのエラーの定めは、NETCONF の応答の定めです。§8.3.1 は RFC 7950 では NETCONF の制約の検査の節(NETCONF Constraint Enforcement Model)の中にあり、RFC 6020 §13 も YANG に関わる NETCONF のエラー応答を定める節です。
A number of NETCONF error responses are defined for error cases related to the data-model handling. If the relevant YANG statement has an “error-app-tag” substatement, that overrides the default value specified below.
RESTCONF の型違反にどの error-tag を返すかを名指しする文は、RFC 8040 にはありません。RFC 8040 §3.6.3 には、operation の入力の uint32 の leaf(delay)に -33 を送り、400 と invalid-value を返す例があります。規定の文ではなく例で、対象も data resource への PATCH ではありません。
The server might respond with an “invalid-value” error:
RFC 8040 §7 は、NETCONF の error-tag と HTTP のステータスの対応を表にしています。
Since an operation resource is defined with a YANG “rpc” statement and an action is defined with a YANG “action” statement, a mapping from the NETCONF <error-tag> value to the HTTP status code is needed.
| invalid-value | 400, 404, or 406 |
| unknown-element | 400 |
| malformed-message | 400 |
400 は invalid-value・unknown-element・malformed-message のどれにも対応するので、HTTP のステータスだけでは区別できず、応答の errors の error-tag まで読む必要があります。本ラボの RESTCONF は型違反に malformed-message を、NETCONF は invalid-value を返しました。RFC 6241 の Appendix A の定義は以下のとおりです。
error-tag: invalid-value error-type: protocol, application error-severity: error error-info: none Description: The request specifies an unacceptable value for one or more parameters.
error-tag: malformed-message error-type: rpc error-severity: error error-info: none Description: A message could not be handled because it failed to be parsed correctly.
error-tag: unknown-element error-type: protocol, application error-severity: error error-info: <bad-element> : name of the unexpected element Description: An unexpected element is present.
RFC 6241 の Appendix A の表は、invalid-value の行の error-info を none、bad-element と unknown-element の行の error-info を <bad-element> としています。本ラボの NETCONF の 3 本は、invalid-value の 2 本も error-info に <bad-element> を持っていました。Appendix A の表が並べるのは必須の error-info で、RFC 6241 §4.3 は、実装が error-info に要素を足すことを認めています(MAY)。invalid-value の応答に <bad-element> が付いていることは、この 2 つの文と食い違いません。
For each error-tag, the valid error-type and error-severity values are listed, together with any mandatory error-info, if any.
The list in Appendix A defines any mandatory error-info content for each error.
An implementation MAY include additional elements to provide extended and/or implementation- specific debugging information.
3 つ目の引用の implementation- specific は、原典のテキストの行末のハイフンで折り返された語を、取得したテキストのまま写したものです。
RESTCONF と NETCONF の error-tag の違いは観測として並べるだけで、どちらが正しいかは判定していません。機器が要求をどの段で拒んだかも撮っていません(§12)。
error-path の書き方も違いました。RESTCONF は要求の URL の path と同じ形(/ietf-interfaces:interfaces/interface=Loopback0)で、NETCONF は接頭辞付きの XPath(/nc:rpc/nc:edit-config/nc:config/if:interfaces/if:interface[if:name='Loopback0']/if:enabled)でした。RFC 6241 は NETCONF の error-path を絶対 XPath の式とし、RFC 8040 は RESTCONF の error-path の型を instance-identifier としています。RFC 7951 §6.11 の instance-identifier の例は、list の要素を [name='eth0'] の形で書いています。
error-path: Contains the absolute XPath [W3C.REC-xpath-19991116] expression identifying the element path to the node that is associated with the error being reported in a particular <rpc-error> element.
leaf error-path { type instance-identifier; description “The YANG instance identifier associated with the error node.”;
For example, /ietf-interfaces:interfaces/interface[name=‘eth0’]/ietf-ip:ipv4/ip is a valid instance-identifier value because the data nodes “interfaces”, “interface”, and “name” are defined in the module “ietf-interfaces”, whereas “ipv4” and “ip” are defined in “ietf-ip”.
11. deviation と feature
11.1 deviation の本文
現実の機器は、モジュールのとおりに実装できないことがあります。deviation 文は、機器がモジュールのどこを、どう違えて実装しているかを示します。
In an ideal world, all devices would be required to implement the model exactly as defined, and deviations from the model would not be allowed. But in the real world, devices are often not able or designed to implement the model as written.
The “deviation” statement defines a hierarchy of a module that the device does not implement faithfully. The argument is a string that identifies the node in the schema tree where a deviation from the module occurs. This node is called the deviation’s target node.
deviate 文の引数は not-supported・add・replace・delete の 4 つで、not-supported は、その節点を機器が実装していないことを示します。
The “deviate” statement defines how the device’s implementation of the target node deviates from its original definition. The argument is one of the strings “not-supported”, “add”, “replace”, or “delete”.
The argument “not-supported” indicates that the target node is not implemented by this device.
deviation を持つ機器は、そのモジュールに完全には準拠していません。
A device that deviates from a module is not fully compliant with the module.
RFC 6020 は、この用語を device deviation と呼び、RFC 7950 は server deviation と呼んでいます(以下の「機器」は RFC 7950 のサーバにあたります)。
device deviation: A failure of the device to implement the module faithfully.
server deviation: A failure of the server to implement a module faithfully.
hello の deviations= は、その capability のモジュールからの外れを持つモジュールの一覧です。
Device deviations are announced via the “deviations” parameter. The value of the “deviations” parameter is a comma-separated list of modules containing deviations from the capability’s module.
機器が get-schema で返した cisco-xe-ietf-ip-deviation の本文(cisco-xe-ietf-ip-deviation@2016-08-10)は以下のとおりです。
module cisco-xe-ietf-ip-deviation {
namespace "http://cisco.com/ns/cisco-xe-ietf-ip-deviation";
prefix ip-devs;
import ietf-interfaces {
prefix if;
}
import ietf-ip {
prefix ip;
}
…(省略)
deviation "/if:interfaces/if:interface/ip:ipv4/ip:enabled" {
deviate not-supported;
description
"Not supported in IOS-XE 3.17 release.";
}
deviation "/if:interfaces/if:interface/ip:ipv4/ip:forwarding" {
deviate not-supported;
description
"Not supported in IOS-XE 3.17 release.";
}
deviation "/if:interfaces/if:interface/ip:ipv4/ip:mtu" {
deviate not-supported;
description
"Not supported in IOS-XE 3.17 release.";
}
…(省略)
deviation "/if:interfaces-state/if:interface/ip:ipv4" {
deviate not-supported;
description
"Not supported in IOS-XE 16.3.2 release";
}
deviation "/if:interfaces-state/if:interface/ip:ipv6" {
deviate not-supported;
description
"Not supported in IOS-XE 16.3.2 release";
}
…(省略)この本文の deviate not-supported; は 12 か所です。deviation の対象の path は /if:interfaces/if:interface/… や /if:interfaces-state/if:interface/… と ietf-interfaces の木から始まり、途中から ietf-ip が augment で足した ip:ipv4・ip:ipv6 の節点に入ります。§4.1 の hello では、このモジュールが ietf-interfaces の行と ietf-ip の行の両方の deviations= に挙がっていました。2 つの行に挙がっている理由は確かめていません。§6.5 の T2b で消えた ip:enabled・ip:forwarding・ip:mtu・ip:neighbor は、この本文の対象と対応しています。
OpenConfig の側の cisco-xe-openconfig-interfaces-deviation の本文(cisco-xe-openconfig-interfaces-deviation@2018-08-21)は、deviate not-supported; が 18 か所で、その中に loopback-mode の 2 か所(config と state)があります。
module cisco-xe-openconfig-interfaces-deviation {
namespace "http://openconfig.net/yang/cisco-xe-openconfig-interfaces-deviation";
prefix oc-if-devs;
import openconfig-interfaces {
prefix oc-if;
}
…(省略)
deviation "/oc-if:interfaces/oc-if:interface/oc-if:config/oc-if:loopback-mode" {
deviate not-supported;
description
"looback-mode not supported in IOS-XE or 16.9.1.";
}
deviation "/oc-if:interfaces/oc-if:interface/oc-if:state/oc-if:loopback-mode" {
deviate not-supported;
description
"looback-mode not supported in IOS-XE or 16.9.1.";
}
…(省略)openconfig-interfaces の deviations= に挙がった 3 本を当てて描いた木(ツール側の観測。以下 T3b)の先頭は以下のとおりです。コマンドは pyang -V --no-path-recurse -p yang -f tree --deviation-module yang/cisco-xe-openconfig-interfaces-deviation@2018-08-21.yang --deviation-module yang/cisco-xe-openconfig-if-ip-deviation@2017-03-04.yang --deviation-module yang/cisco-xe-routing-openconfig-vlan-deviation@2018-12-12.yang yang/openconfig-interfaces@2018-01-05.yang yang/openconfig-if-ip@2018-01-05.yang yang/openconfig-vlan@2016-05-26.yang です。§8.1 の T3a の config と state の下にそれぞれ在った loopback-mode? の行が、T3b には 1 行もありません。
module: openconfig-interfaces
+--rw interfaces
+--rw interface* [name]
+--rw name -> ../config/name
+--rw config
| +--rw name? string
| +--rw type identityref
| +--rw mtu? uint16
| +--rw description? string
| +--rw enabled? boolean
| +--rw oc-vlan:tpid? identityref
+--ro state
| +--ro name? string
| +--ro type identityref
| +--ro mtu? uint16
| +--ro description? string
| +--ro enabled? boolean
| +--ro ifindex? uint32
| +--ro admin-status enumeration
| +--ro oper-status enumeration
| +--ro last-change? oc-types:timeticks64
…(省略)OpenConfig の style guide は、if-feature を避け、実装が満たさない部分は deviation のファイルで表す、としています。ietf-interfaces が任意の部分を feature と if-feature で示していたのと、書き方が違います。
Use of
if-featureshould be avoided.
Non-compliance by implementors should be expressed by deviation files rather than
if-feature.
11.2 deviation で外された節点へ書く
openconfig-interfaces の config の loopback-mode に true を PATCH すると、400 が返りました。error-tag は malformed-message、error-message は unknown element: loopback-mode in … です。
WSL $ curl -sS -i -k --max-time 60 -X PATCH -K - -H 'Accept: application/yang-data+json' -H 'Content-Type: application/yang-data+json' --data-binary '{"openconfig-interfaces:config": {"loopback-mode": true}}' https://172.16.1.241/restconf/data/openconfig-interfaces:interfaces/interface=Loopback0/config
HTTP/1.1 400 Bad Request
Server: openresty
Date: Wed, 30 Sep 2026 18:09:10 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Vary: Accept-Encoding
Pragma: no-cache
{
"errors": {
"error": [
{
"error-message": "unknown element: loopback-mode in /oc-if:interfaces/oc-if:interface[oc-if:name='Loopback0']/oc-if:config/oc-if:loopback-mode",
"error-path": "/openconfig-interfaces:interfaces/interface=Loopback0/config",
"error-tag": "malformed-message",
"error-type": "application"
}
]
}
}NETCONF の <edit-config> で同じ節点に書くと、error-tag は unknown-element で、error-info の <bad-element> は loopback-mode でした。この応答には error-message がありません。
#357
<?xml version="1.0" encoding="UTF-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
<edit-config><target><running/></target><config><interfaces xmlns="http://openconfig.net/yang/interfaces"><interface><name>Loopback0</name><config><loopback-mode>true</loopback-mode></config></interface></interfaces></config></edit-config>
</rpc>
##<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101"><rpc-error>
<error-type>application</error-type>
<error-tag>unknown-element</error-tag>
<error-severity>error</error-severity>
<error-path xmlns:oc-if="http://openconfig.net/yang/interfaces" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
/nc:rpc/nc:edit-config/nc:config/oc-if:interfaces/oc-if:interface[oc-if:name='Loopback0']/oc-if:config/oc-if:loopback-mode
</error-path><error-info><bad-element>loopback-mode</bad-element>
</error-info>
</rpc-error>
</rpc-reply>ietf-ip の ipv4 の mtu(cisco-xe-ietf-ip-deviation で not-supported)に 1400 を PATCH しても、400 が返りました。error-message は unknown element: mtu in /if:interfaces/if:interface[if:name='Loopback0']/ip:ipv4/ip:mtu で、ietf-ip の節点に ip: の接頭辞が付いています。
WSL $ curl -sS -i -k --max-time 60 -X PATCH -K - -H 'Accept: application/yang-data+json' -H 'Content-Type: application/yang-data+json' --data-binary '{"ietf-interfaces:interface": {"name": "Loopback0", "ietf-ip:ipv4": {"mtu": 1400}}}' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0
HTTP/1.1 400 Bad Request
Server: openresty
Date: Wed, 30 Sep 2026 18:09:10 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Vary: Accept-Encoding
Pragma: no-cache
{
"errors": {
"error": [
{
"error-message": "unknown element: mtu in /if:interfaces/if:interface[if:name='Loopback0']/ip:ipv4/ip:mtu",
"error-path": "/ietf-interfaces:interfaces/interface=Loopback0",
"error-tag": "malformed-message",
"error-type": "application"
}
]
}
}§15 の RFC 6020・RFC 7950・RFC 6241・RFC 8040 の本文で not-supported の語が現れるのは、deviate 文の定義・例・文法の所と、別の error-tag の operation-not-supported だけで、not-supported の節点を含む要求への応答を定める文はありませんでした(取得したテキストの文字列検索による)。上の応答は、本機の応答として載せるだけです。機器がどの段でこれらを拒んだかは撮っていません(§12)。
11.3 feature と if-feature — link-up-down-trap-enable
feature を支える機器では、その feature に依る部分が有効になり、支えない機器では、その節点は無視されます。
Schema nodes tagged with a feature are ignored by the device unless the device supports the given feature.
The “if-feature” statement makes its parent statement conditional. The argument is the name of a feature, as defined by a “feature” statement. The parent statement is implemented by servers that support this feature.
RFC 6020 §8.3.1 は、feature を支えない機器が、if-feature の付いた節点のデータを受けたときの応答を unknown-element と定めています。本機は if-mib を名乗っているので、この応答は本ラボでは撮れません(§12)。
If data for a node tagged with “if-feature” is present, and the feature is not supported by the device, the server MUST reply with an “unknown-element” error-tag in the rpc-error.
本ラボで示せるのは、if-feature の付いた leaf を本機に書けたことと、それが CLI に現れたことまでです。link-up-down-trap-enable の本文の description(§6.3 の抜粋)は、この節点が設定されていないとき、他のインタフェースの上で動かないインタフェース(lower-layer-if を持たないもの)では enabled を、それ以外では disabled を使うと書いています。本ラボは、この既定と違う disabled を書きました。
WSL $ curl -sS -i -k --max-time 60 -X PATCH -K - -H 'Accept: application/yang-data+json' -H 'Content-Type: application/yang-data+json' --data-binary '{"ietf-interfaces:interface": {"name": "Loopback0", "link-up-down-trap-enable": "disabled"}}' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0
HTTP/1.1 204 No Content
Server: openresty
Date: Wed, 30 Sep 2026 18:09:13 GMT
Content-Type: text/html
Content-Length: 0
Connection: keep-alive
Last-Modified: Wed, 30 Sep 2026 18:09:13 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Etag: "1790-791753-634199"
Pragma: no-cacheGET で読むと、"link-up-down-trap-enable": "disabled" が現れました。
WSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:09:13 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"ietf-interfaces:interface": {
"name": "Loopback0",
"description": "set-by-ietf",
"type": "iana-if-type:softwareLoopback",
"enabled": true,
"link-up-down-trap-enable": "disabled",
"ietf-ip:ipv4": {
…(省略)CLI の running-config には no snmp trap link-status の行が現れました。
CSR1# show running-config interface Loopback0
Building configuration...
Current configuration : 115 bytes
!
interface Loopback0
description set-by-ietf
ip address 10.7.2.1 255.255.255.255
no snmp trap link-status
endこの leaf を DELETE すると 204 No Content が返り、GET と CLI から trap の行が消えました。DELETE の後の CLI は、書き込みの前(Phase F の最初)の CLI と同じです。
WSL $ curl -sS -i -k --max-time 60 -X DELETE -K - https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0/link-up-down-trap-enable
HTTP/1.1 204 No Content
Server: openresty
Date: Wed, 30 Sep 2026 18:09:16 GMT
Content-Type: text/html
Content-Length: 0
Connection: keep-alive
Last-Modified: Wed, 30 Sep 2026 18:09:16 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Etag: "1790-791756-292427"
Pragma: no-cacheWSL $ curl -sS -i -k --max-time 60 -X GET -K - -H 'Accept: application/yang-data+json' https://172.16.1.241/restconf/data/ietf-interfaces:interfaces/interface=Loopback0
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 30 Sep 2026 18:09:16 GMT
Content-Type: application/yang-data+json
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Pragma: no-cache
{
"ietf-interfaces:interface": {
"name": "Loopback0",
"description": "set-by-ietf",
"type": "iana-if-type:softwareLoopback",
"enabled": true,
"ietf-ip:ipv4": {
…(省略)CSR1# show running-config interface Loopback0
Building configuration...
Current configuration : 89 bytes
!
interface Loopback0
description set-by-ietf
ip address 10.7.2.1 255.255.255.255
end12. 本ラボで確かめていないこと
本節の実測は、同じ構成での 1 回の撮影です。以下は観測していません。
- module-set-id の値が NETCONF と RESTCONF で違う理由と、7-1(candidate を有効にする前)・準備段階の試行(probe)・本ラボの 3 回とも同じ値だった理由。値の計算方法は撮っていません。集合の差(§4.4)は並べましたが、値の差の理由とは確かめていません(共通の 505 件も
schemaの URL が違い、7-1 §10.3 では再起動をはさんで、module=の名前と版の集合が同じまま features とmodule=を持たない capability が変わり、値が変わりました) - schema 資源が
Accept: application/yangにだけ 406 を返した理由。応答の組み合わせ(§5.4)だけを撮りました - 値を拒んだ要求・deviation で外された節点への要求を、機器がどの段で拒んだか。応答の error-tag と error-message だけを撮りました(§10・§11.2)
if-feature if-mibの効き目(feature を持たない機器で節点が無視されること)。本機は if-mib を名乗っていて、feature を持たない機器は撮っていません(§11.3)- native の Loopback の木の全体。pyang 2.7.1 は native とその import・include の 13 本で exit 1(error 2 件)で、示したのはサブモジュールの本文の
list Loopbackの定義までです。native を augment する他のモジュール・feature の選別・native の deviation を当てた形は描いていません(§8.2) module=を持たない 13 本のうち、rollback-on-error・validate・xpath・interleave・with-defaults・tail-f の actions の中身。hello に名前が在るだけで、本ラボでは使っていません(§4.1)- YANG-Patch が使えるか。RESTCONF 側の yang-library に
ietf-yang-patchが載っていた(§4.4)だけで、使っていません。Cisco の 17.3 のガイドの RESTCONF の章は、記述が割れています。制限の一覧に「YANG patch」の項目がある一方で、同じ章の YANG-Patch Support の節は YANG-Patch に対応すると書き、Feature Information の表の行は 17.1.1 で導入し、対応機種に Cloud Services Router 1000V を含めています - hello に YANG 1.1 のモジュールが無いか。yang-version を確かめたのは、get-schema で取り出した 52 本だけです(§5.2)
- 空の
ietf-ip:ipv6が何を意味するか。ietf-ip の本文は、ipv6 の container の presence の説明に、enabled の leaf が false でなければ IPv6 を有効にすると書いていますが、CLI に IPv6 の行は無く(§8.3)、ietf-ip の ipv6 のenabledは deviation で not-supported です(§6.5 の T2b の木でip:ipv6!の下から消えています)。意味は確かめていません(§7) - 3 系統の間で値を受け渡す機器の中の仕組み。1 つの系統で書いた値が他の 2 系統と CLI に現れたことだけを撮りました(§9)
- Cisco native の状態の側(operational)の読み。native は設定の側だけを読みました(§8.3)
- cisco-xe-ietf-ip-deviation が hello の ietf-interfaces の行と ietf-ip の行の両方の
deviations=に挙がる理由(§4.1・§11.1) - NETCONF での key の不一致・未知の leaf・identity に無い値。この 3 種は RESTCONF だけで撮りました(§10)
- OpenConfig のモデルを他のベンダの機器で読むこと。本ラボは Cisco の csr1000v 1 台だけです(§8.1)
- candidate のデータストアでの振る舞い。本ラボは running だけで撮りました(candidate は 7-1 §10)
- 物理インタフェース。読み書きしたのは Loopback だけです(書き込みの対象は Loopback0。Loopback1 は §10 の key の不一致の要求と、その前後の GET だけ)
- 17.3 以外の版。後継の RFC 8525(YANG library)・RFC 8343(インタフェースのモデル)・RFC 8344(IP のモデル)の版のモジュールを載せる機器では撮っていません
YANG-Patch について、Cisco の 17.3 のガイドの RESTCONF の章の対応の文は以下のとおりです。
RESTCONF supports YANG-Patch media type as specified by RFC 8072.
13. まとめ
YANG は、NETCONF と RESTCONF が運ぶ設定と状態のデータの形を、モジュールの本文として書く言語です。本機が get-schema で返した 52 本は、すべて YANG 1.0 でした。
csr1000v 17.03.08a は、持っているモデル(実装するものと、定義を借りるだけのもの)を 3 つの場所で名乗りました。hello の capability は 520 本で、507 本が module=・revision=・features=・deviations= の組み合わせでモジュールの名前を名乗り(497 本は revision= で版も)、13 本は NETCONF の機能の capability でした。yang-library は NETCONF と RESTCONF のどちらでも 507 本(implement 454・import 53)で、片側だけのモジュールが 2 本ずつあり、共通の 505 件も schema の URL の頭が違いました。module-set-id の値も 2 つの口で違いましたが、集合の差が値の差の理由であるかは確かめていません。<schemas> は 543 件で、モジュール 507 とサブモジュール 36 に分かれました(§4)。
本文は get-schema で取り出し、CDATA に包まれた YANG の本文が返りました。import と include を辿って 52 本を取り出し、そのうち公開リポジトリと比べた 12 本では、10 本が同じ名前のファイルとバイト一致しました。存在しない名前と機器に無い版の要求は、どちらも invalid-value でした。RESTCONF の schema 資源は、Accept: application/yang に 406 を返し、他の 7 通りには get-schema と同じ本文を返しました(§5)。
ietf-interfaces の本文は、prefix if;・identity・feature・container・list・key・leaf・config false で書かれていて、7-1 のエラーの文言に出た if: は、この prefix 文の値でした。ietf-ip は augment で ipv4 を足し、足した節点は JSON では ietf-ip:ipv4、XML では ietf-ip の名前空間、木では ip:ipv4 と書かれました(§6・§7)。
同じ Loopback0 は、IETF・OpenConfig・Cisco native の 3 系統で、URL・JSON の最上位の名前・key の型が違う形で読めました。設定と状態の分け方は、IETF(本機の ietf-interfaces 2014-05-08 では別の container)と OpenConfig(config と state)で違いました(native は設定の側だけを読みました)。OpenConfig は config と state に同じ grouping を使い、key は leafref でした。native の Loopback の list は、サブモジュールの中の、key が uint32 の list でした(§8)。1 つの系統で書いた description は、1 回の撮影の中の 3 回の書き込みとも、他の 2 系統と CLI に同じ値で現れました(§9)。
モデルに合わない値は、RESTCONF では 400 と malformed-message(key の不一致は invalid-value)、NETCONF では invalid-value(config false への書き込みは unknown-element)で拒まれました。前後の CLI と GET で確かめた範囲では、running は変わりませんでした(§10)。Cisco の deviation のモジュールが not-supported とした節点は pyang の木から消え、本ラボが書いた 2 つの節点(OpenConfig の loopback-mode と ietf-ip の ipv4 の mtu)への書き込みは 400 などで拒まれました。if-feature の付いた link-up-down-trap-enable は、本機に書けて CLI に現れ、DELETE で消えました(§11)。確かめていないことは §12 にまとめてあります。
14. 次節(7-3 gNMI と Model-Driven Telemetry)
本節では、機器が名乗るモデルの一覧と本文を取り出し、同じ資源を 3 つのモデルで読み書きしました。hello には notification:1.0 と notification:1.1 の capability も並び、ietf-yang-push(2016-10-28・feature は on-change)と ietf-event-notifications(2016-10-27)のモジュールも名乗られていましたが、本節は名前を挙げるだけで、使っていません。YANG の notification 文も、1 行の定義だけを置きました。
次節 7-3 は、gNMI と Model-Driven Telemetry を扱います。Cisco の 17.3 のガイドの Model-Driven Telemetry の章は、telemetry を使うには YANG の知識が要ると書いています。
Knowledge of YANG is needed to understand and define the data that is required when using telemetry.
次節では、本節で読んだ YANG のモデルのデータを、要求への応答ではなく購読と送り出しで受け取る仕組みを見ていきましょう。
15. 出典
本節が参照した資料です。22 件はすべて 2026 年 10 月 1 日に取得・参照しました。本文中の > の引用は、その時点のページとテキストの逐語です。RFC の .txt は、ページの区切りや行末のハイフンで割れた語を、取得したテキストのまま引いています。
手元の機体は csr1000v 17.03.08a で、Cisco の設定ガイドは同じ IOS XE Amsterdam 17.3.x を対象としています。OpenConfig の style guide は、先頭の更新日が 2026 年 1 月 9 日ですが、背景の節の YANG の版の記述(1.0 が現行で 1.1 は近く批准)は RFC 7950 より前の時点のもので、本節は YANG の版の根拠に使っていません。YangModels の公開リポジトリは、機器が返した本文と比べるために参照したもので、本文の引用の原典ではありません。
| 資料 | 版・更新日(資料の表記) | 参照日 | URL |
|---|---|---|---|
| OpenConfig — YANG authoring guidelines for OpenConfig models(openconfig/public の doc/openconfig_style_guide.md) | commit 806f0131・Updated: January 9th 2026 | 2026-10-01 | https://raw.githubusercontent.com/openconfig/public/806f01311393367ff09390570ab63a24a6be9edb/doc/openconfig_style_guide.md |
| Programmability Configuration Guide, Cisco IOS XE Amsterdam 17.3.x — Chapter: gNMI Protocol(本文では引いていない。節の範囲を決めるために読んだ資料) | IOS XE Amsterdam 17.3.x・Updated: July 31, 2020 | 2026-10-01 | https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/prog/configuration/173/b_173_programmability_cg/grpc_network_management_interface.html |
| Programmability Configuration Guide, Cisco IOS XE Amsterdam 17.3.x — Chapter: In-Service Model Update(本文では引いていない。節の範囲を決めるために読んだ資料) | IOS XE Amsterdam 17.3.x・Updated: July 31, 2020 | 2026-10-01 | https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/prog/configuration/173/b_173_programmability_cg/in_service_model_update.html |
| Programmability Configuration Guide, Cisco IOS XE Amsterdam 17.3.x — Chapter: Model-Driven Telemetry | IOS XE Amsterdam 17.3.x・Updated: July 31, 2020 | 2026-10-01 | https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/prog/configuration/173/b_173_programmability_cg/model_driven_telemetry.html |
| Programmability Configuration Guide, Cisco IOS XE Amsterdam 17.3.x — Chapter: NETCONF Protocol | IOS XE Amsterdam 17.3.x・Updated: July 31, 2020 | 2026-10-01 | https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/prog/configuration/173/b_173_programmability_cg/configuring_yang_datamodel.html |
| Programmability Configuration Guide, Cisco IOS XE Amsterdam 17.3.x — Chapter: RESTCONF Protocol | IOS XE Amsterdam 17.3.x・Updated: July 31, 2020 | 2026-10-01 | https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/prog/configuration/173/b_173_programmability_cg/restconf_protocol.html |
| RFC 6020 — YANG - A Data Modeling Language for the Network Configuration Protocol (NETCONF) | RFC 6020(October 2010) | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc6020.txt |
| RFC 6022 — YANG Module for NETCONF Monitoring | RFC 6022(October 2010) | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc6022.txt |
| RFC 6241 — Network Configuration Protocol (NETCONF) | RFC 6241(June 2011)・Obsoletes: 4741 | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc6241.txt |
| RFC 6991 — Common YANG Data Types | RFC 6991(July 2013)・Obsoletes: 6021 | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc6991.txt |
| RFC 7223 — A YANG Data Model for Interface Management | RFC 7223(May 2014) | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc7223.txt |
| RFC 7224 — IANA Interface Type YANG Module(本文では引いていない。iana-if-type を定める RFC として読んだ資料) | RFC 7224(May 2014) | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc7224.txt |
| RFC 7277 — A YANG Data Model for IP Management | RFC 7277(June 2014) | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc7277.txt |
| RFC 7895 — YANG Module Library | RFC 7895(June 2016) | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc7895.txt |
| RFC 7950 — The YANG 1.1 Data Modeling Language | RFC 7950(August 2016) | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc7950.txt |
| RFC 7951 — JSON Encoding of Data Modeled with YANG | RFC 7951(August 2016) | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc7951.txt |
| RFC 8040 — RESTCONF Protocol | RFC 8040(January 2017) | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc8040.txt |
| RFC 8340 — YANG Tree Diagrams | RFC 8340(March 2018) | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc8340.txt |
| RFC 8343 — A YANG Data Model for Interface Management | RFC 8343(March 2018)・Obsoletes: 7223 | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc8343.txt |
| RFC 8344 — A YANG Data Model for IP Management | RFC 8344(March 2018)・Obsoletes: 7277 | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc8344.txt |
| RFC 8525 — YANG Library | RFC 8525(March 2019)・Obsoletes: 7895 | 2026-10-01 | https://www.rfc-editor.org/rfc/rfc8525.txt |
| YangModels/yang — vendor/cisco/xe/1731(機器の get-schema の本文と比べた公開リポジトリ。本文の引用の原典ではない) | commit 0e28ed86 | 2026-10-01 | https://github.com/YangModels/yang/tree/0e28ed86b0a9070b7f15fd06ba4fa501723fac84/vendor/cisco/xe/1731 |