0%

libyang-doc

CESENT公司开源了一套以sysrepo为datastore的网络配置体系。主要有:libyang, sysrepo, libnetconf2, netopeer2,而且libyangsysrepo是我实现RESTCONF的主要依赖,所以这部分看得比较认真。

但是这篇东西基本上就是libyang的doc里面的概述部分。

libyang

Context - Schema - Data

  • difference between imported and implemented?

  • functions for schemas have lys_ prefix while functions for instance data have lyd_ prefix

YANG

  • A container node does not have a value, but it has a list of child nodes in the data tree.

Questions:

  • yang定义的rpc和实现过程中的rpc有什么关系?
    • A: rfc8040里面讲的意思好像是yang里面定义的”rpc”. “action”通过http POST去触发
1
2
3
4
5
6
7
8
9
10
11
12
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<activate-software-image xmlns="http://example.com/system">
<image-name>example-fw-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://example.com/system">
The image example-fw-2.3 is being installed.
</status>
</rpc-reply>
  • 头部的namespace是怎么写的,是多一点操作就要多加一条相关的吗?
  • 下面这条rpc, <config>里面的写法还不懂
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<rpc message-id="101"
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
xmlns:yang="urn:ietf:params:xml:ns:yang:1">
<edit-config>
<target>
<running/>
</target>
<config>
<system xmlns="urn:example:config"
xmlns:ex="urn:example:config">
<user nc:operation="create"
yang:insert="after"
yang:key="[ex:first-name=’fred’]
[ex:surname=’flintstone’]">
<first-name>barney</first-name>
<surname>rubble</surname>
<type>admin</type>
</user>
</system>
</config>
</edit-config>
</rpc>
  • 为什么ietf-restconf.yang里面只定义了group
1
2
3
4
5
The "ietf-restconf" module defines conceptual definitions within an
extension and two groupings, which are not meant to be implemented as
datastore contents by a server. For example, the "restconf"
container is not intended to be implemented as a top-level data node
(under the "/restconf/data" URI).

Context

ly_ctx_*

  • The context concept allows callers to work in environments with different sets of YANG schemas.

  • Context holds all modules and their submodules internally.

  • To get a specific module or submodule, use ly_ctx_get_module() and ly_ctx_get_submodule().

  • If you need to do something with all the modules or submodules in the context, it is advised to iterate over them using ly_ctx_get_module_iter(), it is the most efficient way.

  • Alternatively, the ly_ctx_info() function can be used to get complex information about the schemas in the context in the form of data tree defined by ietf-yang-library schema.

  • To get a specific node defined in a module in the context, ly_ctx_find_path() or ly_ctx_get_node() can be used.

Schemas

lys_features_*

lys_parse_*

Schema is an internal libyang’s representation of a YANG data model. Each schema is connected with its context and loaded using parser functions. It means, that the schema cannot be created (nor changed) programmatically. In libyang, schemas are used only to access data model definitions.

  • Basic YANG schemas format described in RFC 6020 and RFC 7951 (so both YANG 1.0 and YANG 1.1 versions are supported).

  • When the context is created, it already contains the following schemas, which are implemented internally by libyang:

    • ietf-yang-metadata@2016-08-05
    • yang@2017-02-20
    • ietf-inet-types@2013-07-15
    • ietf-yang-types@2013-07-15
    • ietf-yang-library@2016-06-21
  • The yang schema is the libyang’s internal module to provide namespace and definitions of for various YANG attributes described in RFC 7951 (such as insert attribute for edit-config’s data).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct lys_node {
const char *name; /**< node name (mandatory) */
const char *dsc; /**< description statement (optional) */
const char *ref; /**< reference statement (optional) */
uint16_t flags; /**< [schema node flags](@ref snodeflags) */
uint8_t ext_size; /**< number of elements in #ext array */
uint8_t iffeature_size; /**< number of elements in the #iffeature array */
uint8_t padding[4];
struct lys_ext_instance **ext; /**< array of pointers to the extension instances */
struct lys_iffeature *iffeature; /**< array of if-feature expressions */
struct lys_module *module; /**< pointer to the node's module (mandatory) */
LYS_NODE nodetype; /**< type of the node (mandatory) */
struct lys_node *parent; /**< pointer to the parent node, NULL in case of a top level node */
struct lys_node *child;
struct lys_node *next; /**< pointer to the next sibling node (NULL if there is no one) */
struct lys_node *prev;
void *priv; /**< private caller's data, not used by libyang */
};

Data Instances

All data nodes in data trees are connected with their schema node - libyang is not able to represent data of an unknown schema.

Parsing data

  • lyd_parse_*

Manipulating Data

Creating data is generally possible in two ways, they can be combined.

  • You can add nodes one-by-one based on the node name and/or its parent (lyd_new(), lyd_new_anydata_*(), lyd_new_leaf(), and their output variants)
  • or address the nodes using a simple XPath addressing (lyd_new_path()).
  • The latter enables to create a whole path of nodes, requires less information about the modified data, and is generally simpler to use. The path format specifics can be found here.

Working with two data subtrees can also be performed two ways.

  • Usually, you would use lyd_insert*() functions. They are generally meant for simple inserts of a node into a data tree.
  • For more complicated inserts and when merging 2 trees use lyd_merge(). It offers additional options and is basically a more powerful insert.

Validating Data

  • lyd_validate()

Default Values

libyang provides support for work with default values as defined in RFC 6243. This document defines 4 modes for handling default nodes in a data tree, libyang adds the fifth mode:

  • explicit - Only the explicitly set configuration data. But in the case of status data, missing default data are added into the tree. In libyang, this mode is represented by LYP_WD_EXPLICIT option.
  • trim - Data nodes containing the schema default value are removed. This mode is applied using LYP_WD_TRIM option.
  • report-all - All the missing default data are added into the data tree. This mode is represented by LYP_WD_ALL option.
  • report-all-tagged - In this case, all the missing default data are added as in case of the report-all mode, but additionally all the nodes (existing as well as added) containing the schema default value are tagged (see the note below). libyang uses LYP_WD_ALL_TAG option for this mode.
  • report-implicit-tagged - The last mode is similar to the previous one, except only the added nodes are tagged. This is the libyang’s extension and it is represented by LYP_WD_IMPL_TAG option.

XPath Addressing

Schema

Regarding identifying schema nodes, we use a slightly modified version of YANG augment target path:

  • strictly speaking, most XPath expressions are not accepted, only simple paths (no predicates, numbers, literals, operators, …),
  • whenever a prefix is used for a node, it is not the import prefix, but the module name itself,
  • current module is specified separately for absolute paths and is the module of the start (current) node for relative paths,
  • unprefixed nodes all use the prefix of the current module so all nodes from other modules than the current module MUST have prefixes,
  • nodes from the current module MAY have prefixes,

Examples

  • get all top-level nodes of the module-name

    1
    /module-name:*
  • get all the descendants of container (excluding container)

    1
    /module-name:container//*
  • get aug-leaf, which was added to module-name from an augment module augment-module

    1
    /module-name:container/container2/augment-module:aug-cont/augment-module:aug-leaf

Functions List

Data

As for paths evaluated on YANG data, we opted for standardized JSON paths (RFC 7951). Summarized, it follows these conventions:

  • generally, you can use almost a full XPath in these paths where it makes sense, but only data nodes (node sets) will always be returned (except for paths, predicates are mostly used),
  • as per the specification, prefixes are actually module names,
  • also in the specification, for absolute paths, the first (leftmost) node MUST have a prefix,
  • for relative paths, you specify the context node, which then acts as a parent for the first node in the path,
  • nodes always inherit their module (prefix) from their parent node so whenever a node is from a different module than its parent, it MUST have a prefix,
  • nodes from the same module as their parent MUST NOT have a prefix,
  • different from schema paths, non-data nodes (choice, case, uses, input, output) are skipped and not included in the path.

Examples

  • get list instance with key1 of value 1 and key2 of value 2 (this can return more list instances if there are more keys than key1 and key2)

    1
    /module-name:container/list[key1='1'][key2='2']
  • get leaf-list instance with the value val

    1
    /module-name:container/leaf-list[.='val']
  • get aug-list with aug-list-key, which was added to module-name from an augment module augment-module

    1
    /module-name:container/container2/augment-module:aug-cont/aug-list[aug-list-key='value']

Functions List

TEST

1
2
3
# need to kill sysrepod
sudo sysrepoctl --uninstall --module=building
sudo sysrepoctl --install --yang=./building@2019-08-07.yang --owner=root:root --permissions=666
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# yang define
# 这个building是我当时测试多级container的yang,是看一个国外老哥的视频写的,也是yang入门了
#(但是我用的是加了一些东西的下一个version)
module building {
yang-version 1;
namespace "urn:building:test";

prefix bld;

organization "building";
contact "building address";
description "yang model for buildings";
revision "2019-08-07" {
description "modified revision";
}

container rooms {
list room {
key "room-number room-name";
leaf room-number {
type uint16;
}
leaf room-name {
type string;
}
leaf size {
type uint32;
}
}
}
}

欢迎关注我的其它发布渠道