]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/yang_wrappers.c
Merge pull request #12708 from donaldsharp/no_notification
[mirror_frr.git] / lib / yang_wrappers.c
index 98f8fea0fec3a074d795e5619ed811fa3d767234..d22379dd237e5f68b19f83b25b1d965f44552a31 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <zebra.h>
 
+#include "base64.h"
 #include "log.h"
 #include "lib_errors.h"
 #include "northbound.h"
 #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)
+
+PRINTFRR(2, 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);
+}
+
+PRINTFRR(2, 0)
+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 +116,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 +132,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 +181,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 +214,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 +227,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 +249,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 +262,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 +284,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;
-
-       assert(dnode);
-       if (xpath_fmt) {
-               va_list ap;
-               char xpath[XPATH_MAXLEN];
+       const struct lyd_value *dvalue;
 
-               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 +325,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 +364,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 +403,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 +442,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 +481,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 +520,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 +559,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 +598,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 +631,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));
@@ -784,6 +679,64 @@ void yang_get_default_string_buf(char *buf, size_t size, const char *xpath_fmt,
                          xpath);
 }
 
+/*
+ * Primitive type: binary.
+ */
+struct yang_data *yang_data_new_binary(const char *xpath, const char *value,
+                                      size_t len)
+{
+       char *value_str;
+       struct base64_encodestate s;
+       int cnt;
+       char *c;
+       struct yang_data *data;
+
+       value_str = (char *)malloc(len * 2);
+       base64_init_encodestate(&s);
+       cnt = base64_encode_block(value, len, value_str, &s);
+       c = value_str + cnt;
+       cnt = base64_encode_blockend(c, &s);
+       c += cnt;
+       *c = 0;
+       data = yang_data_new(xpath, value_str);
+       free(value_str);
+       return data;
+}
+
+size_t yang_dnode_get_binary_buf(char *buf, size_t size,
+                                const struct lyd_node *dnode,
+                                const char *xpath_fmt, ...)
+{
+       const char *canon;
+       size_t cannon_len;
+       size_t decode_len;
+       size_t ret_len;
+       size_t cnt;
+       char *value_str;
+       struct base64_decodestate s;
+
+       canon = YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt);
+       cannon_len = strlen(canon);
+       decode_len = cannon_len + 1;
+       value_str = (char *)malloc(decode_len);
+       base64_init_decodestate(&s);
+       cnt = base64_decode_block(canon, cannon_len, value_str, &s);
+
+       ret_len = size > cnt ? cnt : size;
+       memcpy(buf, value_str, ret_len);
+       if (size < cnt) {
+               char xpath[XPATH_MAXLEN];
+
+               yang_dnode_get_path(dnode, xpath, sizeof(xpath));
+               flog_warn(EC_LIB_YANG_DATA_TRUNCATED,
+                         "%s: value was truncated [xpath %s]", __func__,
+                         xpath);
+       }
+       free(value_str);
+       return ret_len;
+}
+
+
 /*
  * Primitive type: empty.
  */
@@ -797,7 +750,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 +760,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 +789,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 +835,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 +877,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 +917,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 +959,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 +1000,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, ...)