diff options
| author | Christian Hopps <chopps@gmail.com> | 2021-05-04 10:41:58 -0400 | 
|---|---|---|
| committer | Christian Hopps <chopps@labn.net> | 2021-05-13 16:24:48 -0400 | 
| commit | 3bb513c399c2e7c8dd597b7399dd7c0f064842d0 (patch) | |
| tree | 14f3e677c49fce272946788f8a8b8f3f8a3e26b5 | |
| parent | 17daea8a184c0e85b9788329f3c808ceab916ad5 (diff) | |
lib: adapt to version 2 of libyang
Compile with v2.0.0 tag of `libyang2` branch of:
https://github.com/CESNET/libyang
staticd init load time of 10k routes now 6s vs ly1 time of 150s
Signed-off-by: Christian Hopps <chopps@labn.net>
71 files changed, 1226 insertions, 1267 deletions
diff --git a/.clang-format b/.clang-format index 47d681e0e2..e1897bfa99 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 d8e450a646..84dd2d7ec2 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 18f331e201..c66fccb853 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 21810b634d..71824cd6d3 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 57f379b6cc..f8bb31aad6 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 8ca7836a99..a430124b51 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 5b5f166e4b..9be614ad62 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 b54c41cabe..53225192f2 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 c082a9e527..f84a3d3c5e 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 7a08cbbdb0..0bbe99b312 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 5f82447d74..a447f58309 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 f6fa910381..86fbe4f49c 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 0b08c2f278..ead5c56c54 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 ae15e97d4a..cf3999b457 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 2c51f21d77..2a197ab2b7 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 14fa414c52..5aea9f25d9 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 87cd732e0b..68a4581a46 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 2066e4c96d..6469b49262 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); @@ -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 970e82c064..0817182f7a 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 34ad5dbfa9..3634fed04f 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 417ecc81ea..7ccab5cad5 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 81e30bce49..d291a1f24d 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 403537e043..76af494e30 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 58f4e42516..dc2d29c11d 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 63fd40f8d3..7c463dd61f 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; @@ -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 df3b07fb09..1e241f049e 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 b8bf07ee7e..d4517f969a 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 5b1d96f24c..d562e4d29e 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 98f8fea0fe..85aa003db7 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 370484dc1b..55148d9d05 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 90aa15beee..548c866e4d 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 4598297f93..003a9947e4 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 47c6ad41af..e24a84d1e4 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 43e5b21fa1..0c5730b4d5 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 1ef64ff0de..0b927c76fa 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 9832c7c52a..c6c82fb65a 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 11a8fdff87..c4d494804f 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 5a71928fbd..3b8d2076f3 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 aa9076aa88..c1a6253a1d 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 e85e1d0e9f..96dd05c0cf 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 e78f5172a3..cd151bface 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 123d97bc97..cd5186f2ae 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 7f15996daa..64ecab9132 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 8fe1ad0b8a..915f849aec 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 44cc6efe84..49bc0f4fb2 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 cb512211a4..a00f80073c 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 b5f257fa2f..08eb0d527c 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 43fad29fa2..3996699774 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 a785f43cdf..1705a3203f 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 53a53c943c..8aa5695d3e 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 7d9cea3adc..6c3863132d 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 37ae0ab189..86cf8c9657 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 336bd44a49..111c2dbc03 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 677f85efcb..e899b895e7 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 39bf2bb922..a77a81363f 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 344448f104..2417874ea0 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 aefdf02ba6..4b080613d6 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 7b987a93cd..232c78899e 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 1a19d52965..157e4cd614 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 a4b50b156b..d6688eed29 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 452ff1a12f..746ced30cc 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 96505b08a8..ca60c8f7b6 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 ae44447df7..a779bb2054 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 4653e6f009..5997e8866a 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 42a7e8784c..b0150cc061 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 52d8641613..70adb37b26 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 929c916069..d77241cb15 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 91f4c87e33..de0f64d389 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 5c2560837f..a2c6bb4c2b 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.";  | 
