RFC6020 - YANG語言標準中文

dolphin98629發表於2020-10-13

RFC6020 - YANG語言標準中文

2016年08月05日 14:49:04

閱讀數:12297

YANG - A Data Modeling Language for the Network Configuration Protocol (NETCONF)

該標準脫胎於草案draft-ietf-netmod-yang,該草案從2008年5月開始,先後經歷了13個草案版本,最終於2010年8月成為建議標準(Proposed Standard)。本文件的翻譯時間開始於2016年5月12日。

本文件有勘誤表存在。

摘要

YANG是一種資料建模語言,被用來為NETCONF,NETCONF遠端過程呼叫,NETCONF Notification操作的配置和狀態資料進行建模。

本文件狀態

This is an Internet Standards Track document.

This document is a product of the Internet Engineering Task Force 
(IETF). It represents the consensus of the IETF community. It has 
received public review and has been approved for publication by the 
Internet Engineering Steering Group (IESG). Further information on 
Internet Standards is available in Section 2 of RFC 5741.

Information about the current status of this document, any errata, 
and how to provide feedback on it may be obtained at 
http://www.rfc-editor.org/info/rfc6020.

版權資訊

Copyright (c) 2010 IETF Trust and the persons identified as the 
document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust’s Legal 
Provisions Relating to IETF Documents 
(http://trustee.ietf.org/license-info) in effect on the date of 
publication of this document. Please review these documents 
carefully, as they describe your rights and restrictions with respect 
to this document. Code Components extracted from this document must 
include Simplified BSD License text as described in Section 4.e of 
the Trust Legal Provisions and are provided without warranty as 
described in the Simplified BSD License.

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

1. 介紹

YANG是一種資料建模語言,被用來為NETCONF,NETCONF遠端過程呼叫,NETCONF Notification操作的配置和狀態資料進行建模。

本文件描述了YANG語言的語法和語義,在一個YANG module中定義的資料模型如何以XML的形式表示,NETCONF如何運算元據。

2. 關鍵詞

The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, 
“SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and 
“OPTIONAL” in this document are to be interpreted as described in BCP 
14, [RFC2119].

3. 術語

  • anyxml —— 一種資料節點,能夠包含未知的XML格式的資料塊。
  • augment —— 向之前定義的schema node增加新的schema nodes。
  • base type —— 可以被用來繼承的資料型別,可以使built-in型別,也可以是派生的型別。
  • built-in type —— YANG語言定義的YANG資料型別,比如uint32 或者 string
  • choice —— 一個schema node,其值是多個可選項中的一個。
  • configuration data —— 可寫入的資料的集合,被用來轉變系統的狀態【RFC4741】。
  • conformance(一致性) —— 一種評估實際上裝置在多大程度上服從資料模型的方法。
  • container —— 一種內建的資料節點,在data tree中,最多隻能有一個例項存在。一個container沒有值,不過會包含一些子節點。
  • data definition statement —— 一種定義新的資料節點的宣告(statement)。可以是container,leaf,leaf-list,list,choice,case,augment,uses,以及anyxml中的一個。
  • data model —— 一種表述資料如何展現和訪問的資料模型。
  • data node(資料節點) —— schema tree中的一個節點,能夠在data tree中例項化。可以是container,leaf,leaf-list,list,以及anyxml中的一個。
  • data tree —— 由一個裝置上的配置和狀態資料例項化的樹。
  • derived type(派生型別) —— 一種從內建資料型別,或者其他派生型別中派生出來的型別。
  • device deviation(裝置偏差) —— 如實反映裝置在實現YANG模組時候的失敗情況。
  • extension —— 使用非YANG語義宣告的擴充套件。擴充套件宣告定義了新的statement表示這些語義。
  • feature —— 一種可選的能夠標記模型的某一部分的機制。可以使用feature名作為標籤,不過該標籤僅僅在支援該feature的裝置上才有效。
  • grouping —— 一種可重用的schema nodes的集合。該集合可能在定義處的module中被使用,也可能在包含它的modules中使用,還可能在匯入它的modules中被使用。grouping宣告不是一種資料定義宣告,它不會在schema node中定義任何節點。
  • identifier —— 通過名字,被用來識別不同種類的YANG items。
  • instance identifier —— 在data tree中被用來標記特定的一個節點。
  • interior node —— 分層結構中,非leaf node的節點。
  • leaf —— 一種資料節點,在data tree中最多隻能有一個例項存在。一個leaf節點只能有一個值,並且不能有子節點。
  • leaf-list —— 和leaf節點相似,但是定義了一集合的可唯一識別的節點,而非一個節點。其中每一個節點都有值,但是都沒有子節點。
  • list —— 一種內部的資料節點,在data tree中可能會有多個例項存在。一個list沒有值,但是會有一些子節點。
  • module —— 一個YANG module定義了一個具有垂直層級結構的節點集,這些節點能夠被用於基於NETCONF的operations。如果有一個module的定義,以及該module依賴的其他module的定義,則這個module是自足的,以及“可編譯的(compilable)”。
  • RPC —— 遠端過程呼叫,在NETCONF協議中使用的。
  • RPC operation —— 一種特定的遠端過程呼叫,在NETCONF協議中使用的。也被成為協議操作(protocol operation)。
  • schema node —— 在schema tree中的節點。是container,leaf,leaf-list,list,choice,case,rpc,input,output,notification,以及anyxml中的一種。
  • schema tree —— module中的特定垂直結構定義(The definition hierarchy specified within a module.)。
  • state data(狀態資料) —— 系統中的配置資料之外的其他額外資料,比如只讀的狀態資訊,資料統計資訊【RFC4741】。
  • submodule —— 一種區域性的module定義。submodule為所在的module提供了derived types,groupings,data nodes,RPCs,以及notifications。一個YANG module可以由多個submodules組成。
  • top-level data node —— 一個資料節點,在該節點和module/submodule宣告之間,沒有其他的資料節點存在。
  • uses —— 這個“uses”宣告被用來例項化在grouping宣告中定義的schema nodes。這些例項化的節點可能會被擴充套件以滿足特定的需求。

搞不明白feature的具體用法。不知道data tree和schema tree的區別。

3.1 Mandatory Nodes(必須出現的節點)

一個mandatory node是以下中的:

  • “mandatory”宣告為“true”的一個leaf,choice,或者anyxml節點。
  • “min-elements”宣告為大於0的數的一個list,或者leaf-list節點。
  • 沒有“presence”宣告的container節點,它裡面至少要包含一個mandatory node的子節點。

4. YANG總覽

4.1 功能總覽

YANG是一種被用來為NETCONF協議建模的語言。一個YANG module定義了具有垂直結構的資料,這些資料可以被用做基於NETCONF的operations,比如configuration,state date,RPCs,以及notifications。它使得NETCONF的client和server之間能有完整的資料描述。

YANG建模得到的資料具備樹形結構。其中每一個節點都有一個名字,都有一個值或者一些子節點。YANG為這些節點,以及節點之間的互動提供明確清晰的描述。

YANG使用modules和submodule進行資料建模。一個module能夠從其他外部的modules中匯入資料,也可以從submodules中包含資料。YANG定義的垂直結構可以擴充套件,使得一個module能夠增加資料節點給另一個module。這種擴充套件是有條件的,只有特定條件滿足,新的資料節點才會出現。

YANG模型還能描述資料之上增加的約束,基於垂直結構中其他節點的出現與否,值為多少等等來限制一些節點的出現與賦值。這些約束可以被client或者server強制執行。不過如果要使得內容有效,MUST 雙方都要遵守特定的約定。

YANG定義了一系列的內建資料型別,也有定義新資料型別的型別命名機制。派生資料型別可以通過像range,pattern這樣的宣告限制其原生資料型別的取值範圍,這樣的宣告在client或者server端都可以執行。它們還能為派生資料型別定義常用用法,比如定義一個string-based型別,包含主機名。

YANG允許對可重用的grouping中節點的定義。這些groupings中的例項能夠通過特定的增強以滿足特殊的需求。派生型別以及groupings能夠定義在一個module或者submodule中,能夠被本地,其他module/submodule匯入和使用。

YANG的垂直資料結構包括了對list的定義。list中包含的每一項都有唯一的key以區分彼此。這樣的lists有可能被使用者自定義排序或者由系統進行預設排序。對於使用者自定義排序的lists來說,operations是為了對列表項進行排序定義的。

YANG modules可以被轉換為等價的XML格式,稱為YANG Independent Notation(YIN)(Section 11),這使得相關的應用可以通過XML解析器或者XSLT指令碼進行操作。從YANG到YIN的轉換是無損的,因此也可以從YIN格式轉換為YANG檔案。

YANG試圖在高層的資料建模和底層的位元資料編碼(bits-on-the-wire encoding)之間追求平衡。YANG module的reader可以檢視資料模型的高層檢視,同時也能理解在NETCONF operations中,這些資料如何編碼。

YANG是一種可擴充套件語言,允許標準制定者,裝置商,以及個人定義新的宣告(statement)。宣告的語法使得這些擴充套件能夠以一種自然的方式和標準的YANG 宣告共存,同時使得reader能夠有效得認知這些新擴充套件。

YANG resists the tendency to solve all possible problems, limiting the problem space to allow expression of NETCONF data models, not arbitrary XML documents or arbitrary data models. The data models described by YANG are designed to be easily operated upon by NETCONF operations.

為了擴大使用範圍,YANG和SNMP協議的SMIv2(Structure of Management Information,RFC2578RFC2579)保持了相容。基於SMIv2的MIB modules能夠以只讀的方式自動轉換為YANG modules。然而,YANG並不關心如何從YANG轉換為SMIv2。

和NETCONF相似,YANG致力於和裝置本身自帶的管理機制進行平滑整合。這就使得需要利用裝置當前的訪問控制機制去保護/暴露資料模型的相應元素。

4.2 語言總覽

本小節引入了YANG語言中的一些重要結構,這些在後面的章節中,對於理解語言細節能夠提供一些幫助。這種方法解決了難以理解的相互聯絡的YANG概念和宣告的複雜關係問題。關於YANG的宣告(statement)和語法(syntax)的細節描述可見Section 7。

4.2.1 Modules和Submodules

一個module包含了三種型別的宣告:

  • module-header statement(模組頭宣告) —— 描述了該module,給出了module相關的資訊。
  • revision statement(版本宣告)—— 描述了該module的歷史資訊。
  • definition statement(定義宣告) —— 定義了資料模型的內容部分。

一個NETCONF Server可能會實現多個modules,擁有相同裝置資料的多個檢視,或者互不相交的多個子集的多個檢視。這種情況下,Server可能會選擇僅僅實現定義了所有可用資料的一個module。(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. Alternatively, the server may implement only one module that defines all available data.)

根據需求,一個module可以被分為多個submodules。而對外來說,依然是單個module,無論內部擁有多少個submodules。

“include”宣告允許一個module或者submodule引用submodules中定義的資料;“import”宣告允許引用其他modules中定義的資料。

4.2.2 資料建模基礎(Data Modeling Basics)

YANG定義了四種用於資料建模的節點型別。在下面的每一個小節中,都有例子展示了YANG語法以及相應的NETCONF XML表達。

4.2.2.1 Leaf Nodes

一個leaf node包含了像integer或者string這樣的簡單資料。它有且僅有一個特定型別的值,並且沒有子節點。

YANG 示例:

 
  1. leaf host-name {

  2. type string;

  3. description "Hostname for this system";

  4. }

NETCONF XML 示例:

   <host-name>my.example.com</host-name>
  •  

“leaf”的宣告可以在Section 7.6 中找到。

4.2.2.2 Leaf-List Nodes

一個leaf-list是一系列的leaf nodes,每個leaf都有特定型別的值。

YANG 示例:

  1. leaf-list domain-search {

  2. type string;

  3. description "List of domain names to search";

  4. }

NETCONF XML 示例:

 
  1. <domain-search>high.example.com</domain-search>

  2. <domain-search>low.example.com</domain-search>

  3. <domain-search>everywhere.example.com</domain-search>

“leaf-list”的宣告可以在Section 7.7 中找到。

4.2.2.3 Container Nodes

一個container node用來將相關的節點歸總到一個subtree中。一個container node只有子節點,沒有值。一個container可能會包含任何型別的任何數量的子節點(包括leafs,lists,leaf-lists以及containers)。

YANG 示例:

 
  1. container system {

  2. container login {

  3. leaf message {

  4. type string;

  5. description

  6. "Message given at start of login session";

  7. }

  8. }

  9. }

NETCONF XML 示例:

 
  1. <system>

  2. <login>

  3. <message>Good morning</message>

  4. </login>

  5. </system>

“container”的宣告可以在Section 7.5 中找到。

4.2.2.4 List Nodes

一個List定義了一系列的列表項(list entries)。每個列表項都像是一個structure或者一個record instance,通過名為“key”的leaf的值唯一確定。一個list能定義多種key leafs,能夠包含任意型別的任意數目的子節點(包括leafs,lists,containers)。

YANG 示例:

 
  1. list user {

  2. key "name";

  3. leaf name {

  4. type string;

  5. }

  6. leaf full-name {

  7. type string;

  8. }

  9. leaf class {

  10. type string;

  11. }

  12. }

NETCONF XML 示例:

 
  1. <user>

  2. <name>glocks</name>

  3. <full-name>Goldie Locks</full-name>

  4. <class>intruder</class>

  5. </user>

  6. <user>

  7. <name>snowey</name>

  8. <full-name>Snow White</full-name>

  9. <class>free-loader</class>

  10. </user>

  11. <user>

  12. <name>rzell</name>

  13. <full-name>Rapun Zell</full-name>

  14. <class>tower</class>

  15. </user>

“list”的宣告可以在Section 7.8 中找到。

4.2.2.5 Module示例

上述的那些宣告組合起來能夠定義一個簡單的module:

 
  1. // Contents of "acme-system.yang"

  2. module acme-system {

  3. namespace "http://acme.example.com/system";

  4. prefix "acme";

  5.  
  6. organization "ACME Inc.";

  7. contact "joe@acme.example.com";

  8. description

  9. "The module for entities implementing the ACME system.";

  10.  
  11. revision 2007-06-09 {

  12. description "Initial revision.";

  13. }

  14.  
  15. container system {

  16. leaf host-name {

  17. type string;

  18. description "Hostname for this system";

  19. }

  20.  
  21. leaf-list domain-search {

  22. type string;

  23. description "List of domain names to search";

  24. }

  25.  
  26. container login {

  27. leaf message {

  28. type string;

  29. description

  30. "Message given at start of login session";

  31. }

  32.  
  33. list user {

  34. key "name";

  35. leaf name {

  36. type string;

  37. }

  38. leaf full-name {

  39. type string;

  40. }

  41. leaf class {

  42. type string;

  43. }

  44. }

  45. }

  46. }

  47. }

4.2.3 State Data

YANG 能夠通過“config”宣告對state data和configuration data進行建模。當一個節點打上了“config false”的標籤,它的子結構就打上了state data的標籤,會通過NETCONF的操作,而不是操作。作為其父節點的containers,lists,以及key leafs也會上報,以給這個state data明確的上下文環境。

不清楚為什麼還會有key leafs。

在下面的例子中,每個interface都定義了兩個leafs,一個是configured speed(配置速率),另一個是observed speed(觀察速率)。觀察速率是不可配置的,所以它能通過NETCONF的操作獲取,但是不能通過操作獲取,也不能通過操作操作。

 
  1. list interface {

  2. key "name";

  3.  
  4. leaf name {

  5. type string;

  6. }

  7. leaf speed {

  8. type enumeration {

  9. enum 10m;

  10. enum 100m;

  11. enum auto;

  12. }

  13. }

  14. leaf observed-speed {

  15. type uint32;

  16. config false;

  17. }

  18. }

4.2.4 Built-in Types

和一些程式語言類似,YANG也有一系列的內建型別。下面的表格就總結了在Section 9描述的內建資料型別:

 
  1. +---------------------+-------------------------------------+

  2. | Name | Description |

  3. +---------------------+-------------------------------------+

  4. | binary | Any binary data |

  5. | bits | A set of bits or flags |

  6. | boolean | "true" or "false" |

  7. | decimal64 | 64-bit signed decimal number |

  8. | empty | A leaf that does not have any value |

  9. | enumeration | Enumerated strings |

  10. | identityref | A reference to an abstract identity |

  11. | instance-identifier | References a data tree node |

  12. | int8 | 8-bit signed integer |

  13. | int16 | 16-bit signed integer |

  14. | int32 | 32-bit signed integer |

  15. | int64 | 64-bit signed integer |

  16. | leafref | A reference to a leaf instance |

  17. | string | Human-readable string |

  18. | uint8 | 8-bit unsigned integer |

  19. | uint16 | 16-bit unsigned integer |

  20. | uint32 | 32-bit unsigned integer |

  21. | uint64 | 64-bit unsigned integer |

  22. | union | Choice of member types |

  23. +---------------------+-------------------------------------+

“type”的宣告可以在Section 7.4 中找到。

4.2.5 Derived Types(typedef)

YANG能夠使用“typedef”宣告從基本型別中定義派生型別。一個基本型別可以是內建型別或者派生型別。

YANG 示例:

 
  1. typedef percent {

  2. type uint8 {

  3. range "0 .. 100";

  4. }

  5. description "Percentage";

  6. }

  7.  
  8. leaf completed {

  9. type percent;

  10. }

NETCONF XML 示例:

 <completed>20</completed>
  •  

“typedef”的宣告可以在Section 7.3 中找到。

4.2.6 可重用的節點組(grouping)

可以使用“grouping”宣告將一組節點放到可重用的集合中去。一個grouping定義了節點的集合,該集合可以使用“uses”宣告例項化:

YANG 示例: 
grouping target { 
leaf address { 
type inet:ip-address; 
description “Target IP address”; 

leaf port { 
type inet:port-number; 
description “Target port number”; 

}

 
  1. container peer {

  2. container destination {

  3. uses target;

  4. }

  5. }

NETCONF XML 示例:

 
  1. <peer>

  2. <destination>

  3. <address>192.0.2.1</address>

  4. <port>830</port>

  5. </destination>

  6. </peer>

grouping可以根據它被呼叫時候的用途進行優化,重寫特定的宣告來覆蓋原來grouping的定義。在下面的例子中,description被重定義了:

 
  1. container connection {

  2. container source {

  3. uses target {

  4. refine "address" {

  5. description "Source IP address";

  6. }

  7. refine "port" {

  8. description "Source port number";

  9. }

  10. }

  11. }

  12. container destination {

  13. uses target {

  14. refine "address" {

  15. description "Destination IP address";

  16. }

  17. refine "port" {

  18. description "Destination port number";

  19. }

  20. }

  21. }

  22. }

“grouping”的宣告可以在Section 7.11 中找到。

4.2.7 choice

YANG能夠使用“choice”和“case”宣告分離互不相容,不能同時出現的節點。“choice”宣告包含了多個“case”宣告,定義了不能同時出現的schema nodes的集合。每個“case”宣告都可能包含多個節點,但是每個節點都應該只在一個“case”中出現。

當一個case元素被建立,其他所有cases的元素都會被隱式刪除。裝置要強制執行這個約束,以防止出現配置的不協調。

“choice”和“case”節點只會出現在schema tree中,不能出現在data tree或者NETCONF message

YANG 示例:

 
  1. container food {

  2. choice snack {

  3. case sports-arena {

  4. leaf pretzel {

  5. type empty;

  6. }

  7. leaf beer {

  8. type empty;

  9. }

  10. }

  11. case late-night {

  12. leaf chocolate {

  13. type enumeration {

  14. enum dark;

  15. enum milk;

  16. enum first-available;

  17. }

  18. }

  19. }

  20. }

  21. }

NETCONF XML 示例:

 
  1. <food>

  2. <pretzel/>

  3. <beer/>

  4. </food>

“choice”的宣告可以在Section 7.9 中找到。

4.2.8 擴充套件資料模型(augment)

YANG允許一個模組將額外的節點插入到資料模型中,包括當前的module(以及它的submodule)或者一個外部的module。這一點是很有用的,比如對於裝置商來說,需要在標準資料模型中插入裝置商指定的引數。

“augment”宣告定義了在資料模型樹形結構中,新的節點插入的位置。“when”宣告瞭新節點生效的時間。

YANG 示例:

 
  1. augment /system/login/user {

  2. when "class != 'wheel'";

  3. leaf uid {

  4. type uint16 {

  5. range "1000 .. 30000";

  6. }

  7. }

  8. }

這個例子定義了一個“uid”的leaf node,該node僅在user的class不等於wheel的時候才有效。

如果一個module增強了另一個module,則資料的XML表示將會影響增強它的module的字首。比如,如果上一個例子的augment是放在一個“other”字首的module中,則其XML看起來應該是這樣的:

NETCONF XML 示例:

 
  1. <user>

  2. <name>alicew</name>

  3. <full-name>Alice N. Wonderland</full-name>

  4. <class>drop-out</class>

  5. <other:uid>1024</other:uid>

  6. </user>

“augment”的宣告可以在Section 7.15中找到。

4.2.9 RPC定義

YANG也能定義NETCONF中的RPCs。RPC中的operations’ name,輸入引數,和輸出引數都可以通過YANG的資料定義宣告進行建模。

YANG 示例:

 
  1. rpc activate-software-image {

  2. input {

  3. leaf image-name {

  4. type string;

  5. }

  6. }

  7. output {

  8. leaf status {

  9. type string;

  10. }

  11. }

  12. }

NETCONF XML 示例:

 
  1. <rpc message-id="101"

  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">

  3. <activate-software-image xmlns="http://acme.example.com/system">

  4. <image-name>acmefw-2.3</image-name>

  5. </activate-software-image>

  6. </rpc>

  7.  
  8. <rpc-reply message-id="101"

  9. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">

  10. <status xmlns="http://acme.example.com/system">

  11. The image acmefw-2.3 is being installed.

  12. </status>

  13. </rpc-reply>

“rpc”的宣告可以在Section 7.13中找到。

4.2.10 Notification定義。

YANG的notification定義和NETCONF適配。YANG的資料定義宣告被用來為notification的內容建模。

YANG Example:

 
  1. notification link-failure {

  2. description "A link failure has been detected";

  3. leaf if-name {

  4. type leafref {

  5. path "/interface/name";

  6. }

  7. }

  8. leaf if-admin-status {

  9. type admin-status;

  10. }

  11. leaf if-oper-status {

  12. type oper-status;

  13. }

  14. }

NETCONF XML Example:

 
  1. <notification

  2. xmlns="urn:ietf:params:netconf:capability:notification:1.0">

  3. <eventTime>2007-09-01T10:00:00Z</eventTime>

  4. <link-failure xmlns="http://acme.example.com/system">

  5. <if-name>so-1/2/3.0</if-name>

  6. <if-admin-status>up</if-admin-status>

  7. <if-oper-status>down</if-oper-status>

  8. </link-failure>

  9. </notification>

notification和rpc都是NETCONF中的定義,雖然大概明白什麼意思,但是具體就不清楚了,需要去NETCONF的標準中去檢視定義。

“notification”的宣告可以在Section 7.14中找到。

5. 語言概念

5.1 modules和submodules

在YANG語言中,module是基本單位。每個module都定義一個資料模型。一個module能夠定義一個完整的模型,或者對當前資料模型做額外擴充套件。

submodules是module的一部分,能夠為一個module提供相關定義。一個module能包含任意數量的submodules,但是每個submodule只能屬於一個module。

所有標準的modules和submodules的名字都 MUST 是唯一的。我們 RECOMMEND 企業級modules的開發者選擇和標準模型以及其他企業modules不衝突的名字,比如說,使用企業或組織名字作為module名字的字首。

一個module使用“include”宣告包含它的submodules,使用“import”宣告引入外部的modules。相似的,一個submodule會使用“include”宣告引用同一個module中的其他submodules,使用“import”宣告引用其他modules。一個module或submodule MUST NOT 包含其他modules中的submodules,一個submodule MUST NOT 匯入它自己所在的module。

匯入(import)和包含(include)宣告使用如下:

  • 如果一個module或submodule需要引用來自外部的module,外部的module MUST 被imported。
  • 如果一個module需要引用其內部的某個submodule,這個module MUST include這個submodule。
  • 如果一個submodule需要引用同一個module內部的其他submodule,則這個submodule MUST include另一個submodule。

在modules/submodules的imports和includes中,MUST NOT 形成環形呼叫鏈。比如,如果submodule “a”包含了submodule “b”,則“b”就不能包含submodule “a”了。

當在一個外部module的定義被引用時, MUST 使用區域性定義的字首,後面跟著冒號“:”,然後是具體使用的外部module的id。對本地module定義的引用可以使用字首,也可以不使用。由於built-in型別不屬於任何module,所以對built-in型別的引用不能使用任何字首。

5.1.1 Import and Include by Revision

隨著時間的推移,已經發布的modules會慢慢演進出新的版本。為了支援這樣的正常演進過程,modules在被其他module import時需要使用其revisions。當一個module完成時,它會基於當前時間使用可用的帶有特定revisions的其他modules。如果後來,被imported的modules更新了,該module不會受到影響。當這個module的作者準備將“import”的module更新到最新版本,只需要修改“revision”欄位就可以了。

對於submodule來說,方案相似不過更加簡單。一個module或者submodule,在包含其他的submodule的時候都要指定被包含submodules的revision。如果一個submodule改變了,任何包含它的其他module或者submodules都需要被更新。

比如,module “b” 匯入了module “a”:

 
  1. module a {

  2. revision 2008-01-01 { ... }

  3. grouping a {

  4. leaf eh { .... }

  5. }

  6. }

  7.  
  8. module b {

  9. import a {

  10. prefix p;

  11. revision-date 2008-01-01;

  12. }

  13.  
  14. container bee {

  15. uses p:a;

  16. }

  17. }

當module “a” 的作者釋出了一個新的revision,新版本的更改可能不為“b”所接受。如果“b”接受,則需要更新其匯入“a”的import語句中的revision版本。

5.1.2 Module分層

YANG能支援資料模型的多層次劃分,在該劃分中,資料可能有不止一個top-level(頂級)的節點。擁有多個top-level節點的資料模型有時候是更加方便的。

NETCONF協議能夠在<config><data>元素中包含任何XML內容作為載荷。YANG模型中的頂級結點在上述兩種元素中以任意順序,作為子節點存在。在這些子節點中,要保證NETCONF訊息已經封裝成正確的XML格式了。

比如:

 
  1. module my-config {

  2. namespace "http://example.com/schema/config";

  3. prefix "co";

  4.  
  5. container system { ... }

  6. container routing { ... }

  7. }

在NETCONF中被封裝為:

 
  1. <rpc message-id="101"

  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"

  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">

  4. <edit-config>

  5. <target>

  6. <running/>

  7. </target>

  8. <config>

  9. <system xmlns="http://example.com/schema/config">

  10. <!-- system data here -->

  11. </system>

  12. <routing xmlns="http://example.com/schema/config">

  13. <!-- routing data here -->

  14. </routing>

  15. </config>

  16. </edit-config>

  17. </rpc>

除了YANG定義之外的rpc,message-id什麼的都搞不懂。還需要看一下NETCONF啊。

5.2 檔案格式

YANG modules和submodules通常都會以檔案的形式儲存,每個module或者submodule一個檔案。檔案的命名格式SHOULD 是這種格式:

module-or-submodule-name ['@' revision-date] ( '.yang' / '.yin' )
  •  

YANG編譯器能夠通過檔名找到匯入的modules和包含的submodules。當使用YANG語言定義modules的時候,出於效能和manageability的考慮,編譯器可能會分別編譯每一個submodules。在submodules的編譯期間,errors和warnings不能被檢測到。直到將submodules併入module的時候,才會發現錯誤和警告。

5.3 XML Namespace

所有的YANG定義都包含在YANG module中,每個YANG module都會和特定的XML namespace XML NAMES繫結,該名稱空間是全域性唯一的URI RFC3986。NETCONF的客戶端和服務端在封裝資料的時候,使用這個名稱空間。

modules的Namespace釋出在rfc4844中, MUST 由IANA分配,可見Section 14。

私有module的namespace分配由擁有該module的組織分配。Namespace URIs的分配必須保證不能與標準的modules衝突,不能與其他私有的modules衝突,可以在namespace中使用組織/公司名字以避免明明衝突。

“namespace”宣告可以在Section 7.1.3見到。

5.3.1 YANG XML Namespace

YANG 為NETCONF的 <edit-config> 和<error-info>內容定義了XML namespace。這個namespace的名字是“urn:ietf:params:xml:ns:yang:1”。

5.4 解析Grouping,Type,和Identify名

Gouping,Type,和Identify的名字是在它們被定義的地方被解析的,而不是在它們被使用的地方被解析的。groupings, typedefs,identifies的使用者並不被強制要求匯入modules或者包含submodules,以滿足原始定義的引用要求。這種特性類似於傳統程式語言中的靜態變數作用域。

比如,如果一個module定義了一個grouping,在其中引用了一個type。當這個grouping在另一個module中被引用的時候,該type在原來的module的上下文中被解析,而不是在第二個module中被解析。如此一來就不用擔心多個module共同定義同一個type時候引起的衝突問題了。

5.5. Nested Typedefs和Groupings

在很多YANG statements中,typedefs和groupings都可能出現巢狀的情況。在層級結構中,它們在語義上侷限於被定義的層級(也就是說解析的時候不會波及到其他層級)。這使得types和groupings可以定義在和被使用的地方接近的地方,而不是放到層級結構的頂級。這種使用處定義的特性增強了可讀性。(Typedefs and groupings may appear nested under many YANG statements, allowing these to be lexically scoped by the hierarchy under which they appear. This allows types and groupings to be defined near where they are used, rather than placing them at the top level of the hierarchy. The close proximity increases readability.

作用域(scoping)的作用使得在不同submodules定義的types可以出現命名衝突,因為它們的作用域沒有交集。

最後,作用域使得module的作者能夠使得他們定義的types和groupings能夠只對他們的module或submodule有效,防止了其他人的重用。由於只有頂級的types和groupings能夠在module/submodule外部被使用,開發者能夠有更多的控制能力,控制module的哪些部分要對外開放,哪些部分要在內部保持私有。

作用域的定義 MUST NOT 覆蓋更高階別的作用域的定義。當在schema層級結構中,當更高階別中已經定義了,則更低階別中不能再定義相同的“types”和“groupings”了。

對於沒有字首的type或grouping的引用,或者使用當前module名作為字首的引用,會被解析為和type或grouping宣告最匹配的結構。(A reference to an unprefixed type or grouping, or one which uses the prefix of the current module, is resolved by locating the closest matching “typedef” or “grouping” statement among the immediate substatements of each ancestor statement.

5.6 一致性

一致性(conformance)是衡量一個裝置實際上與model契合的程度。通常來說,裝置需要如實完全實現model的定義,這樣一來上層應用才能按照model的定義來看待下面的裝置。裝置與model的差異會降低model的可用性,同時使得使用該model的application更加脆弱。

YANG針對一致性有三種檢查機制:

  • model的基礎行為檢查
  • model可選特性的檢查
  • 和model之間的偏差

接下來我們會挨個討論每一種機制。

5.6.1 基礎行為

model定義了NETCONF的client和server之間的constract(協議),這使得通訊雙方能夠互相理解對方傳送的模型化資料背後蘊含的語法和語義。YANG的優點就是constract的優點。

5.6.2 可選特性

在很多models中,作者會允許models中的某些部分在有一定先決條件的情況下才會出現/禁止出現。裝置可以決定,是否支援model中定義的可選功能。

比如,一個syslog data model可能會選擇支援本地儲存日誌的能力,但是model作者知道,在實際裝置中,只有當這個裝置有本地儲存器的時候才有可能支援該功能。如果裝置上沒有本地儲存器,則application就不能通知裝置去儲存日誌。

YANG通過名為“feature”的結構支援這種可選特性的機制。features使得模型作者能夠讓裝置根據實際情況有選擇實現一些可選的特性。這樣一來,在model中就能表現一些只有部分裝置支援的特性。這些特性被包含在model的定義中,能夠使得不同裝置的模型儘可能保持一致性,讓application能夠獲知哪些特性被支援,並在此基礎上對裝置進行操作。

一個module可以宣告任意數量的features,這些特性用字串id做識別。如果一個裝置支援某個feature,則module中對應的部分對該裝置來說就是可用的;反之亦然。

features是用“feature”宣告定義的。如果該feature是有條件的(conditional),則需要使用“if-feature”宣告。

更多細節可見Section 7.18.1

還是不太明白feature的應用例項。

5.6.3 偏差(deviations)

在理想情況下,所有的裝置都應該完全實現model的定義,不會和model出現任何偏差。但是實際情況下,裝置總會和model有各種各樣的差異存在。為了讓YANG能夠支援針對實際存在的偏差的自動處理,裝置上必須有一種機制能夠通知applications它和model之間的偏差。

比如,一個BGP module能支援任意多的BGP peers,但是一個特定的裝置可能最多隻能支援16個peers。任何application傳送的第17個peer的連線請求都會失敗。相比較於裝置用錯誤訊息通知application,更好的解決方法是application從一開始就知道16個peers的限制,並且能夠避免使用者申請註定失敗的第17個peer連線。

裝置的deviations使用“deviation”宣告,它使用在schema tree中表示一個節點的字串作為引數。The contents of the statement details the manner in which the device implementation deviates from the contract as defined in the module.

更多細節可見Section 7.18.3

5.6.4 在訊息中宣告一致性(Conformance)資訊

名稱空間URI MUST 作為一種能力(capability),在NETCONF的訊息中向外通告,表示NETCONF伺服器支援YANG module。該URI的格式 MUST 如下:

 
  1. capability-string = namespace-uri [ parameter-list ]

  2. parameter-list = "?" parameter *( "&" parameter )

  3. parameter = revision-parameter /

  4. module-parameter /

  5. feature-parameter /

  6. deviation-parameter

  7. revision-parameter = "revision=" revision-date

  8. module-parameter = "module=" module-name

  9. feature-parameter = "features=" feature *( "," feature )

  10. deviation-parameter = "deviations=" deviation *( "," deviation )

  • “revision-date”表示NETCONF伺服器實現的module的revision
  • “module-name”表示module的名字,如同“module”宣告一樣
  • “namespace-uri”表示這個module的namespace URI,如同在“namespace”宣告中出現的一樣
  • “feature”表示裝置實現的可選的feature
  • “eviation”表示定義了裝置的偏差的module的名字

在以上的引數列表中,每個引數 MUST 出現一次。

5.6.4.1 Modules

伺服器通過訊息通告它所支援的modules的名字。Module的namespaces是在capability字串中作為基礎URI編碼的,mdule的名字被編碼為“module”引數放到基礎URI中。

一個伺服器 MUST 宣告它所實現的所有modules的所有revisions。

比如,下面的訊息宣告瞭一個module “syslog”。

 
  1. <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">

  2. <capability>

  3. http://example.com/syslog?module=syslog&amp;revision=2008-04-01

  4. </capability>

  5. </hello>

5.6.4.2 Features

伺服器通過訊息通告它所支援的features的名字。在訊息中,features作為包含在URI中的“features”引數編碼的。這個引數的值是以逗號為分隔符的feature名的列表。

比如,下面的訊息宣告瞭一個module,“syslog”,並告訴客戶端它所支援的名為“local-storage”的feature。

 
  1. <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">

  2. <capability>

  3. http://example.com/syslog?module=syslog&amp;features=local-storage

  4. </capability>

  5. </hello>

5.6.4.3 偏差(Deviations)

裝置的偏差是通過“deviations”引數宣告的。“deviations”引數的值是以逗號為分隔符的包含deviations的modules的列表。

比如,下面的訊息通告了兩個modules,告訴客戶端它偏離module “syslog”的程度,這個程度具體是通過module “my-devs”宣告出來的。

 
  1. <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">

  2. <capability>

  3. http://example.com/syslog?module=syslog&amp;deviations=my-devs

  4. </capability>

  5. <capability>

  6. http://example.com/my-deviations?module=my-devs

  7. </capability>

  8. </hello>

但是這個偏差具體怎麼描述也沒有個說明,它的內容和“syslog”有怎樣的關係?

5.7 Data Store Modification

Data models可能允許伺服器選擇不同的configuration data store的實現,而不僅僅是直接明確地通過NETCONF協議訊息完成。比如,一個data model可能定義了一些系統生成的分配的值作為leafs,但是客戶端可能並不支援。一種指定環境變數的通用機制(前提是這些環境變數允許修改)超出了本文件的討論範圍。

6 YANG Syntax

YANG語法類似於【RFC3780】定義的SMIng,以及程式語言C和C++。這種語法之所以和C相似,主要是為了可讀性。since YANG values the time and effort of the readers of models above those of modules writers and YANG tool-chain developers. This section introduces the YANG syntax.

YANG modules使用【RFC3629】定義的UTF-8作為字元編碼格式。

6.1 詞彙的令牌化(Lexical Tokenization)

YANG modules在解析時會被分為多個tokens。本小節詳細解釋解析這些tokens的規則。YANG的令牌化規則是簡單而強大的。簡單之處在於其力圖保持解析器的實現簡單,強大之處在於模型設計者能夠以一種易讀的格式表現他們設計的models。

6.1.1 註釋(Comments)

Comments是C++風格的。單行註釋開始於“//”,結束於本行。塊註釋開始於“/*”,結束於“*/”。

6.1.2 Tokens

YANG中的一個token是一個keyword,string,semicolon(“;”),或者braces( “{” 或 “}” )。一個string可以是quoted或unquoted的。一個keyword可以是本文件中定義的YANG的關鍵詞,或者是後面跟著冒號“:”,冒號後面跟著語言擴充套件關鍵詞的字首id。keywords是大小寫敏感的。id的正式定義可見section 6.2。

什麼是quoted和unquoted?意思是引號包括的和不用引號包括的。

6.1.3 引號包裹(Quoting)

如果一個string包含任何空格,製表符,分號(“;”),大括號( “{” 或 “}”),註釋符號(“//”,“/*”,或“*/”),則它 MUST用雙引號或者單引號包括。

如果一個用雙引號包括的string中包含一個換行符,換行符後面跟著的是空格或者製表符,該空格或製表符通常用來控制YANG檔案中的文字佈局。這些用於增強文字顯示效果的留白在解析時會被從string中刪掉,一直到第一個非空白字元為止。在該處理流程中,一個製表符被認為是8個空格符。

如果這個用雙引號包括的string中在換行符前包含了空格或者製表符,這種行尾空格也會被從string中刪掉。

一個單括號包裹的string(“””)則會保留單括號內的每一個字元。單括號字元不能出現在單括號包括的string中,即便使用反斜槓(“\”)做了轉義也不可以。

在一個雙括號包括的string理,使用轉義字元(也就是反斜槓)會引入一個特殊字元,這取決於該轉義字元後面跟著的是哪個字元:

 
  1. \n new line

  2. \t a tab character

  3. \" a double quote

  4. \\ a single backslash

如果一個括號包裹的string後面跟著一個加號(“+”),然後跟著另一個括號包裹的string,則這兩個strings會被首尾銜接在一起,合併為一個string。在雙括號包括的strings進行合併之前,該string要先完成空白字元的刪除,以及轉義字元的替換。

6.1.3.1 Quoting例子

下面的strings是等價的:

 
  1. hello

  2. "hello"

  3. 'hello'

  4. "hel" + "lo"

  5. 'hel' + "lo"

下面的例子展示了一些特殊字元:

 
  1. "\"" - string containing a double quote

  2. '"' - string containing a double quote

  3. "\n" - string containing a new line character

  4. '\n' - string containing a backslash followed

  5. by the character n

下面的例子展示了一些非法的字串:

 
  1. '''' - a single-quoted string cannot contain single quotes

  2. """ - a double quote must be escaped in a double-quoted string

  3.  

下面的字串是等價的:

 
  1. "first line

  2. second line"

  3.  
  4. "first line\n" + " second line"

6.2 Identifiers

6.1.2中提到的id。

Identifiers被用來標識不同型別的YANG items。每個identifier都開始於一個大寫,小寫的ASCII字幕,或者是一個下劃線,後面跟著0個或多個ASCII字幕,數字,下劃線,連字元以及點。具體的實現 MUST 支援64個字元的長度。Identifiers是大小寫敏感的。其語法規則的正式定義可見Section 12。Identifiers能被指定為quoted或unquoted strings。

其實看了也不明白這個identifier的具體用途在哪裡

6.2.1 Identifiers和它們的Namespaces

每個identifier在一個namespace中都是有效的,而namespace取決於YANG item被定義的型別。所有的定義在一個namespace中的identifiers都必須是唯一的。

  • 所有的module和submodule的名字都共享同一個全域性的module identifier namespace。
  • 在module以及它的submodules中定義的所有副檔名都共享同一個extension identifier namespace。
  • 所有定義在module以及它的submodules的identity names都共享同一個identity identifier namespace。
  • 所有定義在module以及它的submodules的父節點或者頂級節點的派生型別的名字(derived type names)都共享同一個type identifier namespace。這個namespace對於該父節點或者module的所有下行節點都有效。這意味著任何下行節點都有可能使用typedef,並且MUST NOT 定義和其它type名相同的名字。
  • 所有定義在module以及它的submodules的父節點或者頂級節點的grouping names都共享同一個grouping identifier namespace。這個namespace對於該父節點或者module的所有下行節點都有效。這意味著任何下行節點都有可能使用grouping,並且 MUST NOT 定義和其它grouping名相同的名字。
  • 所有定義在module以及它的submodules的父節點或者頂級節點的leafs,leaf-lists,lists,containers,choices,rpcs,notifications以及anyxmls(直接或者通過“use”宣告定義的 )都共享同一個identifier namespace。這個namespace對於該父節點或者module都有效,除非父節點是一個case node。在那種情況下,這個namespace對於非case或choice節點的最近的祖先節點。
  • 所有在包含在“choice”中的“case”都共享同一個case identifier namespace。這個namespace在父choice node中有效。

這裡還是有問題啊,第六項中,這個namespace對於該父節點或者module有效,而不是對該父節點或者module的所有下行節點都有效。這裡是不是有錯誤啊? 
另外,頂級節點的作用範圍是不是就對應著整個module啊。

YANG語言中允許前向引用(Forward references)。

6.3 宣告(Statements)

一個YANG module包含了一系列的statements。每個statement開始於一個keyword,後面跟著0個或一個引數,然後或者跟著一個分號表示結束,或者跟著用大括號包裹的substatements塊:

 statement = keyword [argument] (";" / "{" *statement "}")
  •  

如果Section 6.1.2的定義,這個引數是一個string。

6.3.1 語言擴充套件(Language Extensions)

在一個module中,可以使用“extension”關鍵詞(見Section 7.17)引入YANG extensions。擴充套件也可以被其它modules使用“import”宣告匯入(見Section 7.1.5)。當一個被匯入的擴充套件被使用時,該擴充套件的關鍵詞 MUST 使用該擴充套件被定義的module的名字作為字首以示區別。如果擴充套件在它被定義的module中使用,則其關鍵詞也 MUST 使用module的字首。由於submodules不能包括其parent module,因此,所有需要在submodules中用到的擴充套件都 MUST 定義在submodule中。然後其它的submodules能夠通過包含該submodule使用該擴充套件。

複習一下,submodule叫include,module叫import。

如果一個YANG編譯器不支援特定的擴充套件,具體表現為在一個YANG module中出現未知的statement(見Section 12),則整個未知的statement包含的內容 MAY 被編譯器忽略。

6.4 XPath Evaluations

XPath的簡介可見http://www.w3school.com.cn/xpath/xpath_intro.asp

XPath 是一門在 XML 文件中查詢資訊的語言。XPath 用於在 XML 文件中通過元素和屬性進行導航。XPath 使用路徑表示式來選取 XML 文件中的節點或者節點集。這些路徑表示式和我們在常規的電腦檔案系統中看到的表示式非常相似。在 XPath 中,有七種型別的節點:元素、屬性、文字、名稱空間、處理指令、註釋以及文件節點(或稱為根節點)。

YANG依賴XML Path Language(XPath) 1.0,將其作為標記表達節點之間的引用和依賴關係。NETCONF的客戶端和服務端並不強制要求實現XPath直譯器,但是 MUST 確保data model中編碼的requirements是強制執行的。執行的方式由實際實現決定。XPath表示式 MUST 在語法結構上保證正確無誤,所有使用的字首 MUST在當前的XPath context中是現成可用的(見Section 6.4.1)。有種實現會選擇手動實現這些,而不是直接使用XPath表示式。

什麼叫確保data model中編碼的requirements是強制的。原文是

NETCONF clients and servers are not required to implement an XPath interpreter, but MUST ensure that the requirements encoded in the data model are enforced. The manner of enforcement is an implementation decision.

The data model used in the XPath expressions is the same as that used 
in XPath 1.0 [XPATH], with the same extension for root node children 
as used by XSLT 1.0 [XSLT] (Section 3.1). Specifically, it means 
that the root node may have any number of element nodes as its 
children.

6.4.1 XPath Context

所有的YANG XPath表示式都共享下面的XPath context定義:

  • The set of namespace declarations is the set of all “import” statements’ prefix and namespace pairs in the module where the XPath expression is specified, and the “prefix” statement’s prefix for the “namespace” statement’s URI.
  • Names without a namespace prefix belong to the same namespace as the identifier of the current node. Inside a grouping, that namespace is affected by where the grouping is used (see Section 7.12).
  • The function library is the core function library defined in [XPATH], and a function “current()” that returns a node set with the initial context node.
  • The set of variable bindings is empty.

The mechanism for handling unprefixed names is adopted from XPath 2.0 [XPATH2.0], and helps simplify XPath expressions in YANG. No ambiguity may ever arise because YANG node identifiers are always qualified names with a non-null namespace URI.

The context node varies with the YANG XPath expression, and is specified where the YANG statement with the XPath expression is defined.

6.5 Schema Node Identifier

這一塊可是重中之重啊,在ODL的YANGTools中,首先要做的就是解析引數為SchemaNodeIdentifier。

一個schema node identifier是一個string,表明了schema tree中的一個節點。它有兩種表達形式,“absolute”(絕對路徑)和“descendant”(相對路徑),其規則分別由Section 12中的“absolute-schema-nodeid”和“descendant-schema-nodeid”制定。一個shema node identifier是由用斜槓(“/”)分隔的不同id組合而成的path組成的。在一個absolute schema node identifier中,第一個斜槓後面的第一個identifier是本module或所有其它被匯入的modules的頂級schema node。

定義在外部modules的對identifiers的引用 MUST 使用合適的字首描述,在當前module以及它的submodules中引用的identifiers MSY 使用字首。

比如,為了表示在頂級節點“a”下的子節點“b”,可以使用字串“/a/b”。

7 YANG Statements

接下來的小節描述了所有的YANG statements。

需要明確一點,即便是在YANG中沒有定義任何substatements的statement也能有裝置商制定的擴充套件作為substatements。比如,“description”宣告在YANG定義中沒有任何substatements,但是下面的寫法是合法的:

 
  1. description "some text" {

  2. acme:documentation-flag 5;

  3. }

7.1 Module Statement

“module”宣告定義了module的名字,將所有屬於該module的宣告都集中在一起。“module”宣告的引數就是該module的名字,後面跟著一塊substatements,其中包含了該module具體的資訊。module的名字服從Section 6.2中針對identifiers的規則。

在RFC streams 【RFC 
4844
】中釋出的modules的名字 MUST 由IANA分配,可見Section 14。

私有的module的名字是由擁有該module的組織分配的。 RECOMMENDED 私有module的名字和標準中的modules以及其它組織的module沒有命名衝突。

一個module的典型佈局如下:

 
  1. module <module-name> {

  2.  
  3. // header information

  4. <yang-version statement>

  5. <namespace statement>

  6. <prefix statement>

  7.  
  8. // linkage statements

  9. <import statements>

  10. <include statements>

  11.  
  12. // meta information

  13. <organization statement>

  14. <contact statement>

  15. <description statement>

  16. <reference statement>

  17.  
  18. // revision history

  19. <revision statements>

  20.  
  21. // module definitions

  22. <other statements>

  23. }

  •  

7.1.1 module的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | anyxml | 7.10 | 0..n |

  5. | augment | 7.15 | 0..n |

  6. | choice | 7.9 | 0..n |

  7. | contact | 7.1.8 | 0..1 |

  8. | container | 7.5 | 0..n |

  9. | description | 7.19.3 | 0..1 |

  10. | deviation | 7.18.3 | 0..n |

  11. | extension | 7.17 | 0..n |

  12. | feature | 7.18.1 | 0..n |

  13. | grouping | 7.11 | 0..n |

  14. | identity | 7.16 | 0..n |

  15. | import | 7.1.5 | 0..n |

  16. | include | 7.1.6 | 0..n |

  17. | leaf | 7.6 | 0..n |

  18. | leaf-list | 7.7 | 0..n |

  19. | list | 7.8 | 0..n |

  20. | namespace | 7.1.3 | 1 |

  21. | notification | 7.14 | 0..n |

  22. | organization | 7.1.7 | 0..1 |

  23. | prefix | 7.1.4 | 1 |

  24. | reference | 7.19.4 | 0..1 |

  25. | revision | 7.1.9 | 0..n |

  26. | rpc | 7.13 | 0..n |

  27. | typedef | 7.3 | 0..n |

  28. | uses | 7.12 | 0..n |

  29. | yang-version | 7.1.2 | 0..1 |

  30. +--------------+---------+-------------+

上面的0..1,表示可以出現0次到1次,0..n表示可以出現任意次數,1表示能且僅能出現一次。

7.1.2 yang-version宣告

“yang-version”是可選的,指定了本module使用的YANG語言的版本號。這個宣告的引數是一個字串。如果出現,它必須包含值“1”,這是YANG語言目前的版本號,也是預設的版本號。

version 1.1已經有了。不過還不知道是哪個RFC。

對於值非“1”的“yang-version”的處理超出了本文件的討論範圍。任何定義更高版本的文件都需要保持版本向前相容。

7.1.3 namespace宣告

“namespace”宣告定義了module中所有的identifiers所屬的XML namespace,除了定義在一個grouping中的data node identifiers以外(見Section 7.12)。它的引數是這個namespace的URI。

詳情可減Section 5.3。

7.1.4 prefix宣告

“prefix”宣告唄用來定義和module以及它的namespace相關聯的字首。“prefix”宣告的引數是一個字首字串。這個字串MAY 指向包含在本module中的定義,比如“if:ifName”。prefix遵循和identifier相同的規則(見Section 6.2)。

當在“module”宣告中使用它時,“prefix”宣告定義了當該module被其它module匯入時需要使用的字首。為了提高NETCONF XML的可讀性,一個使用該字首生成XML或者XPath的NETCONF的客戶端或者服務端 SHOULD 使用這個字首,除非出現了衝突。(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.

當在“import”宣告中使用它時,“prefix”宣告定義了訪問被匯入module中的定義時需要使用的字首。當需要引用一個被匯入module的identifier時,被匯入module的字首字串會被放在identifier前面,用冒號隔開,比如“if:ifIndex”。為了提高YANG modules的可讀性,module中定義的prefix SHOULD 在該module被匯入時使用,除非出現了prefix conflict。如果出現了衝突,比如兩個擁有同樣prefix名的不同的modules同時被匯入,則至少有一個 MUST 改變其prefix。

所有的prefixes,包括module自己本身的prefix,都 MUST 在該module或者submodule內部保持唯一。

這裡用了module或者submodule內部保持唯一。

7.1.5 import宣告

“import”宣告使得一個module的定義能夠在另一個module或submodule內部被使用。它的引數是被匯入的module的名字,其後跟著一塊包含具體匯入資訊的substatements。當一個module被匯入時,匯入它的module可能:

  • 使用被匯入module或者它的submodules中的任何grouping和typedef。
  • 使用被匯入module或者它的submodules中的任何extension,feature,以及identity。
  • 使用被匯入module的schema tree中的“must”,“path”,以及“when”宣告中的任何node,或者作為“augment”和“deviation”宣告的target node。

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.

當可選的“revision-date” substatement在“import”宣告中出現時,任何本地module的定義中引用的typedef,grouping,extension,feature以及identity都是從指定revision的module中匯入的。如果指定的revision不存在,則會出現錯誤。如果沒有“revision-date”出現,則匯入的module的revision不確定。

對於同一個module的多個revisions的匯入是 MUST NOT 的。

 
  1. The import's Substatements

  2.  
  3. +---------------+---------+-------------+

  4. | substatement | section | cardinality |

  5. +---------------+---------+-------------+

  6. | prefix | 7.1.4 | 1 |

  7. | revision-date | 7.1.5.1 | 0..1 |

  8. +---------------+---------+-------------+

7.1.5.1 import的revision-date宣告

“revision-date”宣告用來指定module的具體版本號。其值 MUST 和被匯入module的“revision”宣告的值匹配。

7.1.6 include宣告

“include”宣告被用來將某個submodule的內容對於其父module,或者父module之下的其他submodule可用。其引數是一個identifier,表示被包含的submodule的名字。modules只能包含屬於它的用“belongs-to”宣告定義的submodules,submodules只能包含和它屬於同一個module的其他submodule。

當一個module包含了一個submodule,它就會將這個submodule的內容組合進本module的node hierarchy中。當一個submodule包含了另一個submodule,則另一個submodule的定義對於當前的submodule就是可用的。

當可選的“revision-date” substatement出現,指定revision的submodule會被包含到module中。如果指定revision的submodule不存在,則會出現錯誤。如果沒有“revision-date” substatement出現,則沒有定義哪個revision的submodule會被包含。

對於同一個submodule的多個revisions的匯入是 MUST NOT 的。

 
  1. The includes's Substatements

  2.  
  3. +---------------+---------+-------------+

  4. | substatement | section | cardinality |

  5. +---------------+---------+-------------+

  6. | revision-date | 7.1.5.1 | 0..1 |

  7. +---------------+---------+-------------+

7.1.7 organization宣告

“organization”宣告定義了對該module負責的團體名。其引數是特定組織的文字描述的字串。

7.1.8 contact宣告

“contact”宣告提供了該module的相關聯絡資訊。該引數是一個字串,包含了指定聯絡人的名字,郵件地址,電話號碼,電子郵箱等資訊,技術相關的疑問都可以諮詢他。

7.1.9 revision宣告

“revision”宣告指定了該module的編輯版本歷史,包括最初的一版。一系列的revision宣告能夠詳細描述該module定義上發生的改變細節。其引數是一個日期字串,格式為“YYYY-MM-DD”,後面跟著一塊包含詳細revision資訊的substatements。一個module SHOULD 至少有一個初始的“revision”宣告。對於每次釋出的修改,都 SHOULD 增加一個revision。

7.1.9.1 revision的substatement

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | description | 7.19.3 | 0..1 |

  5. | reference | 7.19.4 | 0..1 |

  6. +--------------+---------+-------------+

7.1.10 使用用例

 
  1. module acme-system {

  2. namespace "http://acme.example.com/system";

  3. prefix "acme";

  4.  
  5. import ietf-yang-types {

  6. prefix "yang";

  7. }

  8.  
  9. include acme-types;

  10.  
  11. organization "ACME Inc.";

  12. contact

  13. "Joe L. User

  14.  
  15. ACME, Inc.

  16. 42 Anywhere Drive

  17. Nowhere, CA 95134

  18. USA

  19.  
  20. Phone: +1 800 555 0100

  21. EMail: joe@acme.example.com";

  22.  
  23. description

  24. "The module for entities implementing the ACME protocol.";

  25.  
  26. revision "2007-06-09" {

  27. description "Initial revision.";

  28. }

  29.  
  30. // definitions follow...

  31. }

7.2 submodule宣告

YANG中最基本的單位是module,一個YANG module本身能夠由多個submodules構成。submodules的存在使得module設計者能夠將一個複雜的model分割成多個共用同一個namespace的submodules,而namespace是由module定義的。

“submodule”宣告定義了submodule的名字,將屬於該submodule的所有宣告都整合到了一起。其引數是submodule的名字,後面跟著相關的詳細substatements資訊。submodule名字遵從identifiers的規則,可見Section 6.2。

在RFC streams 【RFC4844】中釋出的submodules的名字都 MUST 由IANA分配,可見Section 14。

Private submodule names are assigned by the organization owning the 
submodule without a central registry. It is RECOMMENDED to choose 
submodule names that will have a low probability of colliding with 
standard or other enterprise modules and submodules, e.g., by using 
the enterprise or organization name as a prefix for the submodule 
name.

一個經典的submodule的文字佈局如下:

 
  1. submodule <module-name> {

  2.  
  3. <yang-version statement>

  4.  
  5. // module identification

  6. <belongs-to statement>

  7.  
  8. // linkage statements

  9. <import statements>

  10. <include statements>

  11.  
  12. // meta information

  13. <organization statement>

  14. <contact statement>

  15. <description statement>

  16. <reference statement>

  17.  
  18. // revision history

  19. <revision statements>

  20.  
  21. // module definitions

  22. <other statements>

  23. }

7.2.1 submodule的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | anyxml | 7.10 | 0..n |

  5. | augment | 7.15 | 0..n |

  6. * | belongs-to | 7.2.2 | 1 |

  7. | choice | 7.9 | 0..n |

  8. | contact | 7.1.8 | 0..1 |

  9. | container | 7.5 | 0..n |

  10. | description | 7.19.3 | 0..1 |

  11. | deviation | 7.18.3 | 0..n |

  12. | extension | 7.17 | 0..n |

  13. | feature | 7.18.1 | 0..n |

  14. | grouping | 7.11 | 0..n |

  15. | identity | 7.16 | 0..n |

  16. | import | 7.1.5 | 0..n |

  17. | include | 7.1.6 | 0..n |

  18. | leaf | 7.6 | 0..n |

  19. | leaf-list | 7.7 | 0..n |

  20. | list | 7.8 | 0..n |

  21. | notification | 7.14 | 0..n |

  22. | organization | 7.1.7 | 0..1 |

  23. | reference | 7.19.4 | 0..1 |

  24. | revision | 7.1.9 | 0..n |

  25. | rpc | 7.13 | 0..n |

  26. | typedef | 7.3 | 0..n |

  27. | uses | 7.12 | 0..n |

  28. | yang-version | 7.1.2 | 0..1 |

  29. +--------------+---------+-------------+

和module相比,多了一個belongs-to,少了一個prefix。

7.2.2 belongs-to宣告

“belongs-to”宣告指定了submodule所屬的module。其引數是module名字。

一個submodule MUST 只能被它所屬的module,或者被它所屬的module的其它submodules包含。

“belongs-to”宣告有一個必須出現的“prefix”宣告,該宣告指定了所屬的module的prefix。在本地submodule中的所有定義,以及它所包含的submodules都能通過這個prefix訪問。

 
  1. The belongs-to's Substatements

  2.  
  3. +--------------+---------+-------------+

  4. | substatement | section | cardinality |

  5. +--------------+---------+-------------+

  6. | prefix | 7.1.4 | 1 |

  7. +--------------+---------+-------------+

7.2.3 使用用例

 
  1. submodule acme-types {

  2.  
  3. belongs-to "acme-system" {

  4. prefix "acme";

  5. }

  6.  
  7. import ietf-yang-types {

  8. prefix "yang";

  9. }

  10.  
  11. organization "ACME Inc.";

  12. contact

  13. "Joe L. User

  14.  
  15. ACME, Inc.

  16. 42 Anywhere Drive

  17. Nowhere, CA 95134

  18. USA

  19.  
  20. Phone: +1 800 555 0100

  21. EMail: joe@acme.example.com";

  22.  
  23. description

  24. "This submodule defines common ACME types.";

  25.  
  26. revision "2007-06-09" {

  27. description "Initial revision.";

  28. }

  29.  
  30. // definitions follows...

  31. }

7.3 typedef宣告

根據Section 5.5中的規則,“typedef”宣告定義了一個新的type,能夠在module內部,包含該module的modules或submodules,以及匯入該module的其它modules使用。新的type稱為“derived type”(派生型別),被派生的型別稱為“base type”(基本型別)。所有的派生型別都能最重追溯到YANG的內建型別。

“typedef”宣告的引數是一個identifier,該id就是新定義的型別的名字,其後面 MUST 跟著包含typedef詳細資訊的一塊substatements。

這個type的名字 MUST NOT 是YANG的內建型別。如果typedef定義在YANG module或submodule的top level,則其名字MUST 在整個module中保持唯一。

7.3.1 typedef的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | default | 7.3.4 | 0..1 |

  5. | description | 7.19.3 | 0..1 |

  6. | reference | 7.19.4 | 0..1 |

  7. | status | 7.19.2 | 0..1 |

  8. | type | 7.3.2 | 1 |

  9. | units | 7.3.3 | 0..1 |

  10. +--------------+---------+-------------+

7.3.2 typedef的type宣告

“type”宣告 MSUT 出現在typedef中,定義了新定義type所派生的基本型別。可見Section 7.4。

7.3.3 units宣告

“units”宣告是可選的,其內容是一個字串,包含了和這個type相關的units的文字定義。

7.3.4 typedef的default宣告

“default”宣告的引數是新的type的預設值。

“default”宣告的值 MUST 是有效的。

如果base type有一個預設值,新的派生型別沒有指定新的預設值,則base type的預設值也是新的派生型別的預設值。

如果這個type的預設值,在派生型別或者leaf的定義中,根據相關restrictions,是無效的,則派生型別或leaf定義就 MUST指定一個新的預設值,以匹配restrictions。

7.3.5 使用用例

 
  1. typedef listen-ipv4-address {

  2. type inet:ipv4-address;

  3. default "0.0.0.0";

  4. }

7.4 type宣告

“type”宣告的引數是YANG的內建型別(見Section 9)或者派生型別(見Section 7.3),後面跟著可選的一塊substatements,用於進一步對該type施加限制(restrictions)。

所有內建型別能夠使用的restriction宣告取決於被限定的型別。

7.4.1 type的substatements

 
  1. +------------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +------------------+---------+-------------+

  4. | bit | 9.7.4 | 0..n |

  5. | enum | 9.6.4 | 0..n |

  6. | length | 9.4.4 | 0..1 |

  7. | path | 9.9.2 | 0..1 |

  8. | pattern | 9.4.6 | 0..n |

  9. | range | 9.2.4 | 0..1 |

  10. | require-instance | 9.13.2 | 0..1 |

  11. | type | 7.4 | 0..n |

  12. +------------------+---------+-------------+

沒清楚這裡使用type有什麼意義?需要例子。

7.5 constainer宣告

“container”宣告被用來定義一個schema tree中包含的內部資料節點(interior data node)。它有一個引數,是一個identifier,後面跟著一塊描述進詳細資訊的substatements。

一個container節點沒有一個值,但是在data tree中有一個列表的子節點。子節點都定義在container的substatements中。

7.5.1 Containers with Presence

YANG支援兩種風格的containers,一種僅僅用於組織data nodes的垂直結構,一種出現在configuration中,有明確的意義。

第一種風格中,container本身沒有任何意義,它的存在僅僅是為了包含子節點。這是預設的風格。

比如,同步光網路(SONET)的scrambling options的集合能被放到一個名為“scrambling”的container中,以增強配置結構的層次化,將這些節點整合到一起。這個“scrambling”節點本身沒有意義,所以在它變成空的的時候可以移除該節點。

在第二種風格中,container本身就是配置型資料(configuration)data,表示配置型資料的一個簡單bit。The container acts as both a configuration knob and a means of organizing related configuration. 這些containers的建立和刪除操作都必須是明確無誤的。

YANG稱這種風格的container為一個“presence container”,這表示要使用“presence”宣告,作為它的

比如,一個“ssh”的container可能會啟動使用ssh方式將日誌寫進裝置的能力,不過也能包含任何和ssh相關的configuration knobs,比如連線速率和重試次數限制。

“presence”宣告(見Section 7.5.5)用來在data tree中給container的存在以語義。

說這麼多,都不如一個demo來的實在。真的是沒看懂啊。

7.5.2 container的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | anyxml | 7.10 | 0..n |

  5. | choice | 7.9 | 0..n |

  6. | config | 7.19.1 | 0..1 |

  7. | container | 7.5 | 0..n |

  8. | description | 7.19.3 | 0..1 |

  9. | grouping | 7.11 | 0..n |

  10. | if-feature | 7.18.2 | 0..n |

  11. | leaf | 7.6 | 0..n |

  12. | leaf-list | 7.7 | 0..n |

  13. | list | 7.8 | 0..n |

  14. | must | 7.5.3 | 0..n |

  15. | presence | 7.5.5 | 0..1 |

  16. | reference | 7.19.4 | 0..1 |

  17. | status | 7.19.2 | 0..1 |

  18. | typedef | 7.3 | 0..n |

  19. | uses | 7.12 | 0..n |

  20. | when | 7.19.5 | 0..1 |

  21. +--------------+---------+-------------+

7.5.3 must宣告

“must”宣告是可選的,其引數是一個字串包含了一個XPath表示式(見Section 6.4)。它被用來正式宣告有效資料上的約束。約束根據Section 8的規則執行。

當一個datastore可用時,所有的“must”約束都會對data tree中的每個data node,對於使用預設值的所有leafs(見Section 7.6.1)進行概念上的評估。如果一個data node在data tree中並不存在,並且沒有一個預設值,則它的“must”宣告不會被評估。(When a datastore is validated, all “must” constraints are conceptually evaluated once for each data node in the data tree, and for all leafs with default values in use (see Section 7.6.1). If a data node does not exist in the data tree, and it does not have a default value, its “must” statements are not evaluated.

所有這樣的約束 MUST 評估為true,這樣data才是有效的。

XPath表示式在下述的上下文,以及Section 6.4.1的定義中也要進行概念上的評估(conceptually evaluated):

  • The context node is the node in the data tree for which the “must” statement is defined.
  • The accessible tree is made up of all nodes in the data tree, and all leafs with default values in use (see Section 7.6.1).

可訪問的tree取決於context node:

  • If the context node represents configuration, the tree is the data in the NETCONF datastore where the context node exists. The XPath root node has all top-level configuration data nodes in all modules as children.
  • If the context node represents state data, the tree is all state data on the device, and the datastore. The XPath root node has all top-level data nodes in all modules as children.
  • If the context node represents notification content, the tree is the notification XML instance document. The XPath root node has the element representing the notification being defined as the only child.
  • If the context node represents RPC input parameters, the tree is the RPC XML instance document. The XPath root node has the element representing the RPC operation being defined as the only child.
  • If the context node represents RPC output parameters, the tree is the RPC reply instance document. The XPath root node has the elements representing the RPC output parameters as children.

使用標準的XPath規則評估的XPath表示式的結果會被轉化為一個boolean值。

Note that since all leaf values in the data tree are conceptually stored in their canonical form (see Sections 7.6 and 7.7), any XPath comparisons are done on the canonical value.

Also note that the XPath expression is conceptually evaluated. This means that an implementation does not have to use an XPath evaluator on the device. How the evaluation is done in practice is an implementation decision.

7.5.4 must的substatements

 
  1. +---------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +---------------+---------+-------------+

  4. | description | 7.19.3 | 0..1 |

  5. | error-app-tag | 7.5.4.2 | 0..1 |

  6. | error-message | 7.5.4.1 | 0..1 |

  7. | reference | 7.19.4 | 0..1 |

  8. +---------------+---------+-------------+

7.5.4.1 error-message宣告

“error-message”宣告是可選的,其引數是一個字串。如果約束的評估結果為false,這個字串會被放在的中。

7.5.4.2 error-app-tag宣告

“error-app-tag”宣告是可選的,其引數是一個字串。如果約束的評估結果為false,這個字串會被放在的中。

7.5.4.3 must和error-message的使用用例

 
  1. container interface {

  2. leaf ifType {

  3. type enumeration {

  4. enum ethernet;

  5. enum atm;

  6. }

  7. }

  8. leaf ifMTU {

  9. type uint32;

  10. }

  11. must "ifType != 'ethernet' or " +

  12. "(ifType = 'ethernet' and ifMTU = 1500)" {

  13. error-message "An ethernet MTU must be 1500";

  14. }

  15. must "ifType != 'atm' or " +

  16. "(ifType = 'atm' and ifMTU <= 17966 and ifMTU >= 64)" {

  17. error-message "An atm MTU must be 64 .. 17966";

  18. }

  19. }

7.5.5 presence宣告

“presence”宣告指定了在data tree中一個container的presence的含義。它的引數是一個字串,包含了node的presence means的文字描述。

如果一個container有“presence”宣告,則存在於data tree中的該container就是有意義的。否則,該container就是第一型別的container,僅僅用於將資料結構化,本身並不攜帶任何意義。

更多資訊可見Section 7.5.1。

簡單來說,這個宣告存在的意義就是用來判別container是第一類還是第二類的。不過沒有見到哪個文件裡有具體的實現啊。

7.5.6 container的child node宣告

在一個container中,child nodes可以是“container”,“leaf”,“list”,“leaf-list”,“uses”,“choice”,以及“anyxml”宣告。

7.5.7 XML 對映規則

一個container節點被編碼為一個XML element。這個element的local name就是container的identifier,它的namespace就是module的XML namespace(見Section 7.1.3)。

container的child nodes被編碼為container element的subelements。如果container定義了RPC input或output引數,這些subelements被編碼的順序和它們在“container”宣告中定義的順序一致。否則,subelements的編碼順序隨意。

一個NETCONF服務端在回覆一個或請求的時候,如果container node沒有“presence”宣告並且沒有child nodes存在,則MAY 不會傳送這個container element作為回覆。因此,一個傳送或後獲得回覆的客戶端,必須能夠處理一種情況,那就是在XML中沒有不包含“presence”宣告的container node。

涉及到NETCONF的時候就一臉蒙逼。

7.5.8 NETCONF 操作

containers可以通過在中使用“operation”屬性(見【RFC4741】 Section 7.2)被建立,刪除,替換和修改。

如果一個container沒有包含“presence”宣告,並且最後一個child node都被刪除了,則NETCONF服務端 MAY 刪除這個container。當一個NETCONF服務端處理一個請求的時候,container node的處理流程如下:

  • 如果operation是“merge”或者“replace”,當該node不存在時則會被建立。
  • 如果operation是“create”,當該node不存在時會被建立。如果該node已經存在了,則會返回一個“data-exists”錯誤。
  • 如果operation是“delete”,當該node存在時會被哦刪除。如果該node不存在,則會返回“data-missing”錯誤。

7.5.9 使用用例

給出下面的container的定義:

 
  1. container system {

  2. description "Contains various system parameters";

  3. container services {

  4. description "Configure externally available services";

  5. container "ssh" {

  6. presence "Enables SSH";

  7. description "SSH service specific configuration";

  8. // more leafs, containers and stuff here...

  9. }

  10. }

  11. }

對應的XML例項為:

 
  1. <system>

  2. <services>

  3. <ssh/>

  4. </services>

  5. </system>

由於 element出現了,所以ssh是enabled的。

使用刪除一個container:

 
  1. <rpc message-id="101"

  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"

  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">

  4. <edit-config>

  5. <target>

  6. <running/>

  7. </target>

  8. <config>

  9. <system xmlns="http://example.com/schema/config">

  10. <services>

  11. <ssh nc:operation="delete"/>

  12. </services>

  13. </system>

  14. </config>

  15. </edit-config>

  16. </rpc>

7.6 leaf宣告

“leaf”宣告被用來在schema tree中定義一個leaf node。它只有一個引數,是identifier,後面跟著詳細描述該leaf資訊的一塊substatements。

一個leaf node有一個值,但是在data tree中沒有child nodes。概念上將,data tree中的值總是以canonical form存在的(見Section 9.1)。

在data tree中存在0個或者1個leaf node。

“leaf”宣告被用來定義一個特定型別的標量變數。

7.6.1 leaf的預設值(default value)

一個leaf的預設值是當在data tree中沒有該leaf存在時,服務端採用的值。預設值的採用取決於schema tree中離該leaf最近的帶有“presence” 的container的祖先節點:

  • 如果在schema tree中沒有這樣的祖先節點,則預設值 MUST 被使用
  • 否則,如果這個祖先節點是一個case node,則如果data tree中有任何該case的node存在,或者這個case node就是choice的預設case,並且data tree中沒有任何其它的case存在,這樣一來就必須使用預設值。
  • 再否則,如果在data tree中有這樣的祖先節點存在,則預設值 MUST 被使用。

表示完全看不懂上面說了些啥?並且不明白為什麼這麼設定。

在這些例子中,預設值都要被使用。

當預設值被使用的時候,服務端 MUST 表現得好像這個值為預設值的這個leaf node就存在於data tree中一樣。

如果一個leaf有一個“default”宣告,則該leaf的預設值就是“default”宣告指定的值。否則,如果leaf的type有一個預設的值,並且該leaf不是強制出現(mandatory)的,則該leaf的預設值就是該type的預設值。在所有其它情況下,這個leaf沒有一個預設值。

7.6.2 leaf的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | config | 7.19.1 | 0..1 |

  5. | default | 7.6.4 | 0..1 |

  6. | description | 7.19.3 | 0..1 |

  7. | if-feature | 7.18.2 | 0..n |

  8. | mandatory | 7.6.5 | 0..1 |

  9. | must | 7.5.3 | 0..n |

  10. | reference | 7.19.4 | 0..1 |

  11. | status | 7.19.2 | 0..1 |

  12. | type | 7.6.3 | 1 |

  13. | units | 7.3.3 | 0..1 |

  14. | when | 7.19.5 | 0..1 |

  15. +--------------+---------+-------------+

7.6.3 leaf的type宣告

“type”宣告, MUST要出現,有一個引數,是當前已有的內建或者佩聲型別。在這個type上有可選的substatements指定了相關的restrictions。可見Section 7.4。

7.6.4 leaf的default宣告

“default”宣告,是可選的,其引數是一個字串,包含了leaf的預設值。

“default”宣告的值 MUST是有效可用的,不能違背對應type的規則。

如果“mantory”為true,則“default”宣告 MUST NOT 不能出現在nodes中。

7.6.5 leaf的mandatory宣告

The “mandatory” statement, which is optional, takes as an argument 
the string “true” or “false”, and puts a constraint on valid data. 
If not specified, the default is “false”.

If “mandatory” is “true”, the behavior of the constraint depends on 
the type of the leaf’s closest ancestor node in the schema tree that 
is not a non-presence container (see Section 7.5.1):

o If no such ancestor exists in the schema tree, the leaf MUST 
exist.

o Otherwise, if this ancestor is a case node, the leaf MUST exist if 
any node from the case exists in the data tree.

o Otherwise, the leaf MUST exist if the ancestor node exists in the 
data tree.

This constraint is enforced according to the rules in Section 8.

7.6.6 XML對映規則

 
  1. A leaf node is encoded as an XML element. The element's local name

  2.  

is the leaf’s identifier, and its namespace is the module’s XML 
namespace (see Section 7.1.3).

The value of the leaf node is encoded to XML according to the type, 
and sent as character data in the element.

A NETCONF server that replies to a or request MAY 
choose not to send the leaf element if its value is the default 
value. Thus, a client that receives an for a or 
request, MUST be prepared to handle the case that a leaf 
node with a default value is not present in the XML. In this case, 
the value used by the server is known to be the default value.

See Section 7.6.8 for an example.

7.6.7 NETCONF Operations

When a NETCONF server processes an request, the 
elements of procedure for the leaf node are:

 
  1. If the operation is "merge" or "replace", the node is created if

  2. it does not exist, and its value is set to the value found in the

  3. XML RPC data.

  4.  
  5. If the operation is "create", the node is created if it does not

  6. exist. If the node already exists, a "data-exists" error is

  7. returned.

  8.  
  9. If the operation is "delete", the node is deleted if it exists.

  10. If the node does not exist, a "data-missing" error is returned.

7.6.8 使用例項

給定下面的“leaf”宣告,放到之前定義的 “ssh”的container中(可見Section 7.5.9):

 
  1. leaf port {

  2. type inet:port-number;

  3. default 22;

  4. description "The port to which the SSH server listens"

  5. }

對應的XML例項為:

 <port>2022</port>
  •  

在中設定該leaf的值:

 
  1. <rpc message-id="101"

  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"

  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">

  4. <edit-config>

  5. <target>

  6. <running/>

  7. </target>

  8. <config>

  9. <system xmlns="http://example.com/schema/config">

  10. <services>

  11. <ssh>

  12. <port>2022</port>

  13. </ssh>

  14. </services>

  15. </system>

  16. </config>

  17. </edit-config>

  18. </rpc>

7.7 leaf-list宣告

“leaf”宣告是被用來定義一個簡單的特定型別的標量變數,而“leaf-list”宣告被用來定義特定型別的一個陣列。“leaf-list”宣告有一個引數,是一個identifier,後面跟著描述具體內容的一塊substatements。

“leaf-list”的值 MUST 是唯一的。

概念上來講,data tree中的值總是以canonical form存在的(見Section 9.1)。

如果“leaf-list”引用的type有預設值,預設值對leaf-list產生什麼影響(If the type referenced by the leaf-list has a default value, it has no effect in the leaf-list.)。

7.7.1 排序

對於“list”和“leaf-list”宣告,YANG支援兩種風格的排序方式。在很多lists中,為了使被排列的列表項不影響列表配置的具體實現,裝置能夠以任何合理的順序給list的列表項進行排序。不過在“description”中可能會有關於排序的建議。YANG稱這種風格為“system ordered”,這種排序的宣告為“ordered-by system”。

比如,有時候為了對到來的流量進行過濾,防火牆的過濾條件列表項的順序就變得有用。使用者可能需要決定丟棄所有TCP流量的過濾項是放在允許信任介面流量通過的過濾項之前還是之後。這時候對於列表的排序就至關重要了。

YANG為NETCONF的操作提供了豐富的特性集以便列表能夠以使用者規定的方式進行排序。列表項可能會被插入,或重新排列到列表的第一項或最後一項,或者放到某一個特定列表項的前面或者後面。

“ordered-by”宣告在Section 7.7.5 中有所包含。

7.7.2 leaf-list的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | config | 7.19.1 | 0..1 |

  5. | description | 7.19.3 | 0..1 |

  6. | if-feature | 7.18.2 | 0..n |

  7. | max-elements | 7.7.4 | 0..1 |

  8. | min-elements | 7.7.3 | 0..1 |

  9. | must | 7.5.3 | 0..n |

  10. | ordered-by | 7.7.5 | 0..1 |

  11. | reference | 7.19.4 | 0..1 |

  12. | status | 7.19.2 | 0..1 |

  13. | type | 7.4 | 1 |

  14. | units | 7.3.3 | 0..1 |

  15. | when | 7.19.5 | 0..1 |

  16. +--------------+---------+-------------+

7.7.3 min-elements宣告

“min-elements”宣告,是可選的,取值為一個非負的整型,是對有效列表項的一個約束。一個可用的“leaf-list”或者“list”MUST 至少有min-elements個列表項。

如果該宣告不存在,則預設為0。

The behavior of the constraint depends on the type of the leaf-list’s 
or list’s closest ancestor node in the schema tree that is not a non- 
presence container (see Section 7.5.1):

o If this ancestor is a case node, the constraint is enforced if any 
other node from the case exists.

o Otherwise, it is enforced if the ancestor node exists.

The constraint is further enforced according to the rules in 
Section 8.

7.7.4 max-elements宣告

The “max-elements” statement, which is optional, takes as an argument 
a positive integer or the string “unbounded”, which puts a constraint 
on valid list entries. A valid leaf-list or list always has at most 
max-elements entries.

If no “max-elements” statement is present, it defaults to 
“unbounded”.

The “max-elements” constraint is enforced according to the rules in 
Section 8.

7.7.5 ordered-by宣告

“ordered-by”宣告定義了列表中列表項的順序是使用者定義還是系統自定義。其引數是“system”和“user”中的一個。如果該宣告沒有出現,預設值是“system”。

如果列表表達的是state date,RPC output parameters,或者notification content,則這個宣告會被忽略,因為對以上三種資料,都沒有排序的必要。

更多資訊可見Section 7.7.1

7.7.5.1 ordered-by system

The entries in the list are sorted according to an unspecified order. 
Thus, an implementation is free to sort the entries in the most 
appropriate order. An implementation SHOULD use the same order for 
the same data, regardless of how the data were created. Using a 
deterministic order will make comparisons possible using simple tools 
like “diff”.

This is the default order.

7.7.5.2 ordered-by user

列表項的排序是使用者通過中的特殊XML屬性控制的。可見Section 7.7.7

7.7.6 XML對映規則

A leaf-list node is encoded as a series of XML elements. Each 
element’s local name is the leaf-list’s identifier, and its namespace 
is the module’s XML namespace (see Section 7.1.3).

The value of each leaf-list entry is encoded to XML according to the 
type, and sent as character data in the element.

The XML elements representing leaf-list entries MUST appear in the 
order specified by the user if the leaf-list is “ordered-by user”; 
otherwise, the order is implementation-dependent. The XML elements 
representing leaf-list entries MAY be interleaved with other sibling 
elements, unless the leaf-list defines RPC input or output 
parameters.

See Section 7.7.8 for an example.

7.7.7 NETCONF 操作

Leaf-list entries can be created and deleted, but not modified, 
through , by using the “operation” attribute in the 
leaf-list entry’s XML element.

In an “ordered-by user” leaf-list, the attributes “insert” and 
“value” in the YANG XML namespace (Section 5.3.1) can be used to 
control where in the leaf-list the entry is inserted. These can be 
used during “create” operations to insert a new leaf-list entry, or 
during “merge” or “replace” operations to insert a new leaf-list 
entry or move an existing one.

The “insert” attribute can take the values “first”, “last”, “before”, 
and “after”. If the value is “before” or “after”, the “value” 
attribute MUST also be used to specify an existing entry in the leaf- 
list.

If no “insert” attribute is present in the “create” operation, it 
defaults to “last”.

If several entries in an “ordered-by user” leaf-list are modified in 
the same request, the entries are modified one at the 
time, in the order of the XML elements in the request.

In a , or an with a “replace” operation 
that covers the entire leaf-list, the leaf-list order is the same as 
the order of the XML elements in the request.

When a NETCONF server processes an request, the 
elements of procedure for a leaf-list node are:

 
  1. If the operation is "merge" or "replace", the leaf-list entry is

  2. created if it does not exist.

  3.  
  4. If the operation is "create", the leaf-list entry is created if it

  5. does not exist. If the leaf-list entry already exists, a

  6. "data-exists" error is returned.

  7.  
  8. If the operation is "delete", the entry is deleted from the leaf-

  9. list if it exists. If the leaf-list entry does not exist, a

  10. "data-missing" error is returned.

7.7.8 使用用例

 
  1. leaf-list allow-user {

  2. type string;

  3. description "A list of user name patterns to allow";

  4. }

對應的XML例項:

 
  1. <allow-user>alice</allow-user>

  2. <allow-user>bob</allow-user>

為了在列表中增加一個新元素,使用中的操作“merge”:

 
  1. <rpc message-id="101"

  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"

  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">

  4. <edit-config>

  5. <target>

  6. <running/>

  7. </target>

  8. <config>

  9. <system xmlns="http://example.com/schema/config">

  10. <services>

  11. <ssh>

  12. <allow-user>eric</allow-user>

  13. </ssh>

  14. </services>

  15. </system>

  16. </config>

  17. </edit-config>

  18. </rpc>

給定下面的使用者排序的例子:

 
  1. leaf-list cipher {

  2. type string;

  3. ordered-by user;

  4. description "A list of ciphers";

  5. }

下面的語句是要在“3des-cbc”後面插入一條新的cipher “blowfish-cbc”:

 
  1. <rpc message-id="101"

  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"

  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"

  4. xmlns:yang="urn:ietf:params:xml:ns:yang:1">

  5. <edit-config>

  6. <target>

  7. <running/>

  8. </target>

  9. <config>

  10. <system xmlns="http://example.com/schema/config">

  11. <services>

  12. <ssh>

  13. <cipher nc:operation="create"

  14. yang:insert="after"

  15. yang:value="3des-cbc">blowfish-cbc</cipher>

  16. </ssh>

  17. </services>

  18. </system>

  19. </config>

  20. </edit-config>

  21. </rpc>

7.8 list宣告

“list”宣告被用來定義一個schema tree中的內部資料節點(interior data node)。一個list node在data tree中可能有多個例項存在。每個這樣的例項都被認為是一個列表項。“list”宣告有一個引數,是identifier,後面跟著描述更詳細資訊的一塊substatements。

一個列表項是由該列表的keys的值唯一指定的,前提是keys存在。

7.8.1 list的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | anyxml | 7.10 | 0..n |

  5. | choice | 7.9 | 0..n |

  6. | config | 7.19.1 | 0..1 |

  7. | container | 7.5 | 0..n |

  8. | description | 7.19.3 | 0..1 |

  9. | grouping | 7.11 | 0..n |

  10. | if-feature | 7.18.2 | 0..n |

  11. | key | 7.8.2 | 0..1 |

  12. | leaf | 7.6 | 0..n |

  13. | leaf-list | 7.7 | 0..n |

  14. | list | 7.8 | 0..n |

  15. | max-elements | 7.7.4 | 0..1 |

  16. | min-elements | 7.7.3 | 0..1 |

  17. | must | 7.5.3 | 0..n |

  18. | ordered-by | 7.7.5 | 0..1 |

  19. | reference | 7.19.4 | 0..1 |

  20. | status | 7.19.2 | 0..1 |

  21. | typedef | 7.3 | 0..n |

  22. | unique | 7.8.3 | 0..n |

  23. | uses | 7.12 | 0..n |

  24. | when | 7.19.5 | 0..1 |

  25. +--------------+---------+-------------+

7.8.2 list的key宣告

“key”宣告,如果該list表示的是configuration資訊,則 MUST 存在;其他情況下,則MAY 存在。有一個字串的引數,該字串是一個用空格符作為分隔符的這個list中的leaf的identifiers的列表。在key中,一個leaf的identifier MUST NOT 出現超過一次。每個這樣的leaf identifier MUST 是該list的child leaf中的一個。這個leafs能直接在list的substatements中定義,也可以在list中的groupings裡使用。

在key中指定的所有leafs的值的組合唯一確定了一個列表項(感覺有點類似於資料庫中的聯合主鍵)。當一個列表項被建立時,所有的key leafs都 MUST 被賦值。這樣一來,在key leafs中的任何預設值都會被忽略。key leafs中的任何mandatory statement都會被忽略。

不太明白啥意思。附上原文:Thus, any default values in the key leafs or their types are ignored. It also implies that any mandatory statement in the key leafs are ignored.

作為key的一部分的一個leaf能夠是任何內建型別或者派生型別,但是 MUST NOT 是內建型別“empty”。

All key leafs in a list MUST have the same value for their “config” as the list itself.

key的字串的語法是Section 12中的“key-arg”規則定義的。

7.8.3 list的unique宣告

“unique”宣告被用來對有效的列表項施加約束的。它有一個引數,是一個字串。該字串中包含了schema node identifiers的以空格為分隔符的列表,這些ids MUST 是descendant form的形式(見Section 12中的“descendant-schema-nodeid”規則)。每個這樣的schema node identifier MUST 指向一個leaf。

如果被引用的leafs中有一個是configuration data,則所有被引用的leafs都 MUST 表示configuration data。

“unique”約束指定:所有在引數字串中指定的leafs的例項的值,包括那些使用預設值的leafs,都 MUST 在所有列表項例項中保證唯一。這個約束根據Section 8的規則強制執行。

“unique”字串語法由Section 12中的“unique-arg”語法正式定義。

7.8.3.1 使用用例

假設有下面的list定義:

 
  1. list server {

  2. key "name";

  3. unique "ip port";

  4. leaf name {

  5. type string;

  6. }

  7. leaf ip {

  8. type inet:ip-address;

  9. }

  10. leaf port {

  11. type inet:port-number;

  12. }

  13. }

則下面兩個configuration是無效的:

 
  1. <server>

  2. <name>smtp</name>

  3. <ip>192.0.2.1</ip>

  4. <port>25</port>

  5. </server>

  6.  
  7. <server>

  8. <name>http</name>

  9. <ip>192.0.2.1</ip>

  10. <port>25</port>

  11. </server>

下面的configuration是有效的,因為“http”和“ftp”的list表項沒有實現所有被unique引用的leafs,因此在“unique”約束執行檢查的時候不會被約束掉:

 
  1. <server>

  2. <name>smtp</name>

  3. <ip>192.0.2.1</ip>

  4. <port>25</port>

  5. </server>

  6.  
  7. <server>

  8. <name>http</name>

  9. <ip>192.0.2.1</ip>

  10. </server>

  11.  
  12. <server>

  13. <name>ftp</name>

  14. <ip>192.0.2.1</ip>

  15. </server>

7.8.4 list的child node statements

list的child nodes可以是”container”, “leaf”, “list”, “leaf-list”, “uses”, 
“choice”, 以及 “anyxml”。

7.8.5 XML對映規則

A list is encoded as a series of XML elements, one for each entry in 
the list. Each element’s local name is the list’s identifier, and 
its namespace is the module’s XML namespace (see Section 7.1.3).

The list’s key nodes are encoded as subelements to the list’s 
identifier element, in the same order as they are defined within the 
“key” statement.

The rest of the list’s child nodes are encoded as subelements to the 
list element, after the keys. If the list defines RPC input or 
output parameters, the subelements are encoded in the same order as 
they are defined within the “list” statement. Otherwise, the 
subelements are encoded in any order.

The XML elements representing list entries MUST appear in the order 
specified by the user if the list is “ordered-by user”, otherwise the 
order is implementation-dependent. The XML elements representing 
list entries MAY be interleaved with other sibling elements, unless 
the list defines RPC input or output parameters.

7.8.6 NETCONF 操作

List entries can be created, deleted, replaced, and modified through 
, by using the “operation” attribute in the list’s XML 
element. In each case, the values of all keys are used to uniquely 
identify a list entry. If all keys are not specified for a list 
entry, a “missing-element” error is returned.

In an “ordered-by user” list, the attributes “insert” and “key” in 
the YANG XML namespace (Section 5.3.1) can be used to control where 
in the list the entry is inserted. These can be used during “create” 
operations to insert a new list entry, or during “merge” or “replace” 
operations to insert a new list entry or move an existing one.

The “insert” attribute can take the values “first”, “last”, “before”, 
and “after”. If the value is “before” or “after”, the “key” 
attribute MUST also be used, to specify an existing element in the 
list. The value of the “key” attribute is the key predicates of the 
full instance identifier (see Section 9.13) for the list entry.

If no “insert” attribute is present in the “create” operation, it 
defaults to “last”.

If several entries in an “ordered-by user” list are modified in the 
same request, the entries are modified one at the time, 
in the order of the XML elements in the request.

In a , or an with a “replace” operation 
that covers the entire list, the list entry order is the same as the 
order of the XML elements in the request.

When a NETCONF server processes an request, the 
elements of procedure for a list node are:

 
  1. If the operation is "merge" or "replace", the list entry is

  2. created if it does not exist. If the list entry already exists

  3. and the "insert" and "key" attributes are present, the list entry

  4. is moved according to the values of the "insert" and "key"

  5. attributes. If the list entry exists and the "insert" and "key"

  6. attributes are not present, the list entry is not moved.

  7.  
  8. If the operation is "create", the list entry is created if it does

  9. not exist. If the list entry already exists, a "data-exists"

  10. error is returned.

  11.  
  12. If the operation is "delete", the entry is deleted from the list

  13. if it exists. If the list entry does not exist, a "data-missing"

  14. error is returned.

  15.  

7.8.7 使用用例

給定下面的一個list:

 
  1. list user {

  2. key "name";

  3. config true;

  4. description "This is a list of users in the system.";

  5.  
  6. leaf name {

  7. type string;

  8. }

  9. leaf type {

  10. type string;

  11. }

  12. leaf full-name {

  13. type string;

  14. }

  15. }

對應的XML例項:

 
  1. <user>

  2. <name>fred</name>

  3. <type>admin</type>

  4. <full-name>Fred Flintstone</full-name>

  5. </user>

建立一個新使用者“barney”:

 
  1. <rpc message-id="101"

  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"

  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">

  4. <edit-config>

  5. <target>

  6. <running/>

  7. </target>

  8. <config>

  9. <system xmlns="http://example.com/schema/config">

  10. <user nc:operation="create">

  11. <name>barney</name>

  12. <type>admin</type>

  13. <full-name>Barney Rubble</full-name>

  14. </user>

  15. </system>

  16. </config>

  17. </edit-config>

  18. </rpc>

改變“fred”的型別為“superuser”:

 
  1. <rpc message-id="101"

  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"

  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">

  4. <edit-config>

  5. <target>

  6. <running/>

  7. </target>

  8. <config>

  9. <system xmlns="http://example.com/schema/config">

  10. <user>

  11. <name>fred</name>

  12. <type>superuser</type>

  13. </user>

  14. </system>

  15. </config>

  16. </edit-config>

  17. </rpc>

給定下面的ordered-by user list:

 
  1. list user {

  2. description "This is a list of users in the system.";

  3. ordered-by user;

  4. config true;

  5.  
  6. key "name";

  7.  
  8. leaf name {

  9. type string;

  10. }

  11. leaf type {

  12. type string;

  13. }

  14. leaf full-name {

  15. type string;

  16. }

  17. }

下面的xml表示在使用者“fred”後面插入一個新使用者“barney”:

 
  1. <rpc message-id="101"

  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"

  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"

  4. xmlns:yang="urn:ietf:params:xml:ns:yang:1">

  5. <edit-config>

  6. <target>

  7. <running/>

  8. </target>

  9. <config>

  10. <system xmlns="http://example.com/schema/config"

  11. xmlns:ex="http://example.com/schema/config">

  12. <user nc:operation="create"

  13. yang:insert="after"

  14. yang:key="[ex:name='fred']">

  15. <name>barney</name>

  16. <type>admin</type>

  17. <full-name>Barney Rubble</full-name>

  18. </user>

  19. </system>

  20. </config>

  21. </edit-config>

  22. </rpc>

下面的語句是將使用者“barney”移到使用者“fred”前面:

 
  1. <rpc message-id="101"

  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"

  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"

  4. xmlns:yang="urn:ietf:params:xml:ns:yang:1">

  5. <edit-config>

  6. <target>

  7. <running/>

  8. </target>

  9. <config>

  10. <system xmlns="http://example.com/schema/config"

  11. xmlns:ex="http://example.com/schema/config">

  12. <user nc:operation="merge"

  13. yang:insert="before"

  14. yang:key="[ex:name='fred']">

  15. <name>barney</name>

  16. </user>

  17. </system>

  18. </config>

  19. </edit-config>

  20. </rpc>

7.9 choice宣告

“choice”宣告定義了可選項的一個集合,同時只能有其中的一個存在。其引數是一個identifier,後面跟著描述具體資訊的一塊substatements。這個identifier被用來在schema tree中標識這個choice node。choice node不會在data tree中存在。

一個choice由多個branches組成,這些branches是用“case” substatement定義的。每個branch都包含多個child nodes。在這些branches中同時最多隻能有其中一個branch的nodes能夠存在。

更多資訊可見Section 8.3.2

7.9.1 choice的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | anyxml | 7.10 | 0..n |

  5. | case | 7.9.2 | 0..n |

  6. | config | 7.19.1 | 0..1 |

  7. | container | 7.5 | 0..n |

  8. | default | 7.9.3 | 0..1 |

  9. | description | 7.19.3 | 0..1 |

  10. | if-feature | 7.18.2 | 0..n |

  11. | leaf | 7.6 | 0..n |

  12. | leaf-list | 7.7 | 0..n |

  13. | list | 7.8 | 0..n |

  14. | mandatory | 7.9.4 | 0..1 |

  15. | reference | 7.19.4 | 0..1 |

  16. | status | 7.19.2 | 0..1 |

  17. | when | 7.19.5 | 0..1 |

  18. +--------------+---------+-------------+

7.9.2 choice的case宣告

“case”宣告被用來定義choice的branches。它有一個引數,是identifier,後面跟著描述詳細資訊的一塊substatements。

這個identifier被用來在schema tree中標識這個case node。在data tree中不存在case node。

在一個“case”宣告中,其child nodes可以用“anyxml”,“choice”, “container”,“leaf”, “list”,“leaf-list”,以及“uses”宣告。所有child nodes的identifiers都 MUST 在該choice的所有cases中保持唯一。例如,下面的定義就是非法的:

 
  1. choice interface-type { // This example is illegal YANG

  2. case a {

  3. leaf ethernet { ... }

  4. }

  5. case b {

  6. container ethernet { ...}

  7. }

  8. }

YANG中有一種簡略的寫法,當branch中包含單個的“anyxml”,“container”,“leaf”,“list”或者“leaf-list”宣告的時候,“case”宣告可以省略。這種情況下,這個case的identifier和其中的宣告的identifier一樣。下面是一個例子:

 
  1. choice interface-type {

  2. container ethernet { ... }

  3. }

等價於:

 
  1. choice interface-type {

  2. case ethernet {

  3. container ethernet { ... }

  4. }

  5. }

在一個choice中,case identifier MUST 是唯一的。

7.9.2.1 case的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | anyxml | 7.10 | 0..n |

  5. | choice | 7.9 | 0..n |

  6. | container | 7.5 | 0..n |

  7. | description | 7.19.3 | 0..1 |

  8. | if-feature | 7.18.2 | 0..n |

  9. | leaf | 7.6 | 0..n |

  10. | leaf-list | 7.7 | 0..n |

  11. | list | 7.8 | 0..n |

  12. | reference | 7.19.4 | 0..1 |

  13. | status | 7.19.2 | 0..1 |

  14. | uses | 7.12 | 0..n |

  15. | when | 7.19.5 | 0..1 |

  16. +--------------+---------+-------------+

7.9.3 choice的default宣告

The “default” statement indicates if a case should be considered as 
the default if no child nodes from any of the choice’s cases exist. 
The argument is the identifier of the “case” statement. If the 
“default” statement is missing, there is no default case.

當“mandatory”的值為true時,“default”宣告 MUST 不能出現。

The default case is only important when considering the default 
values of nodes under the cases. The default values for nodes under 
the default case are used if none of the nodes under any of the cases 
are present.

There MUST NOT be any mandatory nodes (Section 3.1) directly under 
the default case.

Default values for child nodes under a case are only used if one of 
the nodes under that case is present, or if that case is the default 
case. If none of the nodes under a case are present and the case is 
not the default case, the default values of the cases’ child nodes 
are ignored.

In this example, the choice defaults to “interval”, and the default 
value will be used if none of “daily”, “time-of-day”, or “manual” are 
present. If “daily” is present, the default value for “time-of-day” 
will be used.

 
  1. container transfer {

  2. choice how {

  3. default interval;

  4. case interval {

  5. leaf interval {

  6. type uint16;

  7. default 30;

  8. units minutes;

  9. }

  10. }

  11. case daily {

  12. leaf daily {

  13. type empty;

  14. }

  15. leaf time-of-day {

  16. type string;

  17. units 24-hour-clock;

  18. default 1am;

  19. }

  20. }

  21. case manual {

  22. leaf manual {

  23. type empty;

  24. }

  25. }

  26. }

  27. }

7.9.4 choice的mandatory宣告

“mandatory”宣告,是可選的,其引數是值為“true”或“false”的string,作用是對有效的資料施加一種約束。如果取值為“true”,則說明choice的case branches中特定的某個branch中的至少一個node MUST 存在。

如果沒有指定,預設值是“false”。

The behavior of the constraint depends on the type of the choice’s 
closest ancestor node in the schema tree which is not a non-presence 
container (see Section 7.5.1):

o If this ancestor is a case node, the constraint is enforced if any 
other node from the case exists.

o Otherwise, it is enforced if the ancestor node exists.

The constraint is further enforced according to the rules in 
Section 8.

7.9.5 XML對映規則

choice和case nodes在XML中不可見。

The child nodes of the selected “case” statement MUST be encoded in 
the same order as they are defined in the “case” statement if they 
are part of an RPC input or output parameter definition. Otherwise, 
the subelements are encoded in any order.

7.9.6 NETCONF 操作

Since only one of the choice’s cases can be valid at any time, the 
creation of a node from one case implicitly deletes all nodes from 
all other cases. If an operation creates a node from a 
case, the NETCONF server will delete any existing nodes that are 
defined in other cases inside the choice.

7.9.7 使用用例

給定下面的choice:

 
  1. container protocol {

  2. choice name {

  3. case a {

  4. leaf udp {

  5. type empty;

  6. }

  7. }

  8. case b {

  9. leaf tcp {

  10. type empty;

  11. }

  12. }

  13. }

  14. }

對應的XML例項可以是:

 
  1. <protocol>

  2. <tcp/>

  3. </protocol>

將protocol從tcp改成udp:

 
  1. <rpc message-id="101"

  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"

  3. xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">

  4. <edit-config>

  5. <target>

  6. <running/>

  7. </target>

  8. <config>

  9. <system xmlns="http://example.com/schema/config">

  10. <protocol>

  11. <udp nc:operation="create"/>

  12. </protocol>

  13. </system>

  14. </config>

  15. </edit-config>

  16. </rpc>

7.10 anyxml宣告

“anyxml”宣告定義了schema tree的一個內部節點(interior node)。它有一個引數,是一個identifier,後面跟著描述詳細資訊的一塊substatements。

“anyxml”宣告被用來標識XML中未知的文字塊。在XML上沒有施加任何restrictions。這是相當有用的一點,比如說,在RPC的replies中。給出一個例子,在操作中的引數。

一個anyxml節點不能被擴充套件(augmented),可見Section 7.15。

由於對“anyxml”的使用會限制對內容的操控,所以 RECOMMENDED “anyxml”宣告不要被用來表示configuration data。

在data tree中,一個anyxml node只能存在於0個或1個例項中。

上面這句話沒明白,是說在data tree中,只能有一個anyxml的實現嗎?原文如下:_An anyxml node exists in zero or one instances in the data tree. 
_

7.10.1 anyxml的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | config | 7.19.1 | 0..1 |

  5. | description | 7.19.3 | 0..1 |

  6. | if-feature | 7.18.2 | 0..n |

  7. | mandatory | 7.6.5 | 0..1 |

  8. | must | 7.5.3 | 0..n |

  9. | reference | 7.19.4 | 0..1 |

  10. | status | 7.19.2 | 0..1 |

  11. | when | 7.19.5 | 0..1 |

  12. +--------------+---------+-------------+

7.10.2 XML對映規則

一個anyxml node會被編碼為一個XML element。這個element的local name就是這個anyxml的identifier,它的namespace就是module的XML namespace。anyxml node的值會被編碼為這個element的XML內容。

需要明白,在編碼中使用到的任何字首對於每個例項來說都是本地有效的。這意味著,在不同的實現中,同一個XML會被編碼為不同的東西。(Note that any prefixes used in the encoding are local to each instance encoding. This means that the same XML may be encoded differently by different implementations.

7.10.3 NETCONF 操作

一個anyxml node被認為是一塊不透明的資料塊(因為不知道里面什麼內容,無法解析)。這個資料塊只能整個被替換。

在anyxml node的subelements中出現的任何“operation”屬性都會被NETCONF服務端忽略,不作處理。

When a NETCONF server processes an request, the 
elements of procedure for the anyxml node are:

 
  1. If the operation is "merge" or "replace", the node is created if

  2. it does not exist, and its value is set to the XML content of the

  3. anyxml node found in the XML RPC data.

  4.  
  5. If the operation is "create", the node is created if it does not

  6. exist, and its value is set to the XML content of the anyxml node

  7. found in the XML RPC data. If the node already exists, a

  8. "data-exists" error is returned.

  9.  
  10. If the operation is "delete", the node is deleted if it exists.

  11. If the node does not exist, a "data-missing" error is returned.

7.10.4 使用用例

給定下面的“anyxml”宣告:

 anyxml data;
  •  

下面是同一個anyxml值的兩種不同的編碼:

 
  1. <data xmlns:if="http://example.com/ns/interface">

  2. <if:interface>

  3. <if:ifIndex>1</if:ifIndex>

  4. </if:interface>

  5. </data>

  6.  
  7. <data>

  8. <interface xmlns="http://example.com/ns/interface">

  9. <ifIndex>1</ifIndex>

  10. </interface>

  11. </data>

7.11 grouping宣告

“grouping”宣告被用來定義可重用的block of nodes,可能會在module內部被使用,在包含它的modules中使用,或者匯入它的其它modules中被使用。它有一個引數,是一個identifier,後面跟著描述更詳細資訊的一塊substatements。

“grouping”宣告不是一個data 定義的宣告,在schema tree中不會定義任何nodes。

一個grouping類似於常見程式語言中的“structure”或者“record”。

一旦一個grouping被定義,它就能通過“uses”宣告被引用(見Section 7.12)。一個grouping MUST NOT 引用它自己,也不能間接通過其它的groupings的引用鏈引用到自己。

如果grouping定義在YANG module或submodule的top level,grouping的identifier就MUST 在module內是唯一的。

grouping的作用不僅僅是一種文字替換機制,而且將某些nodes整合到了一個集合中。grouping中的identifiers會放到grouping定義的地方進行範圍的界定,而不是放到其被使用的地方。而prefix mappings,type names,grouping names,以及extension usage會在“grouping”宣告出現的垂直結構中進行評估。以extensions為例,這意味著extensions會被應用到grouping node,而不是uses node。

沒想明白為什麼會放到grouping定義的地方進行scope的界定,如果這樣的話,被引用的地方就有可能出現identifiers的衝突了吧?

7.11.1 grouping的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | anyxml | 7.10 | 0..n |

  5. | choice | 7.9 | 0..n |

  6. | container | 7.5 | 0..n |

  7. | description | 7.19.3 | 0..1 |

  8. | grouping | 7.11 | 0..n |

  9. | leaf | 7.6 | 0..n |

  10. | leaf-list | 7.7 | 0..n |

  11. | list | 7.8 | 0..n |

  12. | reference | 7.19.4 | 0..1 |

  13. | status | 7.19.2 | 0..1 |

  14. | typedef | 7.3 | 0..n |

  15. | uses | 7.12 | 0..n |

  16. +--------------+---------+-------------+

7.11.2 使用用例

 
  1. import ietf-inet-types {

  2. prefix "inet";

  3. }

  4.  
  5. grouping endpoint {

  6. description "A reusable endpoint group.";

  7. leaf ip {

  8. type inet:ip-address;

  9. }

  10. leaf port {

  11. type inet:port-number;

  12. }

  13. }

7.12 uses宣告

“uses”宣告被用來引用一個“grouping”定義。它有一個引數,就是所引用的grouping的名字。

“uses”的作用就是它所引用的grouping所包含的nodes會被複制到當前的schema tree中,並且後面會根據“refine”和“augment”宣告而更新。

暫時還不知道refine和augment是啥?

在grouping中定義的identifiers不回繫結到一個在“grouping”宣告內部沒有出現的namespace,除非這個grouping的內容通過“uses”宣告被增加到對應的schema tree中,這種情況下,它們就會被繫結到當前的module中。

以防誤解,附上原文:The identifiers defined in the grouping are not bound to a namespace until the contents of the grouping are added to the schema tree via a “uses” statement that does not appear inside a “grouping” statement, at which point they are bound to the namespace of the current module.

7.12.1 uses的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | augment | 7.15 | 0..1 |

  5. | description | 7.19.3 | 0..1 |

  6. | if-feature | 7.18.2 | 0..n |

  7. | refine | 7.12.2 | 0..1 |

  8. | reference | 7.19.4 | 0..1 |

  9. | status | 7.19.2 | 0..1 |

  10. | when | 7.19.5 | 0..1 |

  11. +--------------+---------+-------------+

7.12.2 refine宣告

在grouping中的每個node的某些屬性都能通過“refine”宣告refined。其引數是grouping中的某個node的identifier。這個node被稱為這個refine的target node。如果grouping中的一個node在“refine”宣告中沒有作為target node出現,它就不會被refined,因此被引用的時候就按照它在grouping中定義的那樣被引用。

引數字串是一個descendant schema node identifier(見Section 6.5)。

可以進行下面的refinements:

  • 一個leaf或choice node可能通過“refine”獲得一個預設值,或者本來就有一個預設值,被新的預設值替代了。
  • 任何node都能通過它獲得應用場景下的“description”字串。
  • 任何node都能通過它獲得應用場景下的“reference”字串。
  • 任何node都能通過它獲得一個不同的“config”宣告。
  • 一個leaf,anyxml,或者choice node都能通過它獲得一個不同的“mandatory”宣告。
  • 一個container node能通過它獲得一個“presence”宣告。表示一個container是否有實際意義
  • 一個leaf,leaf-list,list,container或anyxml node能通過它獲得額外的“must”表示式。
  • 一個leaf-list或list node能通過它獲得一個不同的“min-elements”或“max-elements”宣告。

refined這個詞在詞典中的意思是“精煉的”。不過給我的感覺更像是redefined或者modified。是為了適應grouping的使用場景對其做的一些修改。

7.12.3 XML 對映規則

在grouping中的每個node在編碼時表現就像它是被內聯進去的,即便它是其它XML namespace的另一個module中匯入的。(簡單來說,就按照C++裡面的inline關鍵詞理解就行了

7.12.4 使用用例

為了在其它module中定義的HTTP server中使用Section 7.11.2中定義的“endpoint” grouping,我們可以這麼寫:

 
  1. import acme-system {

  2. prefix "acme";

  3. }

  4.  
  5. container http-server {

  6. leaf name {

  7. type string;

  8. }

  9. uses acme:endpoint;

  10. }

對應的XML例項例子有:

 
  1. <http-server>

  2. <name>extern-web</name>

  3. <ip>192.0.2.1</ip>

  4. <port>80</port>

  5. </http-server>

如果埠80應該是HTTP Server的預設埠,則可以這麼寫:

 
  1. container http-server {

  2. leaf name {

  3. type string;

  4. }

  5. uses acme:endpoint {

  6. refine port {

  7. default 80;

  8. }

  9. }

  10. }

如果我們要定義一個servers的list,其中每個server都將ip和port作為keys,我們可以這麼寫:

 
  1. list server {

  2. key "ip port";

  3. leaf name {

  4. type string;

  5. }

  6. uses acme:endpoint;

  7. }

下面是一個錯誤用例:

 
  1. container http-server {

  2. uses acme:endpoint;

  3. leaf ip { // illegal - same identifier "ip" used twice

  4. type string;

  5. }

  6. }

7.13 rpc宣告

“rpc”宣告被用來定義一個NETCONF RPC操作。它有一個引數,是一個identifier,後面跟著描述詳細資訊的一塊substatements。這個引數是RPC的名字,在XML中作為 element的element名字,as designated by the substitution group “rpcOperation” in RFC4741

“rpc”宣告在schema tree中定義了一個rpc node。在這個rpc node之下,也會定義兩個schema node,一個名字叫“input”,一個叫“output”。node “input”和“output”都是定義在module的namespace中的。

7.13.1 rpc的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | description | 7.19.3 | 0..1 |

  5. | grouping | 7.11 | 0..n |

  6. | if-feature | 7.18.2 | 0..n |

  7. | input | 7.13.2 | 0..1 |

  8. | output | 7.13.3 | 0..1 |

  9. | reference | 7.19.4 | 0..1 |

  10. | status | 7.19.2 | 0..1 |

  11. | typedef | 7.3 | 0..n |

  12. +--------------+---------+-------------+

7.13.2 input宣告

“input”宣告,是可選的,被用來定義RPC操作的輸入引數。它沒有引數。“input”的substatements直接定義在input node之下。

如果在input tree中的一個leaf的“mandatory”宣告的值為“true”,這個leaf MUST 在NETCONF RPC呼叫時出現,否則,服務端 MUST 返回一個“missing-element”的錯誤。

如果一個在input tree中的leaf有預設值,則NETCONF伺服器 MUST 在和如Section 7.6.1 相同的場景下使用這個值。在這些場景下,伺服器 MUST 表現得好像在NETCONF RPC 呼叫中這個leaf本身就存在,並且其值為預設值。

如果一個“config”宣告出現在input tree中的任何node中,它都不會被處理。

如果任何node的“when”宣告的約束都被評估為false,則這個node MUST NOT 出現在input tree中。

7.13.2.1 input的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | anyxml | 7.10 | 0..n |

  5. | choice | 7.9 | 0..n |

  6. | container | 7.5 | 0..n |

  7. | grouping | 7.11 | 0..n |

  8. | leaf | 7.6 | 0..n |

  9. | leaf-list | 7.7 | 0..n |

  10. | list | 7.8 | 0..n |

  11. | typedef | 7.3 | 0..n |

  12. | uses | 7.12 | 0..n |

  13. +--------------+---------+-------------+

7.13.3 output宣告

“output”宣告,是可選的,被用來定義RPC操作中的輸出引數。它沒有引數。“output”的substatements直接定義在其後。

如果output tree中的一個leaf的“mandatory”宣告的值為“true”,則這個leaf MUST 出現在NETCONF RPC reply中。

如果output tree中的一個leaf有一個預設值,則NETCONF 客戶端 MUST 在和Section 7.6.1描述的場景相同的情況下使用這個值。在這些情況下,客戶端 MUST 表現得好像NETCONF RPC reply中本來就有這個leaf,並且其值就是預設值一樣。

如果一個“config”宣告出現在output tree中的任何node中,則這個“config”宣告不會被處理,會被忽略。

如果任何node中有一個“when”宣告約束,並且評估結果為false,則這個node MUST NOT 出現在output tree中。

7.13.3.1 output的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | anyxml | 7.10 | 0..n |

  5. | choice | 7.9 | 0..n |

  6. | container | 7.5 | 0..n |

  7. | grouping | 7.11 | 0..n |

  8. | leaf | 7.6 | 0..n |

  9. | leaf-list | 7.7 | 0..n |

  10. | list | 7.8 | 0..n |

  11. | typedef | 7.3 | 0..n |

  12. | uses | 7.12 | 0..n |

  13. +--------------+---------+-------------+

7.13.4 XML對映規則

一個rpc node會被編碼為【RFC4741】中定義的 element的child XML element。這個element的local name就是rpc的identifier,它的namespace就是rpc node所在module的XML namespace。

input引數會被編碼為rpc node的XML element的child XML elements,其排列順序和“input” statement中定義的順序一致。

如果RPC 操作的呼叫成功,並且沒有output引數返回,則會僅僅包含一個簡單的 element。如果output引數有返回,它們會被編碼為 element的child elements,其順序和“output”宣告中定義的順序一致。

7.13.5 使用用例

下面的例子定義了一個RPC操作:

 
  1. module rock {

  2. namespace "http://example.net/rock";

  3. prefix "rock";

  4.  
  5. rpc rock-the-house {

  6. input {

  7. leaf zip-code {

  8. type string;

  9. }

  10. }

  11. }

  12. }

對應的完整的rpc和rpc-reply的XML例項為:

 
  1. <rpc message-id="101"

  2. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">

  3. <rock-the-house xmlns="http://example.net/rock">

  4. <zip-code>27606-0100</zip-code>

  5. </rock-the-house>

  6. </rpc>

  7.  
  8. <rpc-reply message-id="101"

  9. xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">

  10. <ok/>

  11. </rpc-reply>

7.14 notification宣告

“notification”宣告被用來定義NETCONF的notification。它有一個引數,是一個identifier,後面跟著描述更詳細資訊的一塊substatements。“notification”宣告在schema tree中定義了一個notification node。

如果notification tree中的一個leaf有值為true的“mandatory”宣告,這個leaf MUST 在NETCONF的notification中出現。

如果notification tree中的一個leaf有預設值,則NETCONF 客戶端 MUST 在和Section 7.6.1描述的場景相同的情況下使用這個值。在這些情況下,客戶端 MUST 表現得好像NETCONF notification中本來就有這個leaf,並且其值就是預設值一樣。

如果“config”宣告出現在notification tree中的任何一個node中,則該宣告會被忽略。

7.14.1 notification的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | anyxml | 7.10 | 0..n |

  5. | choice | 7.9 | 0..n |

  6. | container | 7.5 | 0..n |

  7. | description | 7.19.3 | 0..1 |

  8. | grouping | 7.11 | 0..n |

  9. | if-feature | 7.18.2 | 0..n |

  10. | leaf | 7.6 | 0..n |

  11. | leaf-list | 7.7 | 0..n |

  12. | list | 7.8 | 0..n |

  13. | reference | 7.19.4 | 0..1 |

  14. | status | 7.19.2 | 0..1 |

  15. | typedef | 7.3 | 0..n |

  16. | uses | 7.12 | 0..n |

  17. +--------------+---------+-------------+

7.14.2 XML對映規則

一個notification node會作為【RFC5277】中定義的NETCONF Event Notifications對應的 element的child XML element存在。這個element的local name就是notification的identifier,它的namespace就是notification所在的module的XML namespace。

7.14.3 使用用例

下面的例子定義了一個notification:

 
  1. module event {

  2.  
  3. namespace "http://example.com/event";

  4. prefix "ev";

  5.  
  6. notification event {

  7. leaf event-class {

  8. type string;

  9. }

  10. anyxml reporting-entity;

  11. leaf severity {

  12. type string;

  13. }

  14. }

  15. }

完整的notification的對應的XML例項為:

 
  1. <notification

  2. xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">

  3. <eventTime>2008-07-08T00:01:00Z</eventTime>

  4. <event xmlns="http://example.com/event">

  5. <event-class>fault</event-class>

  6. <reporting-entity>

  7. <card>Ethernet0</card>

  8. </reporting-entity>

  9. <severity>major</severity>

  10. </event>

  11. </notification>

7.15 augment宣告

“augment”宣告允許將一個module或submodule增加到另外一個module定義的schema tree中,或者增加到當前module以及它的submodules,或者增加到使用“uses”宣告定義的grouping所引用的nodes中去。其引數是一個string,標識了一個node在schema tree中的位置。這個節點稱為augment的target node。這個target node MUST container,list,choice,case,input,output或者notification node的一種。在該宣告的substatements中定義的nodes會被augmented到target node中去。

augment的引數字串是一個schema node identifier(見Section 6.5)。如果“augment”宣告是module或submodule的一個top level的node, MUST 在schema node identifier中使用absolute form(見Section 12中的“absolute-schema-nodeid”)。如果“augment”宣告是“uses”宣告的一個substatement,則 MUST 使用descendant form(見Section 12的“descendant-schema-nodeid”)。

如果target node是一個containet,list,case,input,output或者notification node,則“container”,“leaf”,“list”,“leaf-list”,“uses”以及“choice”宣告可以被用在“augment”宣告中。

如果target node是一個choice node, 則“case”宣告,或者一個case的簡寫版的宣告(見Section 7.9.2)可以被用在“augment”宣告中。

如果target node在另外一個module中,則由augmentation增加的nodes MUST NOT 是mandatory nodes(可見Section 3.1).(If the target node is in another module, then nodes added by the augmentation MUST NOT be mandatory nodes (see Section 3.1).

The “augment” statement MUST NOT add multiple nodes with the same name from the same module to the target node.

7.15.1 augment的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | anyxml | 7.10 | 0..n |

  5. | case | 7.9.2 | 0..n |

  6. | choice | 7.9 | 0..n |

  7. | container | 7.5 | 0..n |

  8. | description | 7.19.3 | 0..1 |

  9. | if-feature | 7.18.2 | 0..n |

  10. | leaf | 7.6 | 0..n |

  11. | leaf-list | 7.7 | 0..n |

  12. | list | 7.8 | 0..n |

  13. | reference | 7.19.4 | 0..1 |

  14. | status | 7.19.2 | 0..1 |

  15. | uses | 7.12 | 0..n |

  16. | when | 7.19.5 | 0..1 |

  17. +--------------+---------+-------------+

status這個宣告貌似還沒見過呢。

7.15.2 XML對映規則

所有“augment”宣告中定義的data nodes都會編碼成“augment”被指定的那個module對應的XML namespace的XML elements。

當一個node被augmented的時候,augmenting child nodes會被編碼為augmented node的subelements,順序任意。

7.15.3 使用用例

在namespace “http://example.com/schema/interfaces”中,我們有:

 
  1. container interfaces {

  2. list ifEntry {

  3. key "ifIndex";

  4.  
  5. leaf ifIndex {

  6. type uint32;

  7. }

  8. leaf ifDescr {

  9. type string;

  10. }

  11. leaf ifType {

  12. type iana:IfType;

  13. }

  14. leaf ifMtu {

  15. type int32;

  16. }

  17. }

  18. }

這裡的ifType的型別為 “iana:IfType”。

然後,在namespace “http://example.com/schema/ds0”中,我們有:

 
  1. import interface-module {

  2. prefix "if";

  3. }

  4. augment "/if:interfaces/if:ifEntry" {

  5. when "if:ifType='ds0'";

  6. leaf ds0ChannelNumber {

  7. type ChannelNumber;

  8. }

  9. }

對應的XML例項是:

 
  1. <interfaces xmlns="http://example.com/schema/interfaces"

  2. xmlns:ds0="http://example.com/schema/ds0">

  3. <ifEntry>

  4. <ifIndex>1</ifIndex>

  5. <ifDescr>Flintstone Inc Ethernet A562</ifDescr>

  6. <ifType>ethernetCsmacd</ifType>

  7. <ifMtu>1500</ifMtu>

  8. </ifEntry>

  9. <ifEntry>

  10. <ifIndex>2</ifIndex>

  11. <ifDescr>Flintstone Inc DS0</ifDescr>

  12. <ifType>ds0</ifType>

  13. <!-- 型別為ds0的時候,增加了ds0ChannelNumber -->

  14. <ds0:ds0ChannelNumber>1</ds0:ds0ChannelNumber>

  15. </ifEntry>

  16. </interfaces>

另外一個例子中,我們假設有一個在Section 7.9.7中定義的choice。下面的結構能被用來擴充套件其中的protocol的定義:

 
  1. augment /ex:system/ex:protocol/ex:name {

  2. case c {

  3. leaf smtp {

  4. type empty;

  5. }

  6. }

  7. }

對應的XML例項為:

 
  1. <ex:system>

  2. <ex:protocol>

  3. <ex:tcp/>

  4. </ex:protocol>

  5. </ex:system>

或者:

 
  1. <ex:system>

  2. <ex:protocol>

  3. <other:smtp/>

  4. </ex:protocol>

  5. </ex:system>

7.16 identity宣告

“identity”宣告被用來定義一個新的,全域性唯一的,抽象的,沒有特定型別的identity。它的唯一目的就是對外宣示它的名字,語義以及存在。一個identity既能夠從頭開始定義,也能夠從一個base identity處繼承。identity的引數是一個identifier,就是這個identity的名字。後面跟著描述更具體資訊的一塊substatements。

內建的資料型別“identityref”(見Section 9.10)能夠在一個data model內部被用來引用identities。

7.16.1 identity的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | base | 7.16.2 | 0..1 |

  5. | description | 7.19.3 | 0..1 |

  6. | reference | 7.19.4 | 0..1 |

  7. | status | 7.19.2 | 0..1 |

  8. +--------------+---------+-------------+

7.16.2 base宣告

“base”宣告是可選的,其引數是一個已存在的identity的名字,本次定義的identity就是從它那裡繼承來的。如果“base”宣告沒有出現,則這個identity的定義就是從零開始的。

如果在base的名字中有字首,該字首會指向定義這個identity的module,或者,如果該字首正好是local module的字首,則就指向本module。否則,MUST 指向當前的module或者一個被包含的submodule。

local module 和 current module是有區別的,我日啊,之前一直以為是同樣的東西。local表示本地,本地不一定只有current這一個module啊,也可以有其它module。

由於submodules不能包含其父module,所以任何在module中定義的identities,如果需要被submodules引用,則 MUST 定義到某個submodule中去。submodules能夠接著引用這個submodule去獲取這個identity的定義。

一個identity MUST NOT 引用自己,無論是直接的還是通過其它的identities形成的引用鏈進行的間接引用。

7.1。3 使用用例

 
  1. module crypto-base {

  2. namespace "http://example.com/crypto-base";

  3. prefix "crypto";

  4.  
  5. identity crypto-alg {

  6. description

  7. "Base identity from which all crypto algorithms

  8. are derived.";

  9. }

  10. }

  11.  
  12. module des {

  13. namespace "http://example.com/des";

  14. prefix "des";

  15.  
  16. import "crypto-base" {

  17. prefix "crypto";

  18. }

  19.  
  20. identity des {

  21. base "crypto:crypto-alg";

  22. description "DES crypto algorithm";

  23. }

  24.  
  25. identity des3 {

  26. base "crypto:crypto-alg";

  27. description "Triple DES crypto algorithm";

  28. }

  29. }

按照上面的描述來說,identity在schema tree中存在,在data tree中不存在了?

7.17 extension宣告

“extension”宣告允許在YANG語言中定義新的宣告。這個新的宣告的定義可以被其它modules匯入和使用。

該宣告的引數是一個identifier,表示擴充套件的新keyword,後面必須跟一塊描述詳細擴充套件資訊的substatements。“extension”宣告的目標就是定義一個keyword,這樣它才能被其它modules匯入和使用。

extension能像普通的YANG宣告一樣被使用,宣告後面跟一個引數,後面還有可選的一塊substatements。新宣告的名字是該extension所在的module的字首,跟上冒號(“:”),再跟上keyword,中間沒有空白。extension的substatements是由extension定義的,使用了本標準以外的某些機制。在語法構成上,substatements MUST 是YANG宣告,或者也是用“extension”宣告定義的新宣告。在extensions中使用的YANG宣告 MUST 遵循Section 12中定義的語法上的規則。

7.17.1 extension的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | argument | 7.17.2 | 0..1 |

  5. | description | 7.19.3 | 0..1 |

  6. | reference | 7.19.4 | 0..1 |

  7. | status | 7.19.2 | 0..1 |

  8. +--------------+---------+-------------+

7.17.2 argument宣告

“argument”宣告,是可選的,是一個字串,表示keyword的引數的名字。如果沒有argument宣告,則keyword在被使用的時候沒有引數。

argument的name在YIN mapping中被使用,在那裡作為XML attribute或者element name,具體要取決於argument的“yin-element”宣告。

7.17.2.1 argument的substatements

 
  1. +--------------+----------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+----------+-------------+

  4. | yin-element | 7.17.2.2 | 0..1 |

  5. +--------------+----------+-------------+

7.17.2.2 yin-element宣告

“yin-element”宣告,是可選的,其引數為“true”或者“false”的字串。這個宣告說明了是否將argument對映到YIN中的一個XML element,或者一個XML attribute(見Section 11)。

如果該宣告沒有出現,預設值是“false”。

7.17.3 使用用例

首先,定義一個extension:

 
  1. module my-extensions {

  2. ...

  3.  
  4. extension c-define {

  5. description

  6. "Takes as argument a name string.

  7. Makes the code generator use the given name in the

  8. #define.";

  9. argument "name";

  10. }

  11. }

接著,使用這個extension:

 
  1. module my-interfaces {

  2. ...

  3. import my-extensions {

  4. prefix "myext";

  5. }

  6. ...

  7.  
  8. container interfaces {

  9. ...

  10. myext:c-define "MY_INTERFACES";

  11. }

  12. }

7.18 conformance-related宣告

這個小姐定義了和一致性(conformance)相關的宣告,如Section 5.6中描述的一樣。

7.18.1 feature宣告

The “feature” statement is used to define a mechanism by which 
portions of the schema are marked as conditional. A feature name is 
defined that can later be referenced using the “if-feature” statement 
(see Section 7.18.2). Schema nodes tagged with a feature are ignored 
by the device unless the device supports the given feature. This 
allows portions of the YANG module to be conditional based on 
conditions on the device. The model can represent the abilities of 
the device within the model, giving a richer model that allows for 
differing device abilities and roles.

The argument to the “feature” statement is the name of the new 
feature, and follows the rules for identifiers in Section 6.2. This 
name is used by the “if-feature” statement to tie the schema nodes to 
the feature.

In this example, a feature called “local-storage” represents the 
ability for a device to store syslog messages on local storage of 
some sort. This feature is used to make the “local-storage-limit” 
leaf conditional on the presence of some sort of local storage. If 
the device does not report that it supports this feature, the 
“local-storage-limit” node is not supported.

 
  1. module syslog {

  2. ...

  3. feature local-storage {

  4. description

  5. "This feature means the device supports local

  6. storage (memory, flash or disk) that can be used to

  7. store syslog messages.";

  8. }

  9.  
  10. container syslog {

  11. leaf local-storage-limit {

  12. if-feature local-storage;

  13. type uint64;

  14. units "kilobyte";

  15. config false;

  16. description

  17. "The amount of local storage that can be

  18. used to hold syslog messages.";

  19. }

  20. }

  21. }

The “if-feature” statement can be used in many places within the YANG 
syntax. Definitions tagged with “if-feature” are ignored when the 
device does not support that feature.

A feature MUST NOT reference itself, neither directly nor indirectly 
through a chain of other features.

In order for a device to implement a feature that is dependent on any 
other features (i.e., the feature has one or more “if-feature” sub- 
statements), the device MUST also implement all the dependant 
features.

7.18.1.1 feature的substatements

 
  1. +--------------+---------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+---------+-------------+

  4. | description | 7.19.3 | 0..1 |

  5. | if-feature | 7.18.2 | 0..n |

  6. | status | 7.19.2 | 0..1 |

  7. | reference | 7.19.4 | 0..1 |

  8. +--------------+---------+-------------+

7.18.2 if-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. If a prefix is present on the feature name, it 
refers to a feature defined in the module that was imported with that 
prefix, or the local module if the prefix matches the local module’s 
prefix. Otherwise, a feature with the matching name MUST be defined 
in the current module or an included submodule.

Since submodules cannot include the parent module, any features in 
the module that need to be exposed to submodules MUST be defined in a 
submodule. Submodules can then include this submodule to find the 
definition of the feature.

7.18.3 deviation宣告

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. The 
contents of the “deviation” statement give details about the 
deviation.

The argument string is an absolute schema node identifier (see 
Section 6.5).

Deviations define the way a device or class of devices deviate from a 
standard. This means that deviations MUST never be part of a 
published standard, since they are the mechanism for learning how 
implementations vary from the standards.

Device deviations are strongly discouraged and MUST only be used as a 
last resort. Telling the application how a device fails to follow a 
standard is no substitute for implementing the standard correctly. A 
device that deviates from a module is not fully compliant with the 
module.

However, in some cases, a particular device may not have the hardware 
or software ability to support parts of a standard module. When this 
occurs, the device makes a choice either to treat attempts to 
configure unsupported parts of the module as an error that is 
reported back to the unsuspecting application or ignore those 
incoming requests. Neither choice is acceptable.

Instead, YANG allows devices to document portions of a base module 
that are not supported or supported but with different syntax, by 
using the “deviation” statement.

7.18.3.1 deviation的substatements

 
  1. +--------------+----------+-------------+

  2. | substatement | section | cardinality |

  3. +--------------+----------+-------------+

  4. | description | 7.19.3 | 0..1 |

  5. | deviate | 7.18.3.2 | 1..n |

  6. | reference | 7.19.4 | 0..1 |

  7. +--------------+----------+-------------+

7.18.3.2 divate宣告

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.

The argument “add” adds properties to the target node. The 
properties to add are identified by substatements to the “deviate” 
statement. If a property can only appear once, the property MUST NOT 
exist in the target node.

The argument “replace” replaces properties of the target node. The 
properties to replace are identified by substatements to the 
“deviate” statement. The properties to replace MUST exist in the 
target node.

The argument “delete” deletes properties from the target node. The 
properties to delete are identified by substatements to the “delete” 
statement. The substatement’s keyword MUST match a corresponding 
keyword in the target node, and the argument’s string MUST be equal 
to the corresponding keyword’s argument string in the target node.

 
  1. The deviates's Substatements

  2.  
  3. +--------------+---------+-------------+

  4. | substatement | section | cardinality |

  5. +--------------+---------+-------------+

  6. | config | 7.19.1 | 0..1 |

  7. | default | 7.6.4 | 0..1 |

  8. | mandatory | 7.6.5 | 0..1 |

  9. | max-elements | 7.7.4 | 0..1 |

  10. | min-elements | 7.7.3 | 0..1 |

  11. | must | 7.5.3 | 0..n |

  12. | type | 7.4 | 0..1 |

  13. | unique | 7.8.3 | 0..n |

  14. | units | 7.3.3 | 0..1 |

  15. +--------------+---------+-------------+

7.18.3.3 使用用例

In this example, the device is informing client applications that it 
does not support the “daytime” service in the style of RFC 867.

 
  1. deviation /base:system/base:daytime {

  2. deviate not-supported;

  3. }

The following example sets a device-specific default value to a leaf 
that does not have a default value defined:

 
  1. deviation /base:system/base:user/base:type {

  2. deviate add {

  3. default "admin"; // new users are 'admin' by default

  4. }

  5. }

In this example, the device limits the number of name servers to 3:

 
  1. deviation /base:system/base:name-server {

  2. deviate replace {

  3. max-elements 3;

  4. }

  5. }

If the original definition is:

 
  1. container system {

  2. must "daytime or time";

  3. ...

  4. }

a device might remove this must constraint by doing:

 
  1. deviation "/base:system" {

  2. deviate delete {

  3. must "daytime or time";

  4. }

  5. }

7.19 通用的宣告

本小節定義了一些對其他宣告來說都可以用的substatements。

7.19.1 config宣告

“config”宣告有一個引數,取值為“true”或者“false”。如果值為“true”,則表示本定義表示的是configuration。定義configuration的data nodes會是 request的回應的一部分,能夠放在或者 request中傳送出去。

如果值為“false”,則表示本定義表示的是state data。定義state data的data nodes會是對 request的回應的一部分,單不會回應 request,並且不能放到或者 request中。

如果沒有指定“config”,則預設值和其parent schema node的“config”的值一樣。如果parent node是一個“case” node,則這個值就和“case”node的parent “choice” noce相同。

如果top node沒有指定“config”宣告,則預設值為“true”。

如果一個node的“config”設定為“false”,則該節點的所有子節點都不能將“config”設定為“true”。

7.19.2 status宣告

“status”宣告的引數是一個字串,是“current”,“deprecated”或者“obsolete”中的一個。

  • “current”意味著該定義在當前是有效的。
  • “deprecated”表示該定義已經被廢棄,不過保證在暫時在後續的實現中支援該定義,以保證向前相容。
  • “obsolete”意味著這個定義已經被廢棄,並且 SHOULD NOT 被實現。

如果沒有指定status,則預設值為“current”。

如果一個定義是“current”,則它 MUST NOT 在同一個module中引用“deprecated”或“obsolete”定義。

如果一個定義是“deprecated”,則它 MUST NOT 在同一個module中引用“obsolete”定義。

比如說,下面的例子就是非法的:

 
  1. typedef my-type {

  2. status deprecated;

  3. type int32;

  4. }

  5.  
  6. leaf my-leaf {

  7. status current;

  8. type my-type; // illegal, since my-type is deprecated

  9. }

7.19.3 description宣告

The “description” statement takes as an argument a string that 
contains a human-readable textual description of this definition. 
The text is provided in a language (or languages) chosen by the 
module developer; for the sake of interoperability, it is RECOMMENDED 
to choose a language that is widely understood among the community of 
network administrators who will use the module.

7.19.4 reference宣告

“reference”宣告有一個引數,是字串,該引數被用來指定一個到外部文件的交叉引用,既可以是定義了相關管理資訊的另一個module,也可以是能對本定義提供相關額外資訊的一個文件。

比如,定義了名為“uri” 的一個typedef,可以這麼寫:

 
  1. typedef uri {

  2. type string;

  3. reference

  4. "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax";

  5. ...

  6. }

7.19.5 when宣告

“when”宣告可以使它的parent data 定義宣告變成有條件的。由其parent data定義宣告所定義的node僅當該“when”宣告提供的要求(condition)得到滿足時才有可能是有效的。該宣告的引數是一個XPath表示式(見Section 6.4),該表示式被用來精確描述這個條件(condition)。如果XPath表示式針對特定的例項被評估為“true”的話,則該parent data定義宣告所定義的node就是有效的,反之亦然。

更多資訊可見Section 8.3.2。

The XPath expression is conceptually evaluated in the following 
context, in addition to the definition in Section 6.4.1:

o If the “when” statement is a child of an “augment” statement, then 
the context node is the augment’s target node in the data tree, if 
the target node is a data node. Otherwise, the context node is 
the closest ancestor node to the target node that is also a data 
node.

o If the “when” statement is a child of a “uses”, “choice”, or 
“case” statement, then the context node is the closest ancestor 
node to the “uses”, “choice”, or “case” node that is also a data 
node.

o If the “when” statement is a child of any other data definition 
statement, the context node is the data definition’s node in the 
data tree.

o The accessible tree is made up of all nodes in the data tree, and 
all leafs with default values in use (see Section 7.6.1).

The accessible tree depends on the context node:

o If the context node represents configuration, the tree is the data 
in the NETCONF datastore where the context node exists. The XPath 
root node has all top-level configuration data nodes in all 
modules as children.

o If the context node represents state data, the tree is all state 
data on the device, and the datastore. The XPath root 
node has all top-level data nodes in all modules as children.

o If the context node represents notification content, the tree is 
the notification XML instance document. The XPath root node has 
the element representing the notification being defined as the 
only child.

o If the context node represents RPC input parameters, the tree is 
the RPC XML instance document. The XPath root node has the 
element representing the RPC operation being defined as the only 
child.

o If the context node represents RPC output parameters, the tree is 
the RPC reply instance document. The XPath root node has the 
elements representing the RPC output parameters as children.

The result of the XPath expression is converted to a boolean value 
using the standard XPath rules.

Note that the XPath expression is conceptually evaluated. This means 
that an implementation does not have to use an XPath evaluator on the 
device. The “when” statement can very well be implemented with 
specially written code.

8 constraints

第八章僅僅給出目錄,具體內容感覺暫時不需要看。

8.1 constraints on data

8.2. Hierarchy of Constraints

8.3. Constraint Enforcement Model

8.3.1. Payload Parsing

8.3.2. NETCONF Processing

8.3.3. Validation

9 內建型別

這一章暫時沒有必要看。稍微對程式語言有點了解,就能把這裡的內建型別理解個差不多。遇到問題的時候再回頭翻原文吧。

10 更新module

這一章內容比較少,不過又不是自己寫module,所以暫時也沒必要看。

11 YIN

好像完全沒有見過YIN的應用。

一個YANG module能被轉換為一種可選的基於XML語法的格式,稱為YIN。被轉換的module稱為YIN module。本小節描述了這YANG和YIN這兩種格式之間的對映關係。

YANG和YIN格式使用不同的符號包含了同樣的資訊。YIN的符號使得開發者能夠在XML中表示YANG的data models,因此能夠使用基於XML的工具對資料做過濾,驗證,程式碼和文件的自動生成以及其它的工作。想XSLT或XML 驗證器這樣的工具就能用到了。

YANG和YIN之間的對映不會改變model本身的內容。comments和whitespace不會被保留。

11.1 正規的YIN定義

在YANG的keywords和YIN的elements之間有一對一的雙射。一個YIN element的local name等同於對應的yANG的keyword。這意味著,YIN文件中的文件元素(root)總是和YANG中的或對應。

對應到YANG keywords的YIN elements的namespace是“urn:ietf:params:xml:ns:yang:yin:1”。

對應到YANG的extension keywords的YIN elements屬於extension關鍵詞通過“extension”宣告宣告的YANG module的namespace。

所有的YIN elements的名字 MUST 上述指定的namespaces相匹配,也就是要使用標準的[XML-NAMES]機制,比如:“xmlns”以及“xmlns:xxx”屬性。

YANG宣告的引數在YIN中是作為XML attribute或者keyword element的subelement而存在。Table 1定義了YANG keywords到YIN的對映關係。對於extensions來說,引數對映是在“extension”宣告中指定的(見Section 7.17)。對於引數,有下面的規則:

  • 如果引數被對映為一個attribute,則該attribute沒有namespace。
  • 如果引數被對映為一個element,則其namespace和其parent keyword element一樣。
  • 如果引數被對映為一個element,則它 MUST 是keyword element的第一個子節點。

YANG宣告的substatements會被對映為該宣告對應的keyword element的children,substatements之間的相對順序 MUST和YANG中定義的順序完全一致。

YANG中的comments MAY 對映為XML的comments。

 
  1. Mapping of arguments of the YANG statements.

  2.  
  3. +------------------+---------------+-------------+

  4. | keyword | argument name | yin-element |

  5. +------------------+---------------+-------------+

  6. | anyxml | name | false |

  7. | argument | name | false |

  8. | augment | target-node | false |

  9. | base | name | false |

  10. | belongs-to | module | false |

  11. | bit | name | false |

  12. | case | name | false |

  13. | choice | name | false |

  14. | config | value | false |

  15. | contact | text | true |

  16. | container | name | false |

  17. | default | value | false |

  18. | description | text | true |

  19. | deviate | value | false |

  20. | deviation | target-node | false |

  21. | enum | name | false |

  22. | error-app-tag | value | false |

  23. | error-message | value | true |

  24. | extension | name | false |

  25. | feature | name | false |

  26. | fraction-digits | value | false |

  27. | grouping | name | false |

  28. | identity | name | false |

  29. | if-feature | name | false |

  30. | import | module | false |

  31. | include | module | false |

  32. | input | <no argument> | n/a |

  33. | key | value | false |

  34. | leaf | name | false |

  35. | leaf-list | name | false |

  36. | length | value | false |

  37. | list | name | false |

  38. | mandatory | value | false |

  39. | max-elements | value | false |

  40. | min-elements | value | false |

  41. | module | name | false |

  42. | must | condition | false |

  43. | namespace | uri | false |

  44. | notification | name | false |

  45. | ordered-by | value | false |

  46. | organization | text | true |

  47. | output | <no argument> | n/a |

  48. | path | value | false |

  49. | pattern | value | false |

  50. | position | value | false |

  51. | prefix | value | false |

  52. | presence | value | false |

  53. | range | value | false |

  54. | reference | text | true |

  55. | refine | target-node | false |

  56. | require-instance | value | false |

  57. | revision | date | false |

  58. | revision-date | date | false |

  59. | rpc | name | false |

  60. | status | value | false |

  61. | submodule | name | false |

  62. | type | name | false |

  63. | typedef | name | false |

  64. | unique | tag | false |

  65. | units | name | false |

  66. | uses | name | false |

  67. | value | value | false |

  68. | when | condition | false |

  69. | yang-version | value | false |

  70. | yin-element | value | false |

  71. +------------------+---------------+-------------+

  72.  
  73. Table 1

11.1.1 使用用例

下面的YANG module:

 
  1. module acme-foo {

  2. namespace "http://acme.example.com/foo";

  3. prefix "acfoo";

  4.  
  5. import my-extensions {

  6. prefix "myext";

  7. }

  8.  
  9. list interface {

  10. key "name";

  11. leaf name {

  12. type string;

  13. }

  14.  
  15. leaf mtu {

  16. type uint32;

  17. description "The MTU of the interface.";

  18. myext:c-define "MY_MTU";

  19. }

  20. }

  21. }

其中的“c-define”定義在Section 7.7.3,將上述module轉化為下面的YIN:

 
  1. <module name="acme-foo"

  2. xmlns="urn:ietf:params:xml:ns:yang:yin:1"

  3. xmlns:acfoo="http://acme.example.com/foo"

  4. xmlns:myext="http://example.com/my-extensions">

  5.  
  6. <namespace uri="http://acme.example.com/foo"/>

  7. <prefix value="acfoo"/>

  8.  
  9. <import module="my-extensions">

  10. <prefix value="myext"/>

  11. </import>

  12.  
  13. <list name="interface">

  14. <key value="name"/>

  15. <leaf name="name">

  16. <type name="string"/>

  17. </leaf>

  18. <leaf name="mtu">

  19. <type name="uint32"/>

  20. <description>

  21. <text>The MTU of the interface.</text>

  22. </description>

  23. <myext:c-define name="MY_MTU"/>

  24. </leaf>

  25. </list>

  26. </module>

12 YANG ABNF Grammar

ABNF, Augmented Backus-Naur Form

這一章看不懂,後面就不粘了。

在YANG中,幾乎所有的statements都是無序的。ABNF grammar 【RFC5234】 為這些宣告定義了標準的順序。為了提高module的可讀性, RECOMMENDED 有序。

13 YANG相關錯誤的Error Responses

這一章對於我們實現來說,並不關心,所以跳過。

14 IANA Considerations

這一章同樣沒什麼用。

This document defines a registry for YANG module and submodule names. 
The name of the registry is “YANG Module Names”.

The registry shall record for each entry:

o the name of the module or submodule

o for modules, the assigned XML namespace

o for modules, the prefix of the module

o for submodules, the name of the module it belongs to

o a reference to the (sub)module’s documentation (e.g., the RFC 
number)

There are no initial assignments.

For allocation, RFC publication is required as per RFC 5226 
[RFC5226]. All registered YANG module names MUST comply with the 
rules for identifiers stated in Section 6.2, and MUST have a module 
name prefix.

The module name prefix ‘ietf-’ is reserved for IETF stream documents 
[RFC4844], while the module name prefix ‘irtf-’ is reserved for IRTF 
stream documents. Modules published in other RFC streams MUST have a 
similar suitable prefix.

All module and submodule names in the registry MUST be unique.

All XML namespaces in the registry MUST be unique.

This document registers two URIs for the YANG and YIN XML namespaces 
in the IETF XML registry [RFC3688]. Following the format in RFC 
3688, the following have been registered.

 
  1. URI: urn:ietf:params:xml:ns:yang:yin:1

  2.  
  3. URI: urn:ietf:params:xml:ns:yang:1

  4.  
  5. Registrant Contact: The IESG.

  6.  
  7. XML: N/A, the requested URIs are XML namespaces.

This document registers two new media types as defined in the 
following sections.

14.1 Media type application/yang

MIME media type name: application

MIME subtype name: yang

Mandatory parameters: none

Optional parameters: none

Encoding considerations: 8-bit

Security considerations: See Section 15 in RFC 6020

Interoperability considerations: None

Published specification: RFC 6020

Applications that use this media type:

 
  1. YANG module validators, web servers used for downloading YANG

  2. modules, email clients, etc.

Additional information:

 
  1. Magic Number: None

  2.  
  3. File Extension: .yang

  4.  
  5. Macintosh file type code: 'TEXT'

Personal and email address for further information: 
Martin Bjorklund mbj@tail-f.com

Intended usage: COMMON

Author: 
This specification is a work item of the IETF NETMOD working group, 
with mailing list address netmod@ietf.org
Change controller: 
The IESG iesg@ietf.org

14.2 Media type application/yin+xml

MIME media type name: application

MIME subtype name: yin+xml

Mandatory parameters: none

Optional parameters:

 
  1. "charset": This parameter has identical semantics to the charset

  2. parameter of the "application/xml" media type as specified in

  3. [RFC3023].

Encoding considerations:

 
  1. Identical to those of "application/xml" as

  2. described in [RFC3023], Section 3.2.

Security considerations: See Section 15 in RFC 6020

Interoperability considerations: None

Published specification: RFC 6020

Applications that use this media type:

 
  1. YANG module validators, web servers used for downloading YANG

  2. modules, email clients, etc.

Additional information:

 
  1. Magic Number: As specified for "application/xml" in [RFC3023],

  2. Section 3.2.

  3.  
  4. File Extension: .yin

  5.  
  6. Macintosh file type code: 'TEXT'

Personal and email address for further information: 
Martin Bjorklund mbj@tail-f.com

Intended usage: COMMON

Author: 
This specification is a work item of the IETF NETMOD working group, 
with mailing list address netmod@ietf.org.

Change controller: 
The IESG iesg@ietf.org

15 Security Considerations

This document defines a language with which to write and read 
descriptions of management information. The language itself has no 
security impact on the Internet.

The same considerations are relevant as for the base NETCONF protocol 
(see [RFC4741], Section 9).

Data modeled in YANG might contain sensitive information. RPCs or 
notifications defined in YANG might transfer sensitive information.

Security issues are related to the usage of data modeled in YANG. 
Such issues shall be dealt with in documents describing the data 
models and documents about the interfaces used to manipulate the data 
e.g., the NETCONF documents.

Data modeled in YANG is dependent upon:

o the security of the transmission infrastructure used to send 
sensitive information.

o the security of applications that store or release such sensitive 
information.

o adequate authentication and access control mechanisms to restrict 
the usage of sensitive data.

YANG parsers need to be robust with respect to malformed documents. 
Reading malformed documents from unknown or untrusted sources could 
result in an attacker gaining privileges of the user running the YANG 
parser. In an extreme situation, the entire machine could be 
compromised.

16 貢獻者

The following people all contributed significantly to the initial 
YANG document:

 
  1. - Andy Bierman (Brocade)

  2. - Balazs Lengyel (Ericsson)

  3. - David Partain (Ericsson)

  4. - Juergen Schoenwaelder (Jacobs University Bremen)

  5. - Phil Shafer (Juniper Networks)

17 Acknowledgements

The editor wishes to thank the following individuals, who all 
provided helpful comments on various versions of this document: 
Mehmet Ersue, Washam Fan, Joel Halpern, Leif Johansson, Ladislav 
Lhotka, Gerhard Muenz, Tom Petch, Randy Presuhn, David Reid, and Bert 
Wijnen.

18 引用

18.1 對標準的引用

 
  1. [ISO.10646] International Organization for Standardization,

  2. "Information Technology - Universal Multiple-Octet Coded

  3. Character Set (UCS)", ISO Standard 10646:2003, 2003.

  4.  
  5. [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate

  6. Requirement Levels", BCP 14, RFC 2119, March 1997.

  7.  
  8. [RFC3023] Murata, M., St. Laurent, S., and D. Kohn, "XML Media

  9. Types", RFC 3023, January 2001.

  10.  
  11. [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO

  12. 10646", STD 63, RFC 3629, November 2003.

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

  15. January 2004.

  16.  
  17. [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform

  18. Resource Identifier (URI): Generic Syntax", STD 66,

  19. RFC 3986, January 2005.

  20.  
  21. [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data

  22. Encodings", RFC 4648, October 2006.

  23.  
  24. [RFC4741] Enns, R., "NETCONF Configuration Protocol", RFC 4741,

  25. December 2006.

  26.  
  27. [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an

  28. IANA Considerations Section in RFCs", BCP 26, RFC 5226,

  29. May 2008.

  30.  
  31. [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax

  32. Specifications: ABNF", STD 68, RFC 5234, January 2008.

  33.  
  34. [RFC5277] Chisholm, S. and H. Trevino, "NETCONF Event

  35. Notifications", RFC 5277, July 2008.

  36.  
  37. [XML-NAMES] Hollander, D., Tobin, R., Thompson, H., Bray, T., and A.

  38. Layman, "Namespaces in XML 1.0 (Third Edition)", World

  39. Wide Web Consortium Recommendation REC-xml-names-

  40. 20091208, December 2009,

  41. <http://www.w3.org/TR/2009/REC-xml-names-20091208>.

  42.  
  43. [XPATH] Clark, J. and S. DeRose, "XML Path Language (XPath)

  44. Version 1.0", World Wide Web Consortium

  45. Recommendation REC-xpath-19991116, November 1999,

  46. <http://www.w3.org/TR/1999/REC-xpath-19991116>.

  47.  
  48. [XSD-TYPES] Malhotra, A. and P. Biron, "XML Schema Part 2: Datatypes

  49. Second Edition", World Wide Web Consortium

  50. Recommendation REC-xmlschema-2-20041028, October 2004,

  51. <http://www.w3.org/TR/2004/REC-xmlschema-2-20041028>.

  52.  

18.2 對informative文稿的引用

 
  1. [RFC2578] McCloghrie, K., Ed., Perkins, D., Ed., and J.

  2. Schoenwaelder, Ed., "Structure of Management Information

  3. Version 2 (SMIv2)", STD 58, RFC 2578, April 1999.

  4.  
  5. [RFC2579] McCloghrie, K., Ed., Perkins, D., Ed., and J.

  6. Schoenwaelder, Ed., "Textual Conventions for SMIv2",

  7. STD 58, RFC 2579, April 1999.

  8.  
  9. [RFC3780] Strauss, F. and J. Schoenwaelder, "SMIng - Next

  10. Generation Structure of Management Information",

  11. RFC 3780, May 2004.

  12.  
  13. [RFC4844] Daigle, L. and Internet Architecture Board, "The RFC

  14. Series and RFC Editor", RFC 4844, July 2007.

  15.  
  16. [XPATH2.0] Berglund, A., Boag, S., Chamberlin, D., Fernandez, M.,

  17. Kay, M., Robie, J., and J. Simeon, "XML Path Language

  18. (XPath) 2.0", World Wide Web Consortium

  19. Recommendation REC-xpath20-20070123, January 2007,

  20. <http://www.w3.org/TR/2007/REC-xpath20-20070123>.

  21. [XSLT] Clark, J., "XSL Transformations (XSLT) Version 1.0",

  22. World Wide Web Consortium Recommendation REC-xslt-

  23. 19991116, November 1999,

  24. <http://www.w3.org/TR/1999/REC-xslt-19991116>.

作者聯絡地址

Martin Bjorklund (editor) 
Tail-f Systems

EMail: mbj@tail-f.com

相關文章