- reading notes of YANG related topics
about YANG
- YANG is used to model network device config/state information, stated in the following RFCs:
- https://datatracker.ietf.org/doc/html/rfc6020
- https://datatracker.ietf.org/doc/html/rfc6021
- https://datatracker.ietf.org/doc/html/rfc7950
sonic-yang-models
sonic-yang-modelscontains YANG files to model variousCONFIG_DBtables.- contribution guide: https://github.com/Azure/SONiC/blob/master/doc/mgmt/SONiC_YANG_Model_Guidelines.md
how to understand a YANG file
- demo YANG file from: https://github.com/Azure/sonic-buildimage/blob/master/src/sonic-yang-models/yang-models/sonic-interface.yang
sonic-interface.yangmodels theINTERFACEtable
module sonic-interface {
yang-version 1.1;
namespace "http://github.com/Azure/sonic-interface";
prefix intf;
import sonic-types {
prefix stypes;
revision-date 2019-07-01;
}
import sonic-extension {
prefix ext;
revision-date 2019-07-01;
}
import sonic-port {
prefix port;
revision-date 2019-07-01;
}
import sonic-vrf {
prefix vrf;
}
description "INTERFACE yang Module for SONiC OS";
revision 2021-03-30 {
description "Modify the type of vrf name";
}
revision 2019-07-01 {
description "First Revision";
}
container sonic-interface {
container INTERFACE {
description "INTERFACE part of config_db.json";
list INTERFACE_LIST {
description "INTERFACE part of config_db.json with vrf";
key "name";
leaf name {
type leafref {
path /port:sonic-port/port:PORT/port:PORT_LIST/port:name;
}
}
leaf vrf_name {
type leafref {
path "/vrf:sonic-vrf/vrf:VRF/vrf:VRF_LIST/vrf:name";
}
}
leaf nat_zone {
description "NAT Zone for the interface";
type uint8 {
range "0..3" {
error-message "Invalid nat zone for the interface.";
error-app-tag nat-zone-invalid;
}
}
default "0";
}
leaf mpls {
description "Enable/disable MPLS routing for the interface";
type enumeration {
enum enable;
enum disable;
}
}
}
/* end of INTERFACE_LIST */
list INTERFACE_IPPREFIX_LIST {
description "INTERFACE part of config_db.json with ip-prefix";
key "name ip-prefix";
leaf name {
/* This node must be present in INTERFACE_LIST */
must "(current() = ../../INTERFACE_LIST[name=current()]/name)"
{
error-message "Must condition not satisfied, Try adding PORT: {}, Example: 'Ethernet0': {}";
}
type leafref {
path /port:sonic-port/port:PORT/port:PORT_LIST/port:name;
}
}
leaf ip-prefix {
type union {
type stypes:sonic-ip4-prefix;
type stypes:sonic-ip6-prefix;
}
}
leaf scope {
type enumeration {
enum global;
enum local;
}
}
leaf family {
/* family leaf needed for backward compatibility
Both ip4 and ip6 address are string in IETF RFC 6021,
so must statement can check based on : or ., family
should be IPv4 or IPv6 according.
*/
must "(contains(../ip-prefix, ':') and current()='IPv6') or
(contains(../ip-prefix, '.') and current()='IPv4')";
type stypes:ip-family;
}
}
/* end of INTERFACE_IPPREFIX_LIST */
}
/* end of INTERFACE container */
}
}
modulestatement- defines the module name, must be the same as the filename
- substatements:
yang-version: either1or1.1namespace: XML namespaceprefix: two using scenarios- used inside the
modulestatement: when the module is imported by other modules, theprefixstatement’s argument is used as a prefix to access the module- if other module imports
sonic-interface, it must use prefixintfto reference definitions insidesonic-interface, likeintf:sonic-interfaceto refer to thesonic-interfacecontainer defined insidesonic-interface
- if other module imports
- used inside the
import- substatements
prefix- used inside the
importstatement`: defines the prefix to be used to access definitions inside the imported module - this is more like naming an alias to the imported module
- used inside the
revision-date- specify the revision to import
- could not import multiple revisions from the same module
description- definition description
revision- of format
YYYY-MM-DD - each module should have at least one revision - the initial revision statement
- revisions should be placed in reverse chronological order
- of format
- substatements
must: declares a constraint on valid data- the argument is a XPATH expression
YANGhas four types of data nodes for modelingleaf- contains simple data like an integer or a string
- no child nodes
leaf-list- an array of a pariticular type
container- like a set, used to group related nodes, has only child nodes but no value
list- like a dictionary, the key to each entry is uniquely identified by the values of its key leafs
- substatements:
key- specifies the key leafs that uniquely identifies a list entry
- a space-separated list of leaf identifiers of this list
- a leaf identifier refers to a valid child leaf of the list
- a leaf identifier must not appear more than once
- builtin types
- integer types
- int8, int16, int32, int64, uint8, uint16, uint32, uint64
- integer types could use
rangeto limit the values - multiple ranges could be joined by
|, and must be in ascending order
string- a string can be restricted with the
lengthandpatternstatementslengthpattern- modifier
invert-match: restrict to values that do not match the pattern
- modifier
- a string can be restricted with the
leafref- used to reference a particular leaf instance in the data tree
pathstatement must be present to refer to aleaforleaf-listnode.- its argument is an XPATH expression
- integer types
- XPATH expression
- XPATH is used to navigate through the hierachical structure of XML doc
- when used in YANG, XPATH is a way to specify references between nodes(
leafref), and dependencies between nodes(mustorwhen)
- when used in YANG, XPATH is a way to specify references between nodes(
- XPATH uses path expressions to select a collection of nodes
- XPATH built-in functions
concatconcat("hello", " ", "world")
starts-withcountcount(/sys/host)
currentre-matchderived-fromderived-from-or-selfenum-valuebit-is-setderef- follows the reference defiend by the first node in the argument and returns the nodes it refers to
- when to use XPATH in YANG?
muststatementwhenstatementleafref
- what is a context node?
- it is the node on which the XPATH expression appears, so it can be used in relative paths
- XPATH is used to navigate through the hierachical structure of XML doc
leafref and deref
- a simple usage of
leafrefto define a listinterfaceto have all l3 interfaces and a containerdefault-addressto define the default address for interface in the listinterface
list interface {
key "name";
leaf name {
type string;
}
leaf admin-status {
type admin-status;
}
list address {
key "ip";
leaf ip {
type yang:ip-address;
}
}
}
container default-address {
leaf ifname {
type leafref {
path "../../interface/name";
}
}
leaf address {
type leafref {
path "../../interface[name = current()/../ifname]"
+ "/address/ip";
}
}
}
ifnameindefault-addressreferences to the name of an interface in listinterfaceaddressindefault-addresswants to reference to the interface ip address of the interface with name asifname- could use
derefto rewrite the XPATH expression in the leafaddress
container default-address {
leaf ifname {
type leafref {
path "../../interface/name";
}
}
leaf address {
type leafref {
path "deref(../ifname)/../address";
}
}
}
how to validate YANG file
- use
pyangcommand to validate the YANG file
$ pyang yang-models/sonic-vlan-sub-interface.yang -p yang-models
yang-models/sonic-port.yang:13: warning: imported module "sonic-extension" not used
yang-models/sonic-portchannel.yang:13: warning: imported module "sonic-extension" not used
yang-models/sonic-vrf.yang:5: warning: imported module "sonic-extension" not used
$ pyang yang-models/sonic-vlan-sub-interface.yang -p yang-models -f tree
module: sonic-vlan-sub-interface
+--rw sonic-vlan-sub-interface
+--rw VLAN_SUB_INTERFACE
+--rw VLAN_SUB_INTERFACE_LIST* [name vlan]
| +--rw name union
| +--rw vlan uint16
| +--rw admin_status? stypes:admin_status
| +--rw vrf_name? -> /vrf:sonic-vrf/VRF/VRF_LIST/name
+--rw VLAN_SUB_INTERFACE_IPPREFIX_LIST* [name ip-prefix]
+--rw name -> ../../VLAN_SUB_INTERFACE_LIST/name
+--rw ip-prefix stypes:sonic-ip-prefix
references
- https://info.tail-f.com/hubfs/Whitepapers/Whitepaper:%20XPath%20in%20NETCONF%20and%20YANG.pdf
- https://datatracker.ietf.org/doc/html/rfc6020
- https://datatracker.ietf.org/doc/html/rfc7950
- https://ultraconfig.com.au/blog/learn-yang-full-tutorial-for-beginners/