summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-format3
-rw-r--r--.travis.yml16
-rw-r--r--bfdd/bfd.c8
-rw-r--r--bgpd/bgp_nb.c3
-rw-r--r--bgpd/bgp_nb.h6
-rw-r--r--bgpd/bgp_nb_config.c62
-rw-r--r--bgpd/bgp_vty.c48
-rw-r--r--bgpd/subdir.am4
-rw-r--r--configure.ac4
-rw-r--r--debian/control4
-rw-r--r--doc/developer/building-libyang.rst22
-rw-r--r--docker/ubuntu18-ci/Dockerfile14
-rw-r--r--docker/ubuntu20-ci/Dockerfile14
-rw-r--r--eigrpd/eigrp_cli.c2
-rw-r--r--isisd/isis_circuit.c2
-rw-r--r--isisd/isis_cli.c26
-rw-r--r--isisd/isis_nb_config.c32
-rw-r--r--lib/grammar_sandbox_main.c1
-rw-r--r--lib/if.c6
-rw-r--r--lib/libfrr.c6
-rw-r--r--lib/northbound.c377
-rw-r--r--lib/northbound.h15
-rw-r--r--lib/northbound_cli.c93
-rw-r--r--lib/northbound_confd.c16
-rw-r--r--lib/northbound_grpc.cpp2
-rw-r--r--lib/northbound_sysrepo.c22
-rw-r--r--lib/vrf.c3
-rw-r--r--lib/yang.c400
-rw-r--r--lib/yang.h143
-rw-r--r--lib/yang_translator.c129
-rw-r--r--lib/yang_wrappers.c546
-rw-r--r--pathd/path_pcep_debug.c2
-rw-r--r--pimd/pim_cmd.c76
-rw-r--r--pimd/pim_nb_config.c9
-rw-r--r--redhat/frr.spec.in2
-rw-r--r--ripd/rip_cli.c12
-rw-r--r--ripd/rip_interface.c2
-rw-r--r--ripd/ripd.c10
-rw-r--r--ripngd/ripng_interface.c2
-rw-r--r--ripngd/ripngd.c10
-rw-r--r--staticd/static_nb.c2
-rw-r--r--staticd/static_nb.h4
-rw-r--r--staticd/static_nb_config.c37
-rw-r--r--tests/bgpd/test_peer_attr.c3
-rw-r--r--tests/helpers/c/main.c1
-rw-r--r--tests/isisd/test_isis_spf.c2
-rw-r--r--tests/lib/cli/common_cli.c1
-rw-r--r--tests/lib/cli/test_commands.c1
-rw-r--r--tests/lib/northbound/test_oper_data.c1
-rw-r--r--tests/subdir.am2
-rw-r--r--tools/gen_northbound_callbacks.c29
-rw-r--r--tools/gen_yang_deviations.c7
-rw-r--r--vrrpd/vrrp_vty.c2
-rwxr-xr-xvtysh/extract.pl.in2
-rw-r--r--vtysh/vtysh.c33
-rw-r--r--watchfrr/subdir.am2
-rw-r--r--yang/embedmodel.py2
-rw-r--r--yang/frr-bgp-bmp.yang2
-rw-r--r--yang/frr-bgp-common-multiprotocol.yang30
-rw-r--r--yang/frr-bgp-common-structure.yang3
-rw-r--r--yang/frr-bgp-common.yang7
-rw-r--r--yang/frr-bgp-neighbor.yang3
-rw-r--r--yang/frr-bgp-peer-group.yang3
-rw-r--r--yang/frr-bgp-route-map.yang88
-rw-r--r--yang/frr-bgp.yang4
-rw-r--r--yang/frr-isisd.yang18
-rw-r--r--yang/frr-ospfd.yang6
-rw-r--r--yang/frr-pim.yang4
-rw-r--r--yang/frr-ripd.yang12
-rw-r--r--yang/frr-zebra-route-map.yang26
-rw-r--r--yang/frr-zebra.yang2
71 files changed, 1226 insertions, 1267 deletions
diff --git a/.clang-format b/.clang-format
index 47d681e0e..e1897bfa9 100644
--- a/.clang-format
+++ b/.clang-format
@@ -50,8 +50,11 @@ ForEachMacros:
- FOR_ALL_INTERFACES_ADDRESSES
- JSON_FOREACH
# libyang
+ - LY_FOR_KEYS
+ - LY_LIST_FOR
- LY_TREE_FOR
- LY_TREE_DFS_BEGIN
+ - LYD_TREE_DFS_BEGIN
# zebra
- RE_DEST_FOREACH_ROUTE
- RE_DEST_FOREACH_ROUTE_SAFE
diff --git a/.travis.yml b/.travis.yml
index d8e450a64..84dd2d7ec 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,14 +5,14 @@ services:
- docker
jobs:
include:
- - script:
- - docker/centos-7/build.sh
- - docker images
- name: centos7
- - script:
- - docker/centos-8/build.sh
- - docker images
- name: centos8
+ # - script:
+ # - docker/centos-7/build.sh
+ # - docker images
+ # name: centos7
+ # - script:
+ # - docker/centos-8/build.sh
+ # - docker images
+ # name: centos8
- script:
- sudo apt install -y linux-modules-extra-$(uname -r)
- docker build -t frr-ubuntu18:latest -f docker/ubuntu18-ci/Dockerfile .
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index 18f331e20..c66fccb85 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -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",
bs->key.vrfname);
- bfd_dnode = yang_dnode_get(running_config->dnode, xpath,
- bs->key.vrfname);
+ bfd_dnode = yang_dnode_getf(running_config->dnode, xpath,
+ bs->key.vrfname);
if (bfd_dnode) {
- yang_dnode_get_path(bfd_dnode->parent, oldpath,
+ yang_dnode_get_path(lyd_parent(bfd_dnode), oldpath,
sizeof(oldpath));
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));
nb_running_move_tree(oldpath, newpath);
running_config->version++;
diff --git a/bgpd/bgp_nb.c b/bgpd/bgp_nb.c
index 21810b634..71824cd6d 100644
--- a/bgpd/bgp_nb.c
+++ b/bgpd/bgp_nb.c
@@ -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",
.cbs = {
.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",
.cbs = {
.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",
.cbs = {
.modify = bgp_peer_groups_peer_group_local_as_no_prepend_modify,
- .destroy = bgp_peer_groups_peer_group_local_as_no_prepend_destroy,
}
},
{
diff --git a/bgpd/bgp_nb.h b/bgpd/bgp_nb.h
index 57f379b6c..f8bb31aad 100644
--- a/bgpd/bgp_nb.h
+++ b/bgpd/bgp_nb.h
@@ -233,8 +233,6 @@ int bgp_neighbors_neighbor_local_as_local_as_destroy(
struct nb_cb_destroy_args *args);
int bgp_neighbors_neighbor_local_as_no_prepend_modify(
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(
struct nb_cb_modify_args *args);
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);
int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_modify(
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(
struct nb_cb_modify_args *args);
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);
int bgp_peer_groups_peer_group_local_as_no_prepend_modify(
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(
struct nb_cb_modify_args *args);
int bgp_peer_groups_peer_group_bfd_options_enable_modify(
diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c
index 8ca7836a9..a430124b5 100644
--- a/bgpd/bgp_nb_config.c
+++ b/bgpd/bgp_nb_config.c
@@ -239,8 +239,8 @@ int bgp_global_local_as_modify(struct nb_cb_modify_args *args)
* If the instance already exists - return the validation
* error.
*/
- bgp = nb_running_get_entry_non_rec(args->dnode->parent->parent,
- NULL, false);
+ bgp = nb_running_get_entry_non_rec(
+ lyd_parent(lyd_parent(args->dnode)), NULL, false);
if (bgp) {
snprintf(args->errmsg, args->errmsg_len,
"Changing AS number is not allowed");
@@ -580,16 +580,11 @@ int bgp_global_route_reflector_route_reflector_cluster_id_modify(
struct bgp *bgp;
struct in_addr cluster_id;
- const struct lyd_node_leaf_list *dleaf;
bgp = nb_running_get_entry(args->dnode, NULL, true);
- dleaf = (const struct lyd_node_leaf_list *)args->dnode;
- if (dleaf->value_type == LY_TYPE_STRING)
- yang_dnode_get_ipv4(&cluster_id, args->dnode, NULL);
- else
- (void)inet_aton(dleaf->value_str, &cluster_id);
-
+ /* cluster-id is either dotted-quad or a uint32 */
+ (void)inet_aton(lyd_get_value(args->dnode), &cluster_id);
bgp_cluster_id_set(bgp, &cluster_id);
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
* error.
*/
- bgp = nb_running_get_entry_non_rec(args->dnode->parent->parent,
- NULL, false);
+ bgp = nb_running_get_entry_non_rec(
+ lyd_parent(lyd_parent(args->dnode)), NULL, false);
if (bgp) {
snprintf(args->errmsg, args->errmsg_len,
"Changing instance type is not allowed");
@@ -3560,21 +3555,6 @@ int bgp_neighbors_neighbor_local_as_no_prepend_modify(
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:
* /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;
}
-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:
* /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;
}
-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:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-replace-as
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 5b5f166e4..9be614ad6 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -4372,12 +4372,12 @@ DEFUN_YANG(neighbor_remote_as,
snprintf(prgrp_xpath, sizeof(prgrp_xpath),
FRR_BGP_PEER_GROUP_XPATH, argv[idx_peer]->arg, "");
- if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
- VTY_CURR_XPATH, unnbr_xpath + 1)) {
+ if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
+ VTY_CURR_XPATH, unnbr_xpath + 1)) {
strlcpy(base_xpath, unnbr_xpath, sizeof(base_xpath));
- } else if (yang_dnode_exists(vty->candidate_config->dnode,
- "%s%s", VTY_CURR_XPATH,
- prgrp_xpath + 1)) {
+ } else if (yang_dnode_existsf(vty->candidate_config->dnode,
+ "%s%s", VTY_CURR_XPATH,
+ prgrp_xpath + 1)) {
snprintf(base_xpath, sizeof(base_xpath),
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) {
snprintf(num_xpath, sizeof(num_xpath),
FRR_BGP_NEIGHBOR_NUM_XPATH, argv[idx_peer]->arg, "");
- if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
- VTY_CURR_XPATH, num_xpath + 1)) {
+ if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
+ VTY_CURR_XPATH, num_xpath + 1)) {
strlcpy(base_xpath, num_xpath, sizeof(base_xpath));
}
} else {
@@ -4659,12 +4659,12 @@ DEFUN_YANG(no_neighbor,
snprintf(prgrp_xpath, sizeof(prgrp_xpath),
FRR_BGP_PEER_GROUP_XPATH, argv[idx_peer]->arg, "");
- if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
- VTY_CURR_XPATH, unnbr_xpath + 1)) {
+ if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
+ VTY_CURR_XPATH, unnbr_xpath + 1)) {
strlcpy(base_xpath, unnbr_xpath, sizeof(base_xpath));
- } else if (yang_dnode_exists(vty->candidate_config->dnode,
- "%s%s", VTY_CURR_XPATH,
- prgrp_xpath + 1)) {
+ } else if (yang_dnode_existsf(vty->candidate_config->dnode,
+ "%s%s", VTY_CURR_XPATH,
+ prgrp_xpath + 1)) {
strlcpy(base_xpath, prgrp_xpath, sizeof(base_xpath));
} else {
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,
argv[idx_peer]->arg, "");
- if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
- VTY_CURR_XPATH, unnbr_xpath + 1)) {
+ if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
+ VTY_CURR_XPATH, unnbr_xpath + 1)) {
strlcpy(base_xpath, unnbr_xpath, sizeof(base_xpath));
- } else if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
- VTY_CURR_XPATH, prgrp_xpath + 1)) {
+ } else if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
+ VTY_CURR_XPATH, prgrp_xpath + 1)) {
strlcpy(base_xpath, prgrp_xpath, sizeof(base_xpath));
} else {
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) {
snprintf(num_xpath, sizeof(num_xpath),
"/neighbors/neighbor[remote-address='%s']", peer_str);
- if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
- VTY_CURR_XPATH, num_xpath)) {
+ if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
+ VTY_CURR_XPATH, num_xpath)) {
snprintf(base_xpath, xpath_len,
FRR_BGP_NEIGHBOR_NUM_XPATH, peer_str,
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_str);
- if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
- VTY_CURR_XPATH, unnbr_xpath)) {
+ if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
+ VTY_CURR_XPATH, unnbr_xpath)) {
snprintf(base_xpath, xpath_len,
FRR_BGP_NEIGHBOR_UNNUM_XPATH, peer_str,
xpath ? xpath : "");
- } else if (yang_dnode_exists(vty->candidate_config->dnode,
- "%s%s", VTY_CURR_XPATH,
- prgrp_xpath)) {
+ } else if (yang_dnode_existsf(vty->candidate_config->dnode,
+ "%s%s", VTY_CURR_XPATH,
+ prgrp_xpath)) {
snprintf(base_xpath, xpath_len,
FRR_BGP_PEER_GROUP_XPATH, peer_str,
xpath ? xpath : "");
@@ -8085,7 +8085,7 @@ DEFPY_YANG(
bgp_afi_safi_get_container_str(afi, safi));
if (!no) {
- if (!yang_dnode_exists(
+ if (!yang_dnode_existsf(
vty->candidate_config->dnode,
"/frr-route-map:lib/route-map[name='%s']",
rmap_str)) {
diff --git a/bgpd/subdir.am b/bgpd/subdir.am
index b54c41cab..53225192f 100644
--- a/bgpd/subdir.am
+++ b/bgpd/subdir.am
@@ -214,8 +214,8 @@ bgpd_bgpd_SOURCES = bgpd/bgp_main.c
bgpd_bgp_btoa_SOURCES = bgpd/bgp_btoa.c
# 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_bgp_btoa_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 $(LIBYANG_LIBS) $(LIBCAP) $(LIBM) $(UST_LIBS)
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
diff --git a/configure.ac b/configure.ac
index c082a9e52..f84a3d3c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1866,8 +1866,8 @@ AC_SUBST([SNMP_CFLAGS])
dnl ---------------
dnl libyang
dnl ---------------
-PKG_CHECK_MODULES([LIBYANG], [libyang >= 1.0.184 libyang < 2.0], , [
- AC_MSG_ERROR([libyang (>= 1.0.184) was not found on your system.])
+PKG_CHECK_MODULES([LIBYANG], [libyang >= 2.0.0], , [
+ AC_MSG_ERROR([libyang (>= 2.0.0) was not found on your system.])
])
ac_cflags_save="$CFLAGS"
CFLAGS="$CFLAGS $LIBYANG_CFLAGS"
diff --git a/debian/control b/debian/control
index 7a08cbbdb..0bbe99b31 100644
--- a/debian/control
+++ b/debian/control
@@ -16,14 +16,14 @@ Build-Depends: bison,
libelf-dev,
libjson-c-dev | libjson0-dev,
libpam0g-dev | libpam-dev,
- libpcre3-dev,
+ libpcre2-dev,
libpython3-dev,
libreadline-dev,
librtr-dev <!pkg.frr.nortrlib>,
libsnmp-dev,
libssh-dev <!pkg.frr.nortrlib>,
libsystemd-dev <!pkg.frr.nosystemd>,
- libyang-dev (>= 1.0.184),
+ libyang2-dev,
lsb-base,
pkg-config,
python3,
diff --git a/doc/developer/building-libyang.rst b/doc/developer/building-libyang.rst
index 5f82447d7..a447f5830 100644
--- a/doc/developer/building-libyang.rst
+++ b/doc/developer/building-libyang.rst
@@ -10,11 +10,12 @@ The FRR project builds some binary ``libyang`` packages.
RPM packages are at our `RPM repository <https://rpm.frrouting.org>`_.
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::
- ``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::
@@ -26,31 +27,22 @@ DEB packages are available as CI artifacts `here
Depending on your platform, you may also need to install the PCRE
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**
.. note::
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
``libpcre-dev`` or ``pcre-devel``.
.. code-block:: console
- git clone https://github.com/CESNET/libyang.git
+ git clone https://github.com/CESNET/libyang.git -b libyang2
cd libyang
+ git checkout v2.0.0
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" ..
make
sudo make install
diff --git a/docker/ubuntu18-ci/Dockerfile b/docker/ubuntu18-ci/Dockerfile
index f6fa91038..86fbe4f49 100644
--- a/docker/ubuntu18-ci/Dockerfile
+++ b/docker/ubuntu18-ci/Dockerfile
@@ -26,19 +26,19 @@ RUN groupadd -r -g 92 frr && \
echo 'frr ALL = NOPASSWD: ALL' | tee /etc/sudoers.d/frr && \
mkdir -p /home/frr && chown frr.frr /home/frr
-#for libyang 1
-RUN apt-get install -y cmake libpcre3-dev
+#for libyang 2
+RUN apt-get install -y cmake libpcre2-dev
USER frr:frr
# build and install libyang1
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 && \
- git checkout v1.0.225 && \
+ git checkout v2.0.0 && \
mkdir build; cd build && \
- cmake -DENABLE_LYD_PRIV=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr \
- -D CMAKE_BUILD_TYPE:String="Release" .. && \
+ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \
+ -DCMAKE_BUILD_TYPE:String="Release" .. && \
make -j $(nproc) && \
sudo make install
@@ -47,7 +47,7 @@ COPY --chown=frr:frr . /home/frr/frr/
RUN cd && ls -al && ls -al frr
RUN cd ~/frr && \
- ./bootstrap.sh && \
+ ./bootstrap.sh && \
./configure \
--prefix=/usr \
--localstatedir=/var/run/frr \
diff --git a/docker/ubuntu20-ci/Dockerfile b/docker/ubuntu20-ci/Dockerfile
index 0b08c2f27..ead5c56c5 100644
--- a/docker/ubuntu20-ci/Dockerfile
+++ b/docker/ubuntu20-ci/Dockerfile
@@ -29,19 +29,19 @@ RUN groupadd -r -g 92 frr && \
echo 'frr ALL = NOPASSWD: ALL' | tee /etc/sudoers.d/frr && \
mkdir -p /home/frr && chown frr.frr /home/frr
-#for libyang 1
-RUN apt-get install -y cmake libpcre3-dev
+#for libyang 2
+RUN apt-get install -y cmake libpcre2-dev
USER frr:frr
# build and install libyang1
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 && \
- git checkout v1.0.225 && \
+ git checkout v2.0.0 && \
mkdir build; cd build && \
- cmake -DENABLE_LYD_PRIV=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr \
- -D CMAKE_BUILD_TYPE:String="Release" .. && \
+ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \
+ -DCMAKE_BUILD_TYPE:String="Release" .. && \
make -j $(nproc) && \
sudo make install
@@ -50,7 +50,7 @@ COPY --chown=frr:frr . /home/frr/frr/
RUN cd && ls -al && ls -al frr
RUN cd ~/frr && \
- ./bootstrap.sh && \
+ ./bootstrap.sh && \
./configure \
--prefix=/usr \
--localstatedir=/var/run/frr \
diff --git a/eigrpd/eigrp_cli.c b/eigrpd/eigrp_cli.c
index ae15e97d4..cf3999b45 100644
--- a/eigrpd/eigrp_cli.c
+++ b/eigrpd/eigrp_cli.c
@@ -880,7 +880,7 @@ static int eigrp_write_interface(struct vty *vty)
RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
FOR_ALL_INTERFACES(vrf, ifp) {
- dnode = yang_dnode_get(
+ dnode = yang_dnode_getf(
running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']",
ifp->name, vrf->name);
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 2c51f21d7..2a197ab2b 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -1306,7 +1306,7 @@ static int isis_interface_config_write(struct vty *vty)
FOR_ALL_INTERFACES (vrf, ifp) {
struct lyd_node *dnode;
- dnode = yang_dnode_get(
+ dnode = yang_dnode_getf(
running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']",
ifp->name, vrf->name);
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index 14fa414c5..5aea9f25d 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -110,7 +110,7 @@ DEFPY_YANG(no_router_isis, no_router_isis_cmd,
if (!vrf_name)
vrf_name = VRF_DEFAULT_NAME;
- if (!yang_dnode_exists(
+ if (!yang_dnode_existsf(
vty->candidate_config->dnode,
"/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag,
vrf_name)) {
@@ -277,8 +277,8 @@ DEFPY_YANG(no_ip_router_isis, no_ip_router_isis_cmd,
{
const struct lyd_node *dnode;
- dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-isisd:isis", VTY_CURR_XPATH);
+ dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-isisd:isis", VTY_CURR_XPATH);
if (!dnode)
return CMD_SUCCESS;
@@ -345,8 +345,8 @@ DEFPY_YANG(isis_bfd,
{
const struct lyd_node *dnode;
- dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-isisd:isis", VTY_CURR_XPATH);
+ dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-isisd:isis", VTY_CURR_XPATH);
if (dnode == NULL) {
vty_out(vty, "ISIS is not enabled on this circuit\n");
return CMD_SUCCESS;
@@ -371,8 +371,8 @@ DEFPY_YANG(isis_bfd_profile,
{
const struct lyd_node *dnode;
- dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-isisd:isis", VTY_CURR_XPATH);
+ dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-isisd:isis", VTY_CURR_XPATH);
if (dnode == NULL) {
vty_out(vty, "ISIS is not enabled on this circuit\n");
return CMD_SUCCESS;
@@ -3092,8 +3092,8 @@ DEFPY(isis_mpls_if_ldp_sync, isis_mpls_if_ldp_sync_cmd,
{
const struct lyd_node *dnode;
- dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-isisd:isis", VTY_CURR_XPATH);
+ dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-isisd:isis", VTY_CURR_XPATH);
if (dnode == NULL) {
vty_out(vty, "ISIS is not enabled on this circuit\n");
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;
- dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-isisd:isis", VTY_CURR_XPATH);
+ dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-isisd:isis", VTY_CURR_XPATH);
if (dnode == NULL) {
vty_out(vty, "ISIS is not enabled on this circuit\n");
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;
- dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-isisd:isis", VTY_CURR_XPATH);
+ dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-isisd:isis", VTY_CURR_XPATH);
if (dnode == NULL) {
vty_out(vty, "ISIS is not enabled on this circuit\n");
return CMD_SUCCESS;
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index 87cd732e0..68a4581a4 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -2509,10 +2509,10 @@ int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args)
if (args->event == NB_EV_VALIDATE) {
/* libyang doesn't like relative paths across module boundaries
*/
- ifname = yang_dnode_get_string(args->dnode->parent->parent,
- "./name");
- vrfname = yang_dnode_get_string(args->dnode->parent->parent,
- "./vrf");
+ ifname = yang_dnode_get_string(
+ lyd_parent(lyd_parent(args->dnode)), "./name");
+ vrfname = yang_dnode_get_string(
+ lyd_parent(lyd_parent(args->dnode)), "./vrf");
vrf = vrf_lookup_by_name(vrfname);
assert(vrf);
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:
/* libyang doesn't like relative paths across module boundaries
*/
- ifname = yang_dnode_get_string(args->dnode->parent->parent,
- "./name");
- vrfname = yang_dnode_get_string(args->dnode->parent->parent,
- "./vrf");
+ ifname = yang_dnode_get_string(
+ lyd_parent(lyd_parent(args->dnode)), "./name");
+ vrfname = yang_dnode_get_string(
+ lyd_parent(lyd_parent(args->dnode)), "./vrf");
vrf = vrf_lookup_by_name(vrfname);
assert(vrf);
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) {
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)
return NB_ERR_VALIDATION;
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) {
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)
return NB_ERR_VALIDATION;
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) {
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)
return NB_ERR_VALIDATION;
if (if_is_loopback(ifp)) {
diff --git a/lib/grammar_sandbox_main.c b/lib/grammar_sandbox_main.c
index 2066e4c96..6469b4926 100644
--- a/lib/grammar_sandbox_main.c
+++ b/lib/grammar_sandbox_main.c
@@ -54,7 +54,6 @@ int main(int argc, char **argv)
vty_init(master, true);
lib_cmd_init();
- yang_init(true);
nb_init(master, NULL, 0, false);
vty_stdio(vty_do_exit);
diff --git a/lib/if.c b/lib/if.c
index f8a693d8f..de2af435f 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -266,16 +266,16 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
char oldpath[XPATH_MAXLEN];
char newpath[XPATH_MAXLEN];
- if_dnode = yang_dnode_get(
+ if_dnode = yang_dnode_getf(
running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']/vrf",
ifp->name, old_vrf->name);
if (if_dnode) {
- yang_dnode_get_path(if_dnode->parent, oldpath,
+ yang_dnode_get_path(lyd_parent(if_dnode), oldpath,
sizeof(oldpath));
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));
nb_running_move_tree(oldpath, newpath);
running_config->version++;
diff --git a/lib/libfrr.c b/lib/libfrr.c
index 970e82c06..0817182f7 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -765,16 +765,14 @@ struct thread_master *frr_init(void)
log_ref_vty_init();
lib_error_init();
- yang_init(true);
-
- debug_init_cli();
-
nb_init(master, di->yang_modules, di->n_yang_modules, true);
if (nb_db_init() != NB_OK)
flog_warn(EC_LIB_NB_DATABASE,
"%s: failed to initialize northbound database",
__func__);
+ debug_init_cli();
+
return master;
}
diff --git a/lib/northbound.c b/lib/northbound.c
index 34ad5dbfa..3634fed04 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -83,14 +83,14 @@ static int nb_transaction_process(enum nb_event event,
char *errmsg, size_t errmsg_len);
static void nb_transaction_apply_finish(struct nb_transaction *transaction,
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 struct yang_list_keys *list_keys,
struct yang_translator *translator,
bool first, uint32_t flags,
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;
@@ -102,10 +102,10 @@ static int nb_node_check_config_only(const struct lys_node *snode, void *arg)
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 lys_node *sparent, *sparent_list;
+ struct lysc_node *sparent, *sparent_list;
nb_node = XCALLOC(MTYPE_NB_NODE, sizeof(*nb_node));
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);
}
if (CHECK_FLAG(snode->nodetype, LYS_LIST)) {
- struct lys_node_list *slist;
-
- slist = (struct lys_node_list *)snode;
- if (slist->keys_size == 0)
+ if (yang_snode_num_keys(snode) == 0)
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;
assert(snode->priv == NULL);
- lys_set_private(snode, nb_node);
+ ((struct lysc_node *)snode)->priv = nb_node;
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;
nb_node = snode->priv;
if (nb_node) {
- lys_set_private(snode, NULL);
+ ((struct lysc_node *)snode)->priv = NULL;
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);
}
-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).
*/
- snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0);
+ snode = lys_find_path(ly_native_ctx, NULL, path, 0);
if (!snode)
return NULL;
@@ -288,7 +285,7 @@ static unsigned int nb_node_validate_priority(const struct nb_node *nb_node)
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;
unsigned int *errors = arg;
@@ -339,7 +336,7 @@ int nb_config_merge(struct nb_config *config_dst, struct nb_config *config_src,
{
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)
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) {
case LYS_LEAF:
case LYS_LEAFLIST:
- if (lyd_wd_default((struct lyd_node_leaf_list *)dnode))
+ if (lyd_is_default(dnode))
break;
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);
/* Process child nodes recursively. */
- LY_TREE_FOR (dnode->child, child) {
+ LY_LIST_FOR (lyd_child(dnode), child) {
nb_config_diff_created(child, seq, changes);
}
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
* 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);
}
}
}
+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. */
static void nb_config_diff(const struct nb_config *config1,
const struct nb_config *config2,
struct nb_config_cbs *changes)
{
- struct lyd_difflist *diff;
- uint32_t seq = 0;
+ 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
- diff = lyd_diff(config1->dnode, config2->dnode,
- LYD_DIFFOPT_WITHDEFAULTS);
- assert(diff);
+ err = lyd_diff_siblings(config1->dnode, config2->dnode,
+ LYD_DIFF_DEFAULTS, &diff);
+ assert(!err);
- for (int i = 0; diff->type[i] != LYD_DIFF_END; i++) {
- LYD_DIFFTYPE type;
- struct lyd_node *dnode;
+ if (diff && DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL))
+ nb_config_diff_dnode_log("iterating diff", diff);
- type = diff->type[i];
+ uint32_t seq = 0;
+ LY_LIST_FOR (diff, root) {
+ LYD_TREE_DFS_BEGIN (root, dnode) {
+ op = nb_lyd_diff_get_op(dnode);
+
+ path = lyd_path(dnode, LYD_PATH_STD, NULL, 0);
+
+#if 0 /* Useful (but noisy) when debugging diff code, and for improving later \
+ */
+ 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);
+
+ /* 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) {
- case LYD_DIFF_CREATED:
- dnode = diff->second[i];
- nb_config_diff_created(dnode, &seq, changes);
- break;
- case LYD_DIFF_DELETED:
- dnode = diff->first[i];
- nb_config_diff_deleted(dnode, &seq, changes);
- break;
- case LYD_DIFF_CHANGED:
- dnode = diff->second[i];
- nb_config_diff_add_change(changes, NB_OP_MODIFY, &seq,
- dnode);
- break;
- case LYD_DIFF_MOVEDAFTER1:
- case LYD_DIFF_MOVEDAFTER2:
- default:
- continue;
+ /* Skip rest of sub-tree, move to next sibling
+ */
+ LYD_TREE_DFS_continue = 1;
+ break;
+ case 'r': /* replace */
+ /* either moving an entry or changing a value */
+ target = yang_dnode_get(config2->dnode, path);
+ assert(target);
+ nb_config_diff_add_change(changes, NB_OP_MODIFY,
+ &seq, target);
+ break;
+ case 'n': /* none */
+ default:
+ break;
+ }
+ free(path);
+ LYD_TREE_DFS_END(root, dnode);
}
}
- lyd_free_diff(diff);
+ lyd_free_tree(diff);
}
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;
char xpath_edit[XPATH_MAXLEN];
char dep_xpath[XPATH_MAXLEN];
+ LY_ERR err;
/* Use special notation for leaf-lists (RFC 6020, section 9.13.5). */
if (nb_node->snode->nodetype == LYS_LEAFLIST)
@@ -565,11 +653,15 @@ int nb_candidate_edit(struct nb_config *candidate,
switch (operation) {
case NB_OP_CREATE:
case NB_OP_MODIFY:
- ly_errno = 0;
- dnode = lyd_new_path(candidate->dnode, ly_native_ctx,
- xpath_edit, (void *)data->value, 0,
- LYD_PATH_OPT_UPDATE);
- if (dnode) {
+ err = lyd_new_path(candidate->dnode, ly_native_ctx, xpath_edit,
+ (void *)data->value, LYD_NEW_PATH_UPDATE,
+ &dnode);
+ if (err) {
+ flog_warn(EC_LIB_LIBYANG,
+ "%s: lyd_new_path(%s) failed: %d", __func__,
+ xpath_edit, err);
+ return NB_ERR;
+ } else if (dnode) {
/*
* create dependency
*
@@ -581,22 +673,18 @@ int nb_candidate_edit(struct nb_config *candidate,
nb_node->dep_cbs.get_dependency_xpath(
dnode, dep_xpath);
- ly_errno = 0;
- dep_dnode = lyd_new_path(candidate->dnode,
- ly_native_ctx,
- dep_xpath, NULL, 0,
- LYD_PATH_OPT_UPDATE);
- if (!dep_dnode && ly_errno) {
- flog_warn(EC_LIB_LIBYANG,
- "%s: lyd_new_path(%s) failed",
- __func__, dep_xpath);
+ err = lyd_new_path(candidate->dnode,
+ ly_native_ctx, dep_xpath,
+ NULL, LYD_NEW_PATH_UPDATE,
+ &dep_dnode);
+ if (err) {
+ flog_warn(
+ EC_LIB_LIBYANG,
+ "%s: lyd_new_path(%s) failed: %d",
+ __func__, dep_xpath, 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;
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);
if (dep_dnode)
- lyd_free(dep_dnode);
+ lyd_free_tree(dep_dnode);
}
- lyd_free(dnode);
+ lyd_free_tree(dnode);
break;
case NB_OP_MOVE:
/* 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,
size_t errmsg_len)
{
- if (lyd_validate(&candidate->dnode,
- LYD_OPT_STRICT | LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL,
- ly_native_ctx)
+ if (lyd_validate_all(&candidate->dnode, ly_native_ctx,
+ LYD_VALIDATE_NO_STATE, NULL)
!= 0) {
yang_print_errors(ly_native_ctx, errmsg, errmsg_len);
return NB_ERR_VALIDATION;
@@ -678,12 +765,12 @@ static int nb_candidate_validate_code(struct nb_context *context,
char *errmsg, size_t errmsg_len)
{
struct nb_config_cb *cb;
- struct lyd_node *root, *next, *child;
+ struct lyd_node *root, *child;
int ret;
/* First validate the candidate as a whole. */
- LY_TREE_FOR (candidate->dnode, root) {
- LY_TREE_DFS_BEGIN (root, next, child) {
+ LY_LIST_FOR (candidate->dnode, root) {
+ LYD_TREE_DFS_BEGIN (root, child) {
struct nb_node *nb_node;
nb_node = child->schema->priv;
@@ -696,7 +783,7 @@ static int nb_candidate_validate_code(struct nb_context *context,
return NB_ERR_VALIDATION;
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) {
char xpath[XPATH_MAXLEN];
- dnode = dnode->parent;
+ dnode = lyd_parent(dnode);
if (!dnode)
break;
@@ -1470,7 +1557,7 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction,
nb_apply_finish_cb_new(&cbs, nb_node, dnode);
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 struct yang_list_keys *list_keys,
struct yang_translator *translator,
bool first, uint32_t flags,
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;
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;
/* 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;
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,
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;
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. */
do {
+ const struct lysc_node_leaf *skey;
struct yang_list_keys list_keys;
char xpath[XPATH_MAXLEN * 2];
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. */
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),
sizeof(xpath) - strlen(xpath),
- "[%s='%s']", slist->keys[i]->name,
+ "[%s='%s']", skey->name,
list_keys.key[i]);
+ i++;
}
+ assert(i == list_keys.num);
} else {
/*
* 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;
}
-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 void *list_entry,
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. */
strlcpy(xpath, xpath_parent, sizeof(xpath));
if (!first && snode->nodetype != LYS_USES) {
- struct lys_node *parent;
+ struct lysc_node *parent;
/* Get the real parent. */
parent = snode->parent;
- while (parent && parent->nodetype == LYS_USES)
- parent = parent->parent;
/*
* When necessary, include the namespace of the augmenting
* module.
*/
- if (parent && parent->nodetype == LYS_AUGMENT)
+ if (parent && parent->module != snode->module)
snprintf(xpath + strlen(xpath),
sizeof(xpath) - strlen(xpath), "/%s:%s",
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
* all YANG lists (if any).
*/
- ly_errno = 0;
- dnode = lyd_new_path(NULL, ly_native_ctx, xpath, NULL, 0,
- LYD_PATH_OPT_UPDATE | LYD_PATH_OPT_NOPARENTRET);
- if (!dnode) {
- flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path() failed",
- __func__);
+
+ LY_ERR err = lyd_new_path(NULL, ly_native_ctx, xpath, NULL,
+ LYD_NEW_PATH_UPDATE, &dnode);
+ if (err || !dnode) {
+ const char *errmsg =
+ 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;
}
@@ -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.
*/
list_dnodes = list_new();
- for (dn = dnode; dn; dn = dn->parent) {
- if (dn->schema->nodetype != LYS_LIST || !dn->child)
+ for (dn = dnode; dn; dn = lyd_parent(dn)) {
+ if (dn->schema->nodetype != LYS_LIST || !lyd_child(dn))
continue;
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. */
memset(&list_keys, 0, sizeof(list_keys));
- LY_TREE_FOR (dn->child, child) {
- if (!lys_is_key((struct lys_node_leaf *)child->schema,
- NULL))
- continue;
+ LY_LIST_FOR (lyd_child(dn), child) {
+ if (!lysc_is_key(child->schema))
+ break;
strlcpy(list_keys.key[n],
yang_dnode_get_string(child, NULL),
sizeof(list_keys.key[n]));
n++;
}
list_keys.num = n;
- if (list_keys.num
- != ((struct lys_node_list *)dn->schema)->keys_size) {
+ if (list_keys.num != yang_snode_num_keys(dn->schema)) {
list_delete(&list_dnodes);
yang_dnode_free(dnode);
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 (dnode->schema->nodetype == LYS_LIST && dnode->child)
+ if (dnode->schema->nodetype == LYS_LIST && lyd_child(dnode))
ret = nb_oper_data_iter_children(
nb_node->snode, xpath, list_entry, &list_keys,
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,
- const struct lys_node *snode)
+ const struct lysc_node *snode)
{
struct nb_node *nb_node = snode->priv;
- struct lys_node_container *scontainer;
- struct lys_node_leaf *sleaf;
+ struct lysc_node_container *scontainer;
+ struct lysc_node_leaf *sleaf;
switch (operation) {
case NB_OP_CREATE:
@@ -1866,13 +1956,13 @@ bool nb_operation_is_valid(enum nb_operation operation,
switch (snode->nodetype) {
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
- if (sleaf->type.base != LY_TYPE_EMPTY)
+ sleaf = (struct lysc_node_leaf *)snode;
+ if (sleaf->type->basetype != LY_TYPE_EMPTY)
return false;
break;
case LYS_CONTAINER:
- scontainer = (struct lys_node_container *)snode;
- if (!scontainer->presence)
+ scontainer = (struct lysc_node_container *)snode;
+ if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE))
return false;
break;
case LYS_LIST:
@@ -1888,12 +1978,12 @@ bool nb_operation_is_valid(enum nb_operation operation,
switch (snode->nodetype) {
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
- if (sleaf->type.base == LY_TYPE_EMPTY)
+ sleaf = (struct lysc_node_leaf *)snode;
+ if (sleaf->type->basetype == LY_TYPE_EMPTY)
return false;
/* List keys can't be modified. */
- if (lys_is_key(sleaf, NULL))
+ if (lysc_is_key(sleaf))
return false;
break;
default:
@@ -1906,10 +1996,10 @@ bool nb_operation_is_valid(enum nb_operation operation,
switch (snode->nodetype) {
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
+ sleaf = (struct lysc_node_leaf *)snode;
/* List keys can't be deleted. */
- if (lys_is_key(sleaf, NULL))
+ if (lysc_is_key(sleaf))
return false;
/*
@@ -1925,8 +2015,8 @@ bool nb_operation_is_valid(enum nb_operation operation,
return false;
break;
case LYS_CONTAINER:
- scontainer = (struct lys_node_container *)snode;
- if (!scontainer->presence)
+ scontainer = (struct lysc_node_container *)snode;
+ if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE))
return false;
break;
case LYS_LIST:
@@ -1943,7 +2033,7 @@ bool nb_operation_is_valid(enum nb_operation operation,
switch (snode->nodetype) {
case LYS_LIST:
case LYS_LEAFLIST:
- if (!CHECK_FLAG(snode->flags, LYS_USERORDERED))
+ if (!CHECK_FLAG(snode->flags, LYS_ORDBY_USER))
return false;
break;
default:
@@ -1964,8 +2054,8 @@ bool nb_operation_is_valid(enum nb_operation operation,
case LYS_LEAFLIST:
break;
case LYS_CONTAINER:
- scontainer = (struct lys_node_container *)snode;
- if (!scontainer->presence)
+ scontainer = (struct lysc_node_container *)snode;
+ if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE))
return false;
break;
default:
@@ -2114,7 +2204,7 @@ static void *nb_running_unset_entry_helper(const struct lyd_node *dnode)
/* Unset user pointers from the child nodes. */
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);
}
}
@@ -2156,7 +2246,7 @@ static void *nb_running_get_entry_worker(const struct lyd_node *dnode,
rec_flag = rec_search;
- dnode = dnode->parent;
+ dnode = lyd_parent(dnode);
}
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,
const struct frr_yang_module_info *const modules[],
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;
+ yang_init(true, explicit_compile);
+
/* Load YANG modules and their corresponding northbound callbacks. */
- for (size_t i = 0; i < nmodules; i++)
- nb_load_module(modules[i]);
+ for (size_t i = 0; i < nmodules; 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. */
nb_validate_callbacks();
diff --git a/lib/northbound.h b/lib/northbound.h
index 417ecc81e..7ccab5cad 100644
--- a/lib/northbound.h
+++ b/lib/northbound.h
@@ -537,7 +537,7 @@ struct nb_dependency_callbacks {
*/
struct nb_node {
/* Back pointer to the libyang schema node. */
- const struct lys_node *snode;
+ const struct lysc_node *snode;
/* Data path of this YANG node. */
char xpath[XPATH_MAXLEN];
@@ -685,7 +685,7 @@ struct nb_transaction {
};
/* 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_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.
*/
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'
@@ -1285,15 +1285,6 @@ extern const char *nb_client_name(enum nb_client client);
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
* daemon initialization process.
*
diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c
index 81e30bce4..d291a1f24 100644
--- a/lib/northbound_cli.c
+++ b/lib/northbound_cli.c
@@ -448,6 +448,7 @@ static int nb_cli_candidate_load_file(struct vty *vty,
struct ly_ctx *ly_ctx;
int ly_format;
char buf[BUFSIZ];
+ LY_ERR err;
switch (format) {
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_ctx = translator ? translator->ly_ctx : ly_native_ctx;
- dnode = lyd_parse_path(ly_ctx, path, ly_format, LYD_OPT_EDIT);
- if (!dnode) {
+ err = lyd_parse_data_path(ly_ctx, path, ly_format,
+ LYD_PARSE_ONLY | LYD_PARSE_NO_STATE,
+ 0, &dnode);
+ if (err || !dnode) {
flog_warn(EC_LIB_LIBYANG, "%s: lyd_parse_path() failed",
__func__);
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)
return;
- lyd_schema_sort(config->dnode, 1);
-
/*
* Call lyd_validate() only to create default child nodes, ignoring
* 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.
*/
if (config != running_config)
- (void)lyd_validate(&config->dnode,
- LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL,
- ly_native_ctx);
+ (void)lyd_validate_all(&config->dnode, ly_native_ctx,
+ LYD_VALIDATE_NO_STATE, NULL);
}
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;
void *data;
- LY_TREE_FOR (root->child, child) {
+ LY_LIST_FOR (lyd_child(root), child) {
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 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);
+ }
vty_out(vty, "!\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;
}
- SET_FLAG(options, LYP_FORMAT | LYP_WITHSIBLINGS);
+ SET_FLAG(options, LYD_PRINT_WITHSIBLINGS);
if (with_defaults)
- SET_FLAG(options, LYP_WD_ALL);
+ SET_FLAG(options, LYD_PRINT_WD_ALL);
else
- SET_FLAG(options, LYP_WD_TRIM);
+ SET_FLAG(options, LYD_PRINT_WD_TRIM);
if (lyd_print_mem(&strp, dnode, format, options) == 0 && strp) {
vty_out(vty, "%s", strp);
@@ -1401,7 +1402,7 @@ DEFPY (show_config_transaction,
#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_data *data, void *arg)
{
@@ -1427,12 +1428,12 @@ static int nb_cli_oper_data_cb(const struct lys_node *snode,
} else
ly_ctx = ly_native_ctx;
- ly_errno = 0;
- dnode = lyd_new_path(dnode, ly_ctx, data->xpath, (void *)data->value, 0,
- LYD_PATH_OPT_UPDATE);
- if (!dnode && ly_errno) {
- flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path() failed",
- __func__);
+ LY_ERR err =
+ lyd_new_path(dnode, ly_ctx, data->xpath, (void *)data->value,
+ LYD_NEW_PATH_UPDATE, &dnode);
+ if (err) {
+ flog_warn(EC_LIB_LIBYANG, "%s: lyd_new_path(%s) failed: %s",
+ __func__, data->xpath, ly_errmsg(ly_native_ctx));
goto error;
}
@@ -1494,11 +1495,11 @@ DEFPY (show_yang_operational_data,
yang_dnode_free(dnode);
return CMD_WARNING;
}
- lyd_validate(&dnode, LYD_OPT_GET, ly_ctx);
+ (void)lyd_validate_all(&dnode, ly_ctx, 0, NULL);
/* Display the data. */
if (lyd_print_mem(&strp, dnode, format,
- LYP_FORMAT | LYP_WITHSIBLINGS | LYP_WD_ALL)
+ LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL)
!= 0
|| !strp) {
vty_out(vty, "%% Failed to display operational data.\n");
@@ -1551,13 +1552,12 @@ DEFPY (show_yang_module,
snprintf(flags, sizeof(flags), "%c%c",
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,
- (module->version == 2) ? "1.1" : "1.0",
- (module->rev_size > 0) ? module->rev[0].date
- : "-",
- flags, module->ns);
+ (module->parsed->version == 2) ? "1.1" : "1.0",
+ module->revision ? module->revision : "-", flags,
+ module->ns);
}
/* Dump the generated table. */
@@ -1577,21 +1577,21 @@ DEFPY (show_yang_module,
return CMD_SUCCESS;
}
-DEFPY (show_yang_module_detail,
- show_yang_module_detail_cmd,
- "show yang module\
+DEFPY(show_yang_module_detail, show_yang_module_detail_cmd,
+ "show yang module\
[module-translator WORD$translator_family]\
- WORD$module_name <summary|tree$tree|yang$yang|yin$yin>",
- SHOW_STR
- "YANG information\n"
- "Show loaded modules\n"
- "YANG module translator\n"
- "YANG module translator\n"
- "Module name\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")
+ WORD$module_name <compiled$compiled|summary|tree$tree|yang$yang|yin$yin>",
+ 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")
{
struct ly_ctx *ly_ctx;
struct yang_translator *translator = NULL;
@@ -1610,7 +1610,7 @@ DEFPY (show_yang_module_detail,
} else
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) {
vty_out(vty, "%% Module \"%s\" not found\n", module_name);
return CMD_WARNING;
@@ -1620,12 +1620,17 @@ DEFPY (show_yang_module_detail,
format = LYS_OUT_YANG;
else if (yin)
format = LYS_OUT_YIN;
+ else if (compiled)
+ format = LYS_OUT_YANG_COMPILED;
else if (tree)
format = LYS_OUT_TREE;
- else
- format = LYS_OUT_INFO;
+ else {
+ 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);
free(strp);
} else {
diff --git a/lib/northbound_confd.c b/lib/northbound_confd.c
index 403537e04..76af494e3 100644
--- a/lib/northbound_confd.c
+++ b/lib/northbound_confd.c
@@ -515,7 +515,7 @@ static int frr_confd_init_cdb(void)
/* Subscribe to all loaded YANG data modules. */
confd_spoints = list_new();
RB_FOREACH (module, yang_modules, &yang_modules) {
- struct lys_node *snode;
+ struct lysc_node *snode;
module->confd_hash = confd_str2hash(module->info->ns);
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
* 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;
int *spoint;
int ret;
@@ -762,7 +762,7 @@ static int frr_confd_data_get_object(struct confd_trans_ctx *tctx,
confd_hkeypath_t *kp)
{
struct nb_node *nb_node;
- const struct lys_node *child;
+ const struct lysc_node *child;
char xpath[XPATH_MAXLEN];
char xpath_child[XPATH_MAXLEN * 2];
struct list *elements;
@@ -789,7 +789,7 @@ static int frr_confd_data_get_object(struct confd_trans_ctx *tctx,
elements = yang_data_list_new();
/* 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;
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));
for (int j = 0; j < CONFD_OBJECTS_PER_TIME; j++) {
struct confd_next_object *object;
- struct lys_node *child;
+ struct lysc_node *child;
struct yang_data *data;
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. */
- 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;
char xpath_child[XPATH_MAXLEN * 2];
confd_value_t *v;
@@ -1187,7 +1187,7 @@ static int frr_confd_dp_read(struct thread *thread)
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 confd_data_cbs *data_cbs = arg;
@@ -1391,7 +1391,7 @@ static void frr_confd_cli_init(void)
/* ------------ 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)
{
struct nb_node *nb_node = snode->priv;
diff --git a/lib/northbound_grpc.cpp b/lib/northbound_grpc.cpp
index 58f4e4251..dc2d29c11 100644
--- a/lib/northbound_grpc.cpp
+++ b/lib/northbound_grpc.cpp
@@ -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_data *data, void *arg)
{
diff --git a/lib/northbound_sysrepo.c b/lib/northbound_sysrepo.c
index 63fd40f8d..7c463dd61 100644
--- a/lib/northbound_sysrepo.c
+++ b/lib/northbound_sysrepo.c
@@ -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)
{
struct nb_node *nb_node;
- const struct lys_node *snode;
- struct lys_node_container *scontainer;
- struct lys_node_leaf *sleaf;
- struct lys_node_leaflist *sleaflist;
+ const struct lysc_node *snode;
+ struct lysc_node_container *scontainer;
+ struct lysc_node_leaf *sleaf;
+ struct lysc_node_leaflist *sleaflist;
LY_DATA_TYPE type;
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;
switch (snode->nodetype) {
case LYS_CONTAINER:
- scontainer = (struct lys_node_container *)snode;
- if (!scontainer->presence)
+ scontainer = (struct lysc_node_container *)snode;
+ if (!CHECK_FLAG(scontainer->flags, LYS_PRESENCE))
return -1;
sr_data->type = SR_CONTAINER_PRESENCE_T;
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;
return 0;
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
+ sleaf = (struct lysc_node_leaf *)snode;
type = sleaf->type.base;
break;
case LYS_LEAFLIST:
- sleaflist = (struct lys_node_leaflist *)snode;
+ sleaflist = (struct lysc_node_leaflist *)snode;
type = sleaflist->type.base;
break;
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_data *data, void *arg)
{
@@ -562,7 +562,7 @@ static void frr_sr_subscribe_config(struct yang_module *module)
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 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;
}
-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 nb_node *nb_node;
diff --git a/lib/vrf.c b/lib/vrf.c
index 7888d435f..b6a53839c 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -1214,7 +1214,8 @@ const struct frr_yang_module_info frr_vrf_info = {
.get_next = lib_vrf_get_next,
.get_keys = lib_vrf_get_keys,
.lookup_entry = lib_vrf_lookup_entry,
- }
+ },
+ .priority = NB_DFLT_PRIORITY - 2,
},
{
.xpath = "/frr-vrf:lib/vrf/state/id",
diff --git a/lib/yang.c b/lib/yang.c
index df3b07fb0..1e241f049 100644
--- a/lib/yang.c
+++ b/lib/yang.c
@@ -25,8 +25,6 @@
#include "yang_translator.h"
#include "northbound.h"
-#include <libyang/user_types.h>
-
DEFINE_MTYPE_STATIC(LIB, YANG_MODULE, "YANG module");
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;
}
-static const char *yang_module_imp_clb(const char *mod_name,
- const char *mod_rev,
- const char *submod_name,
- const char *submod_rev,
- void *user_data,
- LYS_INFORMAT *format,
- void (**free_module_data)
- (void *, void*))
+static LY_ERR yang_module_imp_clb(const char *mod_name, const char *mod_rev,
+ const char *submod_name,
+ const char *submod_rev, void *user_data,
+ LYS_INFORMAT *format,
+ const char **module_data,
+ void (**free_module_data)(void *, void *))
{
struct yang_module_embed *e;
@@ -69,15 +65,17 @@ static const char *yang_module_imp_clb(const char *mod_name,
}
*format = e->format;
- return e->data;
+ *module_data = e->data;
+ return LY_SUCCESS;
}
- flog_warn(
- EC_LIB_YANG_MODULE_LOAD,
+ /* We get here for indirect modules like ietf-inet-types */
+ zlog_debug(
"YANG model \"%s@%s\" \"%s@%s\"not embedded, trying external file",
mod_name, mod_rev ? mod_rev : "*",
submod_name ? submod_name : "*", submod_rev ? submod_rev : "*");
- return NULL;
+
+ return LY_ENOTFOUND;
}
/* clang-format off */
@@ -111,7 +109,8 @@ struct yang_module *yang_module_load(const char *module_name)
struct yang_module *module;
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) {
flog_err(EC_LIB_YANG_MODULE_LOAD,
"%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);
}
-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,
yang_iterate_cb cb, uint16_t flags, void *arg)
{
- struct lys_node *child;
+ const struct lysc_node *child;
int ret = YANG_ITER_CONTINUE;
if (module && snode->module != module)
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) {
case LYS_CONTAINER:
if (CHECK_FLAG(flags, YANG_ITER_FILTER_NPCONTAINERS)) {
- struct lys_node_container *scontainer;
-
- scontainer = (struct lys_node_container *)snode;
- if (!scontainer->presence)
+ if (!CHECK_FLAG(snode->flags, LYS_PRESENCE))
goto next;
}
break;
case LYS_LEAF:
if (CHECK_FLAG(flags, YANG_ITER_FILTER_LIST_KEYS)) {
- struct lys_node_leaf *sleaf;
-
/* Ignore list keys. */
- sleaf = (struct lys_node_leaf *)snode;
- if (lys_is_key(sleaf, NULL))
+ if (lysc_is_key(snode))
goto next;
}
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_OUTPUT:
if (CHECK_FLAG(flags, YANG_ITER_FILTER_INPUT_OUTPUT))
goto next;
break;
default:
+ assert(snode->nodetype != LYS_AUGMENT
+ && snode->nodetype != LYS_GROUPING
+ && snode->nodetype != LYS_USES);
break;
}
@@ -212,19 +188,17 @@ int yang_snodes_iterate_subtree(const struct lys_node *snode,
next:
/*
- * YANG leafs and leaf-lists can't have child nodes, and trying to
- * access snode->child is undefined behavior.
+ * YANG leafs and leaf-lists can't have child nodes.
*/
if (CHECK_FLAG(snode->nodetype, LYS_LEAF | LYS_LEAFLIST))
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,
arg);
if (ret == YANG_ITER_STOP)
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);
while ((module_iter = ly_ctx_get_module_iter(ly_native_ctx, &idx))) {
- struct lys_node *snode;
+ struct lysc_node *snode;
if (!module_iter->implemented)
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,
flags, arg);
if (ret == YANG_ITER_STOP)
@@ -253,38 +239,32 @@ int yang_snodes_iterate(const struct lys_module *module, yang_iterate_cb cb,
return ret;
}
-void yang_snode_get_path(const struct lys_node *snode, enum yang_path_type type,
- char *xpath, size_t xpath_len)
+void yang_snode_get_path(const struct lysc_node *snode,
+ enum yang_path_type type, char *xpath,
+ size_t xpath_len)
{
- char *xpath_ptr;
-
switch (type) {
case YANG_PATH_SCHEMA:
- xpath_ptr = lys_path(snode, 0);
+ (void)lysc_path(snode, LYSC_PATH_LOG, xpath, xpath_len);
break;
case YANG_PATH_DATA:
- xpath_ptr = lys_data_path(snode);
+ (void)lysc_path(snode, LYSC_PATH_DATA, xpath, xpath_len);
break;
default:
flog_err(EC_LIB_DEVELOPMENT, "%s: unknown yang path type: %u",
__func__, type);
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) {
- struct lys_node_container *scontainer;
-
switch (parent->nodetype) {
case LYS_CONTAINER:
- scontainer = (struct lys_node_container *)parent;
- if (scontainer->presence)
+ if (CHECK_FLAG(parent->flags, LYS_PRESENCE))
return parent;
break;
case LYS_LIST:
@@ -298,9 +278,9 @@ struct lys_node *yang_snode_real_parent(const struct lys_node *snode)
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) {
switch (parent->nodetype) {
@@ -315,14 +295,14 @@ struct lys_node *yang_snode_parent_list(const struct lys_node *snode)
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) {
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
- if (sleaf->type.base == LY_TYPE_EMPTY)
+ sleaf = (struct lysc_node_leaf *)snode;
+ if (sleaf->type->basetype == LY_TYPE_EMPTY)
return true;
return false;
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) {
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
-
- /* NOTE: this might be null. */
- return sleaf->dflt;
+ sleaf = (const struct lysc_node_leaf *)snode;
+ return sleaf->dflt ? lyd_value_get_canonical(sleaf->module->ctx,
+ sleaf->dflt)
+ : NULL;
case LYS_LEAFLIST:
/* TODO: check leaf-list default values */
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 lys_type *type;
+ struct lysc_node_leaf *sleaf = (struct lysc_node_leaf *)snode;
+ struct lysc_type *type;
if (!CHECK_FLAG(sleaf->nodetype, LYS_LEAF | LYS_LEAFLIST))
return NULL;
- type = &sleaf->type;
- while (type->base == LY_TYPE_LEAFREF)
- type = &type->info.lref.target->type;
+ type = sleaf->type;
+ while (type->basetype == LY_TYPE_LEAFREF)
+ type = ((struct lysc_type_leafref *)type)->realtype;
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,
size_t xpath_len)
{
- char *xpath_ptr;
-
- xpath_ptr = lyd_path(dnode);
- strlcpy(xpath, xpath_ptr, xpath_len);
- free(xpath_ptr);
+ lyd_path(dnode, LYD_PATH_STD, xpath, xpath_len);
}
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;
}
-struct lyd_node *yang_dnode_get(const struct lyd_node *dnode,
- const char *xpath_fmt, ...)
+struct lyd_node *yang_dnode_get(const struct lyd_node *dnode, const char *xpath)
{
- va_list ap;
- char xpath[XPATH_MAXLEN];
- struct ly_set *set;
+ struct ly_set *set = NULL;
struct lyd_node *dnode_ret = NULL;
- va_start(ap, xpath_fmt);
- vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
- va_end(ap);
+ /*
+ * XXX a lot of the code uses this for style I guess. It shouldn't, as
+ * it adds to the xpath parsing complexity in libyang.
+ */
+ if (xpath[0] == '.' && xpath[1] == '/')
+ xpath += 2;
- set = lyd_find_path(dnode, xpath);
- assert(set);
- if (set->number == 0)
+ if (lyd_find_xpath(dnode, xpath, &set)) {
+ assert(0); /* XXX replicates old libyang1 base code */
+ goto exit;
+ }
+ if (set->count == 0)
goto exit;
- if (set->number > 1) {
+ if (set->count > 1) {
flog_warn(EC_LIB_YANG_DNODE_NOT_FOUND,
"%s: found %u elements (expected 0 or 1) [xpath %s]",
- __func__, set->number, xpath);
+ __func__, set->count, xpath);
goto exit;
}
- dnode_ret = set->set.d[0];
+ dnode_ret = set->dnodes[0];
exit:
- ly_set_free(set);
+ ly_set_free(set, NULL);
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;
char xpath[XPATH_MAXLEN];
- struct ly_set *set;
- bool found;
va_start(ap, xpath_fmt);
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
- set = lyd_find_path(dnode, xpath);
- assert(set);
- found = (set->number > 0);
- ly_set_free(set);
+ return yang_dnode_get(dnode, xpath);
+}
+
+bool yang_dnode_exists(const struct lyd_node *dnode, const char *xpath)
+{
+ struct ly_set *set = NULL;
+ bool exists = false;
- return found;
+ 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,
@@ -461,52 +475,42 @@ void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg,
vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
va_end(ap);
- set = lyd_find_path(dnode, xpath);
- assert(set);
- for (unsigned int i = 0; i < set->number; i++) {
+ if (lyd_find_xpath(dnode, xpath, &set)) {
+ assert(0); /* XXX libyang2: ly1 code asserted success */
+ return;
+ }
+ for (unsigned int i = 0; i < set->count; i++) {
int ret;
- dnode = set->set.d[i];
- ret = (*cb)(dnode, arg);
+ ret = (*cb)(set->dnodes[i], arg);
if (ret == YANG_ITER_STOP)
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;
- struct lys_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);
+ const struct lysc_node *snode;
+ struct lysc_node_leaf *sleaf;
+ if (xpath)
dnode = yang_dnode_get(dnode, xpath);
- }
assert(dnode);
snode = dnode->schema;
switch (snode->nodetype) {
case LYS_LEAF:
- sleaf = (struct lys_node_leaf *)snode;
- if (sleaf->type.base == LY_TYPE_EMPTY)
+ sleaf = (struct lysc_node_leaf *)snode;
+ if (sleaf->type->basetype == LY_TYPE_EMPTY)
return false;
- return lyd_wd_default((struct lyd_node_leaf_list *)dnode);
+ return lyd_is_default(dnode);
case LYS_LEAFLIST:
/* TODO: check leaf-list default values */
return false;
case LYS_CONTAINER:
- scontainer = (struct lys_node_container *)snode;
- if (scontainer->presence)
+ if (CHECK_FLAG(snode->flags, LYS_PRESENCE))
return false;
return true;
default:
@@ -514,24 +518,39 @@ bool yang_dnode_is_default(const struct lyd_node *dnode, const char *xpath_fmt,
}
}
-bool yang_dnode_is_default_recursive(const struct lyd_node *dnode)
+bool yang_dnode_is_defaultf(const struct lyd_node *dnode, const char *xpath_fmt,
+ ...)
{
- struct lys_node *snode;
- struct lyd_node *root, *next, *dnode_iter;
-
- snode = dnode->schema;
- if (CHECK_FLAG(snode->nodetype, LYS_LEAF | LYS_LEAFLIST))
+ 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)
+{
+ struct lyd_node *root, *dnode_iter;
if (!yang_dnode_is_default(dnode, NULL))
return false;
- LY_TREE_FOR (dnode->child, root) {
- LY_TREE_DFS_BEGIN (root, next, dnode_iter) {
+ if (CHECK_FLAG(dnode->schema->nodetype, LYS_LEAF | LYS_LEAFLIST))
+ return true;
+
+ LY_LIST_FOR (lyd_child(dnode), root) {
+ LYD_TREE_DFS_BEGIN (root, dnode_iter) {
if (!yang_dnode_is_default(dnode_iter, NULL))
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)
{
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 *dnode;
- int options;
-
- if (config_only)
- options = LYD_OPT_CONFIG;
- else
- options = LYD_OPT_DATA | LYD_OPT_DATA_NO_YANGLIB;
+ struct lyd_node *dnode = NULL;
+ int options = config_only ? LYD_VALIDATE_NO_STATE : 0;
- dnode = NULL;
- if (lyd_validate(&dnode, options, ly_ctx) != 0) {
+ if (lyd_validate_all(&dnode, ly_ctx, options, NULL) != 0) {
/* Should never happen. */
flog_err(EC_LIB_LIBYANG, "%s: lyd_validate() failed", __func__);
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)
{
- 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)
{
while (dnode->parent)
- dnode = dnode->parent;
- lyd_free_withsiblings(dnode);
+ dnode = lyd_parent(dnode);
+ lyd_free_all(dnode);
}
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)
{
if (enable) {
- ly_verb(LY_LLDBG);
- ly_verb_dbg(0xFF);
+ ly_log_level(LY_LLDBG);
+ ly_log_dbg_groups(0xFF);
} else {
- ly_verb(LY_LLERR);
- ly_verb_dbg(0);
+ ly_log_level(LY_LLERR);
+ 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;
+ LY_ERR err;
if (access(yang_models_path, R_OK | X_OK)) {
yang_models_path = NULL;
@@ -703,8 +721,11 @@ struct ly_ctx *yang_ctx_new_setup(bool embedded_modules)
YANG_MODELS_PATH);
}
- ctx = ly_ctx_new(yang_models_path, LY_CTX_DISABLE_SEARCHDIR_CWD);
- if (!ctx)
+ uint options = LY_CTX_NO_YANGLIBRARY | LY_CTX_DISABLE_SEARCHDIR_CWD;
+ if (explicit_compile)
+ options |= LY_CTX_EXPLICIT_COMPILE;
+ err = ly_ctx_new(yang_models_path, options, &ctx);
+ if (err)
return NULL;
if (embedded_modules)
@@ -713,14 +734,14 @@ struct ly_ctx *yang_ctx_new_setup(bool embedded_modules)
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. */
ly_set_log_clb(ly_log_cb, 1);
ly_log_options(LY_LOLOG | LY_LOSTORE);
/* 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) {
flog_err(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__);
exit(1);
@@ -729,6 +750,17 @@ void yang_init(bool embedded_modules)
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)
{
struct yang_module *module;
@@ -748,7 +780,7 @@ void yang_terminate(void)
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,
@@ -767,7 +799,7 @@ const struct lyd_node *yang_dnode_get_parent(const struct lyd_node *dnode,
break;
}
- orig_dnode = orig_dnode->parent;
+ orig_dnode = lyd_parent(orig_dnode);
}
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)
{
const struct lyd_node *parent;
- const struct lys_node_list *snode;
const struct lyd_node *key_leaf;
uint8_t keys_size;
switch (dnode->schema->nodetype) {
case LYS_LIST:
assert(dnode->parent);
- parent = dnode->parent;
- snode = (struct lys_node_list *)parent->schema;
+ parent = lyd_parent(dnode);
+ uint snode_num_keys = yang_snode_num_keys(parent->schema);
+ /* XXX libyang2: q: really don't understand this code. */
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;
if (key_leaf->prev == dnode)
return true;
@@ -812,13 +844,11 @@ bool yang_is_last_level_dnode(const struct lyd_node *dnode)
return false;
}
-
const struct lyd_node *
yang_get_subtree_with_no_sibling(const struct lyd_node *dnode)
{
bool parent = true;
const struct lyd_node *node;
- const struct lys_node_container *snode;
node = dnode;
if (node->schema->nodetype != LYS_LIST)
@@ -827,13 +857,11 @@ yang_get_subtree_with_no_sibling(const struct lyd_node *dnode)
while (parent) {
switch (node->schema->nodetype) {
case LYS_CONTAINER:
- snode = (struct lys_node_container *)node->schema;
- if ((!snode->presence)
- && yang_is_last_level_dnode(node)) {
+ if (!CHECK_FLAG(node->schema->flags, LYS_PRESENCE)) {
if (node->parent
&& (node->parent->schema->module
== dnode->schema->module))
- node = node->parent;
+ node = lyd_parent(node);
else
parent = false;
} else
@@ -845,7 +873,7 @@ yang_get_subtree_with_no_sibling(const struct lyd_node *dnode)
if (node->parent
&& (node->parent->schema->module
== dnode->schema->module))
- node = node->parent;
+ node = lyd_parent(node);
else
parent = false;
} 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)
{
unsigned int count;
- struct lys_node *schema;
+ const struct lysc_node *schema;
if (!node
|| ((node->schema->nodetype != LYS_LIST)
@@ -884,11 +912,3 @@ uint32_t yang_get_list_elements_count(const struct lyd_node *node)
} while (node);
return count;
}
-
-
-const struct lyd_node *yang_dnode_get_child(const struct lyd_node *dnode)
-{
- if (dnode)
- return dnode->child;
- return NULL;
-}
diff --git a/lib/yang.h b/lib/yang.h
index b8bf07ee7..d4517f969 100644
--- a/lib/yang.h
+++ b/lib/yang.h
@@ -99,13 +99,10 @@ enum yang_iter_flags {
/* Filter RPC input/output nodes. */
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. */
-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. */
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:
* 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,
yang_iterate_cb cb, uint16_t flags,
void *arg);
@@ -222,7 +219,7 @@ extern int yang_snodes_iterate(const struct lys_module *module,
* xpath_len
* 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,
size_t xpath_len);
@@ -236,7 +233,7 @@ extern void yang_snode_get_path(const struct lys_node *snode,
* Returns:
* 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.
@@ -247,7 +244,7 @@ extern struct lys_node *yang_snode_real_parent(const struct lys_node *snode);
* Returns:
* 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,
@@ -259,7 +256,7 @@ extern struct lys_node *yang_snode_parent_list(const struct lys_node *snode);
* Returns:
* 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.
@@ -270,7 +267,7 @@ extern bool yang_snode_is_typeless_data(const struct lys_node *snode);
* Returns:
* 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
@@ -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
* 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.
@@ -322,14 +339,49 @@ extern const char *yang_dnode_get_schema_name(const struct lyd_node *dnode,
* dnode
* Base libyang data node to operate on.
*
- * xpath_fmt
- * XPath expression (absolute or relative).
+ * xpath
+ * Limited XPath (absolute or relative) string. See Path in libyang
+ * documentation for restrictions.
*
* Returns:
* The libyang data node if found, or NULL if not found.
*/
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.
@@ -338,13 +390,17 @@ extern struct lyd_node *yang_dnode_get(const struct lyd_node *dnode,
* Base libyang data node to operate on.
*
* 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:
- * 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,
- const char *xpath_fmt, ...);
+extern bool yang_dnode_existsf(const struct lyd_node *dnode,
+ const char *xpath_fmt, ...);
/*
* 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 expression (absolute or relative).
+ *
+ * ...
+ * any parameters for xpath_fmt.
*/
void yang_dnode_iterate(yang_dnode_iter_cb cb, void *arg,
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
* Base libyang data node to operate on.
*
- * xpath_fmt
+ * xpath
* Optional XPath expression (absolute or relative) to specify a different
* 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.
*/
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
@@ -437,7 +516,8 @@ extern struct lyd_node *yang_dnode_dup(const struct lyd_node *dnode);
* Delete a libyang data node.
*
* 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);
@@ -493,8 +573,13 @@ extern struct yang_data *yang_data_list_find(const struct list *list,
*
* embedded_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.
@@ -528,8 +613,16 @@ extern const char *yang_print_errors(struct ly_ctx *ly_ctx, char *buf,
*
* embedded_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
@@ -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);
-
-/* 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 */
bool yang_is_last_list_dnode(const struct lyd_node *dnode);
diff --git a/lib/yang_translator.c b/lib/yang_translator.c
index 5b1d96f24..d562e4d29 100644
--- a/lib/yang_translator.c
+++ b/lib/yang_translator.c
@@ -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,
- const struct lys_node *snode,
+ const struct lysc_node *snode,
const char *xpath_from_fmt,
const char *xpath_to_fmt)
{
@@ -135,13 +135,15 @@ struct yang_translator *yang_translator_load(const char *path)
struct lyd_node *dnode;
struct ly_set *set;
struct listnode *ln;
+ LY_ERR err;
/* Load module translator (JSON file). */
- dnode = lyd_parse_path(ly_translator_ctx, path, LYD_JSON,
- LYD_OPT_CONFIG);
- if (!dnode) {
+ err = lyd_parse_data_path(ly_translator_ctx, path, LYD_JSON,
+ LYD_PARSE_NO_STATE, LYD_VALIDATE_NO_STATE,
+ &dnode);
+ if (err) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
- "%s: lyd_parse_path() failed", __func__);
+ "%s: lyd_parse_path() failed: %d", __func__, err);
return NULL;
}
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);
/* 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) {
flog_warn(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__);
goto error;
}
- /* Load modules and deviations. */
- set = lyd_find_path(dnode, "./module");
- assert(set);
- for (size_t i = 0; i < set->number; i++) {
+ /* Load modules */
+ if (lyd_find_xpath(dnode, "./module", &set) != LY_SUCCESS)
+ assert(0); /* XXX libyang2: old ly1 code asserted success */
+
+ for (size_t i = 0; i < set->count; i++) {
const char *module_name;
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,
- module_name, NULL);
+ module_name, NULL, NULL);
if (!tmodule->module) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: failed to load module: %s", __func__,
module_name);
- ly_set_free(set);
+ ly_set_free(set, NULL);
goto error;
}
+ }
- module_name =
- yang_dnode_get_string(set->set.d[i], "./deviations");
- tmodule->deviations = ly_ctx_load_module(translator->ly_ctx,
- module_name, NULL);
+ /* Count nodes in modules. */
+ for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) {
+ tmodule->nodes_before_deviations =
+ 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) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: failed to load module: %s", __func__,
module_name);
- ly_set_free(set);
+ ly_set_free(set, NULL);
goto error;
}
- lys_set_disabled(tmodule->deviations);
- listnode_add(translator->modules, tmodule);
+ tmodule->nodes_after_deviations =
+ yang_module_nodes_count(tmodule->module);
}
- ly_set_free(set);
+ ly_set_free(set, NULL);
/* 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 =
- yang_module_nodes_count(tmodule->module);
tmodule->coverage = ((double)tmodule->nodes_after_deviations
/ (double)tmodule->nodes_before_deviations)
* 100;
}
/* Load mappings. */
- set = lyd_find_path(dnode, "./module/mappings");
- assert(set);
- for (size_t i = 0; i < set->number; i++) {
+ if (lyd_find_xpath(dnode, "./module/mappings", &set) != LY_SUCCESS)
+ assert(0); /* XXX libyang2: old ly1 code asserted success */
+ for (size_t i = 0; i < set->count; i++) {
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->dnodes[i], "./custom");
- xpath_custom = yang_dnode_get_string(set->set.d[i], "./custom");
- snode_custom = ly_ctx_get_node(translator->ly_ctx, NULL,
- xpath_custom, 0);
+ snode_custom = lys_find_path(translator->ly_ctx, NULL,
+ xpath_custom, 0);
if (!snode_custom) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: unknown data path: %s", __func__,
xpath_custom);
- ly_set_free(set);
+ ly_set_free(set, NULL);
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 =
- ly_ctx_get_node(ly_native_ctx, NULL, xpath_native, 0);
+ lys_find_path(ly_native_ctx, NULL, xpath_native, 0);
if (!snode_native) {
flog_warn(EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: unknown data path: %s", __func__,
xpath_native);
- ly_set_free(set);
+ ly_set_free(set, NULL);
goto error;
}
@@ -262,7 +269,7 @@ struct yang_translator *yang_translator_load(const char *path)
yang_mapping_add(translator, YANG_TRANSLATE_FROM_NATIVE,
snode_native, xpath_native, xpath_custom);
}
- ly_set_free(set);
+ ly_set_free(set, NULL);
/* Validate mappings. */
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);
translator->modules->del = (void (*)(void *))yang_tmodule_delete;
list_delete(&translator->modules);
- ly_ctx_destroy(translator->ly_ctx, NULL);
+ ly_ctx_destroy(translator->ly_ctx);
RB_REMOVE(yang_translators, &yang_translators, 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)
{
struct ly_ctx *ly_ctx;
- const struct lys_node *snode;
+ const struct lysc_node *snode;
struct yang_mapping_node *mapping;
char xpath_canonical[XPATH_MAXLEN];
char keys[4][LIST_MAXKEYLEN];
@@ -319,7 +326,7 @@ yang_translate_xpath(const struct yang_translator *translator, int dir,
else
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) {
flog_warn(EC_LIB_YANG_TRANSLATION_ERROR,
"%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 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. */
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);
/* Iterate over all nodes from the data tree. */
- LY_TREE_FOR (*dnode, root) {
- LY_TREE_DFS_BEGIN (root, next, dnode_iter) {
+ LY_LIST_FOR (*dnode, root) {
+ LYD_TREE_DFS_BEGIN (root, dnode_iter) {
char xpath[XPATH_MAXLEN];
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. */
- ly_errno = 0;
- if (!lyd_new_path(new, ly_ctx, xpath,
- (void *)yang_dnode_get_string(
- dnode_iter, NULL),
- 0, LYD_PATH_OPT_UPDATE)
- && ly_errno) {
+ if (lyd_new_path(new, ly_ctx, xpath,
+ (void *)yang_dnode_get_string(
+ dnode_iter, NULL),
+ LYD_NEW_PATH_UPDATE, NULL)) {
flog_err(EC_LIB_LIBYANG,
"%s: lyd_new_path() failed", __func__);
goto error;
}
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;
};
-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)
{
struct translator_validate_args *args = arg;
struct yang_mapping_node *mapping;
- const struct lys_node *snode_native;
- const struct lys_type *stype_custom, *stype_native;
+ const struct lysc_node *snode_native;
+ const struct lysc_type *stype_custom, *stype_native;
char xpath[XPATH_MAXLEN];
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 =
- 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);
/* Check if the YANG types are compatible. */
stype_custom = yang_snode_get_type(snode_custom);
stype_native = yang_snode_get_type(snode_native);
if (stype_custom && stype_native) {
- if (stype_custom->base != stype_native->base) {
+ if (stype_custom->basetype != stype_native->basetype) {
flog_warn(
EC_LIB_YANG_TRANSLATOR_LOAD,
"%s: YANG types are incompatible (xpath: \"%s\")",
@@ -486,7 +491,7 @@ static unsigned int yang_translator_validate(struct yang_translator *translator)
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;
@@ -511,14 +516,14 @@ static unsigned int yang_module_nodes_count(const struct lys_module *module)
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) {
flog_err(EC_LIB_LIBYANG, "%s: ly_ctx_new() failed", __func__);
exit(1);
}
if (!ly_ctx_load_module(ly_translator_ctx, "frr-module-translator",
- NULL)) {
+ NULL, NULL)) {
flog_err(
EC_LIB_YANG_MODULE_LOAD,
"%s: failed to load the \"frr-module-translator\" module",
@@ -536,5 +541,5 @@ void yang_translator_terminate(void)
yang_translator_unload(translator);
}
- ly_ctx_destroy(ly_translator_ctx, NULL);
+ ly_ctx_destroy(ly_translator_ctx);
}
diff --git a/lib/yang_wrappers.c b/lib/yang_wrappers.c
index 98f8fea0f..85aa003db 100644
--- a/lib/yang_wrappers.c
+++ b/lib/yang_wrappers.c
@@ -26,12 +26,80 @@
#include "nexthop.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)
{
- const struct lys_node *snode;
+ const struct lysc_node *snode;
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) {
flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
"%s: unknown data path: %s", __func__, xpath);
@@ -45,16 +113,6 @@ static const char *yang_get_default_value(const char *xpath)
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.
*/
@@ -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,
...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_BOOL);
- return dleaf->value.bln;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_BOOL);
+ return dvalue->boolean;
}
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,
...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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);
- }
+ 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;
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_DEC64);
-
- return lyd_dec64_to_double(dnode);
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ dectype = (const struct lysc_type_dec *)dvalue->realtype;
+ assert(dectype->basetype == LY_TYPE_DEC64);
+ assert(dectype->fraction_digits < sizeof(denom) / sizeof(*denom));
+ return (double)dvalue->dec64 * denom[dectype->fraction_digits];
}
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)
{
- const struct lys_node *snode;
- const struct lys_node_leaf *sleaf;
- const struct lys_type *type;
- const struct lys_type_info_enums *enums;
+ const struct lysc_node *snode;
+ const struct lysc_node_leaf *sleaf;
+ const struct lysc_type_enum *type;
+ 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) {
flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
"%s: unknown data path: %s", __func__, xpath);
@@ -185,18 +224,17 @@ int yang_str2enum(const char *xpath, const char *value)
abort();
}
- sleaf = (const struct lys_node_leaf *)snode;
- type = &sleaf->type;
- enums = &type->info.enums;
- while (enums->count == 0 && type->der) {
- type = &type->der->type;
- enums = &type->info.enums;
- }
- for (unsigned int i = 0; i < enums->count; i++) {
- const struct lys_type_enum *enm = &enums->enm[i];
-
- if (strmatch(value, enm->name))
- return enm->value;
+ assert(snode->nodetype == LYS_LEAF);
+ sleaf = (const struct lysc_node_leaf *)snode;
+ type = (const struct lysc_type_enum *)sleaf->type;
+ assert(type->basetype == LY_TYPE_ENUM);
+ enums = type->enums;
+ unsigned int count = LY_ARRAY_COUNT(enums);
+ for (unsigned int i = 0; i < count; i++) {
+ if (strmatch(value, enums[i].name)) {
+ assert(CHECK_FLAG(enums[i].flags, LYS_SET_VALUE));
+ return enums[i].value;
+ }
}
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)
{
- const struct lys_node *snode;
- const struct lys_node_leaf *sleaf;
- const struct lys_type *type;
- const struct lys_type_info_enums *enums;
+ const struct lysc_node *snode;
+ const struct lysc_node_leaf *sleaf;
+ const struct lysc_type_enum *type;
+ 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) {
flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
"%s: unknown data path: %s", __func__, xpath);
@@ -221,18 +259,16 @@ struct yang_data *yang_data_new_enum(const char *xpath, int value)
abort();
}
- sleaf = (const struct lys_node_leaf *)snode;
- type = &sleaf->type;
- enums = &type->info.enums;
- while (enums->count == 0 && type->der) {
- type = &type->der->type;
- enums = &type->info.enums;
- }
- for (unsigned int i = 0; i < enums->count; i++) {
- const struct lys_type_enum *enm = &enums->enm[i];
-
- if (value == enm->value)
- return yang_data_new(xpath, enm->name);
+ assert(snode->nodetype == LYS_LEAF);
+ sleaf = (const struct lysc_node_leaf *)snode;
+ type = (const struct lysc_type_enum *)sleaf->type;
+ assert(type->basetype == LY_TYPE_ENUM);
+ enums = type->enums;
+ unsigned int count = LY_ARRAY_COUNT(enums);
+ for (unsigned int i = 0; i < count; i++) {
+ if (CHECK_FLAG(enums[i].flags, LYS_SET_VALUE)
+ && value == enums[i].value)
+ return yang_data_new(xpath, enums[i].name);
}
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,
...)
{
- const struct lyd_node_leaf_list *dleaf;
+ const struct lyd_value *dvalue;
- 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;
- assert(dleaf->value_type == LY_TYPE_ENUM);
- return dleaf->value.enm->value;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_ENUM);
+ assert(dvalue->enum_item->flags & LYS_SET_VALUE);
+ return dvalue->enum_item->value;
}
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,
...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_INT8);
- return dleaf->value.int8;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_INT8);
+ return dvalue->int8;
}
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_INT16);
- return dleaf->value.int16;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_INT16);
+ return dvalue->int16;
}
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_INT32);
- return dleaf->value.int32;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_INT32);
+ return dvalue->int32;
}
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_INT64);
- return dleaf->value.int64;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_INT64);
+ return dvalue->int64;
}
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_UINT8);
- return dleaf->value.uint8;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_UINT8);
+ return dvalue->uint8;
}
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_UINT16);
- return dleaf->value.uint16;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_UINT16);
+ return dvalue->uint16;
}
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_UINT32);
- return dleaf->value.uint32;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_UINT32);
+ return dvalue->uint32;
}
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_UINT64);
- return dleaf->value.uint64;
+ const struct lyd_value *dvalue;
+ dvalue = YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt);
+ assert(dvalue->realtype->basetype == LY_TYPE_UINT64);
+ return dvalue->uint64;
}
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 *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
+ return YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
}
void yang_dnode_get_string_buf(char *buf, size_t size,
const struct lyd_node *dnode,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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) {
+ const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ if (strlcpy(buf, canon, size) >= size) {
char xpath[XPATH_MAXLEN];
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;
char xpath[XPATH_MAXLEN];
- const struct lyd_node_leaf_list *dleaf;
+ const struct lyd_node_term *dleaf;
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);
if (dnode) {
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- if (dleaf->value_type == LY_TYPE_EMPTY)
+ dleaf = (const struct lyd_node_term *)dnode;
+ if (dleaf->value.realtype->basetype == LY_TYPE_EMPTY)
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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);
- }
-
+ const char *canon;
/*
* Initialize prefix to avoid static analyzer complaints about
* uninitialized memory.
*/
memset(prefix, 0, sizeof(*prefix));
- dleaf = (const struct lyd_node_leaf_list *)dnode;
- assert(dleaf->value_type == LY_TYPE_STRING);
- (void)str2prefix(dleaf->value_str, prefix);
+ /* XXX ip_prefix is a native type now in ly2, leverage? */
+ canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ (void)str2prefix(canon, prefix);
}
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_STRING);
- (void)inet_pton(AF_INET, dleaf->value_str, addr);
+ /* XXX libyang2 IPv4 address is a native type now in ly2 */
+ const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ (void)inet_pton(AF_INET, canon, addr);
}
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
struct prefix_ipv4 *prefix4 = prefix.p4;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_STRING);
- (void)str2prefix_ipv4(dleaf->value_str, prefix4);
+ /* XXX libyang2: ipv4/6 address is a native type now in ly2 */
+ const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ (void)str2prefix_ipv4(canon, prefix4);
}
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_STRING);
- (void)inet_pton(AF_INET6, dleaf->value_str, addr);
+ /* XXX libyang2: IPv6 address is a native type now, leverage. */
+ const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ (void)inet_pton(AF_INET6, canon, addr);
}
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
struct prefix_ipv6 *prefix6 = prefix.p6;
- 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;
- assert(dleaf->value_type == LY_TYPE_STRING);
- (void)str2prefix_ipv6(dleaf->value_str, prefix6);
+ /* XXX IPv6 address is a native type now in ly2 -- can we leverage? */
+ const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ (void)str2prefix_ipv6(canon, prefix6);
}
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,
const char *xpath_fmt, ...)
{
- const struct lyd_node_leaf_list *dleaf;
-
- 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;
- assert(dleaf->value_type == LY_TYPE_STRING);
- (void)str2ipaddr(dleaf->value_str, addr);
+ /* XXX IPv4 address could be a plugin type now in ly2, leverage? */
+ const char *canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+ (void)str2ipaddr(canon, addr);
}
void yang_get_default_ip(struct ipaddr *var, const char *xpath_fmt, ...)
diff --git a/pathd/path_pcep_debug.c b/pathd/path_pcep_debug.c
index 370484dc1..55148d9d0 100644
--- a/pathd/path_pcep_debug.c
+++ b/pathd/path_pcep_debug.c
@@ -980,7 +980,7 @@ const char *format_yang_dnode(struct lyd_node *dnode)
char *buff;
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);
memcpy(_debug_buff, buff, len);
free(buff);
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 90aa15bee..548c866e4 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -7986,8 +7986,8 @@ DEFUN (interface_no_ip_igmp,
snprintf(pim_if_xpath, sizeof(pim_if_xpath),
"%s/frr-pim:pim", VTY_CURR_XPATH);
- pim_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/pim-enable", pim_if_xpath);
+ pim_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/pim-enable", pim_if_xpath);
if (!pim_enable_dnode) {
nb_cli_enqueue_change(vty, pim_if_xpath, 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;
- pim_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-pim:pim/pim-enable",
- VTY_CURR_XPATH);
+ pim_enable_dnode =
+ yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH);
if (!pim_enable_dnode) {
nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY,
"true");
@@ -8157,9 +8157,9 @@ DEFUN (interface_ip_igmp_query_max_response_time,
{
const struct lyd_node *pim_enable_dnode;
- pim_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-pim:pim/pim-enable",
- VTY_CURR_XPATH);
+ pim_enable_dnode =
+ yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH);
if (!pim_enable_dnode) {
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;
- pim_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-pim:pim/pim-enable",
- VTY_CURR_XPATH);
+ pim_enable_dnode =
+ yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH);
if (!pim_enable_dnode) {
nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY,
"true");
@@ -8254,9 +8254,9 @@ DEFUN (interface_ip_igmp_last_member_query_count,
{
const struct lyd_node *pim_enable_dnode;
- pim_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-pim:pim/pim-enable",
- VTY_CURR_XPATH);
+ pim_enable_dnode =
+ yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH);
if (!pim_enable_dnode) {
nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY,
"true");
@@ -8301,9 +8301,9 @@ DEFUN (interface_ip_igmp_last_member_query_interval,
{
const struct lyd_node *pim_enable_dnode;
- pim_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-pim:pim/pim-enable",
- VTY_CURR_XPATH);
+ pim_enable_dnode =
+ yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH);
if (!pim_enable_dnode) {
nb_cli_enqueue_change(vty, "./igmp-enable", NB_OP_MODIFY,
"true");
@@ -8531,8 +8531,8 @@ DEFUN_HIDDEN (interface_no_ip_pim_ssm,
snprintf(igmp_if_xpath, sizeof(igmp_if_xpath),
"%s/frr-igmp:igmp", VTY_CURR_XPATH);
- igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/igmp-enable", igmp_if_xpath);
+ igmp_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/igmp-enable", igmp_if_xpath);
if (!igmp_enable_dnode) {
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),
"%s/frr-igmp:igmp", VTY_CURR_XPATH);
- igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/igmp-enable", igmp_if_xpath);
+ igmp_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/igmp-enable", igmp_if_xpath);
if (!igmp_enable_dnode) {
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),
"%s/frr-igmp:igmp", VTY_CURR_XPATH);
- igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/igmp-enable", igmp_if_xpath);
+ igmp_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/igmp-enable", igmp_if_xpath);
if (!igmp_enable_dnode) {
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;
const struct lyd_node *igmp_enable_dnode;
- igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-igmp:igmp/igmp-enable",
- VTY_CURR_XPATH);
+ igmp_enable_dnode =
+ yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH);
if (!igmp_enable_dnode) {
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
"true");
@@ -9436,9 +9436,9 @@ DEFPY (ip_pim_bfd,
{
const struct lyd_node *igmp_enable_dnode;
- igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-igmp:igmp/igmp-enable",
- VTY_CURR_XPATH);
+ igmp_enable_dnode =
+ yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH);
if (!igmp_enable_dnode)
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
"true");
@@ -9491,9 +9491,9 @@ DEFUN (ip_pim_bsm,
{
const struct lyd_node *igmp_enable_dnode;
- igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-igmp:igmp/igmp-enable",
- VTY_CURR_XPATH);
+ igmp_enable_dnode =
+ yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH);
if (!igmp_enable_dnode)
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
"true");
@@ -9530,9 +9530,9 @@ DEFUN (ip_pim_ucast_bsm,
{
const struct lyd_node *igmp_enable_dnode;
- igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-igmp:igmp/igmp-enable",
- VTY_CURR_XPATH);
+ igmp_enable_dnode =
+ yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH);
if (!igmp_enable_dnode)
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
"true");
@@ -9589,9 +9589,9 @@ DEFUN_HIDDEN(
int idx_number_3 = 5;
const struct lyd_node *igmp_enable_dnode;
- igmp_enable_dnode = yang_dnode_get(vty->candidate_config->dnode,
- "%s/frr-igmp:igmp/igmp-enable",
- VTY_CURR_XPATH);
+ igmp_enable_dnode =
+ yang_dnode_getf(vty->candidate_config->dnode,
+ "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH);
if (!igmp_enable_dnode)
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
"true");
diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c
index 4598297f9..003a9947e 100644
--- a/pimd/pim_nb_config.c
+++ b/pimd/pim_nb_config.c
@@ -524,11 +524,10 @@ static bool is_pim_interface(const struct lyd_node *dnode)
const struct lyd_node *igmp_enable_dnode;
yang_dnode_get_path(dnode, if_xpath, sizeof(if_xpath));
- pim_enable_dnode = yang_dnode_get(dnode, "%s/frr-pim:pim/pim-enable",
- if_xpath);
- igmp_enable_dnode = yang_dnode_get(dnode,
- "%s/frr-igmp:igmp/igmp-enable",
- if_xpath);
+ pim_enable_dnode =
+ yang_dnode_getf(dnode, "%s/frr-pim:pim/pim-enable", if_xpath);
+ igmp_enable_dnode = yang_dnode_getf(
+ dnode, "%s/frr-igmp:igmp/igmp-enable", if_xpath);
if (((pim_enable_dnode) &&
(yang_dnode_get_bool(pim_enable_dnode, "."))) ||
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index 47c6ad41a..e24a84d1e 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -176,7 +176,7 @@ BuildRequires: make
BuildRequires: ncurses-devel
BuildRequires: readline-devel
BuildRequires: texinfo
-BuildRequires: libyang-devel >= 1.0.184
+BuildRequires: libyang2-devel
%if 0%{?rhel} && 0%{?rhel} < 7
#python27-devel is available from ius community repo for RedHat/CentOS 6
BuildRequires: python27-devel
diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c
index 43e5b21fa..0c5730b4d 100644
--- a/ripd/rip_cli.c
+++ b/ripd/rip_cli.c
@@ -903,9 +903,9 @@ DEFPY_YANG (ip_rip_authentication_string,
return CMD_WARNING_CONFIG_FAILED;
}
- if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
- VTY_CURR_XPATH,
- "/frr-ripd:rip/authentication-key-chain")) {
+ if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
+ VTY_CURR_XPATH,
+ "/frr-ripd:rip/authentication-key-chain")) {
vty_out(vty, "%% key-chain configuration exists\n");
return CMD_WARNING_CONFIG_FAILED;
}
@@ -952,9 +952,9 @@ DEFPY_YANG (ip_rip_authentication_key_chain,
"Authentication key-chain\n"
"name of key-chain\n")
{
- if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
- VTY_CURR_XPATH,
- "/frr-ripd:rip/authentication-password")) {
+ if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
+ VTY_CURR_XPATH,
+ "/frr-ripd:rip/authentication-password")) {
vty_out(vty, "%% authentication string configuration exists\n");
return CMD_WARNING_CONFIG_FAILED;
}
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 1ef64ff0d..0b927c76f 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -1113,7 +1113,7 @@ static int rip_interface_config_write(struct vty *vty)
FOR_ALL_INTERFACES (vrf, ifp) {
struct lyd_node *dnode;
- dnode = yang_dnode_get(
+ dnode = yang_dnode_getf(
running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']",
ifp->name, vrf->name);
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 9832c7c52..c6c82fb65 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -3632,16 +3632,16 @@ static int rip_vrf_enable(struct vrf *vrf)
char oldpath[XPATH_MAXLEN];
char newpath[XPATH_MAXLEN];
- rip_dnode = yang_dnode_get(
+ rip_dnode = yang_dnode_getf(
running_config->dnode,
"/frr-ripd:ripd/instance[vrf='%s']/vrf",
old_vrf_name);
if (rip_dnode) {
- yang_dnode_get_path(rip_dnode->parent, oldpath,
- sizeof(oldpath));
+ yang_dnode_get_path(lyd_parent(rip_dnode),
+ oldpath, sizeof(oldpath));
yang_dnode_change_leaf(rip_dnode, vrf->name);
- yang_dnode_get_path(rip_dnode->parent, newpath,
- sizeof(newpath));
+ yang_dnode_get_path(lyd_parent(rip_dnode),
+ newpath, sizeof(newpath));
nb_running_move_tree(oldpath, newpath);
running_config->version++;
}
diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c
index 11a8fdff8..c4d494804 100644
--- a/ripngd/ripng_interface.c
+++ b/ripngd/ripng_interface.c
@@ -933,7 +933,7 @@ static int interface_config_write(struct vty *vty)
FOR_ALL_INTERFACES (vrf, ifp) {
struct lyd_node *dnode;
- dnode = yang_dnode_get(
+ dnode = yang_dnode_getf(
running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']",
ifp->name, vrf->name);
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index 5a71928fb..3b8d2076f 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -2634,16 +2634,16 @@ static int ripng_vrf_enable(struct vrf *vrf)
char oldpath[XPATH_MAXLEN];
char newpath[XPATH_MAXLEN];
- ripng_dnode = yang_dnode_get(
+ ripng_dnode = yang_dnode_getf(
running_config->dnode,
"/frr-ripngd:ripngd/instance[vrf='%s']/vrf",
old_vrf_name);
if (ripng_dnode) {
- yang_dnode_get_path(ripng_dnode->parent, oldpath,
- sizeof(oldpath));
+ yang_dnode_get_path(lyd_parent(ripng_dnode),
+ oldpath, sizeof(oldpath));
yang_dnode_change_leaf(ripng_dnode, vrf->name);
- yang_dnode_get_path(ripng_dnode->parent, newpath,
- sizeof(newpath));
+ yang_dnode_get_path(lyd_parent(ripng_dnode),
+ newpath, sizeof(newpath));
nb_running_move_tree(oldpath, newpath);
running_config->version++;
}
diff --git a/staticd/static_nb.c b/staticd/static_nb.c
index aa9076aa8..c1a6253a1 100644
--- a/staticd/static_nb.c
+++ b/staticd/static_nb.c
@@ -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",
.cbs = {
.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",
.cbs = {
.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,
}
},
{
diff --git a/staticd/static_nb.h b/staticd/static_nb.h
index e85e1d0e9..96dd05c0c 100644
--- a/staticd/static_nb.h
+++ b/staticd/static_nb.h
@@ -37,8 +37,6 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa
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(
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(
struct nb_cb_modify_args *args);
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);
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);
-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(
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(
diff --git a/staticd/static_nb_config.c b/staticd/static_nb_config.c
index e78f5172a..cd151bfac 100644
--- a/staticd/static_nb_config.c
+++ b/staticd/static_nb_config.c
@@ -297,7 +297,7 @@ static int static_nexthop_mpls_label_modify(struct nb_cb_modify_args *args)
uint8_t index;
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) {
flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
"libyang returns invalid label position");
@@ -457,7 +457,7 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa
uint32_t count;
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) {
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);
}
-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:
* /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);
}
-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:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/onlink
diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c
index 123d97bc9..cd5186f2a 100644
--- a/tests/bgpd/test_peer_attr.c
+++ b/tests/bgpd/test_peer_attr.c
@@ -783,6 +783,8 @@ static void test_execute(struct test *test, const char *fmt, ...)
cmd, ret);
}
+ nb_cli_pending_commit_check(test->vty);
+
/* Free memory. */
cmd_free_strvec(vline);
XFREE(MTYPE_TMP, cmd);
@@ -1397,7 +1399,6 @@ static void bgp_startup(void)
zprivs_init(&bgpd_privs);
master = thread_master_create(NULL);
- yang_init(true);
nb_init(master, bgpd_yang_modules, array_size(bgpd_yang_modules), false);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
bgp_option_set(BGP_OPT_NO_LISTEN);
diff --git a/tests/helpers/c/main.c b/tests/helpers/c/main.c
index 7f15996da..64ecab913 100644
--- a/tests/helpers/c/main.c
+++ b/tests/helpers/c/main.c
@@ -155,7 +155,6 @@ int main(int argc, char **argv)
cmd_init(1);
vty_init(master, false);
lib_cmd_init();
- yang_init(true);
nb_init(master, NULL, 0, false);
/* OSPF vty inits. */
diff --git a/tests/isisd/test_isis_spf.c b/tests/isisd/test_isis_spf.c
index 8fe1ad0b8..915f849ae 100644
--- a/tests/isisd/test_isis_spf.c
+++ b/tests/isisd/test_isis_spf.c
@@ -547,7 +547,7 @@ int main(int argc, char **argv)
cmd_init(1);
cmd_hostname_set("test");
vty_init(master, false);
- yang_init(true);
+ yang_init(true, false);
if (debug)
zlog_aux_init("NONE: ", LOG_DEBUG);
else
diff --git a/tests/lib/cli/common_cli.c b/tests/lib/cli/common_cli.c
index 44cc6efe8..49bc0f4fb 100644
--- a/tests/lib/cli/common_cli.c
+++ b/tests/lib/cli/common_cli.c
@@ -79,7 +79,6 @@ int main(int argc, char **argv)
vty_init(master, false);
lib_cmd_init();
- yang_init(true);
nb_init(master, NULL, 0, false);
test_init(argc, argv);
diff --git a/tests/lib/cli/test_commands.c b/tests/lib/cli/test_commands.c
index cb512211a..a00f80073 100644
--- a/tests/lib/cli/test_commands.c
+++ b/tests/lib/cli/test_commands.c
@@ -208,7 +208,6 @@ static void test_init(void)
struct cmd_element *cmd;
cmd_init(1);
- yang_init(true);
nb_init(master, NULL, 0, false);
install_node(&bgp_node);
diff --git a/tests/lib/northbound/test_oper_data.c b/tests/lib/northbound/test_oper_data.c
index b5f257fa2..08eb0d527 100644
--- a/tests/lib/northbound/test_oper_data.c
+++ b/tests/lib/northbound/test_oper_data.c
@@ -399,7 +399,6 @@ int main(int argc, char **argv)
cmd_hostname_set("test");
vty_init(master, false);
lib_cmd_init();
- yang_init(true);
nb_init(master, modules, array_size(modules), false);
/* Create artificial data. */
diff --git a/tests/subdir.am b/tests/subdir.am
index 43fad29fa..399669977 100644
--- a/tests/subdir.am
+++ b/tests/subdir.am
@@ -157,7 +157,7 @@ TESTS_CFLAGS = \
# note no -Werror
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)
OSPFD_TEST_LDADD = ospfd/libfrrospf.a $(ALL_TESTS_LDADD)
OSPF6_TEST_LDADD = ospf6d/libospf6.a $(ALL_TESTS_LDADD)
diff --git a/tools/gen_northbound_callbacks.c b/tools/gen_northbound_callbacks.c
index a785f43cd..1705a3203 100644
--- a/tools/gen_northbound_callbacks.c
+++ b/tools/gen_northbound_callbacks.c
@@ -118,7 +118,7 @@ static void replace_hyphens_by_underscores(char *str)
*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,
size_t size)
{
@@ -126,14 +126,14 @@ static void generate_callback_name(struct lys_node *snode,
struct listnode *ln;
snodes = list_new();
- for (; snode; snode = lys_parent(snode)) {
+ for (; snode; snode = snode->parent) {
/* Skip schema-only snodes. */
if (CHECK_FLAG(snode->nodetype, LYS_USES | LYS_CHOICE | LYS_CASE
| LYS_INPUT
| LYS_OUTPUT))
continue;
- listnode_add_head(snodes, snode);
+ listnode_add_head(snodes, (void *)snode);
}
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);
}
-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) {
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))
continue;
- generate_callback_name((struct lys_node *)snode, cb->operation,
- cb_name, sizeof(cb_name));
+ generate_callback_name(snode, cb->operation, cb_name,
+ sizeof(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);
}
-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;
@@ -250,15 +250,15 @@ static int generate_callbacks(const struct lys_node *snode, void *arg)
first = false;
}
- generate_callback_name((struct lys_node *)snode, cb->operation,
- cb_name, sizeof(cb_name));
+ generate_callback_name(snode, cb->operation, cb_name,
+ sizeof(cb_name));
generate_callback(cb, cb_name);
}
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;
@@ -295,8 +295,8 @@ static int generate_nb_nodes(const struct lys_node *snode, void *arg)
first = false;
}
- generate_callback_name((struct lys_node *)snode, cb->operation,
- cb_name, sizeof(cb_name));
+ generate_callback_name(snode, cb->operation, cb_name,
+ sizeof(cb_name));
printf("\t\t\t\t.%s = %s,\n", nb_operation_name(cb->operation),
cb_name);
}
@@ -350,18 +350,21 @@ int main(int argc, char *argv[])
if (argc != 1)
usage(EXIT_FAILURE);
- yang_init(false);
+ yang_init(false, true);
if (search_path)
ly_ctx_set_searchdir(ly_native_ctx, search_path);
/* Load all FRR native models to ensure all augmentations are loaded. */
yang_module_load_all();
+
module = yang_module_find(argv[0]);
if (!module)
/* Non-native FRR module (e.g. modules from unit tests). */
module = yang_module_load(argv[0]);
+ yang_init_loading_complete();
+
/* Create a nb_node for all YANG schema nodes. */
nb_nodes_create();
diff --git a/tools/gen_yang_deviations.c b/tools/gen_yang_deviations.c
index 53a53c943..8aa5695d3 100644
--- a/tools/gen_yang_deviations.c
+++ b/tools/gen_yang_deviations.c
@@ -32,7 +32,7 @@ static void __attribute__((noreturn)) usage(int 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];
@@ -65,14 +65,13 @@ int main(int argc, char *argv[])
if (argc != 1)
usage(EXIT_FAILURE);
- yang_init(false);
+ yang_init(false, false);
/* Load YANG module. */
module = yang_module_load(argv[0]);
/* Generate deviations. */
- yang_snodes_iterate(module->info, generate_yang_deviation,
- YANG_ITER_FILTER_IMPLICIT, NULL);
+ yang_snodes_iterate(module->info, generate_yang_deviation, 0, NULL);
/* Cleanup and exit. */
yang_terminate();
diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c
index 7d9cea3ad..6c3863132 100644
--- a/vrrpd/vrrp_vty.c
+++ b/vrrpd/vrrp_vty.c
@@ -729,7 +729,7 @@ static int vrrp_config_write_interface(struct vty *vty)
FOR_ALL_INTERFACES (vrf, ifp) {
struct lyd_node *dnode;
- dnode = yang_dnode_get(
+ dnode = yang_dnode_getf(
running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']",
ifp->name, vrf->name);
diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in
index 37ae0ab18..86cf8c965 100755
--- a/vtysh/extract.pl.in
+++ b/vtysh/extract.pl.in
@@ -42,7 +42,7 @@ sub scan_file {
$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 $/;
$line = <FH>;
if (!close (FH)) {
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 336bd44a4..111c2dbc0 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -2890,6 +2890,37 @@ DEFUN (show_yang_operational_data,
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,
debug_nb_cmd,
"[no] debug northbound\
@@ -4449,6 +4480,8 @@ void vtysh_init_vty(void)
/* northbound */
install_element(ENABLE_NODE, &show_config_running_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(CONFIG_NODE, &debug_nb_cmd);
diff --git a/watchfrr/subdir.am b/watchfrr/subdir.am
index 677f85efc..e899b895e 100644
--- a/watchfrr/subdir.am
+++ b/watchfrr/subdir.am
@@ -13,7 +13,7 @@ noinst_HEADERS += \
watchfrr/watchfrr_errors.h \
# end
-watchfrr_watchfrr_LDADD = lib/libfrr.la $(LIBCAP)
+watchfrr_watchfrr_LDADD = lib/libfrr.la $(LIBYANG_LIBS) $(LIBCAP)
watchfrr_watchfrr_SOURCES = \
watchfrr/watchfrr.c \
watchfrr/watchfrr_errors.c \
diff --git a/yang/embedmodel.py b/yang/embedmodel.py
index 39bf2bb92..a77a81363 100644
--- a/yang/embedmodel.py
+++ b/yang/embedmodel.py
@@ -94,7 +94,7 @@ else:
sub_name = search_name.group(1)
name = re_mainname.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:
raise ValueError("cannot determine YANG module name and revision")
diff --git a/yang/frr-bgp-bmp.yang b/yang/frr-bgp-bmp.yang
index 344448f10..2417874ea 100644
--- a/yang/frr-bgp-bmp.yang
+++ b/yang/frr-bgp-bmp.yang
@@ -13,8 +13,6 @@ submodule frr-bgp-bmp {
prefix frr-bt;
}
- include frr-bgp-common-multiprotocol;
-
organization
"FRRouting";
contact
diff --git a/yang/frr-bgp-common-multiprotocol.yang b/yang/frr-bgp-common-multiprotocol.yang
index aefdf02ba..4b080613d 100644
--- a/yang/frr-bgp-common-multiprotocol.yang
+++ b/yang/frr-bgp-common-multiprotocol.yang
@@ -9,8 +9,6 @@ submodule frr-bgp-common-multiprotocol {
prefix frr-rt;
}
- include frr-bgp-common;
-
organization
"FRRouting";
contact
@@ -67,7 +65,7 @@ submodule frr-bgp-common-multiprotocol {
"A common grouping used for contents of the list that is used
for AFI-SAFI entries.";
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
"Include this container for IPv4 Unicast specific
configuration.";
@@ -77,7 +75,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for IPv6 Unicast specific
configuration.";
@@ -87,7 +85,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for IPv4 Labeled Unicast specific
configuration.";
@@ -97,7 +95,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for IPv6 Labeled Unicast specific
configuration.";
@@ -107,7 +105,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for IPv4 Unicast L3VPN specific
configuration.";
@@ -117,7 +115,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for unicast IPv6 L3VPN specific
configuration.";
@@ -127,7 +125,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for multicast IPv4 L3VPN specific
configuration.";
@@ -137,7 +135,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for multicast IPv6 L3VPN specific
configuration.";
@@ -147,7 +145,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for BGP-signalled VPLS specific
configuration.";
@@ -157,7 +155,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for BGP EVPN specific
configuration.";
@@ -167,7 +165,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for IPv4 multicast specific
configuration.";
@@ -177,7 +175,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for IPv6 multicast specific
configuration.";
@@ -187,7 +185,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for IPv4 flowspec specific
configuration.";
@@ -197,7 +195,7 @@ submodule frr-bgp-common-multiprotocol {
}
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
"Include this container for IPv6 flowspec specific
configuration.";
diff --git a/yang/frr-bgp-common-structure.yang b/yang/frr-bgp-common-structure.yang
index 7b987a93c..232c78899 100644
--- a/yang/frr-bgp-common-structure.yang
+++ b/yang/frr-bgp-common-structure.yang
@@ -25,8 +25,6 @@ submodule frr-bgp-common-structure {
prefix frr-bt;
}
- include frr-bgp-common;
-
organization
"FRRouting";
contact
@@ -118,7 +116,6 @@ submodule frr-bgp-common-structure {
}
leaf no-prepend {
- when "../local-as != 0";
type boolean;
default "false";
description
diff --git a/yang/frr-bgp-common.yang b/yang/frr-bgp-common.yang
index 1a19d5296..157e4cd61 100644
--- a/yang/frr-bgp-common.yang
+++ b/yang/frr-bgp-common.yang
@@ -455,11 +455,14 @@ submodule frr-bgp-common {
grouping global-network-config {
leaf import-check {
type boolean;
- default "false";
+ default "true";
description
"When set to 'true' bgp creates entries for network statements
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";
}
}
diff --git a/yang/frr-bgp-neighbor.yang b/yang/frr-bgp-neighbor.yang
index a4b50b156..d6688eed2 100644
--- a/yang/frr-bgp-neighbor.yang
+++ b/yang/frr-bgp-neighbor.yang
@@ -5,9 +5,6 @@ submodule frr-bgp-neighbor {
prefix "bgp";
}
- include frr-bgp-common-structure;
- include frr-bgp-common-multiprotocol;
-
organization
"FRRouting";
contact
diff --git a/yang/frr-bgp-peer-group.yang b/yang/frr-bgp-peer-group.yang
index 452ff1a12..746ced30c 100644
--- a/yang/frr-bgp-peer-group.yang
+++ b/yang/frr-bgp-peer-group.yang
@@ -13,9 +13,6 @@ submodule frr-bgp-peer-group {
prefix frr-bt;
}
- include frr-bgp-common-structure;
- include frr-bgp-neighbor;
-
organization
"FRRouting";
contact
diff --git a/yang/frr-bgp-route-map.yang b/yang/frr-bgp-route-map.yang
index 96505b08a..ca60c8f7b 100644
--- a/yang/frr-bgp-route-map.yang
+++ b/yang/frr-bgp-route-map.yang
@@ -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" {
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 {
type uint32 {
range "0..4294967295";
@@ -341,14 +341,14 @@ module frr-bgp-route-map {
}
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 {
type string;
}
}
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 {
type enumeration {
enum "egp" {
@@ -371,7 +371,7 @@ module frr-bgp-route-map {
}
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 {
type enumeration {
enum "invalid" {
@@ -394,7 +394,7 @@ module frr-bgp-route-map {
}
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 {
type uint8 {
range "0..100";
@@ -403,14 +403,14 @@ module frr-bgp-route-map {
}
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 {
type string;
}
}
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 {
description
"Value of the peer";
@@ -449,10 +449,10 @@ module frr-bgp-route-map {
}
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 "
- + "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, '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')";
+ 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, '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, '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, 'frr-bgp-route-map:ip-route-source-prefix-list')";
description
"Access-list name";
leaf list-name {
@@ -461,7 +461,7 @@ module frr-bgp-route-map {
}
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
"Match default EVPN type-5 route";
leaf evpn-default-route {
@@ -470,7 +470,7 @@ module frr-bgp-route-map {
}
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
"Match eVPN VNI";
leaf evpn-vni {
@@ -481,7 +481,7 @@ module frr-bgp-route-map {
}
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
"Match eVPN route-type";
leaf evpn-route-type {
@@ -506,7 +506,7 @@ module frr-bgp-route-map {
}
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
"Match eVPN route-distinguisher";
leaf route-distinguisher {
@@ -515,9 +515,9 @@ module frr-bgp-route-map {
}
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 "
- + "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, 'match-extcommunity')";
+ 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, '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, 'frr-bgp-route-map:match-extcommunity')";
container comm-list {
leaf comm-list-name {
type bgp-filter:bgp-list-name;
@@ -532,7 +532,7 @@ module frr-bgp-route-map {
}
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 {
type inet:ipv4-address;
description
@@ -541,7 +541,7 @@ module frr-bgp-route-map {
}
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 {
type inet:ipv6-address;
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" {
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 {
type uint8 {
range "0..255";
@@ -561,7 +561,7 @@ module frr-bgp-route-map {
}
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
"Value of the ext-community";
leaf extcommunity-rt {
@@ -572,7 +572,7 @@ module frr-bgp-route-map {
}
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
"Value of the ext-community";
leaf extcommunity-soo {
@@ -583,7 +583,7 @@ module frr-bgp-route-map {
}
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 {
description
"Value of the ext-community.";
@@ -604,7 +604,7 @@ module frr-bgp-route-map {
}
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
"Set the IPv4 address";
leaf ipv4-address {
@@ -613,15 +613,15 @@ module frr-bgp-route-map {
}
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 {
type string;
}
}
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 "
- + "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')";
+ 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, 'frr-bgp-route-map:ipv6-vpn-address')";
description
"Set the IPv6 address";
leaf ipv6-address {
@@ -630,15 +630,15 @@ module frr-bgp-route-map {
}
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 "
- + "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')";
+ 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, 'frr-bgp-route-map:ipv6-peer-address')";
leaf preference {
type boolean;
}
}
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 {
type uint32 {
range "0..1048560";
@@ -647,14 +647,14 @@ module frr-bgp-route-map {
}
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 {
type string;
}
}
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 {
type uint32 {
range "0..4294967295";
@@ -663,7 +663,7 @@ module frr-bgp-route-map {
}
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 {
type enumeration {
enum "egp" {
@@ -686,14 +686,14 @@ module frr-bgp-route-map {
}
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 {
type inet:ipv4-address;
}
}
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 {
type uint32 {
range "1..4294967295";
@@ -702,14 +702,14 @@ module frr-bgp-route-map {
}
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 {
type empty;
}
}
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 {
description
"Value of the BGP AS-path attribute";
@@ -734,7 +734,7 @@ module frr-bgp-route-map {
}
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 {
type string;
description
@@ -743,7 +743,7 @@ module frr-bgp-route-map {
}
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 {
description
"Value of the BGP community attribute";
@@ -766,7 +766,7 @@ module frr-bgp-route-map {
}
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 {
description
"Value of the BGP large-community attribute";
@@ -789,7 +789,7 @@ module frr-bgp-route-map {
}
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 {
leaf aggregator-asn {
type uint32 {
@@ -810,8 +810,8 @@ module frr-bgp-route-map {
}
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 "
- + "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')";
+ 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, 'frr-bgp-route-map:large-comm-list-delete')";
leaf comm-list-name {
type bgp-filter:bgp-list-name;
}
diff --git a/yang/frr-bgp.yang b/yang/frr-bgp.yang
index ae44447df..a779bb205 100644
--- a/yang/frr-bgp.yang
+++ b/yang/frr-bgp.yang
@@ -23,10 +23,10 @@ module frr-bgp {
prefix frr-bt;
}
- include "frr-bgp-common-structure";
-
include "frr-bgp-common";
+ include "frr-bgp-common-structure";
+
include "frr-bgp-common-multiprotocol";
include "frr-bgp-neighbor";
diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang
index 4653e6f00..5997e8866 100644
--- a/yang/frr-isisd.yang
+++ b/yang/frr-isisd.yang
@@ -481,6 +481,10 @@ module frr-isisd {
description
"TI-LFA configuration.";
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;
default false;
description
@@ -804,10 +808,6 @@ module frr-isisd {
container level-1 {
description
"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-remote-lfa;
uses interface-config-ti-lfa;
@@ -815,10 +815,6 @@ module frr-isisd {
container level-2 {
description
"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-remote-lfa;
uses interface-config-ti-lfa;
@@ -1502,14 +1498,15 @@ module frr-isisd {
container srgb {
description
"Global blocks to be advertised.";
- must "./upper-bound > ./lower-bound";
leaf lower-bound {
+ must "../upper-bound > .";
type uint32;
default "16000";
description
"Lower value in the label range.";
}
leaf upper-bound {
+ must ". > ../lower-bound";
type uint32;
default "23999";
description
@@ -1519,14 +1516,15 @@ module frr-isisd {
container srlb {
description
"Local blocks to be advertised.";
- must "./upper-bound > ./lower-bound";
leaf lower-bound {
+ must "../upper-bound > .";
type uint32;
default "15000";
description
"Lower value in the label range.";
}
leaf upper-bound {
+ must ". > ../lower-bound";
type uint32;
default "15999";
description
diff --git a/yang/frr-ospfd.yang b/yang/frr-ospfd.yang
index 42a7e8784..b0150cc06 100644
--- a/yang/frr-ospfd.yang
+++ b/yang/frr-ospfd.yang
@@ -682,8 +682,8 @@ module frr-ospfd {
container global-block {
description
"Segment Routing Global Block label range.";
- must "./upper-bound > ./lower-bound";
leaf lower-bound {
+ must "../upper-bound > .";
type uint32 {
range "0..1048575";
}
@@ -691,6 +691,7 @@ module frr-ospfd {
}
leaf upper-bound {
+ must ". > ../lower-bound";
type uint32 {
range "0..1048575";
}
@@ -701,14 +702,15 @@ module frr-ospfd {
container srlb {
description
"Local blocks to be advertised.";
- must "./upper-bound > ./lower-bound";
leaf lower-bound {
+ must "../upper-bound > .";
type uint32;
default "15000";
description
"Lower value in the label range.";
}
leaf upper-bound {
+ must ". > ../lower-bound";
type uint32;
default "15999";
description
diff --git a/yang/frr-pim.yang b/yang/frr-pim.yang
index 52d864161..70adb37b2 100644
--- a/yang/frr-pim.yang
+++ b/yang/frr-pim.yang
@@ -341,14 +341,14 @@ module frr-pim {
leaf bsm {
type boolean;
- default "false";
+ default "true";
description
"Enables BSM support on the interface.";
}
leaf unicast-bsm {
type boolean;
- default "false";
+ default "true";
description
"Accept/Send unicast BSM on the interface.";
}
diff --git a/yang/frr-ripd.yang b/yang/frr-ripd.yang
index 929c91606..d77241cb1 100644
--- a/yang/frr-ripd.yang
+++ b/yang/frr-ripd.yang
@@ -291,6 +291,10 @@ module frr-ripd {
}
container version {
leaf receive {
+ must
+ '(. = "1" and ../send = "1") or ' +
+ '(. = "2" and ../send = "2") or ' +
+ '(. = "1-2" and ../send = "2")';
type enumeration {
enum "1" {
value 1;
@@ -313,6 +317,10 @@ module frr-ripd {
"Advertisement reception - Version control.";
}
leaf send {
+ must
+ '(../receive = "1" and . = "1") or ' +
+ '(../receive = "2" and . = "2") or ' +
+ '(../receive = "1-2" and . = "2")';
type enumeration {
enum "1" {
value 1;
@@ -329,10 +337,6 @@ module frr-ripd {
description
"Advertisement transmission - Version control.";
}
- must
- '(./receive = "1" and ./send = "1") or ' +
- '(./receive = "2" and ./send = "2") or ' +
- '(./receive = "1-2" and ./send = "2")';
}
/*
diff --git a/yang/frr-zebra-route-map.yang b/yang/frr-zebra-route-map.yang
index 91f4c87e3..de0f64d38 100644
--- a/yang/frr-zebra-route-map.yang
+++ b/yang/frr-zebra-route-map.yang
@@ -64,10 +64,15 @@ module frr-zebra-route-map {
"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 {
- when "derived-from-or-self(../condition, 'ipv4-prefix-length') or "
- + "derived-from-or-self(../condition, 'ipv4-next-hop-prefix-length')";
+ when "derived-from-or-self(../frr-route-map:condition, 'frr-zebra-route-map:ipv4-prefix-length') or "
+ + "derived-from-or-self(../frr-route-map:condition, 'frr-zebra-route-map:ipv4-next-hop-prefix-length')";
leaf ipv4-prefix-length {
type uint8 {
range "0..32";
@@ -76,7 +81,7 @@ module frr-zebra-route-map {
}
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 {
type uint8 {
range "0..128";
@@ -85,7 +90,7 @@ module frr-zebra-route-map {
}
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 {
type uint8 {
range "0..255";
@@ -94,16 +99,21 @@ module frr-zebra-route-map {
}
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 {
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 {
- 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 {
description
"Value of the source address";
diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang
index 5c2560837..a2c6bb4c2 100644
--- a/yang/frr-zebra.yang
+++ b/yang/frr-zebra.yang
@@ -1953,7 +1953,7 @@ module frr-zebra {
}
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;
description
"Peer prefix, for peer-to-peer interfaces.";