早在2003年,IETF成立了一个NETCONF工作组,提出一种基于XML的网络配置管理协议,也就是NETCONF(Network Configuration Protocol),因为该协议的配置功能非常强大,同时兼顾监控和故障管理,安全验证和访问控制,所以得到业界的一致认可,所以广泛采用netconfig来配置网络。NETCONF协议分为传输层、RPC层、操作层和内容层。其中,内容层是唯一没有标准化的层,于是一种新的建模语言yang产生了,它的目标是对NETCONF数据模型、操作进行建模,覆盖NETCONF协议的操作层和内容层。
数据节点
module
module是yang的基本单元,是写yang文件的基本框架,包括以下几种类型语句:
- head语句(yang-version/namespace/prefix)
- 连接语句(import/include)
- 元信息(organization/contract)
- revision语句
- 定义语句(container/leaf/leaf-list/grouping等等)
yang 模块有如下的布局:
module <module-name> {//==== header information ====yang-version statementnamespace statementprefix statement//==== linkage statements ====import statementsinclude statements//==== meta information ====organization statementcontact statementdescription statementreference statement//==== revision history ====revision statements//==== module definitions ====other statements}
对YANG module的解读:
- module的名字是acme-system
- namespace是用来唯一标识这个YANG模型与其它YANG模型不同
- prefix是namespace的一种简写
- organization/contact/description都是用来描述相关信息
- revison描述版本信息,可以有多个revision(一般记录版本更新的内容)
- module中包含一个container system
- container system包含一个leaf(host-name),一个leaf-list(domain-search)和一个container login
- container login包含一个leaf(message),和一个list(user)
Leaf
leaf定义的节点只有一个值,是一个叶子节点,只能有一个实例。
YANG :
leaf host-name {type string;description "Hostname for this system";}
NETCONF XML :
<host-name>my.example.com</host-name>
Leaf-List
leaf-list定义一组相同类型的叶节节点,类似于数组,与leaf区别在于leaf只有一个实例,而leaf-list可以有多个实例,其元素的值type必须保持一致,而且不能重复。
YANG :
leaf-list domain-search {type string;description "List of domain names to search";}
NETCONF XML :
<domain-search>a.example.com</domain-search><domain-search>b.example.com</domain-search><domain-search>c.example.com</domain-search>
list
list描述了一组节点的集合,它像一张数据库表一样,表的每一行用key来标识其主键,有多个实例。
YANG :
list user {key "name";leaf name {type string;}leaf sex {type string;}leaf class {type uint8;}}
NETCONF XML :
<user><name>zhang</name><sex>male</sex><class>1</class></user><user><name>wang</name><sex>male</sex><class>2</class></user><user><name>zhou</name><sex>famale</sex><class>2</class></user>
grouping
grouping定义一个可以重复使用的节点集合,使用时通过use语句,并可通过refine语句进行改进。
container
container主要定义一个schema树的内部节点,它本身没有任何值和意义,只是作为一系列子节点的父亲存在,只有一个实例。
YANG :
container system {leaf host-name {type string;description "Hostname for this system";}leaf-list domain-search {type string;description "List of domain names to search";}container login {leaf message {type string;description"Message given at start of login session";}list user {key "name";leaf name {type string;}leaf full-name {type string;}leaf class {type string;}}}}
NETCONF XML :
<system><host-name>myyang.com</host-name><domain-search>high.example.com</domain-search><domain-search>low.example.com</domain-search><domain-search>everywhere.example.com</domain-search><login><message>Good Morning</message><user><name>glocks</name><full-name>Goldie Locks</full-name><class>intruder</class></user><user><name>snowey</name><full-name>Snow White</full-name><class>free-loader</class></user><user><name>rzell</name><full-name>Rapun Zell</full-name><class>tower</class></user></login></system>
choice
choice节点定义了一个可供选择项的集合,每一个选择项都会在某种情况下存在。一个choice由许多分枝,通过case子语句定义。YANG能够使用“choice”和“case”声明分离互不相容,不能同时出现的节点。“choice”声明包含了多个“case”声明,定义了不能同时出现的schema nodes的集合。每个“case”声明都可能包含多个节点,但是每个节点都应该只在一个“case”中出现。当一个case元素被创建,其他所有cases的元素都会被隐式删除。设备要强制执行这个约束,以防止出现配置的不协调。
YANG :
list pet{choice animal {case cat {leaf name {type empty;}}case dog {leaf color {type empty;}}}}
NETCONF XML :
<pet><cat/></pet><pet><cat/></pet><pet><dog/></pet>
enum
typedef <type-name> {type enumeration {enum "Single" {value 0;description "Single Device.";}enum "Group" {value 1;description "Device Group.";}}}
anyxml
anyxml表示任何未知的数据定义。
augment
yang提供augment语句,扩大一个模块层次,将节点添加到一个已存在的模块或子模块当中。目标结点可以是一个container, list, choice, case, rpc, input, output, notification等。augment可以是条件的,使用when语句,当特定条件满足时,新节点才会出现。
YANG :
//----------- in namespace http://example.com/schema/interfaces ----------------------------container interfaces {list ifEntry {key "ifIndex";leaf ifIndex {type uint32;}leaf ifDescr {type string;}leaf ifType {type iana:IfType;}leaf ifMtu {type int32;}}}//----------- in namespace http://example.com/schema/ds0 ----------------------------import interface-module {prefix "if";}augment "/if:interfaces/if:ifEntry" {when "if:ifType='ds0'";leaf ds0ChannelNumber {type uint32;}}
NETCONF XML :
<interfaces xmlns="http://example.com/schema/interfaces"xmlns:ds0="http://example.com/schema/ds0"><ifEntry><ifIndex>1</ifIndex><ifDescr>Flintstone Inc Ethernet A562</ifDescr><ifType>ethernetCsmacd</ifType><ifMtu>1500</ifMtu></ifEntry><ifEntry><ifIndex>2</ifIndex><ifDescr>Flintstone Inc DS0</ifDescr><ifType>ds0</ifType><ifMtu>1500</ifMtu><ds0:ds0ChannelNumber>1</ds0:ds0ChannelNumber></ifEntry></interfaces>
notification
notification语句用来定义Notification内容,内容数据的定义同yang数据定义一样。
rpc
rpc语句用来定义NETCONF协议的RPCs,input和output使用yang数据定义语句。
YANG :
rpc activate-software-image {input {leaf image-name {type string;}}output {leaf status {type string;}}}
NETCONF XML :
<rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><activate-software-image xmlns="http://acme.example.com/system"><image-name>acmefw-2.3</image-name></activate-software-image></rpc><rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><status xmlns="http://acme.example.com/system">The image acmefw-2.3 is being installed.</status></rpc-reply>
Notification
Notification是一种通告机制,当交换机上出现特性event(事件),交换机会主动发给已经建立netconf连接并订阅了Notification的client。YANG可以定义notification。
YANG :
notification link-failure {description "A link failure has been detected";leaf if-name {type leafref {path "/interface/name";}}leaf if-admin-status {type admin-status;}leaf if-oper-status {type oper-status;}}
NETCONF XML :
<notification xmlns="urn:ietf:params:netconf:capability:notification:1.0"><eventTime>2007-09-01T10:00:00Z</eventTime><link-failure xmlns="http://acme.example.com/system"><if-name>so-1/2/3.0</if-name><if-admin-status>up</if-admin-status><if-oper-status>down</if-oper-status></link-failure></notification>
这样无论是接口的admin状态(shutdown或是no shutdonw),还是链路状态(down/up)发送改变的时候,都可以发送notification给client,并且带上了当前的状态信息。
数据类型
| Name | Description |
|---|---|
| binary | Any binary data |
| bits | A set of bits or flags |
| boolean | “true” or “false” |
| decimal64 | 64-bit signed decimal number |
| empty | A leaf that does not have any value |
| enumeration | Enumerated strings |
| identityref | A reference to an abstract identity |
| instance-identifier | References a data tree node |
| int8 | 8-bit signed integer |
| int16 | 16-bit signed integer |
| int32 | 32-bit signed integer |
| int64 | 64-bit signed integer |
| leafref | A reference to a leaf instance |
| string | Human-readable string |
| uint8 | 8-bit unsigned integer |
| uint16 | 16-bit unsigned integer |
| uint32 | 32-bit unsigned integer |
| uint64 | 64-bit unsigned integer |
| union | Choice of member types |
