lib: adapt to version 2 of libyang

Compile with v2.0.0 tag of `libyang2` branch of:
https://github.com/CESNET/libyang

staticd init load time of 10k routes now 6s vs ly1 time of 150s

Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
Christian Hopps 2021-05-04 10:41:58 -04:00 committed by Christian Hopps
parent 17daea8a18
commit 3bb513c399
71 changed files with 1227 additions and 1268 deletions

View file

@ -50,8 +50,11 @@ ForEachMacros:
- FOR_ALL_INTERFACES_ADDRESSES - FOR_ALL_INTERFACES_ADDRESSES
- JSON_FOREACH - JSON_FOREACH
# libyang # libyang
- LY_FOR_KEYS
- LY_LIST_FOR
- LY_TREE_FOR - LY_TREE_FOR
- LY_TREE_DFS_BEGIN - LY_TREE_DFS_BEGIN
- LYD_TREE_DFS_BEGIN
# zebra # zebra
- RE_DEST_FOREACH_ROUTE - RE_DEST_FOREACH_ROUTE
- RE_DEST_FOREACH_ROUTE_SAFE - RE_DEST_FOREACH_ROUTE_SAFE

View file

@ -5,14 +5,14 @@ services:
- docker - docker
jobs: jobs:
include: include:
- script: # - script:
- docker/centos-7/build.sh # - docker/centos-7/build.sh
- docker images # - docker images
name: centos7 # name: centos7
- script: # - script:
- docker/centos-8/build.sh # - docker/centos-8/build.sh
- docker images # - docker images
name: centos8 # name: centos8
- script: - script:
- sudo apt install -y linux-modules-extra-$(uname -r) - sudo apt install -y linux-modules-extra-$(uname -r)
- docker build -t frr-ubuntu18:latest -f docker/ubuntu18-ci/Dockerfile . - docker build -t frr-ubuntu18:latest -f docker/ubuntu18-ci/Dockerfile .

View file

@ -2195,13 +2195,13 @@ void bfd_session_update_vrf_name(struct bfd_session *bs, struct vrf *vrf)
snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']/vrf", snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']/vrf",
bs->key.vrfname); bs->key.vrfname);
bfd_dnode = yang_dnode_get(running_config->dnode, xpath, bfd_dnode = yang_dnode_getf(running_config->dnode, xpath,
bs->key.vrfname); bs->key.vrfname);
if (bfd_dnode) { if (bfd_dnode) {
yang_dnode_get_path(bfd_dnode->parent, oldpath, yang_dnode_get_path(lyd_parent(bfd_dnode), oldpath,
sizeof(oldpath)); sizeof(oldpath));
yang_dnode_change_leaf(bfd_dnode, vrf->name); yang_dnode_change_leaf(bfd_dnode, vrf->name);
yang_dnode_get_path(bfd_dnode->parent, newpath, yang_dnode_get_path(lyd_parent(bfd_dnode), newpath,
sizeof(newpath)); sizeof(newpath));
nb_running_move_tree(oldpath, newpath); nb_running_move_tree(oldpath, newpath);
running_config->version++; running_config->version++;

View file

@ -632,7 +632,6 @@ const struct frr_yang_module_info frr_bgp_info = {
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/no-prepend", .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/no-prepend",
.cbs = { .cbs = {
.modify = bgp_neighbors_neighbor_local_as_no_prepend_modify, .modify = bgp_neighbors_neighbor_local_as_no_prepend_modify,
.destroy = bgp_neighbors_neighbor_local_as_no_prepend_destroy,
} }
}, },
{ {
@ -923,7 +922,6 @@ const struct frr_yang_module_info frr_bgp_info = {
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/no-prepend", .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/no-prepend",
.cbs = { .cbs = {
.modify = bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_modify, .modify = bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_modify,
.destroy = bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_destroy,
} }
}, },
{ {
@ -1215,7 +1213,6 @@ const struct frr_yang_module_info frr_bgp_info = {
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-prepend", .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-prepend",
.cbs = { .cbs = {
.modify = bgp_peer_groups_peer_group_local_as_no_prepend_modify, .modify = bgp_peer_groups_peer_group_local_as_no_prepend_modify,
.destroy = bgp_peer_groups_peer_group_local_as_no_prepend_destroy,
} }
}, },
{ {

View file

@ -233,8 +233,6 @@ int bgp_neighbors_neighbor_local_as_local_as_destroy(
struct nb_cb_destroy_args *args); struct nb_cb_destroy_args *args);
int bgp_neighbors_neighbor_local_as_no_prepend_modify( int bgp_neighbors_neighbor_local_as_no_prepend_modify(
struct nb_cb_modify_args *args); struct nb_cb_modify_args *args);
int bgp_neighbors_neighbor_local_as_no_prepend_destroy(
struct nb_cb_destroy_args *args);
int bgp_neighbors_neighbor_local_as_no_replace_as_modify( int bgp_neighbors_neighbor_local_as_no_replace_as_modify(
struct nb_cb_modify_args *args); struct nb_cb_modify_args *args);
int bgp_neighbors_neighbor_bfd_options_enable_modify( int bgp_neighbors_neighbor_bfd_options_enable_modify(
@ -367,8 +365,6 @@ int bgp_neighbors_unnumbered_neighbor_local_as_local_as_destroy(
struct nb_cb_destroy_args *args); struct nb_cb_destroy_args *args);
int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_modify( int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_modify(
struct nb_cb_modify_args *args); struct nb_cb_modify_args *args);
int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_destroy(
struct nb_cb_destroy_args *args);
int bgp_neighbors_unnumbered_neighbor_local_as_no_replace_as_modify( int bgp_neighbors_unnumbered_neighbor_local_as_no_replace_as_modify(
struct nb_cb_modify_args *args); struct nb_cb_modify_args *args);
int bgp_neighbors_unnumbered_neighbor_bfd_options_enable_modify( int bgp_neighbors_unnumbered_neighbor_bfd_options_enable_modify(
@ -501,8 +497,6 @@ int bgp_peer_groups_peer_group_local_as_local_as_destroy(
struct nb_cb_destroy_args *args); struct nb_cb_destroy_args *args);
int bgp_peer_groups_peer_group_local_as_no_prepend_modify( int bgp_peer_groups_peer_group_local_as_no_prepend_modify(
struct nb_cb_modify_args *args); struct nb_cb_modify_args *args);
int bgp_peer_groups_peer_group_local_as_no_prepend_destroy(
struct nb_cb_destroy_args *args);
int bgp_peer_groups_peer_group_local_as_no_replace_as_modify( int bgp_peer_groups_peer_group_local_as_no_replace_as_modify(
struct nb_cb_modify_args *args); struct nb_cb_modify_args *args);
int bgp_peer_groups_peer_group_bfd_options_enable_modify( int bgp_peer_groups_peer_group_bfd_options_enable_modify(

View file

@ -239,8 +239,8 @@ int bgp_global_local_as_modify(struct nb_cb_modify_args *args)
* If the instance already exists - return the validation * If the instance already exists - return the validation
* error. * error.
*/ */
bgp = nb_running_get_entry_non_rec(args->dnode->parent->parent, bgp = nb_running_get_entry_non_rec(
NULL, false); lyd_parent(lyd_parent(args->dnode)), NULL, false);
if (bgp) { if (bgp) {
snprintf(args->errmsg, args->errmsg_len, snprintf(args->errmsg, args->errmsg_len,
"Changing AS number is not allowed"); "Changing AS number is not allowed");
@ -580,16 +580,11 @@ int bgp_global_route_reflector_route_reflector_cluster_id_modify(
struct bgp *bgp; struct bgp *bgp;
struct in_addr cluster_id; struct in_addr cluster_id;
const struct lyd_node_leaf_list *dleaf;
bgp = nb_running_get_entry(args->dnode, NULL, true); bgp = nb_running_get_entry(args->dnode, NULL, true);
dleaf = (const struct lyd_node_leaf_list *)args->dnode; /* cluster-id is either dotted-quad or a uint32 */
if (dleaf->value_type == LY_TYPE_STRING) (void)inet_aton(lyd_get_value(args->dnode), &cluster_id);
yang_dnode_get_ipv4(&cluster_id, args->dnode, NULL);
else
(void)inet_aton(dleaf->value_str, &cluster_id);
bgp_cluster_id_set(bgp, &cluster_id); bgp_cluster_id_set(bgp, &cluster_id);
if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len)) if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len))
@ -1495,8 +1490,8 @@ int bgp_global_instance_type_view_modify(struct nb_cb_modify_args *args)
* If the instance already exists - return the validation * If the instance already exists - return the validation
* error. * error.
*/ */
bgp = nb_running_get_entry_non_rec(args->dnode->parent->parent, bgp = nb_running_get_entry_non_rec(
NULL, false); lyd_parent(lyd_parent(args->dnode)), NULL, false);
if (bgp) { if (bgp) {
snprintf(args->errmsg, args->errmsg_len, snprintf(args->errmsg, args->errmsg_len,
"Changing instance type is not allowed"); "Changing instance type is not allowed");
@ -3560,21 +3555,6 @@ int bgp_neighbors_neighbor_local_as_no_prepend_modify(
return NB_OK; return NB_OK;
} }
int bgp_neighbors_neighbor_local_as_no_prepend_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
/* TODO: implement me. */
break;
}
return NB_OK;
}
/* /*
* XPath: * XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/no-replace-as * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/no-replace-as
@ -5576,21 +5556,6 @@ int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_modify(
return NB_OK; return NB_OK;
} }
int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
/* TODO: implement me. */
break;
}
return NB_OK;
}
/* /*
* XPath: * XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/no-replace-as * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/no-replace-as
@ -7493,21 +7458,6 @@ int bgp_peer_groups_peer_group_local_as_no_prepend_modify(
return NB_OK; return NB_OK;
} }
int bgp_peer_groups_peer_group_local_as_no_prepend_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
/* TODO: implement me. */
break;
}
return NB_OK;
}
/* /*
* XPath: * XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-replace-as * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-replace-as

View file

@ -4372,12 +4372,12 @@ DEFUN_YANG(neighbor_remote_as,
snprintf(prgrp_xpath, sizeof(prgrp_xpath), snprintf(prgrp_xpath, sizeof(prgrp_xpath),
FRR_BGP_PEER_GROUP_XPATH, argv[idx_peer]->arg, ""); FRR_BGP_PEER_GROUP_XPATH, argv[idx_peer]->arg, "");
if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s", if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
VTY_CURR_XPATH, unnbr_xpath + 1)) { VTY_CURR_XPATH, unnbr_xpath + 1)) {
strlcpy(base_xpath, unnbr_xpath, sizeof(base_xpath)); strlcpy(base_xpath, unnbr_xpath, sizeof(base_xpath));
} else if (yang_dnode_exists(vty->candidate_config->dnode, } else if (yang_dnode_existsf(vty->candidate_config->dnode,
"%s%s", VTY_CURR_XPATH, "%s%s", VTY_CURR_XPATH,
prgrp_xpath + 1)) { prgrp_xpath + 1)) {
snprintf(base_xpath, sizeof(base_xpath), snprintf(base_xpath, sizeof(base_xpath),
FRR_BGP_PEER_GROUP_XPATH, argv[idx_peer]->arg, FRR_BGP_PEER_GROUP_XPATH, argv[idx_peer]->arg,
""); "");
@ -4648,8 +4648,8 @@ DEFUN_YANG(no_neighbor,
if (str2sockunion(argv[idx_peer]->arg, &su) == 0) { if (str2sockunion(argv[idx_peer]->arg, &su) == 0) {
snprintf(num_xpath, sizeof(num_xpath), snprintf(num_xpath, sizeof(num_xpath),
FRR_BGP_NEIGHBOR_NUM_XPATH, argv[idx_peer]->arg, ""); FRR_BGP_NEIGHBOR_NUM_XPATH, argv[idx_peer]->arg, "");
if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s", if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
VTY_CURR_XPATH, num_xpath + 1)) { VTY_CURR_XPATH, num_xpath + 1)) {
strlcpy(base_xpath, num_xpath, sizeof(base_xpath)); strlcpy(base_xpath, num_xpath, sizeof(base_xpath));
} }
} else { } else {
@ -4659,12 +4659,12 @@ DEFUN_YANG(no_neighbor,
snprintf(prgrp_xpath, sizeof(prgrp_xpath), snprintf(prgrp_xpath, sizeof(prgrp_xpath),
FRR_BGP_PEER_GROUP_XPATH, argv[idx_peer]->arg, ""); FRR_BGP_PEER_GROUP_XPATH, argv[idx_peer]->arg, "");
if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s", if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
VTY_CURR_XPATH, unnbr_xpath + 1)) { VTY_CURR_XPATH, unnbr_xpath + 1)) {
strlcpy(base_xpath, unnbr_xpath, sizeof(base_xpath)); strlcpy(base_xpath, unnbr_xpath, sizeof(base_xpath));
} else if (yang_dnode_exists(vty->candidate_config->dnode, } else if (yang_dnode_existsf(vty->candidate_config->dnode,
"%s%s", VTY_CURR_XPATH, "%s%s", VTY_CURR_XPATH,
prgrp_xpath + 1)) { prgrp_xpath + 1)) {
strlcpy(base_xpath, prgrp_xpath, sizeof(base_xpath)); strlcpy(base_xpath, prgrp_xpath, sizeof(base_xpath));
} else { } else {
vty_out(vty, vty_out(vty,
@ -4740,11 +4740,11 @@ DEFUN_YANG(no_neighbor_interface_peer_group_remote_as,
snprintf(prgrp_xpath, sizeof(prgrp_xpath), FRR_BGP_PEER_GROUP_XPATH, snprintf(prgrp_xpath, sizeof(prgrp_xpath), FRR_BGP_PEER_GROUP_XPATH,
argv[idx_peer]->arg, ""); argv[idx_peer]->arg, "");
if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s", if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
VTY_CURR_XPATH, unnbr_xpath + 1)) { VTY_CURR_XPATH, unnbr_xpath + 1)) {
strlcpy(base_xpath, unnbr_xpath, sizeof(base_xpath)); strlcpy(base_xpath, unnbr_xpath, sizeof(base_xpath));
} else if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s", } else if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
VTY_CURR_XPATH, prgrp_xpath + 1)) { VTY_CURR_XPATH, prgrp_xpath + 1)) {
strlcpy(base_xpath, prgrp_xpath, sizeof(base_xpath)); strlcpy(base_xpath, prgrp_xpath, sizeof(base_xpath));
} else { } else {
vty_out(vty, "%% Create the peer-group or interface first\n"); vty_out(vty, "%% Create the peer-group or interface first\n");
@ -7036,8 +7036,8 @@ static int peer_and_group_lookup_nb(struct vty *vty, const char *peer_str,
if (str2sockunion(peer_str, &su) == 0) { if (str2sockunion(peer_str, &su) == 0) {
snprintf(num_xpath, sizeof(num_xpath), snprintf(num_xpath, sizeof(num_xpath),
"/neighbors/neighbor[remote-address='%s']", peer_str); "/neighbors/neighbor[remote-address='%s']", peer_str);
if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s", if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
VTY_CURR_XPATH, num_xpath)) { VTY_CURR_XPATH, num_xpath)) {
snprintf(base_xpath, xpath_len, snprintf(base_xpath, xpath_len,
FRR_BGP_NEIGHBOR_NUM_XPATH, peer_str, FRR_BGP_NEIGHBOR_NUM_XPATH, peer_str,
xpath ? xpath : ""); xpath ? xpath : "");
@ -7056,14 +7056,14 @@ static int peer_and_group_lookup_nb(struct vty *vty, const char *peer_str,
"/peer-groups/peer-group[peer-group-name='%s']", "/peer-groups/peer-group[peer-group-name='%s']",
peer_str); peer_str);
if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s", if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
VTY_CURR_XPATH, unnbr_xpath)) { VTY_CURR_XPATH, unnbr_xpath)) {
snprintf(base_xpath, xpath_len, snprintf(base_xpath, xpath_len,
FRR_BGP_NEIGHBOR_UNNUM_XPATH, peer_str, FRR_BGP_NEIGHBOR_UNNUM_XPATH, peer_str,
xpath ? xpath : ""); xpath ? xpath : "");
} else if (yang_dnode_exists(vty->candidate_config->dnode, } else if (yang_dnode_existsf(vty->candidate_config->dnode,
"%s%s", VTY_CURR_XPATH, "%s%s", VTY_CURR_XPATH,
prgrp_xpath)) { prgrp_xpath)) {
snprintf(base_xpath, xpath_len, snprintf(base_xpath, xpath_len,
FRR_BGP_PEER_GROUP_XPATH, peer_str, FRR_BGP_PEER_GROUP_XPATH, peer_str,
xpath ? xpath : ""); xpath ? xpath : "");
@ -8085,7 +8085,7 @@ DEFPY_YANG(
bgp_afi_safi_get_container_str(afi, safi)); bgp_afi_safi_get_container_str(afi, safi));
if (!no) { if (!no) {
if (!yang_dnode_exists( if (!yang_dnode_existsf(
vty->candidate_config->dnode, vty->candidate_config->dnode,
"/frr-route-map:lib/route-map[name='%s']", "/frr-route-map:lib/route-map[name='%s']",
rmap_str)) { rmap_str)) {

View file

@ -214,8 +214,8 @@ bgpd_bgpd_SOURCES = bgpd/bgp_main.c
bgpd_bgp_btoa_SOURCES = bgpd/bgp_btoa.c bgpd_bgp_btoa_SOURCES = bgpd/bgp_btoa.c
# RFPLDADD is set in bgpd/rfp-example/librfp/subdir.am # RFPLDADD is set in bgpd/rfp-example/librfp/subdir.am
bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM) $(UST_LIBS) bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBYANG_LIBS) $(LIBCAP) $(LIBM) $(UST_LIBS)
bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM) $(UST_LIBS) bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBYANG_LIBS) $(LIBCAP) $(LIBM) $(UST_LIBS)
bgpd_bgpd_snmp_la_SOURCES = bgpd/bgp_snmp.c bgpd/bgp_mplsvpn_snmp.c bgpd_bgpd_snmp_la_SOURCES = bgpd/bgp_snmp.c bgpd/bgp_mplsvpn_snmp.c
bgpd_bgpd_snmp_la_CFLAGS = $(AM_CFLAGS) $(SNMP_CFLAGS) -std=gnu11 bgpd_bgpd_snmp_la_CFLAGS = $(AM_CFLAGS) $(SNMP_CFLAGS) -std=gnu11

View file

@ -1866,8 +1866,8 @@ AC_SUBST([SNMP_CFLAGS])
dnl --------------- dnl ---------------
dnl libyang dnl libyang
dnl --------------- dnl ---------------
PKG_CHECK_MODULES([LIBYANG], [libyang >= 1.0.184 libyang < 2.0], , [ PKG_CHECK_MODULES([LIBYANG], [libyang >= 2.0.0], , [
AC_MSG_ERROR([libyang (>= 1.0.184) was not found on your system.]) AC_MSG_ERROR([libyang (>= 2.0.0) was not found on your system.])
]) ])
ac_cflags_save="$CFLAGS" ac_cflags_save="$CFLAGS"
CFLAGS="$CFLAGS $LIBYANG_CFLAGS" CFLAGS="$CFLAGS $LIBYANG_CFLAGS"

4
debian/control vendored
View file

@ -16,14 +16,14 @@ Build-Depends: bison,
libelf-dev, libelf-dev,
libjson-c-dev | libjson0-dev, libjson-c-dev | libjson0-dev,
libpam0g-dev | libpam-dev, libpam0g-dev | libpam-dev,
libpcre3-dev, libpcre2-dev,
libpython3-dev, libpython3-dev,
libreadline-dev, libreadline-dev,
librtr-dev <!pkg.frr.nortrlib>, librtr-dev <!pkg.frr.nortrlib>,
libsnmp-dev, libsnmp-dev,
libssh-dev <!pkg.frr.nortrlib>, libssh-dev <!pkg.frr.nortrlib>,
libsystemd-dev <!pkg.frr.nosystemd>, libsystemd-dev <!pkg.frr.nosystemd>,
libyang-dev (>= 1.0.184), libyang2-dev,
lsb-base, lsb-base,
pkg-config, pkg-config,
python3, python3,

View file

@ -10,11 +10,12 @@ The FRR project builds some binary ``libyang`` packages.
RPM packages are at our `RPM repository <https://rpm.frrouting.org>`_. RPM packages are at our `RPM repository <https://rpm.frrouting.org>`_.
DEB packages are available as CI artifacts `here DEB packages are available as CI artifacts `here
<https://ci1.netdef.org/browse/LIBYANG-LY1REL-DEB10AMD64-4/artifact>`_. <https://ci1.netdef.org/browse/LIBYANG-LIBYANG-V2/latestSuccessful/artifact>`_.
.. warning:: .. warning::
``libyang`` version 1.0.184 or newer is required to build FRR. ``libyang`` version 2.0.0 or newer is required to build FRR. Currently a tag
(``v2.0.0``) is used from the libyang2 branch.
.. note:: .. note::
@ -26,31 +27,22 @@ DEB packages are available as CI artifacts `here
Depending on your platform, you may also need to install the PCRE Depending on your platform, you may also need to install the PCRE
development package. Typically this is ``libpcre-dev`` or ``pcre-devel``. development package. Typically this is ``libpcre-dev`` or ``pcre-devel``.
.. note::
For Debian-based systems, the official ``libyang`` package requires recent
versions of ``swig`` (3.0.12) and ``debhelper`` (11) which are only
available in Debian buster (10). However, ``libyang`` packages built on
Debian buster can be installed on both Debian jessie (8) and Debian stretch
(9), as well as various Ubuntu systems. The ``python3-yang`` package will
not work, but the other packages (``libyang-dev`` is the one needed for FRR)
will.
**Option 2: Source Install** **Option 2: Source Install**
.. note:: .. note::
Ensure that the `libyang build requirements Ensure that the `libyang build requirements
<https://github.com/CESNET/libyang/blob/master/README.md#build-requirements>`_ <https://github.com/CESNET/libyang/tree/libyang2#build-requirements>`_
are met before continuing. Usually this entails installing ``cmake`` and are met before continuing. Usually this entails installing ``cmake`` and
``libpcre-dev`` or ``pcre-devel``. ``libpcre-dev`` or ``pcre-devel``.
.. code-block:: console .. code-block:: console
git clone https://github.com/CESNET/libyang.git git clone https://github.com/CESNET/libyang.git -b libyang2
cd libyang cd libyang
git checkout v2.0.0
mkdir build; cd build mkdir build; cd build
cmake -DENABLE_LYD_PRIV=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr \ cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr \
-D CMAKE_BUILD_TYPE:String="Release" .. -D CMAKE_BUILD_TYPE:String="Release" ..
make make
sudo make install sudo make install

View file

@ -26,19 +26,19 @@ RUN groupadd -r -g 92 frr && \
echo 'frr ALL = NOPASSWD: ALL' | tee /etc/sudoers.d/frr && \ echo 'frr ALL = NOPASSWD: ALL' | tee /etc/sudoers.d/frr && \
mkdir -p /home/frr && chown frr.frr /home/frr mkdir -p /home/frr && chown frr.frr /home/frr
#for libyang 1 #for libyang 2
RUN apt-get install -y cmake libpcre3-dev RUN apt-get install -y cmake libpcre2-dev
USER frr:frr USER frr:frr
# build and install libyang1 # build and install libyang1
RUN cd && pwd && ls -al && \ RUN cd && pwd && ls -al && \
git clone https://github.com/CESNET/libyang.git && \ git clone https://github.com/CESNET/libyang.git -b libyang2 && \
cd libyang && \ cd libyang && \
git checkout v1.0.225 && \ git checkout v2.0.0 && \
mkdir build; cd build && \ mkdir build; cd build && \
cmake -DENABLE_LYD_PRIV=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr \ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \
-D CMAKE_BUILD_TYPE:String="Release" .. && \ -DCMAKE_BUILD_TYPE:String="Release" .. && \
make -j $(nproc) && \ make -j $(nproc) && \
sudo make install sudo make install
@ -47,7 +47,7 @@ COPY --chown=frr:frr . /home/frr/frr/
RUN cd && ls -al && ls -al frr RUN cd && ls -al && ls -al frr
RUN cd ~/frr && \ RUN cd ~/frr && \
./bootstrap.sh && \ ./bootstrap.sh && \
./configure \ ./configure \
--prefix=/usr \ --prefix=/usr \
--localstatedir=/var/run/frr \ --localstatedir=/var/run/frr \

View file

@ -29,19 +29,19 @@ RUN groupadd -r -g 92 frr && \
echo 'frr ALL = NOPASSWD: ALL' | tee /etc/sudoers.d/frr && \ echo 'frr ALL = NOPASSWD: ALL' | tee /etc/sudoers.d/frr && \
mkdir -p /home/frr && chown frr.frr /home/frr mkdir -p /home/frr && chown frr.frr /home/frr
#for libyang 1 #for libyang 2
RUN apt-get install -y cmake libpcre3-dev RUN apt-get install -y cmake libpcre2-dev
USER frr:frr USER frr:frr
# build and install libyang1 # build and install libyang1
RUN cd && pwd && ls -al && \ RUN cd && pwd && ls -al && \
git clone https://github.com/CESNET/libyang.git && \ git clone https://github.com/CESNET/libyang.git -b libyang2 && \
cd libyang && \ cd libyang && \
git checkout v1.0.225 && \ git checkout v2.0.0 && \
mkdir build; cd build && \ mkdir build; cd build && \
cmake -DENABLE_LYD_PRIV=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr \ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \
-D CMAKE_BUILD_TYPE:String="Release" .. && \ -DCMAKE_BUILD_TYPE:String="Release" .. && \
make -j $(nproc) && \ make -j $(nproc) && \
sudo make install sudo make install
@ -50,7 +50,7 @@ COPY --chown=frr:frr . /home/frr/frr/
RUN cd && ls -al && ls -al frr RUN cd && ls -al && ls -al frr
RUN cd ~/frr && \ RUN cd ~/frr && \
./bootstrap.sh && \ ./bootstrap.sh && \
./configure \ ./configure \
--prefix=/usr \ --prefix=/usr \
--localstatedir=/var/run/frr \ --localstatedir=/var/run/frr \

View file

@ -880,7 +880,7 @@ static int eigrp_write_interface(struct vty *vty)
RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) { RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
FOR_ALL_INTERFACES(vrf, ifp) { FOR_ALL_INTERFACES(vrf, ifp) {
dnode = yang_dnode_get( dnode = yang_dnode_getf(
running_config->dnode, running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']", "/frr-interface:lib/interface[name='%s'][vrf='%s']",
ifp->name, vrf->name); ifp->name, vrf->name);

View file

@ -1306,7 +1306,7 @@ static int isis_interface_config_write(struct vty *vty)
FOR_ALL_INTERFACES (vrf, ifp) { FOR_ALL_INTERFACES (vrf, ifp) {
struct lyd_node *dnode; struct lyd_node *dnode;
dnode = yang_dnode_get( dnode = yang_dnode_getf(
running_config->dnode, running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']", "/frr-interface:lib/interface[name='%s'][vrf='%s']",
ifp->name, vrf->name); ifp->name, vrf->name);

View file

@ -110,7 +110,7 @@ DEFPY_YANG(no_router_isis, no_router_isis_cmd,
if (!vrf_name) if (!vrf_name)
vrf_name = VRF_DEFAULT_NAME; vrf_name = VRF_DEFAULT_NAME;
if (!yang_dnode_exists( if (!yang_dnode_existsf(
vty->candidate_config->dnode, vty->candidate_config->dnode,
"/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag, "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag,
vrf_name)) { vrf_name)) {
@ -277,8 +277,8 @@ DEFPY_YANG(no_ip_router_isis, no_ip_router_isis_cmd,
{ {
const struct lyd_node *dnode; const struct lyd_node *dnode;
dnode = yang_dnode_get(vty->candidate_config->dnode, dnode = yang_dnode_getf(vty->candidate_config->dnode,
"%s/frr-isisd:isis", VTY_CURR_XPATH); "%s/frr-isisd:isis", VTY_CURR_XPATH);
if (!dnode) if (!dnode)
return CMD_SUCCESS; return CMD_SUCCESS;
@ -345,8 +345,8 @@ DEFPY_YANG(isis_bfd,
{ {
const struct lyd_node *dnode; const struct lyd_node *dnode;
dnode = yang_dnode_get(vty->candidate_config->dnode, dnode = yang_dnode_getf(vty->candidate_config->dnode,
"%s/frr-isisd:isis", VTY_CURR_XPATH); "%s/frr-isisd:isis", VTY_CURR_XPATH);
if (dnode == NULL) { if (dnode == NULL) {
vty_out(vty, "ISIS is not enabled on this circuit\n"); vty_out(vty, "ISIS is not enabled on this circuit\n");
return CMD_SUCCESS; return CMD_SUCCESS;
@ -371,8 +371,8 @@ DEFPY_YANG(isis_bfd_profile,
{ {
const struct lyd_node *dnode; const struct lyd_node *dnode;
dnode = yang_dnode_get(vty->candidate_config->dnode, dnode = yang_dnode_getf(vty->candidate_config->dnode,
"%s/frr-isisd:isis", VTY_CURR_XPATH); "%s/frr-isisd:isis", VTY_CURR_XPATH);
if (dnode == NULL) { if (dnode == NULL) {
vty_out(vty, "ISIS is not enabled on this circuit\n"); vty_out(vty, "ISIS is not enabled on this circuit\n");
return CMD_SUCCESS; return CMD_SUCCESS;
@ -3092,8 +3092,8 @@ DEFPY(isis_mpls_if_ldp_sync, isis_mpls_if_ldp_sync_cmd,
{ {
const struct lyd_node *dnode; const struct lyd_node *dnode;
dnode = yang_dnode_get(vty->candidate_config->dnode, dnode = yang_dnode_getf(vty->candidate_config->dnode,
"%s/frr-isisd:isis", VTY_CURR_XPATH); "%s/frr-isisd:isis", VTY_CURR_XPATH);
if (dnode == NULL) { if (dnode == NULL) {
vty_out(vty, "ISIS is not enabled on this circuit\n"); vty_out(vty, "ISIS is not enabled on this circuit\n");
return CMD_SUCCESS; return CMD_SUCCESS;
@ -3123,8 +3123,8 @@ DEFPY(isis_mpls_if_ldp_sync_holddown, isis_mpls_if_ldp_sync_holddown_cmd,
{ {
const struct lyd_node *dnode; const struct lyd_node *dnode;
dnode = yang_dnode_get(vty->candidate_config->dnode, dnode = yang_dnode_getf(vty->candidate_config->dnode,
"%s/frr-isisd:isis", VTY_CURR_XPATH); "%s/frr-isisd:isis", VTY_CURR_XPATH);
if (dnode == NULL) { if (dnode == NULL) {
vty_out(vty, "ISIS is not enabled on this circuit\n"); vty_out(vty, "ISIS is not enabled on this circuit\n");
return CMD_SUCCESS; return CMD_SUCCESS;
@ -3143,8 +3143,8 @@ DEFPY(no_isis_mpls_if_ldp_sync_holddown, no_isis_mpls_if_ldp_sync_holddown_cmd,
{ {
const struct lyd_node *dnode; const struct lyd_node *dnode;
dnode = yang_dnode_get(vty->candidate_config->dnode, dnode = yang_dnode_getf(vty->candidate_config->dnode,
"%s/frr-isisd:isis", VTY_CURR_XPATH); "%s/frr-isisd:isis", VTY_CURR_XPATH);
if (dnode == NULL) { if (dnode == NULL) {
vty_out(vty, "ISIS is not enabled on this circuit\n"); vty_out(vty, "ISIS is not enabled on this circuit\n");
return CMD_SUCCESS; return CMD_SUCCESS;

View file

@ -2509,10 +2509,10 @@ int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args)
if (args->event == NB_EV_VALIDATE) { if (args->event == NB_EV_VALIDATE) {
/* libyang doesn't like relative paths across module boundaries /* libyang doesn't like relative paths across module boundaries
*/ */
ifname = yang_dnode_get_string(args->dnode->parent->parent, ifname = yang_dnode_get_string(
"./name"); lyd_parent(lyd_parent(args->dnode)), "./name");
vrfname = yang_dnode_get_string(args->dnode->parent->parent, vrfname = yang_dnode_get_string(
"./vrf"); lyd_parent(lyd_parent(args->dnode)), "./vrf");
vrf = vrf_lookup_by_name(vrfname); vrf = vrf_lookup_by_name(vrfname);
assert(vrf); assert(vrf);
ifp = if_lookup_by_name(ifname, vrf->vrf_id); ifp = if_lookup_by_name(ifname, vrf->vrf_id);
@ -2549,10 +2549,10 @@ int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args)
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
/* libyang doesn't like relative paths across module boundaries /* libyang doesn't like relative paths across module boundaries
*/ */
ifname = yang_dnode_get_string(args->dnode->parent->parent, ifname = yang_dnode_get_string(
"./name"); lyd_parent(lyd_parent(args->dnode)), "./name");
vrfname = yang_dnode_get_string(args->dnode->parent->parent, vrfname = yang_dnode_get_string(
"./vrf"); lyd_parent(lyd_parent(args->dnode)), "./vrf");
vrf = vrf_lookup_by_name(vrfname); vrf = vrf_lookup_by_name(vrfname);
assert(vrf); assert(vrf);
ifp = if_lookup_by_name(ifname, vrf->vrf_id); ifp = if_lookup_by_name(ifname, vrf->vrf_id);
@ -3184,8 +3184,9 @@ int lib_interface_isis_mpls_ldp_sync_modify(struct nb_cb_modify_args *args)
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
ifp = nb_running_get_entry(args->dnode->parent->parent->parent, ifp = nb_running_get_entry(
NULL, false); lyd_parent(lyd_parent(lyd_parent(args->dnode))), NULL,
false);
if (ifp == NULL) if (ifp == NULL)
return NB_ERR_VALIDATION; return NB_ERR_VALIDATION;
if (if_is_loopback(ifp)) { if (if_is_loopback(ifp)) {
@ -3239,8 +3240,10 @@ int lib_interface_isis_mpls_holddown_modify(struct nb_cb_modify_args *args)
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
ifp = nb_running_get_entry(args->dnode->parent->parent->parent,
NULL, false); ifp = nb_running_get_entry(
lyd_parent(lyd_parent(lyd_parent(args->dnode))), NULL,
false);
if (ifp == NULL) if (ifp == NULL)
return NB_ERR_VALIDATION; return NB_ERR_VALIDATION;
if (if_is_loopback(ifp)) { if (if_is_loopback(ifp)) {
@ -3283,8 +3286,9 @@ int lib_interface_isis_mpls_holddown_destroy(struct nb_cb_destroy_args *args)
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
ifp = nb_running_get_entry(args->dnode->parent->parent->parent, ifp = nb_running_get_entry(
NULL, false); lyd_parent(lyd_parent(lyd_parent(args->dnode))), NULL,
false);
if (ifp == NULL) if (ifp == NULL)
return NB_ERR_VALIDATION; return NB_ERR_VALIDATION;
if (if_is_loopback(ifp)) { if (if_is_loopback(ifp)) {

View file

@ -54,7 +54,6 @@ int main(int argc, char **argv)
vty_init(master, true); vty_init(master, true);
lib_cmd_init(); lib_cmd_init();
yang_init(true);
nb_init(master, NULL, 0, false); nb_init(master, NULL, 0, false);
vty_stdio(vty_do_exit); vty_stdio(vty_do_exit);

View file

@ -266,16 +266,16 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
char oldpath[XPATH_MAXLEN]; char oldpath[XPATH_MAXLEN];
char newpath[XPATH_MAXLEN]; char newpath[XPATH_MAXLEN];
if_dnode = yang_dnode_get( if_dnode = yang_dnode_getf(
running_config->dnode, running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']/vrf", "/frr-interface:lib/interface[name='%s'][vrf='%s']/vrf",
ifp->name, old_vrf->name); ifp->name, old_vrf->name);
if (if_dnode) { if (if_dnode) {
yang_dnode_get_path(if_dnode->parent, oldpath, yang_dnode_get_path(lyd_parent(if_dnode), oldpath,
sizeof(oldpath)); sizeof(oldpath));
yang_dnode_change_leaf(if_dnode, vrf->name); yang_dnode_change_leaf(if_dnode, vrf->name);
yang_dnode_get_path(if_dnode->parent, newpath, yang_dnode_get_path(lyd_parent(if_dnode), newpath,
sizeof(newpath)); sizeof(newpath));
nb_running_move_tree(oldpath, newpath); nb_running_move_tree(oldpath, newpath);
running_config->version++; running_config->version++;

View file

@ -765,16 +765,14 @@ struct thread_master *frr_init(void)
log_ref_vty_init(); log_ref_vty_init();
lib_error_init(); lib_error_init();
yang_init(true);
debug_init_cli();
nb_init(master, di->yang_modules, di->n_yang_modules, true); nb_init(master, di->yang_modules, di->n_yang_modules, true);
if (nb_db_init() != NB_OK) if (nb_db_init() != NB_OK)
flog_warn(EC_LIB_NB_DATABASE, flog_warn(EC_LIB_NB_DATABASE,
"%s: failed to initialize northbound database", "%s: failed to initialize northbound database",
__func__); __func__);
debug_init_cli();
return master; return master;
} }

View file

@ -83,14 +83,14 @@ static int nb_transaction_process(enum nb_event event,
char *errmsg, size_t errmsg_len); char *errmsg, size_t errmsg_len);
static void nb_transaction_apply_finish(struct nb_transaction *transaction, static void nb_transaction_apply_finish(struct nb_transaction *transaction,
char *errmsg, size_t errmsg_len); char *errmsg, size_t errmsg_len);
static int nb_oper_data_iter_node(const struct lys_node *snode, static int nb_oper_data_iter_node(const struct lysc_node *snode,
const char *xpath, const void *list_entry, const char *xpath, const void *list_entry,
const struct yang_list_keys *list_keys, const struct yang_list_keys *list_keys,
struct yang_translator *translator, struct yang_translator *translator,
bool first, uint32_t flags, bool first, uint32_t flags,
nb_oper_data_cb cb, void *arg); nb_oper_data_cb cb, void *arg);
static int nb_node_check_config_only(const struct lys_node *snode, void *arg) static int nb_node_check_config_only(const struct lysc_node *snode, void *arg)
{ {
bool *config_only = arg; bool *config_only = arg;
@ -102,10 +102,10 @@ static int nb_node_check_config_only(const struct lys_node *snode, void *arg)
return YANG_ITER_CONTINUE; return YANG_ITER_CONTINUE;
} }
static int nb_node_new_cb(const struct lys_node *snode, void *arg) static int nb_node_new_cb(const struct lysc_node *snode, void *arg)
{ {
struct nb_node *nb_node; struct nb_node *nb_node;
struct lys_node *sparent, *sparent_list; struct lysc_node *sparent, *sparent_list;
nb_node = XCALLOC(MTYPE_NB_NODE, sizeof(*nb_node)); nb_node = XCALLOC(MTYPE_NB_NODE, sizeof(*nb_node));
yang_snode_get_path(snode, YANG_PATH_DATA, nb_node->xpath, yang_snode_get_path(snode, YANG_PATH_DATA, nb_node->xpath,
@ -129,10 +129,7 @@ static int nb_node_new_cb(const struct lys_node *snode, void *arg)
SET_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY); SET_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY);
} }
if (CHECK_FLAG(snode->nodetype, LYS_LIST)) { if (CHECK_FLAG(snode->nodetype, LYS_LIST)) {
struct lys_node_list *slist; if (yang_snode_num_keys(snode) == 0)
slist = (struct lys_node_list *)snode;
if (slist->keys_size == 0)
SET_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST); SET_FLAG(nb_node->flags, F_NB_NODE_KEYLESS_LIST);
} }
@ -142,18 +139,18 @@ static int nb_node_new_cb(const struct lys_node *snode, void *arg)
*/ */
nb_node->snode = snode; nb_node->snode = snode;
assert(snode->priv == NULL); assert(snode->priv == NULL);
lys_set_private(snode, nb_node); ((struct lysc_node *)snode)->priv = nb_node;
return YANG_ITER_CONTINUE; return YANG_ITER_CONTINUE;
} }
static int nb_node_del_cb(const struct lys_node *snode, void *arg) static int nb_node_del_cb(const struct lysc_node *snode, void *arg)
{ {
struct nb_node *nb_node; struct nb_node *nb_node;
nb_node = snode->priv; nb_node = snode->priv;
if (nb_node) { if (nb_node) {
lys_set_private(snode, NULL); ((struct lysc_node *)snode)->priv = NULL;
XFREE(MTYPE_NB_NODE, nb_node); XFREE(MTYPE_NB_NODE, nb_node);
} }
@ -170,15 +167,15 @@ void nb_nodes_delete(void)
yang_snodes_iterate(NULL, nb_node_del_cb, 0, NULL); yang_snodes_iterate(NULL, nb_node_del_cb, 0, NULL);
} }
struct nb_node *nb_node_find(const char *xpath) struct nb_node *nb_node_find(const char *path)
{ {
const struct lys_node *snode; const struct lysc_node *snode;
/* /*
* Use libyang to find the schema node associated to the xpath and get * Use libyang to find the schema node associated to the path and get
* the northbound node from there (snode private pointer). * the northbound node from there (snode private pointer).
*/ */
snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0); snode = lys_find_path(ly_native_ctx, NULL, path, 0);
if (!snode) if (!snode)
return NULL; return NULL;
@ -288,7 +285,7 @@ static unsigned int nb_node_validate_priority(const struct nb_node *nb_node)
return 0; return 0;
} }
static int nb_node_validate(const struct lys_node *snode, void *arg) static int nb_node_validate(const struct lysc_node *snode, void *arg)
{ {
struct nb_node *nb_node = snode->priv; struct nb_node *nb_node = snode->priv;
unsigned int *errors = arg; unsigned int *errors = arg;
@ -339,7 +336,7 @@ int nb_config_merge(struct nb_config *config_dst, struct nb_config *config_src,
{ {
int ret; int ret;
ret = lyd_merge(config_dst->dnode, config_src->dnode, LYD_OPT_EXPLICIT); ret = lyd_merge_tree(&config_dst->dnode, config_src->dnode, 0);
if (ret != 0) if (ret != 0)
flog_warn(EC_LIB_LIBYANG, "%s: lyd_merge() failed", __func__); flog_warn(EC_LIB_LIBYANG, "%s: lyd_merge() failed", __func__);
@ -451,7 +448,7 @@ static void nb_config_diff_created(const struct lyd_node *dnode, uint32_t *seq,
switch (dnode->schema->nodetype) { switch (dnode->schema->nodetype) {
case LYS_LEAF: case LYS_LEAF:
case LYS_LEAFLIST: case LYS_LEAFLIST:
if (lyd_wd_default((struct lyd_node_leaf_list *)dnode)) if (lyd_is_default(dnode))
break; break;
if (nb_operation_is_valid(NB_OP_CREATE, dnode->schema)) if (nb_operation_is_valid(NB_OP_CREATE, dnode->schema))
@ -470,7 +467,7 @@ static void nb_config_diff_created(const struct lyd_node *dnode, uint32_t *seq,
dnode); dnode);
/* Process child nodes recursively. */ /* Process child nodes recursively. */
LY_TREE_FOR (dnode->child, child) { LY_LIST_FOR (lyd_child(dnode), child) {
nb_config_diff_created(child, seq, changes); nb_config_diff_created(child, seq, changes);
} }
break; break;
@ -497,52 +494,142 @@ static void nb_config_diff_deleted(const struct lyd_node *dnode, uint32_t *seq,
* do is to call the "destroy" callbacks of their child nodes * do is to call the "destroy" callbacks of their child nodes
* when applicable (i.e. optional nodes). * when applicable (i.e. optional nodes).
*/ */
LY_TREE_FOR (dnode->child, child) { LY_LIST_FOR (lyd_child(dnode), child) {
nb_config_diff_deleted(child, seq, changes); nb_config_diff_deleted(child, seq, changes);
} }
} }
} }
static int nb_lyd_diff_get_op(const struct lyd_node *dnode)
{
const struct lyd_meta *meta;
LY_LIST_FOR (dnode->meta, meta) {
if (strcmp(meta->name, "operation")
|| strcmp(meta->annotation->module->name, "yang"))
continue;
return lyd_get_meta_value(meta)[0];
}
return 'n';
}
static inline void nb_config_diff_dnode_log_path(const char *context,
const char *path,
const struct lyd_node *dnode)
{
if (dnode->schema->nodetype & LYD_NODE_TERM)
zlog_debug("nb_config_diff: %s: %s: %s", context, path,
lyd_get_value(dnode));
else
zlog_debug("nb_config_diff: %s: %s", context, path);
}
static inline void nb_config_diff_dnode_log(const char *context,
const struct lyd_node *dnode)
{
if (!dnode) {
zlog_debug("nb_config_diff: %s: NULL", context);
return;
}
char *path = lyd_path(dnode, LYD_PATH_STD, NULL, 0);
nb_config_diff_dnode_log_path(context, path, dnode);
free(path);
}
/* Calculate the delta between two different configurations. */ /* Calculate the delta between two different configurations. */
static void nb_config_diff(const struct nb_config *config1, static void nb_config_diff(const struct nb_config *config1,
const struct nb_config *config2, const struct nb_config *config2,
struct nb_config_cbs *changes) struct nb_config_cbs *changes)
{ {
struct lyd_difflist *diff; struct lyd_node *diff = NULL;
const struct lyd_node *root, *dnode;
struct lyd_node *target;
int op;
LY_ERR err;
char *path;
#if 0 /* Useful (but noisy) when debugging diff code, and for improving later \
*/
if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) {
LY_LIST_FOR(config1->dnode, root) {
LYD_TREE_DFS_BEGIN(root, dnode) {
nb_config_diff_dnode_log("from", dnode);
LYD_TREE_DFS_END(root, dnode);
}
}
LY_LIST_FOR(config2->dnode, root) {
LYD_TREE_DFS_BEGIN(root, dnode) {
nb_config_diff_dnode_log("to", dnode);
LYD_TREE_DFS_END(root, dnode);
}
}
}
#endif
err = lyd_diff_siblings(config1->dnode, config2->dnode,
LYD_DIFF_DEFAULTS, &diff);
assert(!err);
if (diff && DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL))
nb_config_diff_dnode_log("iterating diff", diff);
uint32_t seq = 0; uint32_t seq = 0;
LY_LIST_FOR (diff, root) {
LYD_TREE_DFS_BEGIN (root, dnode) {
op = nb_lyd_diff_get_op(dnode);
diff = lyd_diff(config1->dnode, config2->dnode, path = lyd_path(dnode, LYD_PATH_STD, NULL, 0);
LYD_DIFFOPT_WITHDEFAULTS);
assert(diff);
for (int i = 0; diff->type[i] != LYD_DIFF_END; i++) { #if 0 /* Useful (but noisy) when debugging diff code, and for improving later \
LYD_DIFFTYPE type; */
struct lyd_node *dnode; if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) {
char context[80];
snprintf(context, sizeof(context),
"iterating diff: oper: %c seq: %u", op, seq);
nb_config_diff_dnode_log_path(context, path, dnode);
}
#endif
switch (op) {
case 'c': /* create */
/*
* This is rather inefficient, but when we use
* dnode from the diff instead of the
* candidate config node we get failures when
* looking up default values, etc, based on
* the diff tree.
*/
target = yang_dnode_get(config2->dnode, path);
nb_config_diff_created(target, &seq, changes);
type = diff->type[i]; /* Skip rest of sub-tree, move to next sibling
*/
LYD_TREE_DFS_continue = 1;
break;
case 'd': /* delete */
target = yang_dnode_get(config1->dnode, path);
nb_config_diff_deleted(target, &seq, changes);
switch (type) { /* Skip rest of sub-tree, move to next sibling
case LYD_DIFF_CREATED: */
dnode = diff->second[i]; LYD_TREE_DFS_continue = 1;
nb_config_diff_created(dnode, &seq, changes); break;
break; case 'r': /* replace */
case LYD_DIFF_DELETED: /* either moving an entry or changing a value */
dnode = diff->first[i]; target = yang_dnode_get(config2->dnode, path);
nb_config_diff_deleted(dnode, &seq, changes); assert(target);
break; nb_config_diff_add_change(changes, NB_OP_MODIFY,
case LYD_DIFF_CHANGED: &seq, target);
dnode = diff->second[i]; break;
nb_config_diff_add_change(changes, NB_OP_MODIFY, &seq, case 'n': /* none */
dnode); default:
break; break;
case LYD_DIFF_MOVEDAFTER1: }
case LYD_DIFF_MOVEDAFTER2: free(path);
default: LYD_TREE_DFS_END(root, dnode);
continue;
} }
} }
lyd_free_diff(diff); lyd_free_tree(diff);
} }
int nb_candidate_edit(struct nb_config *candidate, int nb_candidate_edit(struct nb_config *candidate,
@ -554,6 +641,7 @@ int nb_candidate_edit(struct nb_config *candidate,
struct lyd_node *dnode, *dep_dnode; struct lyd_node *dnode, *dep_dnode;
char xpath_edit[XPATH_MAXLEN]; char xpath_edit[XPATH_MAXLEN];
char dep_xpath[XPATH_MAXLEN]; char dep_xpath[XPATH_MAXLEN];
LY_ERR err;
/* Use special notation for leaf-lists (RFC 6020, section 9.13.5). */ /* Use special notation for leaf-lists (RFC 6020, section 9.13.5). */
if (nb_node->snode->nodetype == LYS_LEAFLIST) if (nb_node->snode->nodetype == LYS_LEAFLIST)
@ -565,11 +653,15 @@ int nb_candidate_edit(struct nb_config *candidate,
switch (operation) { switch (operation) {
case NB_OP_CREATE: case NB_OP_CREATE:
case NB_OP_MODIFY: case NB_OP_MODIFY:
ly_errno = 0; err = lyd_new_path(candidate->dnode, ly_native_ctx, xpath_edit,
dnode = lyd_new_path(candidate->dnode, ly_native_ctx, (void *)data->value, LYD_NEW_PATH_UPDATE,
xpath_edit, (void *)data->value, 0, &dnode);
LYD_PATH_OPT_UPDATE); if (err) {
if (dnode) { flog_warn(EC_LIB_LIBYANG,
"%s: lyd_new_path(%s) failed: %d", __func__,
xpath_edit, err);
return NB_ERR;
} else if (dnode) {
/* /*
* create dependency * create dependency
* *
@ -581,22 +673,18 @@ int nb_candidate_edit(struct nb_config *candidate,
nb_node->dep_cbs.get_dependency_xpath( nb_node->dep_cbs.get_dependency_xpath(
dnode, dep_xpath); dnode, dep_xpath);
ly_errno = 0; err = lyd_new_path(candidate->dnode,
dep_dnode = lyd_new_path(candidate->dnode, ly_native_ctx, dep_xpath,
ly_native_ctx, NULL, LYD_NEW_PATH_UPDATE,
dep_xpath, NULL, 0, &dep_dnode);
LYD_PATH_OPT_UPDATE); if (err) {
if (!dep_dnode && ly_errno) { flog_warn(
flog_warn(EC_LIB_LIBYANG, EC_LIB_LIBYANG,
"%s: lyd_new_path(%s) failed", "%s: lyd_new_path(%s) failed: %d",
__func__, dep_xpath); __func__, dep_xpath, err);
return NB_ERR; return NB_ERR;
} }
} }
} else if (ly_errno) {
flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path(%s) failed",
__func__, xpath_edit);
return NB_ERR;
} }
break; break;
case NB_OP_DESTROY: case NB_OP_DESTROY:
@ -613,9 +701,9 @@ int nb_candidate_edit(struct nb_config *candidate,
dep_dnode = yang_dnode_get(candidate->dnode, dep_xpath); dep_dnode = yang_dnode_get(candidate->dnode, dep_xpath);
if (dep_dnode) if (dep_dnode)
lyd_free(dep_dnode); lyd_free_tree(dep_dnode);
} }
lyd_free(dnode); lyd_free_tree(dnode);
break; break;
case NB_OP_MOVE: case NB_OP_MOVE:
/* TODO: update configuration. */ /* TODO: update configuration. */
@ -660,9 +748,8 @@ int nb_candidate_update(struct nb_config *candidate)
static int nb_candidate_validate_yang(struct nb_config *candidate, char *errmsg, static int nb_candidate_validate_yang(struct nb_config *candidate, char *errmsg,
size_t errmsg_len) size_t errmsg_len)
{ {
if (lyd_validate(&candidate->dnode, if (lyd_validate_all(&candidate->dnode, ly_native_ctx,
LYD_OPT_STRICT | LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL, LYD_VALIDATE_NO_STATE, NULL)
ly_native_ctx)
!= 0) { != 0) {
yang_print_errors(ly_native_ctx, errmsg, errmsg_len); yang_print_errors(ly_native_ctx, errmsg, errmsg_len);
return NB_ERR_VALIDATION; return NB_ERR_VALIDATION;
@ -678,12 +765,12 @@ static int nb_candidate_validate_code(struct nb_context *context,
char *errmsg, size_t errmsg_len) char *errmsg, size_t errmsg_len)
{ {
struct nb_config_cb *cb; struct nb_config_cb *cb;
struct lyd_node *root, *next, *child; struct lyd_node *root, *child;
int ret; int ret;
/* First validate the candidate as a whole. */ /* First validate the candidate as a whole. */
LY_TREE_FOR (candidate->dnode, root) { LY_LIST_FOR (candidate->dnode, root) {
LY_TREE_DFS_BEGIN (root, next, child) { LYD_TREE_DFS_BEGIN (root, child) {
struct nb_node *nb_node; struct nb_node *nb_node;
nb_node = child->schema->priv; nb_node = child->schema->priv;
@ -696,7 +783,7 @@ static int nb_candidate_validate_code(struct nb_context *context,
return NB_ERR_VALIDATION; return NB_ERR_VALIDATION;
next: next:
LY_TREE_DFS_END(root, next, child); LYD_TREE_DFS_END(root, child);
} }
} }
@ -1439,7 +1526,7 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction,
if (change->cb.operation == NB_OP_DESTROY) { if (change->cb.operation == NB_OP_DESTROY) {
char xpath[XPATH_MAXLEN]; char xpath[XPATH_MAXLEN];
dnode = dnode->parent; dnode = lyd_parent(dnode);
if (!dnode) if (!dnode)
break; break;
@ -1470,7 +1557,7 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction,
nb_apply_finish_cb_new(&cbs, nb_node, dnode); nb_apply_finish_cb_new(&cbs, nb_node, dnode);
next: next:
dnode = dnode->parent; dnode = lyd_parent(dnode);
} }
} }
@ -1487,16 +1574,16 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction,
} }
} }
static int nb_oper_data_iter_children(const struct lys_node *snode, static int nb_oper_data_iter_children(const struct lysc_node *snode,
const char *xpath, const void *list_entry, const char *xpath, const void *list_entry,
const struct yang_list_keys *list_keys, const struct yang_list_keys *list_keys,
struct yang_translator *translator, struct yang_translator *translator,
bool first, uint32_t flags, bool first, uint32_t flags,
nb_oper_data_cb cb, void *arg) nb_oper_data_cb cb, void *arg)
{ {
struct lys_node *child; const struct lysc_node *child;
LY_TREE_FOR (snode->child, child) { LY_LIST_FOR (lysc_node_child(snode), child) {
int ret; int ret;
ret = nb_oper_data_iter_node(child, xpath, list_entry, ret = nb_oper_data_iter_node(child, xpath, list_entry,
@ -1521,7 +1608,7 @@ static int nb_oper_data_iter_leaf(const struct nb_node *nb_node,
return NB_OK; return NB_OK;
/* Ignore list keys. */ /* Ignore list keys. */
if (lys_is_key((struct lys_node_leaf *)nb_node->snode, NULL)) if (lysc_is_key(nb_node->snode))
return NB_OK; return NB_OK;
data = nb_callback_get_elem(nb_node, xpath, list_entry); data = nb_callback_get_elem(nb_node, xpath, list_entry);
@ -1605,7 +1692,7 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node,
struct yang_translator *translator, struct yang_translator *translator,
uint32_t flags, nb_oper_data_cb cb, void *arg) uint32_t flags, nb_oper_data_cb cb, void *arg)
{ {
struct lys_node_list *slist = (struct lys_node_list *)nb_node->snode; const struct lysc_node *snode = nb_node->snode;
const void *list_entry = NULL; const void *list_entry = NULL;
uint32_t position = 1; uint32_t position = 1;
@ -1614,6 +1701,7 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node,
/* Iterate over all list entries. */ /* Iterate over all list entries. */
do { do {
const struct lysc_node_leaf *skey;
struct yang_list_keys list_keys; struct yang_list_keys list_keys;
char xpath[XPATH_MAXLEN * 2]; char xpath[XPATH_MAXLEN * 2];
int ret; int ret;
@ -1638,12 +1726,16 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node,
/* Build XPath of the list entry. */ /* Build XPath of the list entry. */
strlcpy(xpath, xpath_list, sizeof(xpath)); strlcpy(xpath, xpath_list, sizeof(xpath));
for (unsigned int i = 0; i < list_keys.num; i++) { unsigned int i = 0;
LY_FOR_KEYS (snode, skey) {
assert(i < list_keys.num);
snprintf(xpath + strlen(xpath), snprintf(xpath + strlen(xpath),
sizeof(xpath) - strlen(xpath), sizeof(xpath) - strlen(xpath),
"[%s='%s']", slist->keys[i]->name, "[%s='%s']", skey->name,
list_keys.key[i]); list_keys.key[i]);
i++;
} }
assert(i == list_keys.num);
} else { } else {
/* /*
* Keyless list - build XPath using a positional index. * Keyless list - build XPath using a positional index.
@ -1664,7 +1756,7 @@ static int nb_oper_data_iter_list(const struct nb_node *nb_node,
return NB_OK; return NB_OK;
} }
static int nb_oper_data_iter_node(const struct lys_node *snode, static int nb_oper_data_iter_node(const struct lysc_node *snode,
const char *xpath_parent, const char *xpath_parent,
const void *list_entry, const void *list_entry,
const struct yang_list_keys *list_keys, const struct yang_list_keys *list_keys,
@ -1683,18 +1775,16 @@ static int nb_oper_data_iter_node(const struct lys_node *snode,
/* Update XPath. */ /* Update XPath. */
strlcpy(xpath, xpath_parent, sizeof(xpath)); strlcpy(xpath, xpath_parent, sizeof(xpath));
if (!first && snode->nodetype != LYS_USES) { if (!first && snode->nodetype != LYS_USES) {
struct lys_node *parent; struct lysc_node *parent;
/* Get the real parent. */ /* Get the real parent. */
parent = snode->parent; parent = snode->parent;
while (parent && parent->nodetype == LYS_USES)
parent = parent->parent;
/* /*
* When necessary, include the namespace of the augmenting * When necessary, include the namespace of the augmenting
* module. * module.
*/ */
if (parent && parent->nodetype == LYS_AUGMENT) if (parent && parent->module != snode->module)
snprintf(xpath + strlen(xpath), snprintf(xpath + strlen(xpath),
sizeof(xpath) - strlen(xpath), "/%s:%s", sizeof(xpath) - strlen(xpath), "/%s:%s",
snode->module->name, snode->name); snode->module->name, snode->name);
@ -1769,12 +1859,14 @@ int nb_oper_data_iterate(const char *xpath, struct yang_translator *translator,
* Create a data tree from the XPath so that we can parse the keys of * Create a data tree from the XPath so that we can parse the keys of
* all YANG lists (if any). * all YANG lists (if any).
*/ */
ly_errno = 0;
dnode = lyd_new_path(NULL, ly_native_ctx, xpath, NULL, 0, LY_ERR err = lyd_new_path(NULL, ly_native_ctx, xpath, NULL,
LYD_PATH_OPT_UPDATE | LYD_PATH_OPT_NOPARENTRET); LYD_NEW_PATH_UPDATE, &dnode);
if (!dnode) { if (err || !dnode) {
flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path() failed", const char *errmsg =
__func__); err ? ly_errmsg(ly_native_ctx) : "node not found";
flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path() failed %s",
__func__, errmsg);
return NB_ERR; return NB_ERR;
} }
@ -1782,8 +1874,8 @@ int nb_oper_data_iterate(const char *xpath, struct yang_translator *translator,
* Create a linked list to sort the data nodes starting from the root. * Create a linked list to sort the data nodes starting from the root.
*/ */
list_dnodes = list_new(); list_dnodes = list_new();
for (dn = dnode; dn; dn = dn->parent) { for (dn = dnode; dn; dn = lyd_parent(dn)) {
if (dn->schema->nodetype != LYS_LIST || !dn->child) if (dn->schema->nodetype != LYS_LIST || !lyd_child(dn))
continue; continue;
listnode_add_head(list_dnodes, dn); listnode_add_head(list_dnodes, dn);
} }
@ -1798,18 +1890,16 @@ int nb_oper_data_iterate(const char *xpath, struct yang_translator *translator,
/* Obtain the list entry keys. */ /* Obtain the list entry keys. */
memset(&list_keys, 0, sizeof(list_keys)); memset(&list_keys, 0, sizeof(list_keys));
LY_TREE_FOR (dn->child, child) { LY_LIST_FOR (lyd_child(dn), child) {
if (!lys_is_key((struct lys_node_leaf *)child->schema, if (!lysc_is_key(child->schema))
NULL)) break;
continue;
strlcpy(list_keys.key[n], strlcpy(list_keys.key[n],
yang_dnode_get_string(child, NULL), yang_dnode_get_string(child, NULL),
sizeof(list_keys.key[n])); sizeof(list_keys.key[n]));
n++; n++;
} }
list_keys.num = n; list_keys.num = n;
if (list_keys.num if (list_keys.num != yang_snode_num_keys(dn->schema)) {
!= ((struct lys_node_list *)dn->schema)->keys_size) {
list_delete(&list_dnodes); list_delete(&list_dnodes);
yang_dnode_free(dnode); yang_dnode_free(dnode);
return NB_ERR_NOT_FOUND; return NB_ERR_NOT_FOUND;
@ -1837,7 +1927,7 @@ int nb_oper_data_iterate(const char *xpath, struct yang_translator *translator,
} }
/* If a list entry was given, iterate over that list entry only. */ /* If a list entry was given, iterate over that list entry only. */
if (dnode->schema->nodetype == LYS_LIST && dnode->child) if (dnode->schema->nodetype == LYS_LIST && lyd_child(dnode))
ret = nb_oper_data_iter_children( ret = nb_oper_data_iter_children(
nb_node->snode, xpath, list_entry, &list_keys, nb_node->snode, xpath, list_entry, &list_keys,
translator, true, flags, cb, arg); translator, true, flags, cb, arg);
@ -1853,11 +1943,11 @@ int nb_oper_data_iterate(const char *xpath, struct yang_translator *translator,
} }
bool nb_operation_is_valid(enum nb_operation operation, bool nb_operation_is_valid(enum nb_operation operation,
const struct lys_node *snode) const struct lysc_node *snode)
{ {
struct nb_node *nb_node = snode->priv; struct nb_node *nb_node = snode->priv;
struct lys_node_container *scontainer; struct lysc_node_container *scontainer;
struct lys_node_leaf *sleaf; struct lysc_node_leaf *sleaf;
switch (operation) { switch (operation) {
case NB_OP_CREATE: case NB_OP_CREATE:
@ -1866,13 +1956,13 @@ bool nb_operation_is_valid(enum nb_operation operation,
switch (snode->nodetype) { switch (snode->nodetype) {
case LYS_LEAF: case LYS_LEAF:
sleaf = (struct lys_node_leaf *)snode; sleaf = (struct lysc_node_leaf *)snode;
if (sleaf->type.base != LY_TYPE_EMPTY) if (sleaf->type->basetype != LY_TYPE_EMPTY)
return false; return false;
break; break;
case LYS_CONTAINER: case LYS_CONTAINER:
scontainer = (struct lys_node_container *)snode; scontainer = (struct lysc_node_container *)snode;
if (!scontainer->presence) if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE))
return false; return false;
break; break;
case LYS_LIST: case LYS_LIST:
@ -1888,12 +1978,12 @@ bool nb_operation_is_valid(enum nb_operation operation,
switch (snode->nodetype) { switch (snode->nodetype) {
case LYS_LEAF: case LYS_LEAF:
sleaf = (struct lys_node_leaf *)snode; sleaf = (struct lysc_node_leaf *)snode;
if (sleaf->type.base == LY_TYPE_EMPTY) if (sleaf->type->basetype == LY_TYPE_EMPTY)
return false; return false;
/* List keys can't be modified. */ /* List keys can't be modified. */
if (lys_is_key(sleaf, NULL)) if (lysc_is_key(sleaf))
return false; return false;
break; break;
default: default:
@ -1906,10 +1996,10 @@ bool nb_operation_is_valid(enum nb_operation operation,
switch (snode->nodetype) { switch (snode->nodetype) {
case LYS_LEAF: case LYS_LEAF:
sleaf = (struct lys_node_leaf *)snode; sleaf = (struct lysc_node_leaf *)snode;
/* List keys can't be deleted. */ /* List keys can't be deleted. */
if (lys_is_key(sleaf, NULL)) if (lysc_is_key(sleaf))
return false; return false;
/* /*
@ -1925,8 +2015,8 @@ bool nb_operation_is_valid(enum nb_operation operation,
return false; return false;
break; break;
case LYS_CONTAINER: case LYS_CONTAINER:
scontainer = (struct lys_node_container *)snode; scontainer = (struct lysc_node_container *)snode;
if (!scontainer->presence) if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE))
return false; return false;
break; break;
case LYS_LIST: case LYS_LIST:
@ -1943,7 +2033,7 @@ bool nb_operation_is_valid(enum nb_operation operation,
switch (snode->nodetype) { switch (snode->nodetype) {
case LYS_LIST: case LYS_LIST:
case LYS_LEAFLIST: case LYS_LEAFLIST:
if (!CHECK_FLAG(snode->flags, LYS_USERORDERED)) if (!CHECK_FLAG(snode->flags, LYS_ORDBY_USER))
return false; return false;
break; break;
default: default:
@ -1964,8 +2054,8 @@ bool nb_operation_is_valid(enum nb_operation operation,
case LYS_LEAFLIST: case LYS_LEAFLIST:
break; break;
case LYS_CONTAINER: case LYS_CONTAINER:
scontainer = (struct lys_node_container *)snode; scontainer = (struct lysc_node_container *)snode;
if (!scontainer->presence) if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE))
return false; return false;
break; break;
default: default:
@ -2114,7 +2204,7 @@ static void *nb_running_unset_entry_helper(const struct lyd_node *dnode)
/* Unset user pointers from the child nodes. */ /* Unset user pointers from the child nodes. */
if (CHECK_FLAG(dnode->schema->nodetype, LYS_LIST | LYS_CONTAINER)) { if (CHECK_FLAG(dnode->schema->nodetype, LYS_LIST | LYS_CONTAINER)) {
LY_TREE_FOR (dnode->child, child) { LY_LIST_FOR (lyd_child(dnode), child) {
(void)nb_running_unset_entry_helper(child); (void)nb_running_unset_entry_helper(child);
} }
} }
@ -2156,7 +2246,7 @@ static void *nb_running_get_entry_worker(const struct lyd_node *dnode,
rec_flag = rec_search; rec_flag = rec_search;
dnode = dnode->parent; dnode = lyd_parent(dnode);
} }
if (!abort_if_not_found) if (!abort_if_not_found)
@ -2312,27 +2402,42 @@ void nb_validate_callbacks(void)
} }
} }
void nb_load_module(const struct frr_yang_module_info *module_info)
{
struct yang_module *module;
DEBUGD(&nb_dbg_events, "northbound: loading %s.yang",
module_info->name);
module = yang_module_load(module_info->name);
yang_snodes_iterate(module->info, nb_node_new_cb, 0, NULL);
nb_load_callbacks(module_info);
}
void nb_init(struct thread_master *tm, void nb_init(struct thread_master *tm,
const struct frr_yang_module_info *const modules[], const struct frr_yang_module_info *const modules[],
size_t nmodules, bool db_enabled) size_t nmodules, bool db_enabled)
{ {
struct yang_module *loaded[nmodules], **loadedp = loaded;
bool explicit_compile;
/*
* Currently using this explicit compile feature in libyang2 leads to
* incorrect behavior in FRR. The functionality suppresses the compiling
* of modules until they have all been loaded into the context. This
* avoids multiple recompiles of the same modules as they are
* imported/augmented etc.
*/
explicit_compile = false;
nb_db_enabled = db_enabled; nb_db_enabled = db_enabled;
yang_init(true, explicit_compile);
/* Load YANG modules and their corresponding northbound callbacks. */ /* Load YANG modules and their corresponding northbound callbacks. */
for (size_t i = 0; i < nmodules; i++) for (size_t i = 0; i < nmodules; i++) {
nb_load_module(modules[i]); DEBUGD(&nb_dbg_events, "northbound: loading %s.yang",
modules[i]->name);
*loadedp++ = yang_module_load(modules[i]->name);
}
if (explicit_compile)
yang_init_loading_complete();
/* Initialize the compiled nodes with northbound data */
for (size_t i = 0; i < nmodules; i++) {
yang_snodes_iterate(loaded[i]->info, nb_node_new_cb, 0, NULL);
nb_load_callbacks(modules[i]);
}
/* Validate northbound callbacks. */ /* Validate northbound callbacks. */
nb_validate_callbacks(); nb_validate_callbacks();

View file

@ -537,7 +537,7 @@ struct nb_dependency_callbacks {
*/ */
struct nb_node { struct nb_node {
/* Back pointer to the libyang schema node. */ /* Back pointer to the libyang schema node. */
const struct lys_node *snode; const struct lysc_node *snode;
/* Data path of this YANG node. */ /* Data path of this YANG node. */
char xpath[XPATH_MAXLEN]; char xpath[XPATH_MAXLEN];
@ -685,7 +685,7 @@ struct nb_transaction {
}; };
/* Callback function used by nb_oper_data_iterate(). */ /* Callback function used by nb_oper_data_iterate(). */
typedef int (*nb_oper_data_cb)(const struct lys_node *snode, typedef int (*nb_oper_data_cb)(const struct lysc_node *snode,
struct yang_translator *translator, struct yang_translator *translator,
struct yang_data *data, void *arg); struct yang_data *data, void *arg);
@ -1114,7 +1114,7 @@ extern int nb_oper_data_iterate(const char *xpath,
* true if the operation is valid, false otherwise. * true if the operation is valid, false otherwise.
*/ */
extern bool nb_operation_is_valid(enum nb_operation operation, extern bool nb_operation_is_valid(enum nb_operation operation,
const struct lys_node *snode); const struct lysc_node *snode);
/* /*
* Send a YANG notification. This is a no-op unless the 'nb_notification_send' * Send a YANG notification. This is a no-op unless the 'nb_notification_send'
@ -1284,15 +1284,6 @@ extern const char *nb_client_name(enum nb_client client);
*/ */
void nb_validate_callbacks(void); void nb_validate_callbacks(void);
/*
* Load a YANG module with its corresponding northbound callbacks.
*
* module_info
* Pointer to structure containing the module name and its northbound
* callbacks.
*/
void nb_load_module(const struct frr_yang_module_info *module_info);
/* /*
* Initialize the northbound layer. Should be called only once during the * Initialize the northbound layer. Should be called only once during the
* daemon initialization process. * daemon initialization process.

View file

@ -448,6 +448,7 @@ static int nb_cli_candidate_load_file(struct vty *vty,
struct ly_ctx *ly_ctx; struct ly_ctx *ly_ctx;
int ly_format; int ly_format;
char buf[BUFSIZ]; char buf[BUFSIZ];
LY_ERR err;
switch (format) { switch (format) {
case NB_CFG_FMT_CMDS: case NB_CFG_FMT_CMDS:
@ -465,8 +466,10 @@ static int nb_cli_candidate_load_file(struct vty *vty,
ly_format = (format == NB_CFG_FMT_JSON) ? LYD_JSON : LYD_XML; ly_format = (format == NB_CFG_FMT_JSON) ? LYD_JSON : LYD_XML;
ly_ctx = translator ? translator->ly_ctx : ly_native_ctx; ly_ctx = translator ? translator->ly_ctx : ly_native_ctx;
dnode = lyd_parse_path(ly_ctx, path, ly_format, LYD_OPT_EDIT); err = lyd_parse_data_path(ly_ctx, path, ly_format,
if (!dnode) { LYD_PARSE_ONLY | LYD_PARSE_NO_STATE,
0, &dnode);
if (err || !dnode) {
flog_warn(EC_LIB_LIBYANG, "%s: lyd_parse_path() failed", flog_warn(EC_LIB_LIBYANG, "%s: lyd_parse_path() failed",
__func__); __func__);
vty_out(vty, "%% Failed to load configuration:\n\n"); vty_out(vty, "%% Failed to load configuration:\n\n");
@ -536,8 +539,6 @@ void nb_cli_show_config_prepare(struct nb_config *config, bool with_defaults)
if (config->dnode == NULL) if (config->dnode == NULL)
return; return;
lyd_schema_sort(config->dnode, 1);
/* /*
* Call lyd_validate() only to create default child nodes, ignoring * Call lyd_validate() only to create default child nodes, ignoring
* any possible validation error. This doesn't need to be done when * any possible validation error. This doesn't need to be done when
@ -545,9 +546,8 @@ void nb_cli_show_config_prepare(struct nb_config *config, bool with_defaults)
* validated. * validated.
*/ */
if (config != running_config) if (config != running_config)
(void)lyd_validate(&config->dnode, (void)lyd_validate_all(&config->dnode, ly_native_ctx,
LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL, LYD_VALIDATE_NO_STATE, NULL);
ly_native_ctx);
} }
static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root, static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root,
@ -559,7 +559,7 @@ static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root,
struct list *sort_list; struct list *sort_list;
void *data; void *data;
LY_TREE_FOR (root->child, child) { LY_LIST_FOR (lyd_child(root), child) {
nb_node = child->schema->priv; nb_node = child->schema->priv;
/* /*
@ -634,8 +634,9 @@ static void nb_cli_show_config_cmds(struct vty *vty, struct nb_config *config,
vty_out(vty, "frr version %s\n", FRR_VER_SHORT); vty_out(vty, "frr version %s\n", FRR_VER_SHORT);
vty_out(vty, "frr defaults %s\n", frr_defaults_profile()); vty_out(vty, "frr defaults %s\n", frr_defaults_profile());
LY_TREE_FOR (config->dnode, root) LY_LIST_FOR (config->dnode, root) {
nb_cli_show_dnode_cmds(vty, root, with_defaults); nb_cli_show_dnode_cmds(vty, root, with_defaults);
}
vty_out(vty, "!\n"); vty_out(vty, "!\n");
vty_out(vty, "end\n"); vty_out(vty, "end\n");
@ -660,11 +661,11 @@ static int nb_cli_show_config_libyang(struct vty *vty, LYD_FORMAT format,
return CMD_WARNING; return CMD_WARNING;
} }
SET_FLAG(options, LYP_FORMAT | LYP_WITHSIBLINGS); SET_FLAG(options, LYD_PRINT_WITHSIBLINGS);
if (with_defaults) if (with_defaults)
SET_FLAG(options, LYP_WD_ALL); SET_FLAG(options, LYD_PRINT_WD_ALL);
else else
SET_FLAG(options, LYP_WD_TRIM); SET_FLAG(options, LYD_PRINT_WD_TRIM);
if (lyd_print_mem(&strp, dnode, format, options) == 0 && strp) { if (lyd_print_mem(&strp, dnode, format, options) == 0 && strp) {
vty_out(vty, "%s", strp); vty_out(vty, "%s", strp);
@ -1401,7 +1402,7 @@ DEFPY (show_config_transaction,
#endif /* HAVE_CONFIG_ROLLBACKS */ #endif /* HAVE_CONFIG_ROLLBACKS */
} }
static int nb_cli_oper_data_cb(const struct lys_node *snode, static int nb_cli_oper_data_cb(const struct lysc_node *snode,
struct yang_translator *translator, struct yang_translator *translator,
struct yang_data *data, void *arg) struct yang_data *data, void *arg)
{ {
@ -1427,12 +1428,12 @@ static int nb_cli_oper_data_cb(const struct lys_node *snode,
} else } else
ly_ctx = ly_native_ctx; ly_ctx = ly_native_ctx;
ly_errno = 0; LY_ERR err =
dnode = lyd_new_path(dnode, ly_ctx, data->xpath, (void *)data->value, 0, lyd_new_path(dnode, ly_ctx, data->xpath, (void *)data->value,
LYD_PATH_OPT_UPDATE); LYD_NEW_PATH_UPDATE, &dnode);
if (!dnode && ly_errno) { if (err) {
flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path() failed", flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path(%s) failed: %s",
__func__); __func__, data->xpath, ly_errmsg(ly_native_ctx));
goto error; goto error;
} }
@ -1494,11 +1495,11 @@ DEFPY (show_yang_operational_data,
yang_dnode_free(dnode); yang_dnode_free(dnode);
return CMD_WARNING; return CMD_WARNING;
} }
lyd_validate(&dnode, LYD_OPT_GET, ly_ctx); (void)lyd_validate_all(&dnode, ly_ctx, 0, NULL);
/* Display the data. */ /* Display the data. */
if (lyd_print_mem(&strp, dnode, format, if (lyd_print_mem(&strp, dnode, format,
LYP_FORMAT | LYP_WITHSIBLINGS | LYP_WD_ALL) LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL)
!= 0 != 0
|| !strp) { || !strp) {
vty_out(vty, "%% Failed to display operational data.\n"); vty_out(vty, "%% Failed to display operational data.\n");
@ -1551,13 +1552,12 @@ DEFPY (show_yang_module,
snprintf(flags, sizeof(flags), "%c%c", snprintf(flags, sizeof(flags), "%c%c",
module->implemented ? 'I' : ' ', module->implemented ? 'I' : ' ',
(module->deviated == 1) ? 'D' : ' '); LY_ARRAY_COUNT(module->deviated_by) ? 'D' : ' ');
ttable_add_row(tt, "%s|%s|%s|%s|%s", module->name, ttable_add_row(tt, "%s|%s|%s|%s|%s", module->name,
(module->version == 2) ? "1.1" : "1.0", (module->parsed->version == 2) ? "1.1" : "1.0",
(module->rev_size > 0) ? module->rev[0].date module->revision ? module->revision : "-", flags,
: "-", module->ns);
flags, module->ns);
} }
/* Dump the generated table. */ /* Dump the generated table. */
@ -1577,21 +1577,21 @@ DEFPY (show_yang_module,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFPY (show_yang_module_detail, DEFPY(show_yang_module_detail, show_yang_module_detail_cmd,
show_yang_module_detail_cmd, "show yang module\
"show yang module\
[module-translator WORD$translator_family]\ [module-translator WORD$translator_family]\
WORD$module_name <summary|tree$tree|yang$yang|yin$yin>", WORD$module_name <compiled$compiled|summary|tree$tree|yang$yang|yin$yin>",
SHOW_STR SHOW_STR
"YANG information\n" "YANG information\n"
"Show loaded modules\n" "Show loaded modules\n"
"YANG module translator\n" "YANG module translator\n"
"YANG module translator\n" "YANG module translator\n"
"Module name\n" "Module name\n"
"Display summary information about the module\n" "Display compiled module in YANG format\n"
"Display module in the tree (RFC 8340) format\n" "Display summary information about the module\n"
"Display module in the YANG format\n" "Display module in the tree (RFC 8340) format\n"
"Display module in the YIN format\n") "Display module in the YANG format\n"
"Display module in the YIN format\n")
{ {
struct ly_ctx *ly_ctx; struct ly_ctx *ly_ctx;
struct yang_translator *translator = NULL; struct yang_translator *translator = NULL;
@ -1610,7 +1610,7 @@ DEFPY (show_yang_module_detail,
} else } else
ly_ctx = ly_native_ctx; ly_ctx = ly_native_ctx;
module = ly_ctx_get_module(ly_ctx, module_name, NULL, 0); module = ly_ctx_get_module_latest(ly_ctx, module_name);
if (!module) { if (!module) {
vty_out(vty, "%% Module \"%s\" not found\n", module_name); vty_out(vty, "%% Module \"%s\" not found\n", module_name);
return CMD_WARNING; return CMD_WARNING;
@ -1620,12 +1620,17 @@ DEFPY (show_yang_module_detail,
format = LYS_OUT_YANG; format = LYS_OUT_YANG;
else if (yin) else if (yin)
format = LYS_OUT_YIN; format = LYS_OUT_YIN;
else if (compiled)
format = LYS_OUT_YANG_COMPILED;
else if (tree) else if (tree)
format = LYS_OUT_TREE; format = LYS_OUT_TREE;
else else {
format = LYS_OUT_INFO; vty_out(vty,
"%% libyang v2 does not currently support summary\n");
return CMD_WARNING;
}
if (lys_print_mem(&strp, module, format, NULL, 0, 0) == 0) { if (lys_print_mem(&strp, module, format, 0) == 0) {
vty_out(vty, "%s\n", strp); vty_out(vty, "%s\n", strp);
free(strp); free(strp);
} else { } else {

View file

@ -515,7 +515,7 @@ static int frr_confd_init_cdb(void)
/* Subscribe to all loaded YANG data modules. */ /* Subscribe to all loaded YANG data modules. */
confd_spoints = list_new(); confd_spoints = list_new();
RB_FOREACH (module, yang_modules, &yang_modules) { RB_FOREACH (module, yang_modules, &yang_modules) {
struct lys_node *snode; struct lysc_node *snode;
module->confd_hash = confd_str2hash(module->info->ns); module->confd_hash = confd_str2hash(module->info->ns);
if (module->confd_hash == 0) { if (module->confd_hash == 0) {
@ -531,7 +531,7 @@ static int frr_confd_init_cdb(void)
* entire YANG module. So we have to find the top level * entire YANG module. So we have to find the top level
* nodes ourselves and subscribe to their paths. * nodes ourselves and subscribe to their paths.
*/ */
LY_TREE_FOR (module->info->data, snode) { LY_LIST_FOR (module->info->data, snode) {
struct nb_node *nb_node; struct nb_node *nb_node;
int *spoint; int *spoint;
int ret; int ret;
@ -762,7 +762,7 @@ static int frr_confd_data_get_object(struct confd_trans_ctx *tctx,
confd_hkeypath_t *kp) confd_hkeypath_t *kp)
{ {
struct nb_node *nb_node; struct nb_node *nb_node;
const struct lys_node *child; const struct lysc_node *child;
char xpath[XPATH_MAXLEN]; char xpath[XPATH_MAXLEN];
char xpath_child[XPATH_MAXLEN * 2]; char xpath_child[XPATH_MAXLEN * 2];
struct list *elements; struct list *elements;
@ -789,7 +789,7 @@ static int frr_confd_data_get_object(struct confd_trans_ctx *tctx,
elements = yang_data_list_new(); elements = yang_data_list_new();
/* Loop through list child nodes. */ /* Loop through list child nodes. */
LY_TREE_FOR (nb_node->snode->child, child) { LY_LIST_FOR (lysc_node_child(nb_node->snode), child) {
struct nb_node *nb_node_child = child->priv; struct nb_node *nb_node_child = child->priv;
confd_value_t *v; confd_value_t *v;
@ -869,7 +869,7 @@ static int frr_confd_data_get_next_object(struct confd_trans_ctx *tctx,
memset(objects, 0, sizeof(objects)); memset(objects, 0, sizeof(objects));
for (int j = 0; j < CONFD_OBJECTS_PER_TIME; j++) { for (int j = 0; j < CONFD_OBJECTS_PER_TIME; j++) {
struct confd_next_object *object; struct confd_next_object *object;
struct lys_node *child; struct lysc_node *child;
struct yang_data *data; struct yang_data *data;
size_t nvalues = 0; size_t nvalues = 0;
@ -919,7 +919,7 @@ static int frr_confd_data_get_next_object(struct confd_trans_ctx *tctx,
} }
/* Loop through list child nodes. */ /* Loop through list child nodes. */
LY_TREE_FOR (nb_node->snode->child, child) { LY_LIST_FOR (lysc_node_child(nb_node->snode), child) {
struct nb_node *nb_node_child = child->priv; struct nb_node *nb_node_child = child->priv;
char xpath_child[XPATH_MAXLEN * 2]; char xpath_child[XPATH_MAXLEN * 2];
confd_value_t *v; confd_value_t *v;
@ -1187,7 +1187,7 @@ static int frr_confd_dp_read(struct thread *thread)
return 0; return 0;
} }
static int frr_confd_subscribe_state(const struct lys_node *snode, void *arg) static int frr_confd_subscribe_state(const struct lysc_node *snode, void *arg)
{ {
struct nb_node *nb_node = snode->priv; struct nb_node *nb_node = snode->priv;
struct confd_data_cbs *data_cbs = arg; struct confd_data_cbs *data_cbs = arg;
@ -1391,7 +1391,7 @@ static void frr_confd_cli_init(void)
/* ------------ Main ------------ */ /* ------------ Main ------------ */
static int frr_confd_calculate_snode_hash(const struct lys_node *snode, static int frr_confd_calculate_snode_hash(const struct lysc_node *snode,
void *arg) void *arg)
{ {
struct nb_node *nb_node = snode->priv; struct nb_node *nb_node = snode->priv;

View file

@ -1109,7 +1109,7 @@ class NorthboundImpl
} }
} }
static int get_oper_data_cb(const struct lys_node *snode, static int get_oper_data_cb(const struct lysc_node *snode,
struct yang_translator *translator, struct yang_translator *translator,
struct yang_data *data, void *arg) struct yang_data *data, void *arg)
{ {

View file

@ -48,10 +48,10 @@ static int frr_sr_finish(void);
static int yang_data_frr2sr(struct yang_data *frr_data, sr_val_t *sr_data) static int yang_data_frr2sr(struct yang_data *frr_data, sr_val_t *sr_data)
{ {
struct nb_node *nb_node; struct nb_node *nb_node;
const struct lys_node *snode; const struct lysc_node *snode;
struct lys_node_container *scontainer; struct lysc_node_container *scontainer;
struct lys_node_leaf *sleaf; struct lysc_node_leaf *sleaf;
struct lys_node_leaflist *sleaflist; struct lysc_node_leaflist *sleaflist;
LY_DATA_TYPE type; LY_DATA_TYPE type;
sr_val_set_xpath(sr_data, frr_data->xpath); sr_val_set_xpath(sr_data, frr_data->xpath);
@ -67,8 +67,8 @@ static int yang_data_frr2sr(struct yang_data *frr_data, sr_val_t *sr_data)
snode = nb_node->snode; snode = nb_node->snode;
switch (snode->nodetype) { switch (snode->nodetype) {
case LYS_CONTAINER: case LYS_CONTAINER:
scontainer = (struct lys_node_container *)snode; scontainer = (struct lysc_node_container *)snode;
if (!scontainer->presence) if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE))
return -1; return -1;
sr_data->type = SR_CONTAINER_PRESENCE_T; sr_data->type = SR_CONTAINER_PRESENCE_T;
return 0; return 0;
@ -76,11 +76,11 @@ static int yang_data_frr2sr(struct yang_data *frr_data, sr_val_t *sr_data)
sr_data->type = SR_LIST_T; sr_data->type = SR_LIST_T;
return 0; return 0;
case LYS_LEAF: case LYS_LEAF:
sleaf = (struct lys_node_leaf *)snode; sleaf = (struct lysc_node_leaf *)snode;
type = sleaf->type.base; type = sleaf->type.base;
break; break;
case LYS_LEAFLIST: case LYS_LEAFLIST:
sleaflist = (struct lys_node_leaflist *)snode; sleaflist = (struct lysc_node_leaflist *)snode;
type = sleaflist->type.base; type = sleaflist->type.base;
break; break;
default: default:
@ -359,7 +359,7 @@ static int frr_sr_config_change_cb(sr_session_ctx_t *session,
} }
} }
static int frr_sr_state_data_iter_cb(const struct lys_node *snode, static int frr_sr_state_data_iter_cb(const struct lysc_node *snode,
struct yang_translator *translator, struct yang_translator *translator,
struct yang_data *data, void *arg) struct yang_data *data, void *arg)
{ {
@ -562,7 +562,7 @@ static void frr_sr_subscribe_config(struct yang_module *module)
sr_strerror(ret)); sr_strerror(ret));
} }
static int frr_sr_subscribe_state(const struct lys_node *snode, void *arg) static int frr_sr_subscribe_state(const struct lysc_node *snode, void *arg)
{ {
struct yang_module *module = arg; struct yang_module *module = arg;
struct nb_node *nb_node; struct nb_node *nb_node;
@ -591,7 +591,7 @@ static int frr_sr_subscribe_state(const struct lys_node *snode, void *arg)
return YANG_ITER_CONTINUE; return YANG_ITER_CONTINUE;
} }
static int frr_sr_subscribe_rpc(const struct lys_node *snode, void *arg) static int frr_sr_subscribe_rpc(const struct lysc_node *snode, void *arg)
{ {
struct yang_module *module = arg; struct yang_module *module = arg;
struct nb_node *nb_node; struct nb_node *nb_node;

View file

@ -1214,7 +1214,8 @@ const struct frr_yang_module_info frr_vrf_info = {
.get_next = lib_vrf_get_next, .get_next = lib_vrf_get_next,
.get_keys = lib_vrf_get_keys, .get_keys = lib_vrf_get_keys,
.lookup_entry = lib_vrf_lookup_entry, .lookup_entry = lib_vrf_lookup_entry,
} },
.priority = NB_DFLT_PRIORITY - 2,
}, },
{ {
.xpath = "/frr-vrf:lib/vrf/state/id", .xpath = "/frr-vrf:lib/vrf/state/id",

View file

@ -25,8 +25,6 @@
#include "yang_translator.h" #include "yang_translator.h"
#include "northbound.h" #include "northbound.h"
#include <libyang/user_types.h>
DEFINE_MTYPE_STATIC(LIB, YANG_MODULE, "YANG module"); DEFINE_MTYPE_STATIC(LIB, YANG_MODULE, "YANG module");
DEFINE_MTYPE_STATIC(LIB, YANG_DATA, "YANG data structure"); DEFINE_MTYPE_STATIC(LIB, YANG_DATA, "YANG data structure");
@ -42,14 +40,12 @@ void yang_module_embed(struct yang_module_embed *embed)
embedupd = &embed->next; embedupd = &embed->next;
} }
static const char *yang_module_imp_clb(const char *mod_name, static LY_ERR yang_module_imp_clb(const char *mod_name, const char *mod_rev,
const char *mod_rev, const char *submod_name,
const char *submod_name, const char *submod_rev, void *user_data,
const char *submod_rev, LYS_INFORMAT *format,
void *user_data, const char **module_data,
LYS_INFORMAT *format, void (**free_module_data)(void *, void *))
void (**free_module_data)
(void *, void*))
{ {
struct yang_module_embed *e; struct yang_module_embed *e;
@ -69,15 +65,17 @@ static const char *yang_module_imp_clb(const char *mod_name,
} }
*format = e->format; *format = e->format;
return e->data; *module_data = e->data;
return LY_SUCCESS;
} }
flog_warn( /* We get here for indirect modules like ietf-inet-types */
EC_LIB_YANG_MODULE_LOAD, zlog_debug(
"YANG model \"%s@%s\" \"%s@%s\"not embedded, trying external file", "YANG model \"%s@%s\" \"%s@%s\"not embedded, trying external file",
mod_name, mod_rev ? mod_rev : "*", mod_name, mod_rev ? mod_rev : "*",
submod_name ? submod_name : "*", submod_rev ? submod_rev : "*"); submod_name ? submod_name : "*", submod_rev ? submod_rev : "*");
return NULL;
return LY_ENOTFOUND;
} }
/* clang-format off */ /* clang-format off */
@ -111,7 +109,8 @@ struct yang_module *yang_module_load(const char *module_name)
struct yang_module *module; struct yang_module *module;
const struct lys_module *module_info; const struct lys_module *module_info;
module_info = ly_ctx_load_module(ly_native_ctx, module_name, NULL); module_info =
ly_ctx_load_module(ly_native_ctx, module_name, NULL, NULL);
if (!module_info) { if (!module_info) {
flog_err(EC_LIB_YANG_MODULE_LOAD, flog_err(EC_LIB_YANG_MODULE_LOAD,
"%s: failed to load data model: %s", __func__, "%s: failed to load data model: %s", __func__,
@ -147,62 +146,39 @@ struct yang_module *yang_module_find(const char *module_name)
return RB_FIND(yang_modules, &yang_modules, &s); return RB_FIND(yang_modules, &yang_modules, &s);
} }
int yang_snodes_iterate_subtree(const struct lys_node *snode, int yang_snodes_iterate_subtree(const struct lysc_node *snode,
const struct lys_module *module, const struct lys_module *module,
yang_iterate_cb cb, uint16_t flags, void *arg) yang_iterate_cb cb, uint16_t flags, void *arg)
{ {
struct lys_node *child; const struct lysc_node *child;
int ret = YANG_ITER_CONTINUE; int ret = YANG_ITER_CONTINUE;
if (module && snode->module != module) if (module && snode->module != module)
goto next; goto next;
if (CHECK_FLAG(flags, YANG_ITER_FILTER_IMPLICIT)) {
switch (snode->nodetype) {
case LYS_CASE:
case LYS_INPUT:
case LYS_OUTPUT:
if (CHECK_FLAG(snode->flags, LYS_IMPLICIT))
goto next;
break;
default:
break;
}
}
switch (snode->nodetype) { switch (snode->nodetype) {
case LYS_CONTAINER: case LYS_CONTAINER:
if (CHECK_FLAG(flags, YANG_ITER_FILTER_NPCONTAINERS)) { if (CHECK_FLAG(flags, YANG_ITER_FILTER_NPCONTAINERS)) {
struct lys_node_container *scontainer; if (!CHECK_FLAG(snode->flags, LYS_PRESENCE))
scontainer = (struct lys_node_container *)snode;
if (!scontainer->presence)
goto next; goto next;
} }
break; break;
case LYS_LEAF: case LYS_LEAF:
if (CHECK_FLAG(flags, YANG_ITER_FILTER_LIST_KEYS)) { if (CHECK_FLAG(flags, YANG_ITER_FILTER_LIST_KEYS)) {
struct lys_node_leaf *sleaf;
/* Ignore list keys. */ /* Ignore list keys. */
sleaf = (struct lys_node_leaf *)snode; if (lysc_is_key(snode))
if (lys_is_key(sleaf, NULL))
goto next; goto next;
} }
break; break;
case LYS_GROUPING:
/* Return since we're not interested in the grouping subtree. */
return YANG_ITER_CONTINUE;
case LYS_USES:
case LYS_AUGMENT:
/* Always ignore nodes of these types. */
goto next;
case LYS_INPUT: case LYS_INPUT:
case LYS_OUTPUT: case LYS_OUTPUT:
if (CHECK_FLAG(flags, YANG_ITER_FILTER_INPUT_OUTPUT)) if (CHECK_FLAG(flags, YANG_ITER_FILTER_INPUT_OUTPUT))
goto next; goto next;
break; break;
default: default:
assert(snode->nodetype != LYS_AUGMENT
&& snode->nodetype != LYS_GROUPING
&& snode->nodetype != LYS_USES);
break; break;
} }
@ -212,19 +188,17 @@ int yang_snodes_iterate_subtree(const struct lys_node *snode,
next: next:
/* /*
* YANG leafs and leaf-lists can't have child nodes, and trying to * YANG leafs and leaf-lists can't have child nodes.
* access snode->child is undefined behavior.
*/ */
if (CHECK_FLAG(snode->nodetype, LYS_LEAF | LYS_LEAFLIST)) if (CHECK_FLAG(snode->nodetype, LYS_LEAF | LYS_LEAFLIST))
return YANG_ITER_CONTINUE; return YANG_ITER_CONTINUE;
LY_TREE_FOR (snode->child, child) { LY_LIST_FOR (lysc_node_child(snode), child) {
ret = yang_snodes_iterate_subtree(child, module, cb, flags, ret = yang_snodes_iterate_subtree(child, module, cb, flags,
arg); arg);
if (ret == YANG_ITER_STOP) if (ret == YANG_ITER_STOP)
return ret; return ret;
} }
return ret; return ret;
} }
@ -237,12 +211,24 @@ int yang_snodes_iterate(const struct lys_module *module, yang_iterate_cb cb,
idx = ly_ctx_internal_modules_count(ly_native_ctx); idx = ly_ctx_internal_modules_count(ly_native_ctx);
while ((module_iter = ly_ctx_get_module_iter(ly_native_ctx, &idx))) { while ((module_iter = ly_ctx_get_module_iter(ly_native_ctx, &idx))) {
struct lys_node *snode; struct lysc_node *snode;
if (!module_iter->implemented) if (!module_iter->implemented)
continue; continue;
LY_TREE_FOR (module_iter->data, snode) { LY_LIST_FOR (module_iter->compiled->data, snode) {
ret = yang_snodes_iterate_subtree(snode, module, cb,
flags, arg);
if (ret == YANG_ITER_STOP)
return ret;
}
LY_LIST_FOR (&module_iter->compiled->rpcs->node, snode) {
ret = yang_snodes_iterate_subtree(snode, module, cb,
flags, arg);
if (ret == YANG_ITER_STOP)
return ret;
}
LY_LIST_FOR (&module_iter->compiled->notifs->node, snode) {
ret = yang_snodes_iterate_subtree(snode, module, cb, ret = yang_snodes_iterate_subtree(snode, module, cb,
flags, arg); flags, arg);
if (ret == YANG_ITER_STOP) if (ret == YANG_ITER_STOP)
@ -253,38 +239,32 @@ int yang_snodes_iterate(const struct lys_module *module, yang_iterate_cb cb,
return ret; return ret;
} }
void yang_snode_get_path(const struct lys_node *snode, enum yang_path_type type, void yang_snode_get_path(const struct lysc_node *snode,
char *xpath, size_t xpath_len) enum yang_path_type type, char *xpath,
size_t xpath_len)
{ {
char *xpath_ptr;
switch (type) { switch (type) {
case YANG_PATH_SCHEMA: case YANG_PATH_SCHEMA:
xpath_ptr = lys_path(snode, 0); (void)lysc_path(snode, LYSC_PATH_LOG, xpath, xpath_len);
break; break;
case YANG_PATH_DATA: case YANG_PATH_DATA:
xpath_ptr = lys_data_path(snode); (void)lysc_path(snode, LYSC_PATH_DATA, xpath, xpath_len);
break; break;
default: default:
flog_err(EC_LIB_DEVELOPMENT, "%s: unknown yang path type: %u", flog_err(EC_LIB_DEVELOPMENT, "%s: unknown yang path type: %u",
__func__, type); __func__, type);
exit(1); exit(1);
} }
strlcpy(xpath, xpath_ptr, xpath_len);
free(xpath_ptr);
} }
struct lys_node *yang_snode_real_parent(const struct lys_node *snode) struct lysc_node *yang_snode_real_parent(const struct lysc_node *snode)
{ {
struct lys_node *parent = snode->parent; struct lysc_node *parent = snode->parent;
while (parent) { while (parent) {
struct lys_node_container *scontainer;
switch (parent->nodetype) { switch (parent->nodetype) {
case LYS_CONTAINER: case LYS_CONTAINER:
scontainer = (struct lys_node_container *)parent; if (CHECK_FLAG(parent->flags, LYS_PRESENCE))
if (scontainer->presence)
return parent; return parent;
break; break;
case LYS_LIST: case LYS_LIST:
@ -298,9 +278,9 @@ struct lys_node *yang_snode_real_parent(const struct lys_node *snode)
return NULL; return NULL;
} }
struct lys_node *yang_snode_parent_list(const struct lys_node *snode) struct lysc_node *yang_snode_parent_list(const struct lysc_node *snode)
{ {
struct lys_node *parent = snode->parent; struct lysc_node *parent = snode->parent;
while (parent) { while (parent) {
switch (parent->nodetype) { switch (parent->nodetype) {
@ -315,14 +295,14 @@ struct lys_node *yang_snode_parent_list(const struct lys_node *snode)
return NULL; return NULL;
} }
bool yang_snode_is_typeless_data(const struct lys_node *snode) bool yang_snode_is_typeless_data(const struct lysc_node *snode)
{ {
struct lys_node_leaf *sleaf; const struct lysc_node_leaf *sleaf;
switch (snode->nodetype) { switch (snode->nodetype) {
case LYS_LEAF: case LYS_LEAF:
sleaf = (struct lys_node_leaf *)snode; sleaf = (struct lysc_node_leaf *)snode;
if (sleaf->type.base == LY_TYPE_EMPTY) if (sleaf->type->basetype == LY_TYPE_EMPTY)
return true; return true;
return false; return false;
case LYS_LEAFLIST: case LYS_LEAFLIST:
@ -332,16 +312,16 @@ bool yang_snode_is_typeless_data(const struct lys_node *snode)
} }
} }
const char *yang_snode_get_default(const struct lys_node *snode) const char *yang_snode_get_default(const struct lysc_node *snode)
{ {
struct lys_node_leaf *sleaf; const struct lysc_node_leaf *sleaf;
switch (snode->nodetype) { switch (snode->nodetype) {
case LYS_LEAF: case LYS_LEAF:
sleaf = (struct lys_node_leaf *)snode; sleaf = (const struct lysc_node_leaf *)snode;
return sleaf->dflt ? lyd_value_get_canonical(sleaf->module->ctx,
/* NOTE: this might be null. */ sleaf->dflt)
return sleaf->dflt; : NULL;
case LYS_LEAFLIST: case LYS_LEAFLIST:
/* TODO: check leaf-list default values */ /* TODO: check leaf-list default values */
return NULL; return NULL;
@ -350,29 +330,40 @@ const char *yang_snode_get_default(const struct lys_node *snode)
} }
} }
const struct lys_type *yang_snode_get_type(const struct lys_node *snode) const struct lysc_type *yang_snode_get_type(const struct lysc_node *snode)
{ {
struct lys_node_leaf *sleaf = (struct lys_node_leaf *)snode; struct lysc_node_leaf *sleaf = (struct lysc_node_leaf *)snode;
struct lys_type *type; struct lysc_type *type;
if (!CHECK_FLAG(sleaf->nodetype, LYS_LEAF | LYS_LEAFLIST)) if (!CHECK_FLAG(sleaf->nodetype, LYS_LEAF | LYS_LEAFLIST))
return NULL; return NULL;
type = &sleaf->type; type = sleaf->type;
while (type->base == LY_TYPE_LEAFREF) while (type->basetype == LY_TYPE_LEAFREF)
type = &type->info.lref.target->type; type = ((struct lysc_type_leafref *)type)->realtype;
return type; return type;
} }
unsigned int yang_snode_num_keys(const struct lysc_node *snode)
{
const struct lysc_node_leaf *skey;
uint count = 0;
if (!CHECK_FLAG(snode->nodetype, LYS_LIST))
return 0;
/* Walk list of children */
LY_FOR_KEYS (snode, skey) {
count++;
}
return count;
}
void yang_dnode_get_path(const struct lyd_node *dnode, char *xpath, void yang_dnode_get_path(const struct lyd_node *dnode, char *xpath,
size_t xpath_len) size_t xpath_len)
{ {
char *xpath_ptr; lyd_path(dnode, LYD_PATH_STD, xpath, xpath_len);
xpath_ptr = lyd_path(dnode);
strlcpy(xpath, xpath_ptr, xpath_len);
free(xpath_ptr);
} }
const char *yang_dnode_get_schema_name(const struct lyd_node *dnode, const char *yang_dnode_get_schema_name(const struct lyd_node *dnode,
@ -398,55 +389,78 @@ const char *yang_dnode_get_schema_name(const struct lyd_node *dnode,
return dnode->schema->name; return dnode->schema->name;
} }
struct lyd_node *yang_dnode_get(const struct lyd_node *dnode, struct lyd_node *yang_dnode_get(const struct lyd_node *dnode, const char *xpath)
const char *xpath_fmt, ...)
{ {
va_list ap; struct ly_set *set = NULL;
char xpath[XPATH_MAXLEN];
struct ly_set *set;
struct lyd_node *dnode_ret = NULL; struct lyd_node *dnode_ret = NULL;
va_start(ap, xpath_fmt); /*
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap); * XXX a lot of the code uses this for style I guess. It shouldn't, as
va_end(ap); * it adds to the xpath parsing complexity in libyang.
*/
if (xpath[0] == '.' && xpath[1] == '/')
xpath += 2;
set = lyd_find_path(dnode, xpath); if (lyd_find_xpath(dnode, xpath, &set)) {
assert(set); assert(0); /* XXX replicates old libyang1 base code */
if (set->number == 0) goto exit;
}
if (set->count == 0)
goto exit; goto exit;
if (set->number > 1) { if (set->count > 1) {
flog_warn(EC_LIB_YANG_DNODE_NOT_FOUND, flog_warn(EC_LIB_YANG_DNODE_NOT_FOUND,
"%s: found %u elements (expected 0 or 1) [xpath %s]", "%s: found %u elements (expected 0 or 1) [xpath %s]",
__func__, set->number, xpath); __func__, set->count, xpath);
goto exit; goto exit;
} }
dnode_ret = set->set.d[0]; dnode_ret = set->dnodes[0];
exit: exit:
ly_set_free(set); ly_set_free(set, NULL);
return dnode_ret; return dnode_ret;
} }
bool yang_dnode_exists(const struct lyd_node *dnode, const char *xpath_fmt, ...) struct lyd_node *yang_dnode_getf(const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{ {
va_list ap; va_list ap;
char xpath[XPATH_MAXLEN]; char xpath[XPATH_MAXLEN];
struct ly_set *set;
bool found;
va_start(ap, xpath_fmt); va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap); vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap); va_end(ap);
set = lyd_find_path(dnode, xpath); return yang_dnode_get(dnode, xpath);
assert(set); }
found = (set->number > 0);
ly_set_free(set);
return found; bool yang_dnode_exists(const struct lyd_node *dnode, const char *xpath)
{
struct ly_set *set = NULL;
bool exists = false;
if (xpath[0] == '.' && xpath[1] == '/')
xpath += 2;
if (lyd_find_xpath(dnode, xpath, &set))
return false;
exists = set->count > 0;
ly_set_free(set, NULL);
return exists;
}
bool yang_dnode_existsf(const struct lyd_node *dnode, const char *xpath_fmt,
...)
{
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
return yang_dnode_exists(dnode, xpath);
} }
void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg, void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg,
@ -461,52 +475,42 @@ void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg,
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap); vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap); va_end(ap);
set = lyd_find_path(dnode, xpath); if (lyd_find_xpath(dnode, xpath, &set)) {
assert(set); assert(0); /* XXX libyang2: ly1 code asserted success */
for (unsigned int i = 0; i < set->number; i++) { return;
}
for (unsigned int i = 0; i < set->count; i++) {
int ret; int ret;
dnode = set->set.d[i]; ret = (*cb)(set->dnodes[i], arg);
ret = (*cb)(dnode, arg);
if (ret == YANG_ITER_STOP) if (ret == YANG_ITER_STOP)
break; break;
} }
ly_set_free(set); ly_set_free(set, NULL);
} }
bool yang_dnode_is_default(const struct lyd_node *dnode, const char *xpath_fmt, bool yang_dnode_is_default(const struct lyd_node *dnode, const char *xpath)
...)
{ {
struct lys_node *snode; const struct lysc_node *snode;
struct lys_node_leaf *sleaf; struct lysc_node_leaf *sleaf;
struct lys_node_container *scontainer;
if (xpath_fmt) {
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
if (xpath)
dnode = yang_dnode_get(dnode, xpath); dnode = yang_dnode_get(dnode, xpath);
}
assert(dnode); assert(dnode);
snode = dnode->schema; snode = dnode->schema;
switch (snode->nodetype) { switch (snode->nodetype) {
case LYS_LEAF: case LYS_LEAF:
sleaf = (struct lys_node_leaf *)snode; sleaf = (struct lysc_node_leaf *)snode;
if (sleaf->type.base == LY_TYPE_EMPTY) if (sleaf->type->basetype == LY_TYPE_EMPTY)
return false; return false;
return lyd_wd_default((struct lyd_node_leaf_list *)dnode); return lyd_is_default(dnode);
case LYS_LEAFLIST: case LYS_LEAFLIST:
/* TODO: check leaf-list default values */ /* TODO: check leaf-list default values */
return false; return false;
case LYS_CONTAINER: case LYS_CONTAINER:
scontainer = (struct lys_node_container *)snode; if (CHECK_FLAG(snode->flags, LYS_PRESENCE))
if (scontainer->presence)
return false; return false;
return true; return true;
default: default:
@ -514,24 +518,39 @@ bool yang_dnode_is_default(const struct lyd_node *dnode, const char *xpath_fmt,
} }
} }
bool yang_dnode_is_defaultf(const struct lyd_node *dnode, const char *xpath_fmt,
...)
{
if (!xpath_fmt)
return yang_dnode_is_default(dnode, NULL);
else {
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
return yang_dnode_is_default(dnode, xpath);
}
}
bool yang_dnode_is_default_recursive(const struct lyd_node *dnode) bool yang_dnode_is_default_recursive(const struct lyd_node *dnode)
{ {
struct lys_node *snode; struct lyd_node *root, *dnode_iter;
struct lyd_node *root, *next, *dnode_iter;
snode = dnode->schema;
if (CHECK_FLAG(snode->nodetype, LYS_LEAF | LYS_LEAFLIST))
return yang_dnode_is_default(dnode, NULL);
if (!yang_dnode_is_default(dnode, NULL)) if (!yang_dnode_is_default(dnode, NULL))
return false; return false;
LY_TREE_FOR (dnode->child, root) { if (CHECK_FLAG(dnode->schema->nodetype, LYS_LEAF | LYS_LEAFLIST))
LY_TREE_DFS_BEGIN (root, next, dnode_iter) { return true;
LY_LIST_FOR (lyd_child(dnode), root) {
LYD_TREE_DFS_BEGIN (root, dnode_iter) {
if (!yang_dnode_is_default(dnode_iter, NULL)) if (!yang_dnode_is_default(dnode_iter, NULL))
return false; return false;
LY_TREE_DFS_END(root, next, dnode_iter); LYD_TREE_DFS_END(root, dnode_iter);
} }
} }
@ -541,21 +560,15 @@ bool yang_dnode_is_default_recursive(const struct lyd_node *dnode)
void yang_dnode_change_leaf(struct lyd_node *dnode, const char *value) void yang_dnode_change_leaf(struct lyd_node *dnode, const char *value)
{ {
assert(dnode->schema->nodetype == LYS_LEAF); assert(dnode->schema->nodetype == LYS_LEAF);
lyd_change_leaf((struct lyd_node_leaf_list *)dnode, value); lyd_change_term(dnode, value);
} }
struct lyd_node *yang_dnode_new(struct ly_ctx *ly_ctx, bool config_only) struct lyd_node *yang_dnode_new(struct ly_ctx *ly_ctx, bool config_only)
{ {
struct lyd_node *dnode; struct lyd_node *dnode = NULL;
int options; int options = config_only ? LYD_VALIDATE_NO_STATE : 0;
if (config_only) if (lyd_validate_all(&dnode, ly_ctx, options, NULL) != 0) {
options = LYD_OPT_CONFIG;
else
options = LYD_OPT_DATA | LYD_OPT_DATA_NO_YANGLIB;
dnode = NULL;
if (lyd_validate(&dnode, options, ly_ctx) != 0) {
/* Should never happen. */ /* Should never happen. */
flog_err(EC_LIB_LIBYANG, "%s: lyd_validate() failed", __func__); flog_err(EC_LIB_LIBYANG, "%s: lyd_validate() failed", __func__);
exit(1); exit(1);
@ -566,14 +579,18 @@ struct lyd_node *yang_dnode_new(struct ly_ctx *ly_ctx, bool config_only)
struct lyd_node *yang_dnode_dup(const struct lyd_node *dnode) struct lyd_node *yang_dnode_dup(const struct lyd_node *dnode)
{ {
return lyd_dup_withsiblings(dnode, 1); struct lyd_node *dup = NULL;
LY_ERR err;
err = lyd_dup_siblings(dnode, NULL, LYD_DUP_RECURSIVE, &dup);
assert(!err);
return dup;
} }
void yang_dnode_free(struct lyd_node *dnode) void yang_dnode_free(struct lyd_node *dnode)
{ {
while (dnode->parent) while (dnode->parent)
dnode = dnode->parent; dnode = lyd_parent(dnode);
lyd_free_withsiblings(dnode); lyd_free_all(dnode);
} }
struct yang_data *yang_data_new(const char *xpath, const char *value) struct yang_data *yang_data_new(const char *xpath, const char *value)
@ -679,18 +696,19 @@ const char *yang_print_errors(struct ly_ctx *ly_ctx, char *buf, size_t buf_len)
void yang_debugging_set(bool enable) void yang_debugging_set(bool enable)
{ {
if (enable) { if (enable) {
ly_verb(LY_LLDBG); ly_log_level(LY_LLDBG);
ly_verb_dbg(0xFF); ly_log_dbg_groups(0xFF);
} else { } else {
ly_verb(LY_LLERR); ly_log_level(LY_LLERR);
ly_verb_dbg(0); ly_log_dbg_groups(0);
} }
} }
struct ly_ctx *yang_ctx_new_setup(bool embedded_modules) struct ly_ctx *yang_ctx_new_setup(bool embedded_modules, bool explicit_compile)
{ {
struct ly_ctx *ctx; struct ly_ctx *ctx = NULL;
const char *yang_models_path = YANG_MODELS_PATH; const char *yang_models_path = YANG_MODELS_PATH;
LY_ERR err;
if (access(yang_models_path, R_OK | X_OK)) { if (access(yang_models_path, R_OK | X_OK)) {
yang_models_path = NULL; yang_models_path = NULL;
@ -703,8 +721,11 @@ struct ly_ctx *yang_ctx_new_setup(bool embedded_modules)
YANG_MODELS_PATH); YANG_MODELS_PATH);
} }
ctx = ly_ctx_new(yang_models_path, LY_CTX_DISABLE_SEARCHDIR_CWD); uint options = LY_CTX_NO_YANGLIBRARY | LY_CTX_DISABLE_SEARCHDIR_CWD;
if (!ctx) if (explicit_compile)
options |= LY_CTX_EXPLICIT_COMPILE;
err = ly_ctx_new(yang_models_path, options, &ctx);
if (err)
return NULL; return NULL;
if (embedded_modules) if (embedded_modules)
@ -713,14 +734,14 @@ struct ly_ctx *yang_ctx_new_setup(bool embedded_modules)
return ctx; return ctx;
} }
void yang_init(bool embedded_modules) void yang_init(bool embedded_modules, bool defer_compile)
{ {
/* Initialize libyang global parameters that affect all containers. */ /* Initialize libyang global parameters that affect all containers. */
ly_set_log_clb(ly_log_cb, 1); ly_set_log_clb(ly_log_cb, 1);
ly_log_options(LY_LOLOG | LY_LOSTORE); ly_log_options(LY_LOLOG | LY_LOSTORE);
/* Initialize libyang container for native models. */ /* Initialize libyang container for native models. */
ly_native_ctx = yang_ctx_new_setup(embedded_modules); ly_native_ctx = yang_ctx_new_setup(embedded_modules, defer_compile);
if (!ly_native_ctx) { if (!ly_native_ctx) {
flog_err(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__); flog_err(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__);
exit(1); exit(1);
@ -729,6 +750,17 @@ void yang_init(bool embedded_modules)
yang_translator_init(); yang_translator_init();
} }
void yang_init_loading_complete(void)
{
/* Compile everything */
if (ly_ctx_compile(ly_native_ctx) != LY_SUCCESS) {
flog_err(EC_LIB_YANG_MODULE_LOAD,
"%s: failed to compile loaded modules: %s", __func__,
ly_errmsg(ly_native_ctx));
exit(1);
}
}
void yang_terminate(void) void yang_terminate(void)
{ {
struct yang_module *module; struct yang_module *module;
@ -748,7 +780,7 @@ void yang_terminate(void)
XFREE(MTYPE_YANG_MODULE, module); XFREE(MTYPE_YANG_MODULE, module);
} }
ly_ctx_destroy(ly_native_ctx, NULL); ly_ctx_destroy(ly_native_ctx);
} }
const struct lyd_node *yang_dnode_get_parent(const struct lyd_node *dnode, const struct lyd_node *yang_dnode_get_parent(const struct lyd_node *dnode,
@ -767,7 +799,7 @@ const struct lyd_node *yang_dnode_get_parent(const struct lyd_node *dnode,
break; break;
} }
orig_dnode = orig_dnode->parent; orig_dnode = lyd_parent(orig_dnode);
} }
return NULL; return NULL;
@ -788,17 +820,17 @@ bool yang_is_last_list_dnode(const struct lyd_node *dnode)
bool yang_is_last_level_dnode(const struct lyd_node *dnode) bool yang_is_last_level_dnode(const struct lyd_node *dnode)
{ {
const struct lyd_node *parent; const struct lyd_node *parent;
const struct lys_node_list *snode;
const struct lyd_node *key_leaf; const struct lyd_node *key_leaf;
uint8_t keys_size; uint8_t keys_size;
switch (dnode->schema->nodetype) { switch (dnode->schema->nodetype) {
case LYS_LIST: case LYS_LIST:
assert(dnode->parent); assert(dnode->parent);
parent = dnode->parent; parent = lyd_parent(dnode);
snode = (struct lys_node_list *)parent->schema; uint snode_num_keys = yang_snode_num_keys(parent->schema);
/* XXX libyang2: q: really don't understand this code. */
key_leaf = dnode->prev; key_leaf = dnode->prev;
for (keys_size = 1; keys_size < snode->keys_size; keys_size++) for (keys_size = 1; keys_size < snode_num_keys; keys_size++)
key_leaf = key_leaf->prev; key_leaf = key_leaf->prev;
if (key_leaf->prev == dnode) if (key_leaf->prev == dnode)
return true; return true;
@ -812,13 +844,11 @@ bool yang_is_last_level_dnode(const struct lyd_node *dnode)
return false; return false;
} }
const struct lyd_node * const struct lyd_node *
yang_get_subtree_with_no_sibling(const struct lyd_node *dnode) yang_get_subtree_with_no_sibling(const struct lyd_node *dnode)
{ {
bool parent = true; bool parent = true;
const struct lyd_node *node; const struct lyd_node *node;
const struct lys_node_container *snode;
node = dnode; node = dnode;
if (node->schema->nodetype != LYS_LIST) if (node->schema->nodetype != LYS_LIST)
@ -827,13 +857,11 @@ yang_get_subtree_with_no_sibling(const struct lyd_node *dnode)
while (parent) { while (parent) {
switch (node->schema->nodetype) { switch (node->schema->nodetype) {
case LYS_CONTAINER: case LYS_CONTAINER:
snode = (struct lys_node_container *)node->schema; if (!CHECK_FLAG(node->schema->flags, LYS_PRESENCE)) {
if ((!snode->presence)
&& yang_is_last_level_dnode(node)) {
if (node->parent if (node->parent
&& (node->parent->schema->module && (node->parent->schema->module
== dnode->schema->module)) == dnode->schema->module))
node = node->parent; node = lyd_parent(node);
else else
parent = false; parent = false;
} else } else
@ -845,7 +873,7 @@ yang_get_subtree_with_no_sibling(const struct lyd_node *dnode)
if (node->parent if (node->parent
&& (node->parent->schema->module && (node->parent->schema->module
== dnode->schema->module)) == dnode->schema->module))
node = node->parent; node = lyd_parent(node);
else else
parent = false; parent = false;
} else } else
@ -867,7 +895,7 @@ uint32_t yang_get_list_pos(const struct lyd_node *node)
uint32_t yang_get_list_elements_count(const struct lyd_node *node) uint32_t yang_get_list_elements_count(const struct lyd_node *node)
{ {
unsigned int count; unsigned int count;
struct lys_node *schema; const struct lysc_node *schema;
if (!node if (!node
|| ((node->schema->nodetype != LYS_LIST) || ((node->schema->nodetype != LYS_LIST)
@ -884,11 +912,3 @@ uint32_t yang_get_list_elements_count(const struct lyd_node *node)
} while (node); } while (node);
return count; return count;
} }
const struct lyd_node *yang_dnode_get_child(const struct lyd_node *dnode)
{
if (dnode)
return dnode->child;
return NULL;
}

View file

@ -99,13 +99,10 @@ enum yang_iter_flags {
/* Filter RPC input/output nodes. */ /* Filter RPC input/output nodes. */
YANG_ITER_FILTER_INPUT_OUTPUT = (1<<2), YANG_ITER_FILTER_INPUT_OUTPUT = (1<<2),
/* Filter implicitely created nodes. */
YANG_ITER_FILTER_IMPLICIT = (1<<3),
}; };
/* Callback used by the yang_snodes_iterate_*() family of functions. */ /* Callback used by the yang_snodes_iterate_*() family of functions. */
typedef int (*yang_iterate_cb)(const struct lys_node *snode, void *arg); typedef int (*yang_iterate_cb)(const struct lysc_node *snode, void *arg);
/* Callback used by the yang_dnode_iterate() function. */ /* Callback used by the yang_dnode_iterate() function. */
typedef int (*yang_dnode_iter_cb)(const struct lyd_node *dnode, void *arg); typedef int (*yang_dnode_iter_cb)(const struct lyd_node *dnode, void *arg);
@ -180,7 +177,7 @@ extern void yang_module_embed(struct yang_module_embed *embed);
* Returns: * Returns:
* The return value of the last called callback. * The return value of the last called callback.
*/ */
extern int yang_snodes_iterate_subtree(const struct lys_node *snode, extern int yang_snodes_iterate_subtree(const struct lysc_node *snode,
const struct lys_module *module, const struct lys_module *module,
yang_iterate_cb cb, uint16_t flags, yang_iterate_cb cb, uint16_t flags,
void *arg); void *arg);
@ -222,7 +219,7 @@ extern int yang_snodes_iterate(const struct lys_module *module,
* xpath_len * xpath_len
* Size of the xpath buffer. * Size of the xpath buffer.
*/ */
extern void yang_snode_get_path(const struct lys_node *snode, extern void yang_snode_get_path(const struct lysc_node *snode,
enum yang_path_type type, char *xpath, enum yang_path_type type, char *xpath,
size_t xpath_len); size_t xpath_len);
@ -236,7 +233,7 @@ extern void yang_snode_get_path(const struct lys_node *snode,
* Returns: * Returns:
* The parent libyang schema node if found, or NULL if not found. * The parent libyang schema node if found, or NULL if not found.
*/ */
extern struct lys_node *yang_snode_real_parent(const struct lys_node *snode); extern struct lysc_node *yang_snode_real_parent(const struct lysc_node *snode);
/* /*
* Find first parent schema node which is a list. * Find first parent schema node which is a list.
@ -247,7 +244,7 @@ extern struct lys_node *yang_snode_real_parent(const struct lys_node *snode);
* Returns: * Returns:
* The parent libyang schema node (list) if found, or NULL if not found. * The parent libyang schema node (list) if found, or NULL if not found.
*/ */
extern struct lys_node *yang_snode_parent_list(const struct lys_node *snode); extern struct lysc_node *yang_snode_parent_list(const struct lysc_node *snode);
/* /*
* Check if the libyang schema node represents typeless data (e.g. containers, * Check if the libyang schema node represents typeless data (e.g. containers,
@ -259,7 +256,7 @@ extern struct lys_node *yang_snode_parent_list(const struct lys_node *snode);
* Returns: * Returns:
* true if the schema node represents typeless data, false otherwise. * true if the schema node represents typeless data, false otherwise.
*/ */
extern bool yang_snode_is_typeless_data(const struct lys_node *snode); extern bool yang_snode_is_typeless_data(const struct lysc_node *snode);
/* /*
* Get the default value associated to a YANG leaf or leaf-list. * Get the default value associated to a YANG leaf or leaf-list.
@ -270,7 +267,7 @@ extern bool yang_snode_is_typeless_data(const struct lys_node *snode);
* Returns: * Returns:
* The default value if it exists, NULL otherwise. * The default value if it exists, NULL otherwise.
*/ */
extern const char *yang_snode_get_default(const struct lys_node *snode); extern const char *yang_snode_get_default(const struct lysc_node *snode);
/* /*
* Get the type structure of a leaf of leaf-list. If the type is a leafref, the * Get the type structure of a leaf of leaf-list. If the type is a leafref, the
@ -283,7 +280,27 @@ extern const char *yang_snode_get_default(const struct lys_node *snode);
* The found type if the schema node represents a leaf or a leaf-list, NULL * The found type if the schema node represents a leaf or a leaf-list, NULL
* otherwise. * otherwise.
*/ */
extern const struct lys_type *yang_snode_get_type(const struct lys_node *snode); extern const struct lysc_type *
yang_snode_get_type(const struct lysc_node *snode);
/*
* Get the number of key nodes for the given list.
*
* snode
* libyang (LYS_LIST) schema node to operate on.
*
* Returns:
* The number of key LYS_LEAFs as children of this list node.
*/
extern unsigned int yang_snode_num_keys(const struct lysc_node *snode);
#define LY_FOR_KEYS(snode, skey) \
for ((skey) = (const struct lysc_node_leaf *)lysc_node_child((snode)); \
(skey); (skey) = (const struct lysc_node_leaf *)((skey)->next)) \
if (!lysc_is_key(skey)) { \
break; \
} else
/* /*
* Build data path of the data node. * Build data path of the data node.
@ -322,14 +339,49 @@ extern const char *yang_dnode_get_schema_name(const struct lyd_node *dnode,
* dnode * dnode
* Base libyang data node to operate on. * Base libyang data node to operate on.
* *
* xpath_fmt * xpath
* XPath expression (absolute or relative). * Limited XPath (absolute or relative) string. See Path in libyang
* documentation for restrictions.
* *
* Returns: * Returns:
* The libyang data node if found, or NULL if not found. * The libyang data node if found, or NULL if not found.
*/ */
extern struct lyd_node *yang_dnode_get(const struct lyd_node *dnode, extern struct lyd_node *yang_dnode_get(const struct lyd_node *dnode,
const char *xpath_fmt, ...); const char *xpath);
/*
* Find a libyang data node by its YANG data path.
*
* dnode
* Base libyang data node to operate on.
*
* xpath_fmt
* Limited XPath (absolute or relative) format string. See Path in libyang
* documentation for restrictions.
*
* ...
* any parameters for xpath_fmt.
*
* Returns:
* The libyang data node if found, or NULL if not found.
*/
extern struct lyd_node *yang_dnode_getf(const struct lyd_node *dnode,
const char *path_fmt, ...);
/*
* Check if a libyang data node exists.
*
* dnode
* Base libyang data node to operate on.
*
* xpath
* Limited XPath (absolute or relative) string. See Path in libyang
* documentation for restrictions.
*
* Returns:
* true if a libyang data node was found, false otherwise.
*/
extern bool yang_dnode_exists(const struct lyd_node *dnode, const char *xpath);
/* /*
* Check if a libyang data node exists. * Check if a libyang data node exists.
@ -338,13 +390,17 @@ extern struct lyd_node *yang_dnode_get(const struct lyd_node *dnode,
* Base libyang data node to operate on. * Base libyang data node to operate on.
* *
* xpath_fmt * xpath_fmt
* XPath expression (absolute or relative). * Limited XPath (absolute or relative) format string. See Path in
* libyang documentation for restrictions.
*
* ...
* any parameters for xpath_fmt.
* *
* Returns: * Returns:
* true if the libyang data node was found, false otherwise. * true if a libyang data node was found, false otherwise.
*/ */
extern bool yang_dnode_exists(const struct lyd_node *dnode, extern bool yang_dnode_existsf(const struct lyd_node *dnode,
const char *xpath_fmt, ...); const char *xpath_fmt, ...);
/* /*
* Iterate over all libyang data nodes that satisfy an XPath query. * Iterate over all libyang data nodes that satisfy an XPath query.
@ -360,6 +416,9 @@ extern bool yang_dnode_exists(const struct lyd_node *dnode,
* *
* xpath_fmt * xpath_fmt
* XPath expression (absolute or relative). * XPath expression (absolute or relative).
*
* ...
* any parameters for xpath_fmt.
*/ */
void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg, void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg,
const struct lyd_node *dnode, const char *xpath_fmt, const struct lyd_node *dnode, const char *xpath_fmt,
@ -372,7 +431,7 @@ void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg,
* dnode * dnode
* Base libyang data node to operate on. * Base libyang data node to operate on.
* *
* xpath_fmt * xpath
* Optional XPath expression (absolute or relative) to specify a different * Optional XPath expression (absolute or relative) to specify a different
* data node to operate on in the same data tree. * data node to operate on in the same data tree.
* *
@ -380,7 +439,27 @@ void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg,
* true if the data node contains the default value, false otherwise. * true if the data node contains the default value, false otherwise.
*/ */
extern bool yang_dnode_is_default(const struct lyd_node *dnode, extern bool yang_dnode_is_default(const struct lyd_node *dnode,
const char *xpath_fmt, ...); const char *xpath);
/*
* Check if the libyang data node contains a default value. Non-presence
* containers are assumed to always contain a default value.
*
* dnode
* Base libyang data node to operate on.
*
* xpath
* Optional limited XPath (absolute or relative) format string. See Path in
* libyang documentation for restrictions.
*
* ...
* any parameters for xpath_fmt.
*
* Returns:
* true if the data node contains the default value, false otherwise.
*/
extern bool yang_dnode_is_defaultf(const struct lyd_node *dnode,
const char *xpath_fmt, ...);
/* /*
* Check if the libyang data node and all of its children contain default * Check if the libyang data node and all of its children contain default
@ -437,7 +516,8 @@ extern struct lyd_node *yang_dnode_dup(const struct lyd_node *dnode);
* Delete a libyang data node. * Delete a libyang data node.
* *
* dnode * dnode
* Pointer to the libyang data node that is going to be deleted. * Pointer to the libyang data node that is going to be deleted along with
* the entire tree it belongs to.
*/ */
extern void yang_dnode_free(struct lyd_node *dnode); extern void yang_dnode_free(struct lyd_node *dnode);
@ -493,8 +573,13 @@ extern struct yang_data *yang_data_list_find(const struct list *list,
* *
* embedded_modules * embedded_modules
* Specify whether libyang should attempt to look for embedded YANG modules. * Specify whether libyang should attempt to look for embedded YANG modules.
*
* explicit_compile
* True if the caller will later call ly_ctx_compile to compile all loaded
* modules at once.
*/ */
extern struct ly_ctx *yang_ctx_new_setup(bool embedded_modules); extern struct ly_ctx *yang_ctx_new_setup(bool embedded_modules,
bool explicit_compile);
/* /*
* Enable or disable libyang verbose debugging. * Enable or disable libyang verbose debugging.
@ -528,8 +613,16 @@ extern const char *yang_print_errors(struct ly_ctx *ly_ctx, char *buf,
* *
* embedded_modules * embedded_modules
* Specify whether libyang should attempt to look for embedded YANG modules. * Specify whether libyang should attempt to look for embedded YANG modules.
* defer_compile
* Hold off on compiling modules until yang_init_loading_complete is called.
*/ */
extern void yang_init(bool embedded_modules); extern void yang_init(bool embedded_modules, bool defer_compile);
/*
* Should be called after yang_init and all yang_module_load()s have been done,
* compiles all modules loaded into the yang context.
*/
extern void yang_init_loading_complete(void);
/* /*
* Finish the YANG subsystem gracefully. Should be called only when the daemon * Finish the YANG subsystem gracefully. Should be called only when the daemon
@ -583,10 +676,6 @@ extern uint32_t yang_get_list_pos(const struct lyd_node *node);
*/ */
extern uint32_t yang_get_list_elements_count(const struct lyd_node *node); extern uint32_t yang_get_list_elements_count(const struct lyd_node *node);
/* To get the immediate child of a dnode */
const struct lyd_node *yang_dnode_get_child(const struct lyd_node *dnode);
/* API to check if the given node is last node in the list */ /* API to check if the given node is last node in the list */
bool yang_is_last_list_dnode(const struct lyd_node *dnode); bool yang_is_last_list_dnode(const struct lyd_node *dnode);

View file

@ -93,7 +93,7 @@ yang_mapping_lookup(const struct yang_translator *translator, int dir,
} }
static void yang_mapping_add(struct yang_translator *translator, int dir, static void yang_mapping_add(struct yang_translator *translator, int dir,
const struct lys_node *snode, const struct lysc_node *snode,
const char *xpath_from_fmt, const char *xpath_from_fmt,
const char *xpath_to_fmt) const char *xpath_to_fmt)
{ {
@ -135,13 +135,15 @@ struct yang_translator *yang_translator_load(const char *path)
struct lyd_node *dnode; struct lyd_node *dnode;
struct ly_set *set; struct ly_set *set;
struct listnode *ln; struct listnode *ln;
LY_ERR err;
/* Load module translator (JSON file). */ /* Load module translator (JSON file). */
dnode = lyd_parse_path(ly_translator_ctx, path, LYD_JSON, err = lyd_parse_data_path(ly_translator_ctx, path, LYD_JSON,
LYD_OPT_CONFIG); LYD_PARSE_NO_STATE, LYD_VALIDATE_NO_STATE,
if (!dnode) { &dnode);
if (err) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD, flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: lyd_parse_path() failed", __func__); "%s: lyd_parse_path() failed: %d", __func__, err);
return NULL; return NULL;
} }
dnode = yang_dnode_get(dnode, dnode = yang_dnode_get(dnode,
@ -171,89 +173,94 @@ struct yang_translator *yang_translator_load(const char *path)
RB_INSERT(yang_translators, &yang_translators, translator); RB_INSERT(yang_translators, &yang_translators, translator);
/* Initialize the translator libyang context. */ /* Initialize the translator libyang context. */
translator->ly_ctx = yang_ctx_new_setup(false); translator->ly_ctx = yang_ctx_new_setup(false, false);
if (!translator->ly_ctx) { if (!translator->ly_ctx) {
flog_warn(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__); flog_warn(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__);
goto error; goto error;
} }
/* Load modules and deviations. */ /* Load modules */
set = lyd_find_path(dnode, "./module"); if (lyd_find_xpath(dnode, "./module", &set) != LY_SUCCESS)
assert(set); assert(0); /* XXX libyang2: old ly1 code asserted success */
for (size_t i = 0; i < set->number; i++) {
for (size_t i = 0; i < set->count; i++) {
const char *module_name; const char *module_name;
tmodule = tmodule =
XCALLOC(MTYPE_YANG_TRANSLATOR_MODULE, sizeof(*tmodule)); XCALLOC(MTYPE_YANG_TRANSLATOR_MODULE, sizeof(*tmodule));
module_name = yang_dnode_get_string(set->set.d[i], "./name"); module_name = yang_dnode_get_string(set->dnodes[i], "./name");
tmodule->module = ly_ctx_load_module(translator->ly_ctx, tmodule->module = ly_ctx_load_module(translator->ly_ctx,
module_name, NULL); module_name, NULL, NULL);
if (!tmodule->module) { if (!tmodule->module) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD, flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: failed to load module: %s", __func__, "%s: failed to load module: %s", __func__,
module_name); module_name);
ly_set_free(set); ly_set_free(set, NULL);
goto error; goto error;
} }
}
module_name = /* Count nodes in modules. */
yang_dnode_get_string(set->set.d[i], "./deviations"); for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) {
tmodule->deviations = ly_ctx_load_module(translator->ly_ctx, tmodule->nodes_before_deviations =
module_name, NULL); yang_module_nodes_count(tmodule->module);
}
/* Load the deviations and count nodes again */
for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) {
const char *module_name = tmodule->module->name;
tmodule->deviations = ly_ctx_load_module(
translator->ly_ctx, module_name, NULL, NULL);
if (!tmodule->deviations) { if (!tmodule->deviations) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD, flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: failed to load module: %s", __func__, "%s: failed to load module: %s", __func__,
module_name); module_name);
ly_set_free(set); ly_set_free(set, NULL);
goto error; goto error;
} }
lys_set_disabled(tmodule->deviations);
listnode_add(translator->modules, tmodule);
}
ly_set_free(set);
/* Calculate the coverage. */
for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) {
tmodule->nodes_before_deviations =
yang_module_nodes_count(tmodule->module);
lys_set_enabled(tmodule->deviations);
tmodule->nodes_after_deviations = tmodule->nodes_after_deviations =
yang_module_nodes_count(tmodule->module); yang_module_nodes_count(tmodule->module);
}
ly_set_free(set, NULL);
/* Calculate the coverage. */
for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) {
tmodule->coverage = ((double)tmodule->nodes_after_deviations tmodule->coverage = ((double)tmodule->nodes_after_deviations
/ (double)tmodule->nodes_before_deviations) / (double)tmodule->nodes_before_deviations)
* 100; * 100;
} }
/* Load mappings. */ /* Load mappings. */
set = lyd_find_path(dnode, "./module/mappings"); if (lyd_find_xpath(dnode, "./module/mappings", &set) != LY_SUCCESS)
assert(set); assert(0); /* XXX libyang2: old ly1 code asserted success */
for (size_t i = 0; i < set->number; i++) { for (size_t i = 0; i < set->count; i++) {
const char *xpath_custom, *xpath_native; const char *xpath_custom, *xpath_native;
const struct lys_node *snode_custom, *snode_native; const struct lysc_node *snode_custom, *snode_native;
xpath_custom = yang_dnode_get_string(set->set.d[i], "./custom"); xpath_custom =
snode_custom = ly_ctx_get_node(translator->ly_ctx, NULL, yang_dnode_get_string(set->dnodes[i], "./custom");
xpath_custom, 0);
snode_custom = lys_find_path(translator->ly_ctx, NULL,
xpath_custom, 0);
if (!snode_custom) { if (!snode_custom) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD, flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: unknown data path: %s", __func__, "%s: unknown data path: %s", __func__,
xpath_custom); xpath_custom);
ly_set_free(set); ly_set_free(set, NULL);
goto error; goto error;
} }
xpath_native = yang_dnode_get_string(set->set.d[i], "./native"); xpath_native =
yang_dnode_get_string(set->dnodes[i], "./native");
snode_native = snode_native =
ly_ctx_get_node(ly_native_ctx, NULL, xpath_native, 0); lys_find_path(ly_native_ctx, NULL, xpath_native, 0);
if (!snode_native) { if (!snode_native) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD, flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: unknown data path: %s", __func__, "%s: unknown data path: %s", __func__,
xpath_native); xpath_native);
ly_set_free(set); ly_set_free(set, NULL);
goto error; goto error;
} }
@ -262,7 +269,7 @@ struct yang_translator *yang_translator_load(const char *path)
yang_mapping_add(translator, YANG_TRANSLATE_FROM_NATIVE, yang_mapping_add(translator, YANG_TRANSLATE_FROM_NATIVE,
snode_native, xpath_native, xpath_custom); snode_native, xpath_native, xpath_custom);
} }
ly_set_free(set); ly_set_free(set, NULL);
/* Validate mappings. */ /* Validate mappings. */
if (yang_translator_validate(translator) != 0) if (yang_translator_validate(translator) != 0)
@ -290,7 +297,7 @@ void yang_translator_unload(struct yang_translator *translator)
hash_clean(translator->mappings[i], yang_mapping_hash_free); hash_clean(translator->mappings[i], yang_mapping_hash_free);
translator->modules->del = (void (*)(void *))yang_tmodule_delete; translator->modules->del = (void (*)(void *))yang_tmodule_delete;
list_delete(&translator->modules); list_delete(&translator->modules);
ly_ctx_destroy(translator->ly_ctx, NULL); ly_ctx_destroy(translator->ly_ctx);
RB_REMOVE(yang_translators, &yang_translators, translator); RB_REMOVE(yang_translators, &yang_translators, translator);
XFREE(MTYPE_YANG_TRANSLATOR, translator); XFREE(MTYPE_YANG_TRANSLATOR, translator);
} }
@ -308,7 +315,7 @@ yang_translate_xpath(const struct yang_translator *translator, int dir,
char *xpath, size_t xpath_len) char *xpath, size_t xpath_len)
{ {
struct ly_ctx *ly_ctx; struct ly_ctx *ly_ctx;
const struct lys_node *snode; const struct lysc_node *snode;
struct yang_mapping_node *mapping; struct yang_mapping_node *mapping;
char xpath_canonical[XPATH_MAXLEN]; char xpath_canonical[XPATH_MAXLEN];
char keys[4][LIST_MAXKEYLEN]; char keys[4][LIST_MAXKEYLEN];
@ -319,7 +326,7 @@ yang_translate_xpath(const struct yang_translator *translator, int dir,
else else
ly_ctx = ly_native_ctx; ly_ctx = ly_native_ctx;
snode = ly_ctx_get_node(ly_ctx, NULL, xpath, 0); snode = lys_find_path(ly_ctx, NULL, xpath, 0);
if (!snode) { if (!snode) {
flog_warn(EC_LIB_YANG_TRANSLATION_ERROR, flog_warn(EC_LIB_YANG_TRANSLATION_ERROR,
"%s: unknown data path: %s", __func__, xpath); "%s: unknown data path: %s", __func__, xpath);
@ -352,7 +359,7 @@ int yang_translate_dnode(const struct yang_translator *translator, int dir,
{ {
struct ly_ctx *ly_ctx; struct ly_ctx *ly_ctx;
struct lyd_node *new; struct lyd_node *new;
struct lyd_node *root, *next, *dnode_iter; struct lyd_node *root, *dnode_iter;
/* Create new libyang data node to hold the translated data. */ /* Create new libyang data node to hold the translated data. */
if (dir == YANG_TRANSLATE_TO_NATIVE) if (dir == YANG_TRANSLATE_TO_NATIVE)
@ -362,8 +369,8 @@ int yang_translate_dnode(const struct yang_translator *translator, int dir,
new = yang_dnode_new(ly_ctx, false); new = yang_dnode_new(ly_ctx, false);
/* Iterate over all nodes from the data tree. */ /* Iterate over all nodes from the data tree. */
LY_TREE_FOR (*dnode, root) { LY_LIST_FOR (*dnode, root) {
LY_TREE_DFS_BEGIN (root, next, dnode_iter) { LYD_TREE_DFS_BEGIN (root, dnode_iter) {
char xpath[XPATH_MAXLEN]; char xpath[XPATH_MAXLEN];
enum yang_translate_result ret; enum yang_translate_result ret;
@ -380,19 +387,17 @@ int yang_translate_dnode(const struct yang_translator *translator, int dir,
} }
/* Create new node in the tree of translated data. */ /* Create new node in the tree of translated data. */
ly_errno = 0; if (lyd_new_path(new, ly_ctx, xpath,
if (!lyd_new_path(new, ly_ctx, xpath, (void *)yang_dnode_get_string(
(void *)yang_dnode_get_string( dnode_iter, NULL),
dnode_iter, NULL), LYD_NEW_PATH_UPDATE, NULL)) {
0, LYD_PATH_OPT_UPDATE)
&& ly_errno) {
flog_err(EC_LIB_LIBYANG, flog_err(EC_LIB_LIBYANG,
"%s: lyd_new_path() failed", __func__); "%s: lyd_new_path() failed", __func__);
goto error; goto error;
} }
next: next:
LY_TREE_DFS_END(root, next, dnode_iter); LYD_TREE_DFS_END(root, dnode_iter);
} }
} }
@ -413,13 +418,13 @@ struct translator_validate_args {
unsigned int errors; unsigned int errors;
}; };
static int yang_translator_validate_cb(const struct lys_node *snode_custom, static int yang_translator_validate_cb(const struct lysc_node *snode_custom,
void *arg) void *arg)
{ {
struct translator_validate_args *args = arg; struct translator_validate_args *args = arg;
struct yang_mapping_node *mapping; struct yang_mapping_node *mapping;
const struct lys_node *snode_native; const struct lysc_node *snode_native;
const struct lys_type *stype_custom, *stype_native; const struct lysc_type *stype_custom, *stype_native;
char xpath[XPATH_MAXLEN]; char xpath[XPATH_MAXLEN];
yang_snode_get_path(snode_custom, YANG_PATH_DATA, xpath, sizeof(xpath)); yang_snode_get_path(snode_custom, YANG_PATH_DATA, xpath, sizeof(xpath));
@ -433,14 +438,14 @@ static int yang_translator_validate_cb(const struct lys_node *snode_custom,
} }
snode_native = snode_native =
ly_ctx_get_node(ly_native_ctx, NULL, mapping->xpath_to_fmt, 0); lys_find_path(ly_native_ctx, NULL, mapping->xpath_to_fmt, 0);
assert(snode_native); assert(snode_native);
/* Check if the YANG types are compatible. */ /* Check if the YANG types are compatible. */
stype_custom = yang_snode_get_type(snode_custom); stype_custom = yang_snode_get_type(snode_custom);
stype_native = yang_snode_get_type(snode_native); stype_native = yang_snode_get_type(snode_native);
if (stype_custom && stype_native) { if (stype_custom && stype_native) {
if (stype_custom->base != stype_native->base) { if (stype_custom->basetype != stype_native->basetype) {
flog_warn( flog_warn(
EC_LIB_YANG_TRANSLATOR_LOAD, EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: YANG types are incompatible (xpath: \"%s\")", "%s: YANG types are incompatible (xpath: \"%s\")",
@ -486,7 +491,7 @@ static unsigned int yang_translator_validate(struct yang_translator *translator)
return args.errors; return args.errors;
} }
static int yang_module_nodes_count_cb(const struct lys_node *snode, void *arg) static int yang_module_nodes_count_cb(const struct lysc_node *snode, void *arg)
{ {
unsigned int *total = arg; unsigned int *total = arg;
@ -511,14 +516,14 @@ static unsigned int yang_module_nodes_count(const struct lys_module *module)
void yang_translator_init(void) void yang_translator_init(void)
{ {
ly_translator_ctx = yang_ctx_new_setup(true); ly_translator_ctx = yang_ctx_new_setup(true, false);
if (!ly_translator_ctx) { if (!ly_translator_ctx) {
flog_err(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__); flog_err(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__);
exit(1); exit(1);
} }
if (!ly_ctx_load_module(ly_translator_ctx, "frr-module-translator", if (!ly_ctx_load_module(ly_translator_ctx, "frr-module-translator",
NULL)) { NULL, NULL)) {
flog_err( flog_err(
EC_LIB_YANG_MODULE_LOAD, EC_LIB_YANG_MODULE_LOAD,
"%s: failed to load the \"frr-module-translator\" module", "%s: failed to load the \"frr-module-translator\" module",
@ -536,5 +541,5 @@ void yang_translator_terminate(void)
yang_translator_unload(translator); yang_translator_unload(translator);
} }
ly_ctx_destroy(ly_translator_ctx, NULL); ly_ctx_destroy(ly_translator_ctx);
} }

View file

@ -26,12 +26,80 @@
#include "nexthop.h" #include "nexthop.h"
#include "printfrr.h" #include "printfrr.h"
#define YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt) \
({ \
va_list __ap; \
va_start(__ap, (xpath_fmt)); \
const struct lyd_value *__dvalue = \
yang_dnode_xpath_get_value(dnode, xpath_fmt, __ap); \
va_end(__ap); \
__dvalue; \
})
#define YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt) \
({ \
va_list __ap; \
va_start(__ap, (xpath_fmt)); \
const char *__canon = \
yang_dnode_xpath_get_canon(dnode, xpath_fmt, __ap); \
va_end(__ap); \
__canon; \
})
#define YANG_DNODE_GET_ASSERT(dnode, xpath) \
do { \
if ((dnode) == NULL) { \
flog_err(EC_LIB_YANG_DNODE_NOT_FOUND, \
"%s: couldn't find %s", __func__, (xpath)); \
zlog_backtrace(LOG_ERR); \
abort(); \
} \
} while (0)
static inline const char *
yang_dnode_xpath_get_canon(const struct lyd_node *dnode, const char *xpath_fmt,
va_list ap)
{
const struct lyd_node_term *__dleaf =
(const struct lyd_node_term *)dnode;
assert(__dleaf);
if (xpath_fmt) {
char __xpath[XPATH_MAXLEN];
vsnprintf(__xpath, sizeof(__xpath), xpath_fmt, ap);
__dleaf = (const struct lyd_node_term *)yang_dnode_get(dnode,
__xpath);
YANG_DNODE_GET_ASSERT(__dleaf, __xpath);
}
return lyd_get_value(&__dleaf->node);
}
static inline const struct lyd_value *
yang_dnode_xpath_get_value(const struct lyd_node *dnode, const char *xpath_fmt,
va_list ap)
{
const struct lyd_node_term *__dleaf =
(const struct lyd_node_term *)dnode;
assert(__dleaf);
if (xpath_fmt) {
char __xpath[XPATH_MAXLEN];
vsnprintf(__xpath, sizeof(__xpath), xpath_fmt, ap);
__dleaf = (const struct lyd_node_term *)yang_dnode_get(dnode,
__xpath);
YANG_DNODE_GET_ASSERT(__dleaf, __xpath);
}
const struct lyd_value *__dvalue = &__dleaf->value;
if (__dvalue->realtype->basetype == LY_TYPE_UNION)
__dvalue = &__dvalue->subvalue->value;
return __dvalue;
}
static const char *yang_get_default_value(const char *xpath) static const char *yang_get_default_value(const char *xpath)
{ {
const struct lys_node *snode; const struct lysc_node *snode;
const char *value; const char *value;
snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0); snode = lys_find_path(ly_native_ctx, NULL, xpath, 0);
if (snode == NULL) { if (snode == NULL) {
flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH, flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
"%s: unknown data path: %s", __func__, xpath); "%s: unknown data path: %s", __func__, xpath);
@ -45,16 +113,6 @@ static const char *yang_get_default_value(const char *xpath)
return value; return value;
} }
#define YANG_DNODE_GET_ASSERT(dnode, xpath) \
do { \
if ((dnode) == NULL) { \
flog_err(EC_LIB_YANG_DNODE_NOT_FOUND, \
"%s: couldn't find %s", __func__, (xpath)); \
zlog_backtrace(LOG_ERR); \
abort(); \
} \
} while (0)
/* /*
* Primitive type: bool. * Primitive type: bool.
*/ */
@ -71,23 +129,10 @@ struct yang_data *yang_data_new_bool(const char *xpath, bool value)
bool yang_dnode_get_bool(const struct lyd_node *dnode, const char *xpath_fmt, bool yang_dnode_get_bool(const struct lyd_node *dnode, const char *xpath_fmt,
...) ...)
{ {
const struct lyd_node_leaf_list *dleaf; const struct lyd_value *dvalue;
dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
assert(dnode); assert(dvalue->realtype->basetype == LY_TYPE_BOOL);
if (xpath_fmt) { return dvalue->boolean;
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_BOOL);
return dleaf->value.bln;
} }
bool yang_get_default_bool(const char *xpath_fmt, ...) bool yang_get_default_bool(const char *xpath_fmt, ...)
@ -133,24 +178,18 @@ struct yang_data *yang_data_new_dec64(const char *xpath, double value)
double yang_dnode_get_dec64(const struct lyd_node *dnode, const char *xpath_fmt, double yang_dnode_get_dec64(const struct lyd_node *dnode, const char *xpath_fmt,
...) ...)
{ {
const struct lyd_node_leaf_list *dleaf; const double denom[19] = {1e0, 1e-1, 1e-2, 1e-3, 1e-4,
1e-5, 1e-6, 1e-7, 1e-8, 1e-9,
1e-10, 1e-11, 1e-12, 1e-13, 1e-14,
1e-15, 1e-16, 1e-17, 1e-18};
const struct lysc_type_dec *dectype;
const struct lyd_value *dvalue;
assert(dnode); dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
if (xpath_fmt) { dectype = (const struct lysc_type_dec *)dvalue->realtype;
va_list ap; assert(dectype->basetype == LY_TYPE_DEC64);
char xpath[XPATH_MAXLEN]; assert(dectype->fraction_digits < sizeof(denom) / sizeof(*denom));
return (double)dvalue->dec64 * denom[dectype->fraction_digits];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_DEC64);
return lyd_dec64_to_double(dnode);
} }
double yang_get_default_dec64(const char *xpath_fmt, ...) double yang_get_default_dec64(const char *xpath_fmt, ...)
@ -172,12 +211,12 @@ double yang_get_default_dec64(const char *xpath_fmt, ...)
*/ */
int yang_str2enum(const char *xpath, const char *value) int yang_str2enum(const char *xpath, const char *value)
{ {
const struct lys_node *snode; const struct lysc_node *snode;
const struct lys_node_leaf *sleaf; const struct lysc_node_leaf *sleaf;
const struct lys_type *type; const struct lysc_type_enum *type;
const struct lys_type_info_enums *enums; const struct lysc_type_bitenum_item *enums;
snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0); snode = lys_find_path(ly_native_ctx, NULL, xpath, 0);
if (snode == NULL) { if (snode == NULL) {
flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH, flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
"%s: unknown data path: %s", __func__, xpath); "%s: unknown data path: %s", __func__, xpath);
@ -185,18 +224,17 @@ int yang_str2enum(const char *xpath, const char *value)
abort(); abort();
} }
sleaf = (const struct lys_node_leaf *)snode; assert(snode->nodetype == LYS_LEAF);
type = &sleaf->type; sleaf = (const struct lysc_node_leaf *)snode;
enums = &type->info.enums; type = (const struct lysc_type_enum *)sleaf->type;
while (enums->count == 0 && type->der) { assert(type->basetype == LY_TYPE_ENUM);
type = &type->der->type; enums = type->enums;
enums = &type->info.enums; unsigned int count = LY_ARRAY_COUNT(enums);
} for (unsigned int i = 0; i < count; i++) {
for (unsigned int i = 0; i < enums->count; i++) { if (strmatch(value, enums[i].name)) {
const struct lys_type_enum *enm = &enums->enm[i]; assert(CHECK_FLAG(enums[i].flags, LYS_SET_VALUE));
return enums[i].value;
if (strmatch(value, enm->name)) }
return enm->value;
} }
flog_err(EC_LIB_YANG_DATA_CONVERT, flog_err(EC_LIB_YANG_DATA_CONVERT,
@ -208,12 +246,12 @@ int yang_str2enum(const char *xpath, const char *value)
struct yang_data *yang_data_new_enum(const char *xpath, int value) struct yang_data *yang_data_new_enum(const char *xpath, int value)
{ {
const struct lys_node *snode; const struct lysc_node *snode;
const struct lys_node_leaf *sleaf; const struct lysc_node_leaf *sleaf;
const struct lys_type *type; const struct lysc_type_enum *type;
const struct lys_type_info_enums *enums; const struct lysc_type_bitenum_item *enums;
snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0); snode = lys_find_path(ly_native_ctx, NULL, xpath, 0);
if (snode == NULL) { if (snode == NULL) {
flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH, flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
"%s: unknown data path: %s", __func__, xpath); "%s: unknown data path: %s", __func__, xpath);
@ -221,18 +259,16 @@ struct yang_data *yang_data_new_enum(const char *xpath, int value)
abort(); abort();
} }
sleaf = (const struct lys_node_leaf *)snode; assert(snode->nodetype == LYS_LEAF);
type = &sleaf->type; sleaf = (const struct lysc_node_leaf *)snode;
enums = &type->info.enums; type = (const struct lysc_type_enum *)sleaf->type;
while (enums->count == 0 && type->der) { assert(type->basetype == LY_TYPE_ENUM);
type = &type->der->type; enums = type->enums;
enums = &type->info.enums; unsigned int count = LY_ARRAY_COUNT(enums);
} for (unsigned int i = 0; i < count; i++) {
for (unsigned int i = 0; i < enums->count; i++) { if (CHECK_FLAG(enums[i].flags, LYS_SET_VALUE)
const struct lys_type_enum *enm = &enums->enm[i]; && value == enums[i].value)
return yang_data_new(xpath, enums[i].name);
if (value == enm->value)
return yang_data_new(xpath, enm->name);
} }
flog_err(EC_LIB_YANG_DATA_CONVERT, flog_err(EC_LIB_YANG_DATA_CONVERT,
@ -245,23 +281,12 @@ struct yang_data *yang_data_new_enum(const char *xpath, int value)
int yang_dnode_get_enum(const struct lyd_node *dnode, const char *xpath_fmt, int yang_dnode_get_enum(const struct lyd_node *dnode, const char *xpath_fmt,
...) ...)
{ {
const struct lyd_node_leaf_list *dleaf; const struct lyd_value *dvalue;
assert(dnode); dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
if (xpath_fmt) { assert(dvalue->realtype->basetype == LY_TYPE_ENUM);
va_list ap; assert(dvalue->enum_item->flags & LYS_SET_VALUE);
char xpath[XPATH_MAXLEN]; return dvalue->enum_item->value;
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_ENUM);
return dleaf->value.enm->value;
} }
int yang_get_default_enum(const char *xpath_fmt, ...) int yang_get_default_enum(const char *xpath_fmt, ...)
@ -297,23 +322,10 @@ struct yang_data *yang_data_new_int8(const char *xpath, int8_t value)
int8_t yang_dnode_get_int8(const struct lyd_node *dnode, const char *xpath_fmt, int8_t yang_dnode_get_int8(const struct lyd_node *dnode, const char *xpath_fmt,
...) ...)
{ {
const struct lyd_node_leaf_list *dleaf; const struct lyd_value *dvalue;
dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
assert(dnode); assert(dvalue->realtype->basetype == LY_TYPE_INT8);
if (xpath_fmt) { return dvalue->int8;
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_INT8);
return dleaf->value.int8;
} }
int8_t yang_get_default_int8(const char *xpath_fmt, ...) int8_t yang_get_default_int8(const char *xpath_fmt, ...)
@ -349,23 +361,10 @@ struct yang_data *yang_data_new_int16(const char *xpath, int16_t value)
int16_t yang_dnode_get_int16(const struct lyd_node *dnode, int16_t yang_dnode_get_int16(const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; const struct lyd_value *dvalue;
dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
assert(dnode); assert(dvalue->realtype->basetype == LY_TYPE_INT16);
if (xpath_fmt) { return dvalue->int16;
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_INT16);
return dleaf->value.int16;
} }
int16_t yang_get_default_int16(const char *xpath_fmt, ...) int16_t yang_get_default_int16(const char *xpath_fmt, ...)
@ -401,23 +400,10 @@ struct yang_data *yang_data_new_int32(const char *xpath, int32_t value)
int32_t yang_dnode_get_int32(const struct lyd_node *dnode, int32_t yang_dnode_get_int32(const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; const struct lyd_value *dvalue;
dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
assert(dnode); assert(dvalue->realtype->basetype == LY_TYPE_INT32);
if (xpath_fmt) { return dvalue->int32;
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_INT32);
return dleaf->value.int32;
} }
int32_t yang_get_default_int32(const char *xpath_fmt, ...) int32_t yang_get_default_int32(const char *xpath_fmt, ...)
@ -453,23 +439,10 @@ struct yang_data *yang_data_new_int64(const char *xpath, int64_t value)
int64_t yang_dnode_get_int64(const struct lyd_node *dnode, int64_t yang_dnode_get_int64(const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; const struct lyd_value *dvalue;
dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
assert(dnode); assert(dvalue->realtype->basetype == LY_TYPE_INT64);
if (xpath_fmt) { return dvalue->int64;
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_INT64);
return dleaf->value.int64;
} }
int64_t yang_get_default_int64(const char *xpath_fmt, ...) int64_t yang_get_default_int64(const char *xpath_fmt, ...)
@ -505,23 +478,10 @@ struct yang_data *yang_data_new_uint8(const char *xpath, uint8_t value)
uint8_t yang_dnode_get_uint8(const struct lyd_node *dnode, uint8_t yang_dnode_get_uint8(const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; const struct lyd_value *dvalue;
dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
assert(dnode); assert(dvalue->realtype->basetype == LY_TYPE_UINT8);
if (xpath_fmt) { return dvalue->uint8;
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_UINT8);
return dleaf->value.uint8;
} }
uint8_t yang_get_default_uint8(const char *xpath_fmt, ...) uint8_t yang_get_default_uint8(const char *xpath_fmt, ...)
@ -557,23 +517,10 @@ struct yang_data *yang_data_new_uint16(const char *xpath, uint16_t value)
uint16_t yang_dnode_get_uint16(const struct lyd_node *dnode, uint16_t yang_dnode_get_uint16(const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; const struct lyd_value *dvalue;
dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
assert(dnode); assert(dvalue->realtype->basetype == LY_TYPE_UINT16);
if (xpath_fmt) { return dvalue->uint16;
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_UINT16);
return dleaf->value.uint16;
} }
uint16_t yang_get_default_uint16(const char *xpath_fmt, ...) uint16_t yang_get_default_uint16(const char *xpath_fmt, ...)
@ -609,23 +556,10 @@ struct yang_data *yang_data_new_uint32(const char *xpath, uint32_t value)
uint32_t yang_dnode_get_uint32(const struct lyd_node *dnode, uint32_t yang_dnode_get_uint32(const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; const struct lyd_value *dvalue;
dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
assert(dnode); assert(dvalue->realtype->basetype == LY_TYPE_UINT32);
if (xpath_fmt) { return dvalue->uint32;
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_UINT32);
return dleaf->value.uint32;
} }
uint32_t yang_get_default_uint32(const char *xpath_fmt, ...) uint32_t yang_get_default_uint32(const char *xpath_fmt, ...)
@ -661,23 +595,10 @@ struct yang_data *yang_data_new_uint64(const char *xpath, uint64_t value)
uint64_t yang_dnode_get_uint64(const struct lyd_node *dnode, uint64_t yang_dnode_get_uint64(const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; const struct lyd_value *dvalue;
dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
assert(dnode); assert(dvalue->realtype->basetype == LY_TYPE_UINT64);
if (xpath_fmt) { return dvalue->uint64;
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_UINT64);
return dleaf->value.uint64;
} }
uint64_t yang_get_default_uint64(const char *xpath_fmt, ...) uint64_t yang_get_default_uint64(const char *xpath_fmt, ...)
@ -707,44 +628,15 @@ struct yang_data *yang_data_new_string(const char *xpath, const char *value)
const char *yang_dnode_get_string(const struct lyd_node *dnode, const char *yang_dnode_get_string(const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; return YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
assert(dnode);
if (xpath_fmt) {
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
return dleaf->value_str;
} }
void yang_dnode_get_string_buf(char *buf, size_t size, void yang_dnode_get_string_buf(char *buf, size_t size,
const struct lyd_node *dnode, const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
if (strlcpy(buf, canon, size) >= size) {
assert(dnode);
if (xpath_fmt) {
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
if (strlcpy(buf, dleaf->value_str, size) >= size) {
char xpath[XPATH_MAXLEN]; char xpath[XPATH_MAXLEN];
yang_dnode_get_path(dnode, xpath, sizeof(xpath)); yang_dnode_get_path(dnode, xpath, sizeof(xpath));
@ -797,7 +689,7 @@ bool yang_dnode_get_empty(const struct lyd_node *dnode, const char *xpath_fmt,
{ {
va_list ap; va_list ap;
char xpath[XPATH_MAXLEN]; char xpath[XPATH_MAXLEN];
const struct lyd_node_leaf_list *dleaf; const struct lyd_node_term *dleaf;
assert(dnode); assert(dnode);
@ -807,8 +699,8 @@ bool yang_dnode_get_empty(const struct lyd_node *dnode, const char *xpath_fmt,
dnode = yang_dnode_get(dnode, xpath); dnode = yang_dnode_get(dnode, xpath);
if (dnode) { if (dnode) {
dleaf = (const struct lyd_node_leaf_list *)dnode; dleaf = (const struct lyd_node_term *)dnode;
if (dleaf->value_type == LY_TYPE_EMPTY) if (dleaf->value.realtype->basetype == LY_TYPE_EMPTY)
return true; return true;
} }
@ -836,29 +728,16 @@ struct yang_data *yang_data_new_prefix(const char *xpath,
void yang_dnode_get_prefix(struct prefix *prefix, const struct lyd_node *dnode, void yang_dnode_get_prefix(struct prefix *prefix, const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; const char *canon;
assert(dnode);
if (xpath_fmt) {
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
/* /*
* Initialize prefix to avoid static analyzer complaints about * Initialize prefix to avoid static analyzer complaints about
* uninitialized memory. * uninitialized memory.
*/ */
memset(prefix, 0, sizeof(*prefix)); memset(prefix, 0, sizeof(*prefix));
dleaf = (const struct lyd_node_leaf_list *)dnode; /* XXX ip_prefix is a native type now in ly2, leverage? */
assert(dleaf->value_type == LY_TYPE_STRING); canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
(void)str2prefix(dleaf->value_str, prefix); (void)str2prefix(canon, prefix);
} }
void yang_get_default_prefix(union prefixptr var, const char *xpath_fmt, ...) void yang_get_default_prefix(union prefixptr var, const char *xpath_fmt, ...)
@ -895,23 +774,9 @@ struct yang_data *yang_data_new_ipv4(const char *xpath,
void yang_dnode_get_ipv4(struct in_addr *addr, const struct lyd_node *dnode, void yang_dnode_get_ipv4(struct in_addr *addr, const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; /* XXX libyang2 IPv4 address is a native type now in ly2 */
const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
assert(dnode); (void)inet_pton(AF_INET, canon, addr);
if (xpath_fmt) {
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_STRING);
(void)inet_pton(AF_INET, dleaf->value_str, addr);
} }
void yang_get_default_ipv4(struct in_addr *var, const char *xpath_fmt, ...) void yang_get_default_ipv4(struct in_addr *var, const char *xpath_fmt, ...)
@ -951,24 +816,10 @@ struct yang_data *yang_data_new_ipv4p(const char *xpath,
void yang_dnode_get_ipv4p(union prefixptr prefix, const struct lyd_node *dnode, void yang_dnode_get_ipv4p(union prefixptr prefix, const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf;
struct prefix_ipv4 *prefix4 = prefix.p4; struct prefix_ipv4 *prefix4 = prefix.p4;
/* XXX libyang2: ipv4/6 address is a native type now in ly2 */
assert(dnode); const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
if (xpath_fmt) { (void)str2prefix_ipv4(canon, prefix4);
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_STRING);
(void)str2prefix_ipv4(dleaf->value_str, prefix4);
} }
void yang_get_default_ipv4p(union prefixptr var, const char *xpath_fmt, ...) void yang_get_default_ipv4p(union prefixptr var, const char *xpath_fmt, ...)
@ -1005,23 +856,9 @@ struct yang_data *yang_data_new_ipv6(const char *xpath,
void yang_dnode_get_ipv6(struct in6_addr *addr, const struct lyd_node *dnode, void yang_dnode_get_ipv6(struct in6_addr *addr, const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; /* XXX libyang2: IPv6 address is a native type now, leverage. */
const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
assert(dnode); (void)inet_pton(AF_INET6, canon, addr);
if (xpath_fmt) {
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_STRING);
(void)inet_pton(AF_INET6, dleaf->value_str, addr);
} }
void yang_get_default_ipv6(struct in6_addr *var, const char *xpath_fmt, ...) void yang_get_default_ipv6(struct in6_addr *var, const char *xpath_fmt, ...)
@ -1061,24 +898,11 @@ struct yang_data *yang_data_new_ipv6p(const char *xpath,
void yang_dnode_get_ipv6p(union prefixptr prefix, const struct lyd_node *dnode, void yang_dnode_get_ipv6p(union prefixptr prefix, const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf;
struct prefix_ipv6 *prefix6 = prefix.p6; struct prefix_ipv6 *prefix6 = prefix.p6;
assert(dnode); /* XXX IPv6 address is a native type now in ly2 -- can we leverage? */
if (xpath_fmt) { const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
va_list ap; (void)str2prefix_ipv6(canon, prefix6);
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_STRING);
(void)str2prefix_ipv6(dleaf->value_str, prefix6);
} }
void yang_get_default_ipv6p(union prefixptr var, const char *xpath_fmt, ...) void yang_get_default_ipv6p(union prefixptr var, const char *xpath_fmt, ...)
@ -1115,23 +939,9 @@ struct yang_data *yang_data_new_ip(const char *xpath, const struct ipaddr *addr)
void yang_dnode_get_ip(struct ipaddr *addr, const struct lyd_node *dnode, void yang_dnode_get_ip(struct ipaddr *addr, const struct lyd_node *dnode,
const char *xpath_fmt, ...) const char *xpath_fmt, ...)
{ {
const struct lyd_node_leaf_list *dleaf; /* XXX IPv4 address could be a plugin type now in ly2, leverage? */
const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
assert(dnode); (void)str2ipaddr(canon, addr);
if (xpath_fmt) {
va_list ap;
char xpath[XPATH_MAXLEN];
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
dnode = yang_dnode_get(dnode, xpath);
YANG_DNODE_GET_ASSERT(dnode, xpath);
}
dleaf = (const struct lyd_node_leaf_list *)dnode;
assert(dleaf->value_type == LY_TYPE_STRING);
(void)str2ipaddr(dleaf->value_str, addr);
} }
void yang_get_default_ip(struct ipaddr *var, const char *xpath_fmt, ...) void yang_get_default_ip(struct ipaddr *var, const char *xpath_fmt, ...)

View file

@ -980,7 +980,7 @@ const char *format_yang_dnode(struct lyd_node *dnode)
char *buff; char *buff;
int len; int len;
lyd_print_mem(&buff, dnode, LYD_JSON, LYP_FORMAT); lyd_print_mem(&buff, dnode, LYD_JSON, LYD_PRINT_WD_ALL);
len = strlen(buff); len = strlen(buff);
memcpy(_debug_buff, buff, len); memcpy(_debug_buff, buff, len);
free(buff); free(buff);

View file

@ -7986,8 +7986,8 @@ DEFUN (interface_no_ip_igmp,
snprintf(pim_if_xpath, sizeof(pim_if_xpath), snprintf(pim_if_xpath, sizeof(pim_if_xpath),
"%s/frr-pim:pim", VTY_CURR_XPATH); "%s/frr-pim:pim", VTY_CURR_XPATH);
pim_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, pim_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
"%s/pim-enable", pim_if_xpath); "%s/pim-enable", pim_if_xpath);
if (!pim_enable_dnode) { if (!pim_enable_dnode) {
nb_cli_enqueue_change(vty, pim_if_xpath, NB_OP_DESTROY, NULL); nb_cli_enqueue_change(vty, pim_if_xpath, NB_OP_DESTROY, NULL);
nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
@ -8081,9 +8081,9 @@ DEFUN (interface_ip_igmp_query_interval,
{ {
const struct lyd_node *pim_enable_dnode; const struct lyd_node *pim_enable_dnode;
pim_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, pim_enable_dnode =
"%s/frr-pim:pim/pim-enable", yang_dnode_getf(vty->candidate_config->dnode,
VTY_CURR_XPATH); "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH);
if (!pim_enable_dnode) { if (!pim_enable_dnode) {
nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY, nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY,
"true"); "true");
@ -8157,9 +8157,9 @@ DEFUN (interface_ip_igmp_query_max_response_time,
{ {
const struct lyd_node *pim_enable_dnode; const struct lyd_node *pim_enable_dnode;
pim_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, pim_enable_dnode =
"%s/frr-pim:pim/pim-enable", yang_dnode_getf(vty->candidate_config->dnode,
VTY_CURR_XPATH); "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH);
if (!pim_enable_dnode) { if (!pim_enable_dnode) {
nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY, nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY,
@ -8206,9 +8206,9 @@ DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
{ {
const struct lyd_node *pim_enable_dnode; const struct lyd_node *pim_enable_dnode;
pim_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, pim_enable_dnode =
"%s/frr-pim:pim/pim-enable", yang_dnode_getf(vty->candidate_config->dnode,
VTY_CURR_XPATH); "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH);
if (!pim_enable_dnode) { if (!pim_enable_dnode) {
nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY, nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY,
"true"); "true");
@ -8254,9 +8254,9 @@ DEFUN (interface_ip_igmp_last_member_query_count,
{ {
const struct lyd_node *pim_enable_dnode; const struct lyd_node *pim_enable_dnode;
pim_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, pim_enable_dnode =
"%s/frr-pim:pim/pim-enable", yang_dnode_getf(vty->candidate_config->dnode,
VTY_CURR_XPATH); "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH);
if (!pim_enable_dnode) { if (!pim_enable_dnode) {
nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY, nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY,
"true"); "true");
@ -8301,9 +8301,9 @@ DEFUN (interface_ip_igmp_last_member_query_interval,
{ {
const struct lyd_node *pim_enable_dnode; const struct lyd_node *pim_enable_dnode;
pim_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, pim_enable_dnode =
"%s/frr-pim:pim/pim-enable", yang_dnode_getf(vty->candidate_config->dnode,
VTY_CURR_XPATH); "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH);
if (!pim_enable_dnode) { if (!pim_enable_dnode) {
nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY, nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY,
"true"); "true");
@ -8531,8 +8531,8 @@ DEFUN_HIDDEN (interface_no_ip_pim_ssm,
snprintf(igmp_if_xpath, sizeof(igmp_if_xpath), snprintf(igmp_if_xpath, sizeof(igmp_if_xpath),
"%s/frr-igmp:igmp", VTY_CURR_XPATH); "%s/frr-igmp:igmp", VTY_CURR_XPATH);
igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, igmp_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
"%s/igmp-enable", igmp_if_xpath); "%s/igmp-enable", igmp_if_xpath);
if (!igmp_enable_dnode) { if (!igmp_enable_dnode) {
nb_cli_enqueue_change(vty, igmp_if_xpath, NB_OP_DESTROY, NULL); nb_cli_enqueue_change(vty, igmp_if_xpath, NB_OP_DESTROY, NULL);
@ -8563,8 +8563,8 @@ DEFUN_HIDDEN (interface_no_ip_pim_sm,
snprintf(igmp_if_xpath, sizeof(igmp_if_xpath), snprintf(igmp_if_xpath, sizeof(igmp_if_xpath),
"%s/frr-igmp:igmp", VTY_CURR_XPATH); "%s/frr-igmp:igmp", VTY_CURR_XPATH);
igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, igmp_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
"%s/igmp-enable", igmp_if_xpath); "%s/igmp-enable", igmp_if_xpath);
if (!igmp_enable_dnode) { if (!igmp_enable_dnode) {
nb_cli_enqueue_change(vty, igmp_if_xpath, NB_OP_DESTROY, NULL); nb_cli_enqueue_change(vty, igmp_if_xpath, NB_OP_DESTROY, NULL);
@ -8594,8 +8594,8 @@ DEFUN (interface_no_ip_pim,
snprintf(igmp_if_xpath, sizeof(igmp_if_xpath), snprintf(igmp_if_xpath, sizeof(igmp_if_xpath),
"%s/frr-igmp:igmp", VTY_CURR_XPATH); "%s/frr-igmp:igmp", VTY_CURR_XPATH);
igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, igmp_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
"%s/igmp-enable", igmp_if_xpath); "%s/igmp-enable", igmp_if_xpath);
if (!igmp_enable_dnode) { if (!igmp_enable_dnode) {
nb_cli_enqueue_change(vty, igmp_if_xpath, NB_OP_DESTROY, NULL); nb_cli_enqueue_change(vty, igmp_if_xpath, NB_OP_DESTROY, NULL);
@ -8716,9 +8716,9 @@ DEFUN (interface_ip_pim_hello,
int idx_hold = 4; int idx_hold = 4;
const struct lyd_node *igmp_enable_dnode; const struct lyd_node *igmp_enable_dnode;
igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, igmp_enable_dnode =
"%s/frr-igmp:igmp/igmp-enable", yang_dnode_getf(vty->candidate_config->dnode,
VTY_CURR_XPATH); "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH);
if (!igmp_enable_dnode) { if (!igmp_enable_dnode) {
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY, nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
"true"); "true");
@ -9436,9 +9436,9 @@ DEFPY (ip_pim_bfd,
{ {
const struct lyd_node *igmp_enable_dnode; const struct lyd_node *igmp_enable_dnode;
igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, igmp_enable_dnode =
"%s/frr-igmp:igmp/igmp-enable", yang_dnode_getf(vty->candidate_config->dnode,
VTY_CURR_XPATH); "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH);
if (!igmp_enable_dnode) if (!igmp_enable_dnode)
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY, nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
"true"); "true");
@ -9491,9 +9491,9 @@ DEFUN (ip_pim_bsm,
{ {
const struct lyd_node *igmp_enable_dnode; const struct lyd_node *igmp_enable_dnode;
igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, igmp_enable_dnode =
"%s/frr-igmp:igmp/igmp-enable", yang_dnode_getf(vty->candidate_config->dnode,
VTY_CURR_XPATH); "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH);
if (!igmp_enable_dnode) if (!igmp_enable_dnode)
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY, nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
"true"); "true");
@ -9530,9 +9530,9 @@ DEFUN (ip_pim_ucast_bsm,
{ {
const struct lyd_node *igmp_enable_dnode; const struct lyd_node *igmp_enable_dnode;
igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, igmp_enable_dnode =
"%s/frr-igmp:igmp/igmp-enable", yang_dnode_getf(vty->candidate_config->dnode,
VTY_CURR_XPATH); "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH);
if (!igmp_enable_dnode) if (!igmp_enable_dnode)
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY, nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
"true"); "true");
@ -9589,9 +9589,9 @@ DEFUN_HIDDEN(
int idx_number_3 = 5; int idx_number_3 = 5;
const struct lyd_node *igmp_enable_dnode; const struct lyd_node *igmp_enable_dnode;
igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode, igmp_enable_dnode =
"%s/frr-igmp:igmp/igmp-enable", yang_dnode_getf(vty->candidate_config->dnode,
VTY_CURR_XPATH); "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH);
if (!igmp_enable_dnode) if (!igmp_enable_dnode)
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY, nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
"true"); "true");

View file

@ -524,11 +524,10 @@ static bool is_pim_interface(const struct lyd_node *dnode)
const struct lyd_node *igmp_enable_dnode; const struct lyd_node *igmp_enable_dnode;
yang_dnode_get_path(dnode, if_xpath, sizeof(if_xpath)); yang_dnode_get_path(dnode, if_xpath, sizeof(if_xpath));
pim_enable_dnode = yang_dnode_get(dnode, "%s/frr-pim:pim/pim-enable", pim_enable_dnode =
if_xpath); yang_dnode_getf(dnode, "%s/frr-pim:pim/pim-enable", if_xpath);
igmp_enable_dnode = yang_dnode_get(dnode, igmp_enable_dnode = yang_dnode_getf(
"%s/frr-igmp:igmp/igmp-enable", dnode, "%s/frr-igmp:igmp/igmp-enable", if_xpath);
if_xpath);
if (((pim_enable_dnode) && if (((pim_enable_dnode) &&
(yang_dnode_get_bool(pim_enable_dnode, "."))) || (yang_dnode_get_bool(pim_enable_dnode, "."))) ||

View file

@ -176,7 +176,7 @@ BuildRequires: make
BuildRequires: ncurses-devel BuildRequires: ncurses-devel
BuildRequires: readline-devel BuildRequires: readline-devel
BuildRequires: texinfo BuildRequires: texinfo
BuildRequires: libyang-devel >= 1.0.184 BuildRequires: libyang2-devel
%if 0%{?rhel} && 0%{?rhel} < 7 %if 0%{?rhel} && 0%{?rhel} < 7
#python27-devel is available from ius community repo for RedHat/CentOS 6 #python27-devel is available from ius community repo for RedHat/CentOS 6
BuildRequires: python27-devel BuildRequires: python27-devel

View file

@ -903,9 +903,9 @@ DEFPY_YANG (ip_rip_authentication_string,
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
} }
if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s", if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
VTY_CURR_XPATH, VTY_CURR_XPATH,
"/frr-ripd:rip/authentication-key-chain")) { "/frr-ripd:rip/authentication-key-chain")) {
vty_out(vty, "%% key-chain configuration exists\n"); vty_out(vty, "%% key-chain configuration exists\n");
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
} }
@ -952,9 +952,9 @@ DEFPY_YANG (ip_rip_authentication_key_chain,
"Authentication key-chain\n" "Authentication key-chain\n"
"name of key-chain\n") "name of key-chain\n")
{ {
if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s", if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
VTY_CURR_XPATH, VTY_CURR_XPATH,
"/frr-ripd:rip/authentication-password")) { "/frr-ripd:rip/authentication-password")) {
vty_out(vty, "%% authentication string configuration exists\n"); vty_out(vty, "%% authentication string configuration exists\n");
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
} }

View file

@ -1113,7 +1113,7 @@ static int rip_interface_config_write(struct vty *vty)
FOR_ALL_INTERFACES (vrf, ifp) { FOR_ALL_INTERFACES (vrf, ifp) {
struct lyd_node *dnode; struct lyd_node *dnode;
dnode = yang_dnode_get( dnode = yang_dnode_getf(
running_config->dnode, running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']", "/frr-interface:lib/interface[name='%s'][vrf='%s']",
ifp->name, vrf->name); ifp->name, vrf->name);

View file

@ -3632,16 +3632,16 @@ static int rip_vrf_enable(struct vrf *vrf)
char oldpath[XPATH_MAXLEN]; char oldpath[XPATH_MAXLEN];
char newpath[XPATH_MAXLEN]; char newpath[XPATH_MAXLEN];
rip_dnode = yang_dnode_get( rip_dnode = yang_dnode_getf(
running_config->dnode, running_config->dnode,
"/frr-ripd:ripd/instance[vrf='%s']/vrf", "/frr-ripd:ripd/instance[vrf='%s']/vrf",
old_vrf_name); old_vrf_name);
if (rip_dnode) { if (rip_dnode) {
yang_dnode_get_path(rip_dnode->parent, oldpath, yang_dnode_get_path(lyd_parent(rip_dnode),
sizeof(oldpath)); oldpath, sizeof(oldpath));
yang_dnode_change_leaf(rip_dnode, vrf->name); yang_dnode_change_leaf(rip_dnode, vrf->name);
yang_dnode_get_path(rip_dnode->parent, newpath, yang_dnode_get_path(lyd_parent(rip_dnode),
sizeof(newpath)); newpath, sizeof(newpath));
nb_running_move_tree(oldpath, newpath); nb_running_move_tree(oldpath, newpath);
running_config->version++; running_config->version++;
} }

View file

@ -933,7 +933,7 @@ static int interface_config_write(struct vty *vty)
FOR_ALL_INTERFACES (vrf, ifp) { FOR_ALL_INTERFACES (vrf, ifp) {
struct lyd_node *dnode; struct lyd_node *dnode;
dnode = yang_dnode_get( dnode = yang_dnode_getf(
running_config->dnode, running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']", "/frr-interface:lib/interface[name='%s'][vrf='%s']",
ifp->name, vrf->name); ifp->name, vrf->name);

View file

@ -2634,16 +2634,16 @@ static int ripng_vrf_enable(struct vrf *vrf)
char oldpath[XPATH_MAXLEN]; char oldpath[XPATH_MAXLEN];
char newpath[XPATH_MAXLEN]; char newpath[XPATH_MAXLEN];
ripng_dnode = yang_dnode_get( ripng_dnode = yang_dnode_getf(
running_config->dnode, running_config->dnode,
"/frr-ripngd:ripngd/instance[vrf='%s']/vrf", "/frr-ripngd:ripngd/instance[vrf='%s']/vrf",
old_vrf_name); old_vrf_name);
if (ripng_dnode) { if (ripng_dnode) {
yang_dnode_get_path(ripng_dnode->parent, oldpath, yang_dnode_get_path(lyd_parent(ripng_dnode),
sizeof(oldpath)); oldpath, sizeof(oldpath));
yang_dnode_change_leaf(ripng_dnode, vrf->name); yang_dnode_change_leaf(ripng_dnode, vrf->name);
yang_dnode_get_path(ripng_dnode->parent, newpath, yang_dnode_get_path(lyd_parent(ripng_dnode),
sizeof(newpath)); newpath, sizeof(newpath));
nb_running_move_tree(oldpath, newpath); nb_running_move_tree(oldpath, newpath);
running_config->version++; running_config->version++;
} }

View file

@ -61,7 +61,6 @@ const struct frr_yang_module_info frr_staticd_info = {
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/bh-type", .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/bh-type",
.cbs = { .cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_modify, .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_destroy,
} }
}, },
{ {
@ -139,7 +138,6 @@ const struct frr_yang_module_info frr_staticd_info = {
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/bh-type", .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/bh-type",
.cbs = { .cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify, .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_destroy,
} }
}, },
{ {

View file

@ -37,8 +37,6 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa
struct nb_cb_destroy_args *args); struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_modify( int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_modify(
struct nb_cb_modify_args *args); struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_modify( int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_modify(
struct nb_cb_modify_args *args); struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_modify( int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_modify(
@ -77,8 +75,6 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr
struct nb_cb_destroy_args *args); struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify( int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify(
struct nb_cb_modify_args *args); struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify( int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify(
struct nb_cb_modify_args *args); struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_modify( int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_modify(

View file

@ -297,7 +297,7 @@ static int static_nexthop_mpls_label_modify(struct nb_cb_modify_args *args)
uint8_t index; uint8_t index;
nh = nb_running_get_entry(args->dnode, NULL, true); nh = nb_running_get_entry(args->dnode, NULL, true);
pos = yang_get_list_pos(args->dnode->parent); pos = yang_get_list_pos(lyd_parent(args->dnode));
if (!pos) { if (!pos) {
flog_warn(EC_LIB_NB_CB_CONFIG_APPLY, flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
"libyang returns invalid label position"); "libyang returns invalid label position");
@ -457,7 +457,7 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa
uint32_t count; uint32_t count;
mls_dnode = yang_dnode_get(args->dnode, "./mpls-label-stack"); mls_dnode = yang_dnode_get(args->dnode, "./mpls-label-stack");
count = yang_get_list_elements_count(yang_dnode_get_child(mls_dnode)); count = yang_get_list_elements_count(lyd_child(mls_dnode));
if (count > MPLS_MAX_LABELS) { if (count > MPLS_MAX_LABELS) {
snprintf(args->errmsg, args->errmsg_len, snprintf(args->errmsg, args->errmsg_len,
@ -689,22 +689,6 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa
return static_nexthop_bh_type_modify(args); return static_nexthop_bh_type_modify(args);
} }
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_destroy(
struct nb_cb_destroy_args *args)
{
/* blackhole type has a boolean type with default value,
* so no need to do any operations in destroy callback
*/
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
break;
}
return NB_OK;
}
/* /*
* XPath: * XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/onlink * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/onlink
@ -1069,23 +1053,6 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr
return static_nexthop_bh_type_modify(args); return static_nexthop_bh_type_modify(args);
} }
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_destroy(
struct nb_cb_destroy_args *args)
{
/* blackhole type has a boolean type with default value,
* so no need to do any operations in destroy callback
*/
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
break;
}
return NB_OK;
}
/* /*
* XPath: * XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/onlink * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/onlink

View file

@ -783,6 +783,8 @@ static void test_execute(struct test *test, const char *fmt, ...)
cmd, ret); cmd, ret);
} }
nb_cli_pending_commit_check(test->vty);
/* Free memory. */ /* Free memory. */
cmd_free_strvec(vline); cmd_free_strvec(vline);
XFREE(MTYPE_TMP, cmd); XFREE(MTYPE_TMP, cmd);
@ -1397,7 +1399,6 @@ static void bgp_startup(void)
zprivs_init(&bgpd_privs); zprivs_init(&bgpd_privs);
master = thread_master_create(NULL); master = thread_master_create(NULL);
yang_init(true);
nb_init(master, bgpd_yang_modules, array_size(bgpd_yang_modules), false); nb_init(master, bgpd_yang_modules, array_size(bgpd_yang_modules), false);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new()); bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
bgp_option_set(BGP_OPT_NO_LISTEN); bgp_option_set(BGP_OPT_NO_LISTEN);

View file

@ -155,7 +155,6 @@ int main(int argc, char **argv)
cmd_init(1); cmd_init(1);
vty_init(master, false); vty_init(master, false);
lib_cmd_init(); lib_cmd_init();
yang_init(true);
nb_init(master, NULL, 0, false); nb_init(master, NULL, 0, false);
/* OSPF vty inits. */ /* OSPF vty inits. */

View file

@ -547,7 +547,7 @@ int main(int argc, char **argv)
cmd_init(1); cmd_init(1);
cmd_hostname_set("test"); cmd_hostname_set("test");
vty_init(master, false); vty_init(master, false);
yang_init(true); yang_init(true, false);
if (debug) if (debug)
zlog_aux_init("NONE: ", LOG_DEBUG); zlog_aux_init("NONE: ", LOG_DEBUG);
else else

View file

@ -79,7 +79,6 @@ int main(int argc, char **argv)
vty_init(master, false); vty_init(master, false);
lib_cmd_init(); lib_cmd_init();
yang_init(true);
nb_init(master, NULL, 0, false); nb_init(master, NULL, 0, false);
test_init(argc, argv); test_init(argc, argv);

View file

@ -208,7 +208,6 @@ static void test_init(void)
struct cmd_element *cmd; struct cmd_element *cmd;
cmd_init(1); cmd_init(1);
yang_init(true);
nb_init(master, NULL, 0, false); nb_init(master, NULL, 0, false);
install_node(&bgp_node); install_node(&bgp_node);

View file

@ -399,7 +399,6 @@ int main(int argc, char **argv)
cmd_hostname_set("test"); cmd_hostname_set("test");
vty_init(master, false); vty_init(master, false);
lib_cmd_init(); lib_cmd_init();
yang_init(true);
nb_init(master, modules, array_size(modules), false); nb_init(master, modules, array_size(modules), false);
/* Create artificial data. */ /* Create artificial data. */

View file

@ -157,7 +157,7 @@ TESTS_CFLAGS = \
# note no -Werror # note no -Werror
ALL_TESTS_LDADD = lib/libfrr.la $(LIBCAP) ALL_TESTS_LDADD = lib/libfrr.la $(LIBCAP)
BGP_TEST_LDADD = bgpd/libbgp.a $(RFPLDADD) $(ALL_TESTS_LDADD) -lm BGP_TEST_LDADD = bgpd/libbgp.a $(RFPLDADD) $(ALL_TESTS_LDADD) $(LIBYANG_LIBS) -lm
ISISD_TEST_LDADD = isisd/libisis.a $(ALL_TESTS_LDADD) ISISD_TEST_LDADD = isisd/libisis.a $(ALL_TESTS_LDADD)
OSPFD_TEST_LDADD = ospfd/libfrrospf.a $(ALL_TESTS_LDADD) OSPFD_TEST_LDADD = ospfd/libfrrospf.a $(ALL_TESTS_LDADD)
OSPF6_TEST_LDADD = ospf6d/libospf6.a $(ALL_TESTS_LDADD) OSPF6_TEST_LDADD = ospf6d/libospf6.a $(ALL_TESTS_LDADD)

View file

@ -118,7 +118,7 @@ static void replace_hyphens_by_underscores(char *str)
*p++ = '_'; *p++ = '_';
} }
static void generate_callback_name(struct lys_node *snode, static void generate_callback_name(const struct lysc_node *snode,
enum nb_operation operation, char *buffer, enum nb_operation operation, char *buffer,
size_t size) size_t size)
{ {
@ -126,14 +126,14 @@ static void generate_callback_name(struct lys_node *snode,
struct listnode *ln; struct listnode *ln;
snodes = list_new(); snodes = list_new();
for (; snode; snode = lys_parent(snode)) { for (; snode; snode = snode->parent) {
/* Skip schema-only snodes. */ /* Skip schema-only snodes. */
if (CHECK_FLAG(snode->nodetype, LYS_USES | LYS_CHOICE | LYS_CASE if (CHECK_FLAG(snode->nodetype, LYS_USES | LYS_CHOICE | LYS_CASE
| LYS_INPUT | LYS_INPUT
| LYS_OUTPUT)) | LYS_OUTPUT))
continue; continue;
listnode_add_head(snodes, snode); listnode_add_head(snodes, (void *)snode);
} }
memset(buffer, 0, size); memset(buffer, 0, size);
@ -153,7 +153,7 @@ static void generate_prototype(const struct nb_callback_info *ncinfo,
printf("%s%s(%s);\n", ncinfo->return_type, cb_name, ncinfo->arguments); printf("%s%s(%s);\n", ncinfo->return_type, cb_name, ncinfo->arguments);
} }
static int generate_prototypes(const struct lys_node *snode, void *arg) static int generate_prototypes(const struct lysc_node *snode, void *arg)
{ {
switch (snode->nodetype) { switch (snode->nodetype) {
case LYS_CONTAINER: case LYS_CONTAINER:
@ -175,8 +175,8 @@ static int generate_prototypes(const struct lys_node *snode, void *arg)
|| !nb_operation_is_valid(cb->operation, snode)) || !nb_operation_is_valid(cb->operation, snode))
continue; continue;
generate_callback_name((struct lys_node *)snode, cb->operation, generate_callback_name(snode, cb->operation, cb_name,
cb_name, sizeof(cb_name)); sizeof(cb_name));
generate_prototype(cb, cb_name); generate_prototype(cb, cb_name);
} }
@ -213,7 +213,7 @@ static void generate_callback(const struct nb_callback_info *ncinfo,
printf("\treturn %s;\n}\n\n", ncinfo->return_value); printf("\treturn %s;\n}\n\n", ncinfo->return_value);
} }
static int generate_callbacks(const struct lys_node *snode, void *arg) static int generate_callbacks(const struct lysc_node *snode, void *arg)
{ {
bool first = true; bool first = true;
@ -250,15 +250,15 @@ static int generate_callbacks(const struct lys_node *snode, void *arg)
first = false; first = false;
} }
generate_callback_name((struct lys_node *)snode, cb->operation, generate_callback_name(snode, cb->operation, cb_name,
cb_name, sizeof(cb_name)); sizeof(cb_name));
generate_callback(cb, cb_name); generate_callback(cb, cb_name);
} }
return YANG_ITER_CONTINUE; return YANG_ITER_CONTINUE;
} }
static int generate_nb_nodes(const struct lys_node *snode, void *arg) static int generate_nb_nodes(const struct lysc_node *snode, void *arg)
{ {
bool first = true; bool first = true;
@ -295,8 +295,8 @@ static int generate_nb_nodes(const struct lys_node *snode, void *arg)
first = false; first = false;
} }
generate_callback_name((struct lys_node *)snode, cb->operation, generate_callback_name(snode, cb->operation, cb_name,
cb_name, sizeof(cb_name)); sizeof(cb_name));
printf("\t\t\t\t.%s = %s,\n", nb_operation_name(cb->operation), printf("\t\t\t\t.%s = %s,\n", nb_operation_name(cb->operation),
cb_name); cb_name);
} }
@ -350,18 +350,21 @@ int main(int argc, char *argv[])
if (argc != 1) if (argc != 1)
usage(EXIT_FAILURE); usage(EXIT_FAILURE);
yang_init(false); yang_init(false, true);
if (search_path) if (search_path)
ly_ctx_set_searchdir(ly_native_ctx, search_path); ly_ctx_set_searchdir(ly_native_ctx, search_path);
/* Load all FRR native models to ensure all augmentations are loaded. */ /* Load all FRR native models to ensure all augmentations are loaded. */
yang_module_load_all(); yang_module_load_all();
module = yang_module_find(argv[0]); module = yang_module_find(argv[0]);
if (!module) if (!module)
/* Non-native FRR module (e.g. modules from unit tests). */ /* Non-native FRR module (e.g. modules from unit tests). */
module = yang_module_load(argv[0]); module = yang_module_load(argv[0]);
yang_init_loading_complete();
/* Create a nb_node for all YANG schema nodes. */ /* Create a nb_node for all YANG schema nodes. */
nb_nodes_create(); nb_nodes_create();

View file

@ -32,7 +32,7 @@ static void __attribute__((noreturn)) usage(int status)
exit(status); exit(status);
} }
static int generate_yang_deviation(const struct lys_node *snode, void *arg) static int generate_yang_deviation(const struct lysc_node *snode, void *arg)
{ {
char xpath[XPATH_MAXLEN]; char xpath[XPATH_MAXLEN];
@ -65,14 +65,13 @@ int main(int argc, char *argv[])
if (argc != 1) if (argc != 1)
usage(EXIT_FAILURE); usage(EXIT_FAILURE);
yang_init(false); yang_init(false, false);
/* Load YANG module. */ /* Load YANG module. */
module = yang_module_load(argv[0]); module = yang_module_load(argv[0]);
/* Generate deviations. */ /* Generate deviations. */
yang_snodes_iterate(module->info, generate_yang_deviation, yang_snodes_iterate(module->info, generate_yang_deviation, 0, NULL);
YANG_ITER_FILTER_IMPLICIT, NULL);
/* Cleanup and exit. */ /* Cleanup and exit. */
yang_terminate(); yang_terminate();

View file

@ -729,7 +729,7 @@ static int vrrp_config_write_interface(struct vty *vty)
FOR_ALL_INTERFACES (vrf, ifp) { FOR_ALL_INTERFACES (vrf, ifp) {
struct lyd_node *dnode; struct lyd_node *dnode;
dnode = yang_dnode_get( dnode = yang_dnode_getf(
running_config->dnode, running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']", "/frr-interface:lib/interface[name='%s'][vrf='%s']",
ifp->name, vrf->name); ifp->name, vrf->name);

View file

@ -42,7 +42,7 @@ sub scan_file {
$cppadd = $fabricd ? "-DFABRICD=1" : ""; $cppadd = $fabricd ? "-DFABRICD=1" : "";
open (FH, "@CPP@ -P -std=gnu11 -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -Ivtysh/@top_builddir@ -Ivtysh/@top_srcdir@ -Ivtysh/@top_srcdir@/lib -Ivtysh/@top_builddir@/lib -Ivtysh/@top_srcdir@/bgpd -Ivtysh/@top_srcdir@/bgpd/rfapi @LUA_INCLUDE@ @CPPFLAGS@ $cppadd $file |"); open (FH, "@CPP@ -P -std=gnu11 -DHAVE_CONFIG_H -DVTYSH_EXTRACT_PL -Ivtysh/@top_builddir@ -Ivtysh/@top_srcdir@ -Ivtysh/@top_srcdir@/lib -Ivtysh/@top_builddir@/lib -Ivtysh/@top_srcdir@/bgpd -Ivtysh/@top_srcdir@/bgpd/rfapi @LUA_INCLUDE@ @CPPFLAGS@ @LIBYANG_CFLAGS@ $cppadd $file |");
local $/; undef $/; local $/; undef $/;
$line = <FH>; $line = <FH>;
if (!close (FH)) { if (!close (FH)) {

View file

@ -2890,6 +2890,37 @@ DEFUN (show_yang_operational_data,
return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text); return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
} }
DEFUN(show_yang_module, show_yang_module_cmd,
"show yang module [module-translator WORD] " DAEMONS_LIST,
SHOW_STR
"YANG information\n"
"Show loaded modules\n"
"YANG module translator\n"
"YANG module translator\n" DAEMONS_STR)
{
return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
}
DEFUN(show_yang_module_detail, show_yang_module_detail_cmd,
"show yang module\
[module-translator WORD]\
WORD <compiled|summary|tree|yang|yin> " DAEMONS_LIST,
SHOW_STR
"YANG information\n"
"Show loaded modules\n"
"YANG module translator\n"
"YANG module translator\n"
"Module name\n"
"Display compiled module in YANG format\n"
"Display summary information about the module\n"
"Display module in the tree (RFC 8340) format\n"
"Display module in the YANG format\n"
"Display module in the YIN format\n" DAEMONS_STR)
{
return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text);
}
DEFUNSH(VTYSH_ALL, debug_nb, DEFUNSH(VTYSH_ALL, debug_nb,
debug_nb_cmd, debug_nb_cmd,
"[no] debug northbound\ "[no] debug northbound\
@ -4449,6 +4480,8 @@ void vtysh_init_vty(void)
/* northbound */ /* northbound */
install_element(ENABLE_NODE, &show_config_running_cmd); install_element(ENABLE_NODE, &show_config_running_cmd);
install_element(ENABLE_NODE, &show_yang_operational_data_cmd); install_element(ENABLE_NODE, &show_yang_operational_data_cmd);
install_element(ENABLE_NODE, &show_yang_module_cmd);
install_element(ENABLE_NODE, &show_yang_module_detail_cmd);
install_element(ENABLE_NODE, &debug_nb_cmd); install_element(ENABLE_NODE, &debug_nb_cmd);
install_element(CONFIG_NODE, &debug_nb_cmd); install_element(CONFIG_NODE, &debug_nb_cmd);

View file

@ -13,7 +13,7 @@ noinst_HEADERS += \
watchfrr/watchfrr_errors.h \ watchfrr/watchfrr_errors.h \
# end # end
watchfrr_watchfrr_LDADD = lib/libfrr.la $(LIBCAP) watchfrr_watchfrr_LDADD = lib/libfrr.la $(LIBYANG_LIBS) $(LIBCAP)
watchfrr_watchfrr_SOURCES = \ watchfrr_watchfrr_SOURCES = \
watchfrr/watchfrr.c \ watchfrr/watchfrr.c \
watchfrr/watchfrr_errors.c \ watchfrr/watchfrr_errors.c \

View file

@ -94,7 +94,7 @@ else:
sub_name = search_name.group(1) sub_name = search_name.group(1)
name = re_mainname.search(data).group(1) name = re_mainname.search(data).group(1)
sub_rev = re_rev.search(data).group(1) sub_rev = re_rev.search(data).group(1)
fmt = "LYS_YANG" fmt = "LYS_IN_YANG"
if name is None or rev is None: if name is None or rev is None:
raise ValueError("cannot determine YANG module name and revision") raise ValueError("cannot determine YANG module name and revision")

View file

@ -13,8 +13,6 @@ submodule frr-bgp-bmp {
prefix frr-bt; prefix frr-bt;
} }
include frr-bgp-common-multiprotocol;
organization organization
"FRRouting"; "FRRouting";
contact contact

View file

@ -9,8 +9,6 @@ submodule frr-bgp-common-multiprotocol {
prefix frr-rt; prefix frr-rt;
} }
include frr-bgp-common;
organization organization
"FRRouting"; "FRRouting";
contact contact
@ -67,7 +65,7 @@ submodule frr-bgp-common-multiprotocol {
"A common grouping used for contents of the list that is used "A common grouping used for contents of the list that is used
for AFI-SAFI entries."; for AFI-SAFI entries.";
container ipv4-unicast { container ipv4-unicast {
when "derived-from-or-self(../afi-safi-name, 'ipv4-unicast')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:ipv4-unicast')" {
description description
"Include this container for IPv4 Unicast specific "Include this container for IPv4 Unicast specific
configuration."; configuration.";
@ -77,7 +75,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container ipv6-unicast { container ipv6-unicast {
when "derived-from-or-self(../afi-safi-name, 'ipv6-unicast')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:ipv6-unicast')" {
description description
"Include this container for IPv6 Unicast specific "Include this container for IPv6 Unicast specific
configuration."; configuration.";
@ -87,7 +85,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container ipv4-labeled-unicast { container ipv4-labeled-unicast {
when "derived-from-or-self(../afi-safi-name, 'ipv4-labeled-unicast')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:ipv4-labeled-unicast')" {
description description
"Include this container for IPv4 Labeled Unicast specific "Include this container for IPv4 Labeled Unicast specific
configuration."; configuration.";
@ -97,7 +95,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container ipv6-labeled-unicast { container ipv6-labeled-unicast {
when "derived-from-or-self(../afi-safi-name, 'ipv6-labeled-unicast')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:ipv6-labeled-unicast')" {
description description
"Include this container for IPv6 Labeled Unicast specific "Include this container for IPv6 Labeled Unicast specific
configuration."; configuration.";
@ -107,7 +105,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container l3vpn-ipv4-unicast { container l3vpn-ipv4-unicast {
when "derived-from-or-self(../afi-safi-name, 'l3vpn-ipv4-unicast')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:l3vpn-ipv4-unicast')" {
description description
"Include this container for IPv4 Unicast L3VPN specific "Include this container for IPv4 Unicast L3VPN specific
configuration."; configuration.";
@ -117,7 +115,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container l3vpn-ipv6-unicast { container l3vpn-ipv6-unicast {
when "derived-from-or-self(../afi-safi-name, 'l3vpn-ipv6-unicast')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:l3vpn-ipv6-unicast')" {
description description
"Include this container for unicast IPv6 L3VPN specific "Include this container for unicast IPv6 L3VPN specific
configuration."; configuration.";
@ -127,7 +125,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container l3vpn-ipv4-multicast { container l3vpn-ipv4-multicast {
when "derived-from-or-self(../afi-safi-name, 'l3vpn-ipv4-multicast')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:l3vpn-ipv4-multicast')" {
description description
"Include this container for multicast IPv4 L3VPN specific "Include this container for multicast IPv4 L3VPN specific
configuration."; configuration.";
@ -137,7 +135,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container l3vpn-ipv6-multicast { container l3vpn-ipv6-multicast {
when "derived-from-or-self(../afi-safi-name, 'l3vpn-ipv6-multicast')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:l3vpn-ipv6-multicast')" {
description description
"Include this container for multicast IPv6 L3VPN specific "Include this container for multicast IPv6 L3VPN specific
configuration."; configuration.";
@ -147,7 +145,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container l2vpn-vpls { container l2vpn-vpls {
when "derived-from-or-self(../afi-safi-name, 'l2vpn-vpls')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:l2vpn-vpls')" {
description description
"Include this container for BGP-signalled VPLS specific "Include this container for BGP-signalled VPLS specific
configuration."; configuration.";
@ -157,7 +155,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container l2vpn-evpn { container l2vpn-evpn {
when "derived-from-or-self(../afi-safi-name, 'l2vpn-evpn')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:l2vpn-evpn')" {
description description
"Include this container for BGP EVPN specific "Include this container for BGP EVPN specific
configuration."; configuration.";
@ -167,7 +165,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container ipv4-multicast { container ipv4-multicast {
when "derived-from-or-self(../afi-safi-name, 'ipv4-multicast')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:ipv4-multicast')" {
description description
"Include this container for IPv4 multicast specific "Include this container for IPv4 multicast specific
configuration."; configuration.";
@ -177,7 +175,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container ipv6-multicast { container ipv6-multicast {
when "derived-from-or-self(../afi-safi-name, 'ipv6-multicast')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:ipv6-multicast')" {
description description
"Include this container for IPv6 multicast specific "Include this container for IPv6 multicast specific
configuration."; configuration.";
@ -187,7 +185,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container ipv4-flowspec { container ipv4-flowspec {
when "derived-from-or-self(../afi-safi-name, 'ipv4-flowspec')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:ipv4-flowspec')" {
description description
"Include this container for IPv4 flowspec specific "Include this container for IPv4 flowspec specific
configuration."; configuration.";
@ -197,7 +195,7 @@ submodule frr-bgp-common-multiprotocol {
} }
container ipv6-flowspec { container ipv6-flowspec {
when "derived-from-or-self(../afi-safi-name, 'ipv6-flowspec')" { when "derived-from-or-self(../afi-safi-name, 'frr-rt:ipv6-flowspec')" {
description description
"Include this container for IPv6 flowspec specific "Include this container for IPv6 flowspec specific
configuration."; configuration.";

View file

@ -25,8 +25,6 @@ submodule frr-bgp-common-structure {
prefix frr-bt; prefix frr-bt;
} }
include frr-bgp-common;
organization organization
"FRRouting"; "FRRouting";
contact contact
@ -118,7 +116,6 @@ submodule frr-bgp-common-structure {
} }
leaf no-prepend { leaf no-prepend {
when "../local-as != 0";
type boolean; type boolean;
default "false"; default "false";
description description

View file

@ -455,11 +455,14 @@ submodule frr-bgp-common {
grouping global-network-config { grouping global-network-config {
leaf import-check { leaf import-check {
type boolean; type boolean;
default "false"; default "true";
description description
"When set to 'true' bgp creates entries for network statements "When set to 'true' bgp creates entries for network statements
if a matching prefix exists in the rib. When set to 'false' bgp if a matching prefix exists in the rib. When set to 'false' bgp
creates entries for networks that the router cannot reach."; creates entries for networks that the router cannot reach.
In FRR versions < 7.4 this used to default to 'false' this is an
incompatible backward change";
} }
} }

View file

@ -5,9 +5,6 @@ submodule frr-bgp-neighbor {
prefix "bgp"; prefix "bgp";
} }
include frr-bgp-common-structure;
include frr-bgp-common-multiprotocol;
organization organization
"FRRouting"; "FRRouting";
contact contact

View file

@ -13,9 +13,6 @@ submodule frr-bgp-peer-group {
prefix frr-bt; prefix frr-bt;
} }
include frr-bgp-common-structure;
include frr-bgp-neighbor;
organization organization
"FRRouting"; "FRRouting";
contact contact

View file

@ -332,7 +332,7 @@ module frr-bgp-route-map {
augment "/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:rmap-match-condition/frr-route-map:match-condition" { augment "/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:rmap-match-condition/frr-route-map:match-condition" {
case local-preference { case local-preference {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'match-local-preference')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-local-preference')";
leaf local-preference { leaf local-preference {
type uint32 { type uint32 {
range "0..4294967295"; range "0..4294967295";
@ -341,14 +341,14 @@ module frr-bgp-route-map {
} }
case script { case script {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'match-script')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-script')";
leaf script { leaf script {
type string; type string;
} }
} }
case origin { case origin {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'match-origin')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-origin')";
leaf origin { leaf origin {
type enumeration { type enumeration {
enum "egp" { enum "egp" {
@ -371,7 +371,7 @@ module frr-bgp-route-map {
} }
case rpki { case rpki {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'rpki')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:rpki')";
leaf rpki { leaf rpki {
type enumeration { type enumeration {
enum "invalid" { enum "invalid" {
@ -394,7 +394,7 @@ module frr-bgp-route-map {
} }
case probability { case probability {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'probability')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:probability')";
leaf probability { leaf probability {
type uint8 { type uint8 {
range "0..100"; range "0..100";
@ -403,14 +403,14 @@ module frr-bgp-route-map {
} }
case source-vrf { case source-vrf {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'source-vrf')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:source-vrf')";
leaf source-vrf { leaf source-vrf {
type string; type string;
} }
} }
case peer { case peer {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'peer')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:peer')";
choice peer { choice peer {
description description
"Value of the peer"; "Value of the peer";
@ -449,10 +449,10 @@ module frr-bgp-route-map {
} }
case access-list-name { case access-list-name {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'mac-address-list') or " when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:mac-address-list') or "
+ "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'as-path-list') or " + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:as-path-list') or "
+ "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'ip-route-source') or " + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:ip-route-source') or "
+ "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'ip-route-source-prefix-list')"; + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:ip-route-source-prefix-list')";
description description
"Access-list name"; "Access-list name";
leaf list-name { leaf list-name {
@ -461,7 +461,7 @@ module frr-bgp-route-map {
} }
case evpn-default-route { case evpn-default-route {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'evpn-default-route')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:evpn-default-route')";
description description
"Match default EVPN type-5 route"; "Match default EVPN type-5 route";
leaf evpn-default-route { leaf evpn-default-route {
@ -470,7 +470,7 @@ module frr-bgp-route-map {
} }
case evpn-vni { case evpn-vni {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'evpn-vni')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:evpn-vni')";
description description
"Match eVPN VNI"; "Match eVPN VNI";
leaf evpn-vni { leaf evpn-vni {
@ -481,7 +481,7 @@ module frr-bgp-route-map {
} }
case evpn-route-type { case evpn-route-type {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'evpn-route-type')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:evpn-route-type')";
description description
"Match eVPN route-type"; "Match eVPN route-type";
leaf evpn-route-type { leaf evpn-route-type {
@ -506,7 +506,7 @@ module frr-bgp-route-map {
} }
case evpn-rd { case evpn-rd {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'evpn-rd')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:evpn-rd')";
description description
"Match eVPN route-distinguisher"; "Match eVPN route-distinguisher";
leaf route-distinguisher { leaf route-distinguisher {
@ -515,9 +515,9 @@ module frr-bgp-route-map {
} }
case comm-list-name { case comm-list-name {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'match-community') or " when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-community') or "
+ "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'match-large-community') or " + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-large-community') or "
+ "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'match-extcommunity')"; + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-extcommunity')";
container comm-list { container comm-list {
leaf comm-list-name { leaf comm-list-name {
type bgp-filter:bgp-list-name; type bgp-filter:bgp-list-name;
@ -532,7 +532,7 @@ module frr-bgp-route-map {
} }
case ipv4-address { case ipv4-address {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'ipv4-nexthop')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:ipv4-nexthop')";
leaf ipv4-address { leaf ipv4-address {
type inet:ipv4-address; type inet:ipv4-address;
description description
@ -541,7 +541,7 @@ module frr-bgp-route-map {
} }
case ipv6-address { case ipv6-address {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'ipv6-nexthop')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:ipv6-nexthop')";
leaf ipv6-address { leaf ipv6-address {
type inet:ipv6-address; type inet:ipv6-address;
description description
@ -552,7 +552,7 @@ module frr-bgp-route-map {
augment "/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:rmap-set-action/frr-route-map:set-action" { augment "/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:rmap-set-action/frr-route-map:set-action" {
case distance { case distance {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'distance')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:distance')";
leaf distance { leaf distance {
type uint8 { type uint8 {
range "0..255"; range "0..255";
@ -561,7 +561,7 @@ module frr-bgp-route-map {
} }
case extcommunity-rt { case extcommunity-rt {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'set-extcommunity-rt')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-rt')";
description description
"Value of the ext-community"; "Value of the ext-community";
leaf extcommunity-rt { leaf extcommunity-rt {
@ -572,7 +572,7 @@ module frr-bgp-route-map {
} }
case extcommunity-soo { case extcommunity-soo {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'set-extcommunity-soo')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-soo')";
description description
"Value of the ext-community"; "Value of the ext-community";
leaf extcommunity-soo { leaf extcommunity-soo {
@ -583,7 +583,7 @@ module frr-bgp-route-map {
} }
case extcommunity-lb { case extcommunity-lb {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'set-extcommunity-lb')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-lb')";
container extcommunity-lb { container extcommunity-lb {
description description
"Value of the ext-community."; "Value of the ext-community.";
@ -604,7 +604,7 @@ module frr-bgp-route-map {
} }
case ipv4-address { case ipv4-address {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'ipv4-vpn-address')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:ipv4-vpn-address')";
description description
"Set the IPv4 address"; "Set the IPv4 address";
leaf ipv4-address { leaf ipv4-address {
@ -613,15 +613,15 @@ module frr-bgp-route-map {
} }
case ipv4-nexthop { case ipv4-nexthop {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'set-ipv4-nexthop')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-ipv4-nexthop')";
leaf ipv4-nexthop { leaf ipv4-nexthop {
type string; type string;
} }
} }
case ipv6-address { case ipv6-address {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'ipv6-nexthop-global') or " when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:ipv6-nexthop-global') or "
+ "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'ipv6-vpn-address')"; + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:ipv6-vpn-address')";
description description
"Set the IPv6 address"; "Set the IPv6 address";
leaf ipv6-address { leaf ipv6-address {
@ -630,15 +630,15 @@ module frr-bgp-route-map {
} }
case preference { case preference {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'ipv6-prefer-global') or " when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:ipv6-prefer-global') or "
+ "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'ipv6-peer-address')"; + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:ipv6-peer-address')";
leaf preference { leaf preference {
type boolean; type boolean;
} }
} }
case label-index { case label-index {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'label-index')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:label-index')";
leaf label-index { leaf label-index {
type uint32 { type uint32 {
range "0..1048560"; range "0..1048560";
@ -647,14 +647,14 @@ module frr-bgp-route-map {
} }
case local-pref { case local-pref {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'set-local-preference')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-local-preference')";
leaf local-pref { leaf local-pref {
type string; type string;
} }
} }
case weight { case weight {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'weight')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:weight')";
leaf weight { leaf weight {
type uint32 { type uint32 {
range "0..4294967295"; range "0..4294967295";
@ -663,7 +663,7 @@ module frr-bgp-route-map {
} }
case origin { case origin {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'set-origin')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-origin')";
leaf origin { leaf origin {
type enumeration { type enumeration {
enum "egp" { enum "egp" {
@ -686,14 +686,14 @@ module frr-bgp-route-map {
} }
case originator-id { case originator-id {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'originator-id')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:originator-id')";
leaf originator-id { leaf originator-id {
type inet:ipv4-address; type inet:ipv4-address;
} }
} }
case table { case table {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'table')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:table')";
leaf table { leaf table {
type uint32 { type uint32 {
range "1..4294967295"; range "1..4294967295";
@ -702,14 +702,14 @@ module frr-bgp-route-map {
} }
case atomic-aggregate { case atomic-aggregate {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'atomic-aggregate')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:atomic-aggregate')";
leaf atomic-aggregate { leaf atomic-aggregate {
type empty; type empty;
} }
} }
case as-path-prepend { case as-path-prepend {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'as-path-prepend')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:as-path-prepend')";
choice as-path-prepend { choice as-path-prepend {
description description
"Value of the BGP AS-path attribute"; "Value of the BGP AS-path attribute";
@ -734,7 +734,7 @@ module frr-bgp-route-map {
} }
case as-path-exclude { case as-path-exclude {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'as-path-exclude')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:as-path-exclude')";
leaf exclude-as-path { leaf exclude-as-path {
type string; type string;
description description
@ -743,7 +743,7 @@ module frr-bgp-route-map {
} }
case community { case community {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'set-community')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-community')";
choice community { choice community {
description description
"Value of the BGP community attribute"; "Value of the BGP community attribute";
@ -766,7 +766,7 @@ module frr-bgp-route-map {
} }
case large-community { case large-community {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'set-large-community')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-large-community')";
choice large-community { choice large-community {
description description
"Value of the BGP large-community attribute"; "Value of the BGP large-community attribute";
@ -789,7 +789,7 @@ module frr-bgp-route-map {
} }
case aggregator { case aggregator {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'aggregator')"; when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:aggregator')";
container aggregator { container aggregator {
leaf aggregator-asn { leaf aggregator-asn {
type uint32 { type uint32 {
@ -810,8 +810,8 @@ module frr-bgp-route-map {
} }
case comm-list-name { case comm-list-name {
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'comm-list-delete') or " when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:comm-list-delete') or "
+ "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'large-comm-list-delete')"; + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:large-comm-list-delete')";
leaf comm-list-name { leaf comm-list-name {
type bgp-filter:bgp-list-name; type bgp-filter:bgp-list-name;
} }

View file

@ -23,10 +23,10 @@ module frr-bgp {
prefix frr-bt; prefix frr-bt;
} }
include "frr-bgp-common-structure";
include "frr-bgp-common"; include "frr-bgp-common";
include "frr-bgp-common-structure";
include "frr-bgp-common-multiprotocol"; include "frr-bgp-common-multiprotocol";
include "frr-bgp-neighbor"; include "frr-bgp-neighbor";

View file

@ -481,6 +481,10 @@ module frr-isisd {
description description
"TI-LFA configuration."; "TI-LFA configuration.";
leaf enable { leaf enable {
must ". = 'false' or ../../lfa/enable = 'false'" {
error-message
"Can't enable both classic LFA and TI-LFA in the same interface.";
}
type boolean; type boolean;
default false; default false;
description description
@ -804,10 +808,6 @@ module frr-isisd {
container level-1 { container level-1 {
description description
"Level-1 IP Fast-reroute configuration."; "Level-1 IP Fast-reroute configuration.";
must "./lfa/enable = 'false' or ./ti-lfa/enable = 'false'" {
error-message
"Can't enable both classic LFA and TI-LFA in the same interface.";
}
uses interface-config-lfa; uses interface-config-lfa;
uses interface-config-remote-lfa; uses interface-config-remote-lfa;
uses interface-config-ti-lfa; uses interface-config-ti-lfa;
@ -815,10 +815,6 @@ module frr-isisd {
container level-2 { container level-2 {
description description
"Level-2 IP Fast-reroute configuration."; "Level-2 IP Fast-reroute configuration.";
must "./lfa/enable = 'false' or ./ti-lfa/enable = 'false'" {
error-message
"Can't enable both classic LFA and TI-LFA in the same interface.";
}
uses interface-config-lfa; uses interface-config-lfa;
uses interface-config-remote-lfa; uses interface-config-remote-lfa;
uses interface-config-ti-lfa; uses interface-config-ti-lfa;
@ -1502,14 +1498,15 @@ module frr-isisd {
container srgb { container srgb {
description description
"Global blocks to be advertised."; "Global blocks to be advertised.";
must "./upper-bound > ./lower-bound";
leaf lower-bound { leaf lower-bound {
must "../upper-bound > .";
type uint32; type uint32;
default "16000"; default "16000";
description description
"Lower value in the label range."; "Lower value in the label range.";
} }
leaf upper-bound { leaf upper-bound {
must ". > ../lower-bound";
type uint32; type uint32;
default "23999"; default "23999";
description description
@ -1519,14 +1516,15 @@ module frr-isisd {
container srlb { container srlb {
description description
"Local blocks to be advertised."; "Local blocks to be advertised.";
must "./upper-bound > ./lower-bound";
leaf lower-bound { leaf lower-bound {
must "../upper-bound > .";
type uint32; type uint32;
default "15000"; default "15000";
description description
"Lower value in the label range."; "Lower value in the label range.";
} }
leaf upper-bound { leaf upper-bound {
must ". > ../lower-bound";
type uint32; type uint32;
default "15999"; default "15999";
description description

View file

@ -682,8 +682,8 @@ module frr-ospfd {
container global-block { container global-block {
description description
"Segment Routing Global Block label range."; "Segment Routing Global Block label range.";
must "./upper-bound > ./lower-bound";
leaf lower-bound { leaf lower-bound {
must "../upper-bound > .";
type uint32 { type uint32 {
range "0..1048575"; range "0..1048575";
} }
@ -691,6 +691,7 @@ module frr-ospfd {
} }
leaf upper-bound { leaf upper-bound {
must ". > ../lower-bound";
type uint32 { type uint32 {
range "0..1048575"; range "0..1048575";
} }
@ -701,14 +702,15 @@ module frr-ospfd {
container srlb { container srlb {
description description
"Local blocks to be advertised."; "Local blocks to be advertised.";
must "./upper-bound > ./lower-bound";
leaf lower-bound { leaf lower-bound {
must "../upper-bound > .";
type uint32; type uint32;
default "15000"; default "15000";
description description
"Lower value in the label range."; "Lower value in the label range.";
} }
leaf upper-bound { leaf upper-bound {
must ". > ../lower-bound";
type uint32; type uint32;
default "15999"; default "15999";
description description

View file

@ -341,14 +341,14 @@ module frr-pim {
leaf bsm { leaf bsm {
type boolean; type boolean;
default "false"; default "true";
description description
"Enables BSM support on the interface."; "Enables BSM support on the interface.";
} }
leaf unicast-bsm { leaf unicast-bsm {
type boolean; type boolean;
default "false"; default "true";
description description
"Accept/Send unicast BSM on the interface."; "Accept/Send unicast BSM on the interface.";
} }

View file

@ -291,6 +291,10 @@ module frr-ripd {
} }
container version { container version {
leaf receive { leaf receive {
must
'(. = "1" and ../send = "1") or ' +
'(. = "2" and ../send = "2") or ' +
'(. = "1-2" and ../send = "2")';
type enumeration { type enumeration {
enum "1" { enum "1" {
value 1; value 1;
@ -313,6 +317,10 @@ module frr-ripd {
"Advertisement reception - Version control."; "Advertisement reception - Version control.";
} }
leaf send { leaf send {
must
'(../receive = "1" and . = "1") or ' +
'(../receive = "2" and . = "2") or ' +
'(../receive = "1-2" and . = "2")';
type enumeration { type enumeration {
enum "1" { enum "1" {
value 1; value 1;
@ -329,10 +337,6 @@ module frr-ripd {
description description
"Advertisement transmission - Version control."; "Advertisement transmission - Version control.";
} }
must
'(./receive = "1" and ./send = "1") or ' +
'(./receive = "2" and ./send = "2") or ' +
'(./receive = "1-2" and ./send = "2")';
} }
/* /*

View file

@ -64,10 +64,15 @@ module frr-zebra-route-map {
"Set IPv4/IPv6 source address for route"; "Set IPv4/IPv6 source address for route";
} }
augment "/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:rmap-match-condition/frr-route-map:match-condition" { augment "/frr-route-map:lib"
+ "/frr-route-map:route-map"
+ "/frr-route-map:entry"
+ "/frr-route-map:match-condition"
+ "/frr-route-map:rmap-match-condition"
+ "/frr-route-map:match-condition" {
case ipv4-prefix-length { case ipv4-prefix-length {
when "derived-from-or-self(../condition, 'ipv4-prefix-length') or " when "derived-from-or-self(../frr-route-map:condition, 'frr-zebra-route-map:ipv4-prefix-length') or "
+ "derived-from-or-self(../condition, 'ipv4-next-hop-prefix-length')"; + "derived-from-or-self(../frr-route-map:condition, 'frr-zebra-route-map:ipv4-next-hop-prefix-length')";
leaf ipv4-prefix-length { leaf ipv4-prefix-length {
type uint8 { type uint8 {
range "0..32"; range "0..32";
@ -76,7 +81,7 @@ module frr-zebra-route-map {
} }
case ipv6-prefix-length { case ipv6-prefix-length {
when "derived-from-or-self(../condition, 'ipv6-prefix-length')"; when "derived-from-or-self(../frr-route-map:condition, 'frr-zebra-route-map:ipv6-prefix-length')";
leaf ipv6-prefix-length { leaf ipv6-prefix-length {
type uint8 { type uint8 {
range "0..128"; range "0..128";
@ -85,7 +90,7 @@ module frr-zebra-route-map {
} }
case source-instance { case source-instance {
when "derived-from-or-self(../condition, 'source-instance')"; when "derived-from-or-self(../frr-route-map:condition, 'frr-zebra-route-map:source-instance')";
leaf source-instance { leaf source-instance {
type uint8 { type uint8 {
range "0..255"; range "0..255";
@ -94,16 +99,21 @@ module frr-zebra-route-map {
} }
case source-protocol { case source-protocol {
when "derived-from-or-self(../condition, 'source-protocol')"; when "derived-from-or-self(../frr-route-map:condition, 'frr-zebra-route-map:source-protocol')";
leaf source-protocol { leaf source-protocol {
type frr-route-types:frr-route-types; type frr-route-types:frr-route-types;
} }
} }
} }
augment "/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:rmap-set-action/frr-route-map:set-action" { augment "/frr-route-map:lib"
+ "/frr-route-map:route-map"
+ "/frr-route-map:entry"
+ "/frr-route-map:set-action"
+ "/frr-route-map:rmap-set-action"
+ "/frr-route-map:set-action" {
case src-address { case src-address {
when "derived-from-or-self(../action, 'src-address')"; when "derived-from-or-self(../frr-route-map:action, 'frr-zebra-route-map:src-address')";
choice src-address { choice src-address {
description description
"Value of the source address"; "Value of the source address";

View file

@ -1953,7 +1953,7 @@ module frr-zebra {
} }
leaf ip4-peer { leaf ip4-peer {
when "derived-from-or-self(../address-family, 'ipv4')"; when "derived-from-or-self(../address-family, 'frr-rt:ipv4')";
type inet:ipv4-prefix; type inet:ipv4-prefix;
description description
"Peer prefix, for peer-to-peer interfaces."; "Peer prefix, for peer-to-peer interfaces.";