2 * Copyright (C) 2018 NetDEF, Inc.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "lib_errors.h"
24 #include "northbound.h"
30 #define YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt) \
33 va_start(__ap, (xpath_fmt)); \
34 const struct lyd_value *__dvalue = \
35 yang_dnode_xpath_get_value(dnode, xpath_fmt, __ap); \
40 #define YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt) \
43 va_start(__ap, (xpath_fmt)); \
44 const char *__canon = \
45 yang_dnode_xpath_get_canon(dnode, xpath_fmt, __ap); \
50 #define YANG_DNODE_GET_ASSERT(dnode, xpath) \
52 if ((dnode) == NULL) { \
53 flog_err(EC_LIB_YANG_DNODE_NOT_FOUND, \
54 "%s: couldn't find %s", __func__, (xpath)); \
55 zlog_backtrace(LOG_ERR); \
60 static inline const char *
61 yang_dnode_xpath_get_canon(const struct lyd_node
*dnode
, const char *xpath_fmt
,
64 const struct lyd_node_term
*__dleaf
=
65 (const struct lyd_node_term
*)dnode
;
68 char __xpath
[XPATH_MAXLEN
];
69 vsnprintf(__xpath
, sizeof(__xpath
), xpath_fmt
, ap
);
70 __dleaf
= (const struct lyd_node_term
*)yang_dnode_get(dnode
,
72 YANG_DNODE_GET_ASSERT(__dleaf
, __xpath
);
74 return lyd_get_value(&__dleaf
->node
);
77 static inline const struct lyd_value
*
78 yang_dnode_xpath_get_value(const struct lyd_node
*dnode
, const char *xpath_fmt
,
81 const struct lyd_node_term
*__dleaf
=
82 (const struct lyd_node_term
*)dnode
;
85 char __xpath
[XPATH_MAXLEN
];
86 vsnprintf(__xpath
, sizeof(__xpath
), xpath_fmt
, ap
);
87 __dleaf
= (const struct lyd_node_term
*)yang_dnode_get(dnode
,
89 YANG_DNODE_GET_ASSERT(__dleaf
, __xpath
);
91 const struct lyd_value
*__dvalue
= &__dleaf
->value
;
92 if (__dvalue
->realtype
->basetype
== LY_TYPE_UNION
)
93 __dvalue
= &__dvalue
->subvalue
->value
;
97 static const char *yang_get_default_value(const char *xpath
)
99 const struct lysc_node
*snode
;
102 snode
= lys_find_path(ly_native_ctx
, NULL
, xpath
, 0);
104 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
105 "%s: unknown data path: %s", __func__
, xpath
);
106 zlog_backtrace(LOG_ERR
);
110 value
= yang_snode_get_default(snode
);
117 * Primitive type: bool.
119 bool yang_str2bool(const char *value
)
121 return strmatch(value
, "true");
124 struct yang_data
*yang_data_new_bool(const char *xpath
, bool value
)
126 return yang_data_new(xpath
, (value
) ? "true" : "false");
129 bool yang_dnode_get_bool(const struct lyd_node
*dnode
, const char *xpath_fmt
,
132 const struct lyd_value
*dvalue
;
133 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
134 assert(dvalue
->realtype
->basetype
== LY_TYPE_BOOL
);
135 return dvalue
->boolean
;
138 bool yang_get_default_bool(const char *xpath_fmt
, ...)
140 char xpath
[XPATH_MAXLEN
];
144 va_start(ap
, xpath_fmt
);
145 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
148 value
= yang_get_default_value(xpath
);
149 return yang_str2bool(value
);
153 * Primitive type: dec64.
155 double yang_str2dec64(const char *xpath
, const char *value
)
159 if (sscanf(value
, "%lf", &dbl
) != 1) {
160 flog_err(EC_LIB_YANG_DATA_CONVERT
,
161 "%s: couldn't convert string to decimal64 [xpath %s]",
163 zlog_backtrace(LOG_ERR
);
170 struct yang_data
*yang_data_new_dec64(const char *xpath
, double value
)
172 char value_str
[BUFSIZ
];
174 snprintf(value_str
, sizeof(value_str
), "%lf", value
);
175 return yang_data_new(xpath
, value_str
);
178 double yang_dnode_get_dec64(const struct lyd_node
*dnode
, const char *xpath_fmt
,
181 const double denom
[19] = {1e0
, 1e-1, 1e-2, 1e-3, 1e-4,
182 1e-5, 1e-6, 1e-7, 1e-8, 1e-9,
183 1e-10, 1e-11, 1e-12, 1e-13, 1e-14,
184 1e-15, 1e-16, 1e-17, 1e-18};
185 const struct lysc_type_dec
*dectype
;
186 const struct lyd_value
*dvalue
;
188 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
189 dectype
= (const struct lysc_type_dec
*)dvalue
->realtype
;
190 assert(dectype
->basetype
== LY_TYPE_DEC64
);
191 assert(dectype
->fraction_digits
< sizeof(denom
) / sizeof(*denom
));
192 return (double)dvalue
->dec64
* denom
[dectype
->fraction_digits
];
195 double yang_get_default_dec64(const char *xpath_fmt
, ...)
197 char xpath
[XPATH_MAXLEN
];
201 va_start(ap
, xpath_fmt
);
202 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
205 value
= yang_get_default_value(xpath
);
206 return yang_str2dec64(xpath
, value
);
210 * Primitive type: enum.
212 int yang_str2enum(const char *xpath
, const char *value
)
214 const struct lysc_node
*snode
;
215 const struct lysc_node_leaf
*sleaf
;
216 const struct lysc_type_enum
*type
;
217 const struct lysc_type_bitenum_item
*enums
;
219 snode
= lys_find_path(ly_native_ctx
, NULL
, xpath
, 0);
221 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
222 "%s: unknown data path: %s", __func__
, xpath
);
223 zlog_backtrace(LOG_ERR
);
227 assert(snode
->nodetype
== LYS_LEAF
);
228 sleaf
= (const struct lysc_node_leaf
*)snode
;
229 type
= (const struct lysc_type_enum
*)sleaf
->type
;
230 assert(type
->basetype
== LY_TYPE_ENUM
);
232 unsigned int count
= LY_ARRAY_COUNT(enums
);
233 for (unsigned int i
= 0; i
< count
; i
++) {
234 if (strmatch(value
, enums
[i
].name
)) {
235 assert(CHECK_FLAG(enums
[i
].flags
, LYS_SET_VALUE
));
236 return enums
[i
].value
;
240 flog_err(EC_LIB_YANG_DATA_CONVERT
,
241 "%s: couldn't convert string to enum [xpath %s]", __func__
,
243 zlog_backtrace(LOG_ERR
);
247 struct yang_data
*yang_data_new_enum(const char *xpath
, int value
)
249 const struct lysc_node
*snode
;
250 const struct lysc_node_leaf
*sleaf
;
251 const struct lysc_type_enum
*type
;
252 const struct lysc_type_bitenum_item
*enums
;
254 snode
= lys_find_path(ly_native_ctx
, NULL
, xpath
, 0);
256 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
257 "%s: unknown data path: %s", __func__
, xpath
);
258 zlog_backtrace(LOG_ERR
);
262 assert(snode
->nodetype
== LYS_LEAF
);
263 sleaf
= (const struct lysc_node_leaf
*)snode
;
264 type
= (const struct lysc_type_enum
*)sleaf
->type
;
265 assert(type
->basetype
== LY_TYPE_ENUM
);
267 unsigned int count
= LY_ARRAY_COUNT(enums
);
268 for (unsigned int i
= 0; i
< count
; i
++) {
269 if (CHECK_FLAG(enums
[i
].flags
, LYS_SET_VALUE
)
270 && value
== enums
[i
].value
)
271 return yang_data_new(xpath
, enums
[i
].name
);
274 flog_err(EC_LIB_YANG_DATA_CONVERT
,
275 "%s: couldn't convert enum to string [xpath %s]", __func__
,
277 zlog_backtrace(LOG_ERR
);
281 int yang_dnode_get_enum(const struct lyd_node
*dnode
, const char *xpath_fmt
,
284 const struct lyd_value
*dvalue
;
286 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
287 assert(dvalue
->realtype
->basetype
== LY_TYPE_ENUM
);
288 assert(dvalue
->enum_item
->flags
& LYS_SET_VALUE
);
289 return dvalue
->enum_item
->value
;
292 int yang_get_default_enum(const char *xpath_fmt
, ...)
294 char xpath
[XPATH_MAXLEN
];
298 va_start(ap
, xpath_fmt
);
299 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
302 value
= yang_get_default_value(xpath
);
303 return yang_str2enum(xpath
, value
);
307 * Primitive type: int8.
309 int8_t yang_str2int8(const char *value
)
311 return strtol(value
, NULL
, 10);
314 struct yang_data
*yang_data_new_int8(const char *xpath
, int8_t value
)
316 char value_str
[BUFSIZ
];
318 snprintf(value_str
, sizeof(value_str
), "%d", value
);
319 return yang_data_new(xpath
, value_str
);
322 int8_t yang_dnode_get_int8(const struct lyd_node
*dnode
, const char *xpath_fmt
,
325 const struct lyd_value
*dvalue
;
326 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
327 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT8
);
331 int8_t yang_get_default_int8(const char *xpath_fmt
, ...)
333 char xpath
[XPATH_MAXLEN
];
337 va_start(ap
, xpath_fmt
);
338 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
341 value
= yang_get_default_value(xpath
);
342 return yang_str2int8(value
);
346 * Primitive type: int16.
348 int16_t yang_str2int16(const char *value
)
350 return strtol(value
, NULL
, 10);
353 struct yang_data
*yang_data_new_int16(const char *xpath
, int16_t value
)
355 char value_str
[BUFSIZ
];
357 snprintf(value_str
, sizeof(value_str
), "%d", value
);
358 return yang_data_new(xpath
, value_str
);
361 int16_t yang_dnode_get_int16(const struct lyd_node
*dnode
,
362 const char *xpath_fmt
, ...)
364 const struct lyd_value
*dvalue
;
365 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
366 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT16
);
367 return dvalue
->int16
;
370 int16_t yang_get_default_int16(const char *xpath_fmt
, ...)
372 char xpath
[XPATH_MAXLEN
];
376 va_start(ap
, xpath_fmt
);
377 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
380 value
= yang_get_default_value(xpath
);
381 return yang_str2int16(value
);
385 * Primitive type: int32.
387 int32_t yang_str2int32(const char *value
)
389 return strtol(value
, NULL
, 10);
392 struct yang_data
*yang_data_new_int32(const char *xpath
, int32_t value
)
394 char value_str
[BUFSIZ
];
396 snprintf(value_str
, sizeof(value_str
), "%d", value
);
397 return yang_data_new(xpath
, value_str
);
400 int32_t yang_dnode_get_int32(const struct lyd_node
*dnode
,
401 const char *xpath_fmt
, ...)
403 const struct lyd_value
*dvalue
;
404 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
405 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT32
);
406 return dvalue
->int32
;
409 int32_t yang_get_default_int32(const char *xpath_fmt
, ...)
411 char xpath
[XPATH_MAXLEN
];
415 va_start(ap
, xpath_fmt
);
416 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
419 value
= yang_get_default_value(xpath
);
420 return yang_str2int32(value
);
424 * Primitive type: int64.
426 int64_t yang_str2int64(const char *value
)
428 return strtoll(value
, NULL
, 10);
431 struct yang_data
*yang_data_new_int64(const char *xpath
, int64_t value
)
433 char value_str
[BUFSIZ
];
435 snprintfrr(value_str
, sizeof(value_str
), "%" PRId64
, value
);
436 return yang_data_new(xpath
, value_str
);
439 int64_t yang_dnode_get_int64(const struct lyd_node
*dnode
,
440 const char *xpath_fmt
, ...)
442 const struct lyd_value
*dvalue
;
443 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
444 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT64
);
445 return dvalue
->int64
;
448 int64_t yang_get_default_int64(const char *xpath_fmt
, ...)
450 char xpath
[XPATH_MAXLEN
];
454 va_start(ap
, xpath_fmt
);
455 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
458 value
= yang_get_default_value(xpath
);
459 return yang_str2int64(value
);
463 * Primitive type: uint8.
465 uint8_t yang_str2uint8(const char *value
)
467 return strtoul(value
, NULL
, 10);
470 struct yang_data
*yang_data_new_uint8(const char *xpath
, uint8_t value
)
472 char value_str
[BUFSIZ
];
474 snprintf(value_str
, sizeof(value_str
), "%u", value
);
475 return yang_data_new(xpath
, value_str
);
478 uint8_t yang_dnode_get_uint8(const struct lyd_node
*dnode
,
479 const char *xpath_fmt
, ...)
481 const struct lyd_value
*dvalue
;
482 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
483 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT8
);
484 return dvalue
->uint8
;
487 uint8_t yang_get_default_uint8(const char *xpath_fmt
, ...)
489 char xpath
[XPATH_MAXLEN
];
493 va_start(ap
, xpath_fmt
);
494 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
497 value
= yang_get_default_value(xpath
);
498 return yang_str2uint8(value
);
502 * Primitive type: uint16.
504 uint16_t yang_str2uint16(const char *value
)
506 return strtoul(value
, NULL
, 10);
509 struct yang_data
*yang_data_new_uint16(const char *xpath
, uint16_t value
)
511 char value_str
[BUFSIZ
];
513 snprintf(value_str
, sizeof(value_str
), "%u", value
);
514 return yang_data_new(xpath
, value_str
);
517 uint16_t yang_dnode_get_uint16(const struct lyd_node
*dnode
,
518 const char *xpath_fmt
, ...)
520 const struct lyd_value
*dvalue
;
521 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
522 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT16
);
523 return dvalue
->uint16
;
526 uint16_t yang_get_default_uint16(const char *xpath_fmt
, ...)
528 char xpath
[XPATH_MAXLEN
];
532 va_start(ap
, xpath_fmt
);
533 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
536 value
= yang_get_default_value(xpath
);
537 return yang_str2uint16(value
);
541 * Primitive type: uint32.
543 uint32_t yang_str2uint32(const char *value
)
545 return strtoul(value
, NULL
, 10);
548 struct yang_data
*yang_data_new_uint32(const char *xpath
, uint32_t value
)
550 char value_str
[BUFSIZ
];
552 snprintf(value_str
, sizeof(value_str
), "%u", value
);
553 return yang_data_new(xpath
, value_str
);
556 uint32_t yang_dnode_get_uint32(const struct lyd_node
*dnode
,
557 const char *xpath_fmt
, ...)
559 const struct lyd_value
*dvalue
;
560 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
561 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT32
);
562 return dvalue
->uint32
;
565 uint32_t yang_get_default_uint32(const char *xpath_fmt
, ...)
567 char xpath
[XPATH_MAXLEN
];
571 va_start(ap
, xpath_fmt
);
572 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
575 value
= yang_get_default_value(xpath
);
576 return yang_str2uint32(value
);
580 * Primitive type: uint64.
582 uint64_t yang_str2uint64(const char *value
)
584 return strtoull(value
, NULL
, 10);
587 struct yang_data
*yang_data_new_uint64(const char *xpath
, uint64_t value
)
589 char value_str
[BUFSIZ
];
591 snprintfrr(value_str
, sizeof(value_str
), "%" PRIu64
, value
);
592 return yang_data_new(xpath
, value_str
);
595 uint64_t yang_dnode_get_uint64(const struct lyd_node
*dnode
,
596 const char *xpath_fmt
, ...)
598 const struct lyd_value
*dvalue
;
599 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
600 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT64
);
601 return dvalue
->uint64
;
604 uint64_t yang_get_default_uint64(const char *xpath_fmt
, ...)
606 char xpath
[XPATH_MAXLEN
];
610 va_start(ap
, xpath_fmt
);
611 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
614 value
= yang_get_default_value(xpath
);
615 return yang_str2uint64(value
);
619 * Primitive type: string.
621 * All string wrappers can be used with non-string types.
623 struct yang_data
*yang_data_new_string(const char *xpath
, const char *value
)
625 return yang_data_new(xpath
, value
);
628 const char *yang_dnode_get_string(const struct lyd_node
*dnode
,
629 const char *xpath_fmt
, ...)
631 return YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
634 void yang_dnode_get_string_buf(char *buf
, size_t size
,
635 const struct lyd_node
*dnode
,
636 const char *xpath_fmt
, ...)
638 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
639 if (strlcpy(buf
, canon
, size
) >= size
) {
640 char xpath
[XPATH_MAXLEN
];
642 yang_dnode_get_path(dnode
, xpath
, sizeof(xpath
));
643 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
644 "%s: value was truncated [xpath %s]", __func__
,
649 const char *yang_get_default_string(const char *xpath_fmt
, ...)
651 char xpath
[XPATH_MAXLEN
];
654 va_start(ap
, xpath_fmt
);
655 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
658 return yang_get_default_value(xpath
);
661 void yang_get_default_string_buf(char *buf
, size_t size
, const char *xpath_fmt
,
664 char xpath
[XPATH_MAXLEN
];
668 va_start(ap
, xpath_fmt
);
669 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
672 value
= yang_get_default_value(xpath
);
673 if (strlcpy(buf
, value
, size
) >= size
)
674 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
675 "%s: value was truncated [xpath %s]", __func__
,
680 * Primitive type: empty.
682 struct yang_data
*yang_data_new_empty(const char *xpath
)
684 return yang_data_new(xpath
, NULL
);
687 bool yang_dnode_get_empty(const struct lyd_node
*dnode
, const char *xpath_fmt
,
691 char xpath
[XPATH_MAXLEN
];
692 const struct lyd_node_term
*dleaf
;
696 va_start(ap
, xpath_fmt
);
697 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
700 dnode
= yang_dnode_get(dnode
, xpath
);
702 dleaf
= (const struct lyd_node_term
*)dnode
;
703 if (dleaf
->value
.realtype
->basetype
== LY_TYPE_EMPTY
)
711 * Derived type: IP prefix.
713 void yang_str2prefix(const char *value
, union prefixptr prefix
)
715 (void)str2prefix(value
, prefix
.p
);
716 apply_mask(prefix
.p
);
719 struct yang_data
*yang_data_new_prefix(const char *xpath
,
720 union prefixconstptr prefix
)
722 char value_str
[PREFIX2STR_BUFFER
];
724 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
725 return yang_data_new(xpath
, value_str
);
728 void yang_dnode_get_prefix(struct prefix
*prefix
, const struct lyd_node
*dnode
,
729 const char *xpath_fmt
, ...)
733 * Initialize prefix to avoid static analyzer complaints about
734 * uninitialized memory.
736 memset(prefix
, 0, sizeof(*prefix
));
738 /* XXX ip_prefix is a native type now in ly2, leverage? */
739 canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
740 (void)str2prefix(canon
, prefix
);
743 void yang_get_default_prefix(union prefixptr var
, const char *xpath_fmt
, ...)
745 char xpath
[XPATH_MAXLEN
];
749 va_start(ap
, xpath_fmt
);
750 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
753 value
= yang_get_default_value(xpath
);
754 yang_str2prefix(value
, var
);
758 * Derived type: ipv4.
760 void yang_str2ipv4(const char *value
, struct in_addr
*addr
)
762 (void)inet_pton(AF_INET
, value
, addr
);
765 struct yang_data
*yang_data_new_ipv4(const char *xpath
,
766 const struct in_addr
*addr
)
768 char value_str
[INET_ADDRSTRLEN
];
770 (void)inet_ntop(AF_INET
, addr
, value_str
, sizeof(value_str
));
771 return yang_data_new(xpath
, value_str
);
774 void yang_dnode_get_ipv4(struct in_addr
*addr
, const struct lyd_node
*dnode
,
775 const char *xpath_fmt
, ...)
777 /* XXX libyang2 IPv4 address is a native type now in ly2 */
778 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
779 (void)inet_pton(AF_INET
, canon
, addr
);
782 void yang_get_default_ipv4(struct in_addr
*var
, const char *xpath_fmt
, ...)
784 char xpath
[XPATH_MAXLEN
];
788 va_start(ap
, xpath_fmt
);
789 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
792 value
= yang_get_default_value(xpath
);
793 yang_str2ipv4(value
, var
);
797 * Derived type: ipv4p.
799 void yang_str2ipv4p(const char *value
, union prefixptr prefix
)
801 struct prefix_ipv4
*prefix4
= prefix
.p4
;
803 (void)str2prefix_ipv4(value
, prefix4
);
804 apply_mask_ipv4(prefix4
);
807 struct yang_data
*yang_data_new_ipv4p(const char *xpath
,
808 union prefixconstptr prefix
)
810 char value_str
[PREFIX2STR_BUFFER
];
812 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
813 return yang_data_new(xpath
, value_str
);
816 void yang_dnode_get_ipv4p(union prefixptr prefix
, const struct lyd_node
*dnode
,
817 const char *xpath_fmt
, ...)
819 struct prefix_ipv4
*prefix4
= prefix
.p4
;
820 /* XXX libyang2: ipv4/6 address is a native type now in ly2 */
821 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
822 (void)str2prefix_ipv4(canon
, prefix4
);
825 void yang_get_default_ipv4p(union prefixptr var
, const char *xpath_fmt
, ...)
827 char xpath
[XPATH_MAXLEN
];
831 va_start(ap
, xpath_fmt
);
832 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
835 value
= yang_get_default_value(xpath
);
836 yang_str2ipv4p(value
, var
);
840 * Derived type: ipv6.
842 void yang_str2ipv6(const char *value
, struct in6_addr
*addr
)
844 (void)inet_pton(AF_INET6
, value
, addr
);
847 struct yang_data
*yang_data_new_ipv6(const char *xpath
,
848 const struct in6_addr
*addr
)
850 char value_str
[INET6_ADDRSTRLEN
];
852 (void)inet_ntop(AF_INET6
, addr
, value_str
, sizeof(value_str
));
853 return yang_data_new(xpath
, value_str
);
856 void yang_dnode_get_ipv6(struct in6_addr
*addr
, const struct lyd_node
*dnode
,
857 const char *xpath_fmt
, ...)
859 /* XXX libyang2: IPv6 address is a native type now, leverage. */
860 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
861 (void)inet_pton(AF_INET6
, canon
, addr
);
864 void yang_get_default_ipv6(struct in6_addr
*var
, const char *xpath_fmt
, ...)
866 char xpath
[XPATH_MAXLEN
];
870 va_start(ap
, xpath_fmt
);
871 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
874 value
= yang_get_default_value(xpath
);
875 yang_str2ipv6(value
, var
);
879 * Derived type: ipv6p.
881 void yang_str2ipv6p(const char *value
, union prefixptr prefix
)
883 struct prefix_ipv6
*prefix6
= prefix
.p6
;
885 (void)str2prefix_ipv6(value
, prefix6
);
886 apply_mask_ipv6(prefix6
);
889 struct yang_data
*yang_data_new_ipv6p(const char *xpath
,
890 union prefixconstptr prefix
)
892 char value_str
[PREFIX2STR_BUFFER
];
894 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
895 return yang_data_new(xpath
, value_str
);
898 void yang_dnode_get_ipv6p(union prefixptr prefix
, const struct lyd_node
*dnode
,
899 const char *xpath_fmt
, ...)
901 struct prefix_ipv6
*prefix6
= prefix
.p6
;
903 /* XXX IPv6 address is a native type now in ly2 -- can we leverage? */
904 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
905 (void)str2prefix_ipv6(canon
, prefix6
);
908 void yang_get_default_ipv6p(union prefixptr var
, const char *xpath_fmt
, ...)
910 char xpath
[XPATH_MAXLEN
];
914 va_start(ap
, xpath_fmt
);
915 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
918 value
= yang_get_default_value(xpath
);
919 yang_str2ipv6p(value
, var
);
925 void yang_str2ip(const char *value
, struct ipaddr
*ip
)
927 (void)str2ipaddr(value
, ip
);
930 struct yang_data
*yang_data_new_ip(const char *xpath
, const struct ipaddr
*addr
)
932 size_t sz
= IS_IPADDR_V4(addr
) ? INET_ADDRSTRLEN
: INET6_ADDRSTRLEN
;
935 ipaddr2str(addr
, value_str
, sizeof(value_str
));
936 return yang_data_new(xpath
, value_str
);
939 void yang_dnode_get_ip(struct ipaddr
*addr
, const struct lyd_node
*dnode
,
940 const char *xpath_fmt
, ...)
942 /* XXX IPv4 address could be a plugin type now in ly2, leverage? */
943 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
944 (void)str2ipaddr(canon
, addr
);
947 void yang_get_default_ip(struct ipaddr
*var
, const char *xpath_fmt
, ...)
949 char xpath
[XPATH_MAXLEN
];
953 va_start(ap
, xpath_fmt
);
954 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
957 value
= yang_get_default_value(xpath
);
958 yang_str2ip(value
, var
);
961 struct yang_data
*yang_data_new_mac(const char *xpath
,
962 const struct ethaddr
*mac
)
964 char value_str
[ETHER_ADDR_STRLEN
];
966 prefix_mac2str(mac
, value_str
, sizeof(value_str
));
967 return yang_data_new(xpath
, value_str
);
970 void yang_str2mac(const char *value
, struct ethaddr
*mac
)
972 (void)prefix_str2mac(value
, mac
);
975 struct yang_data
*yang_data_new_date_and_time(const char *xpath
, time_t time
)
978 char timebuf
[MONOTIME_STRLEN
];
979 struct timeval _time
, time_real
;
985 monotime_to_realtime(&_time
, &time_real
);
987 gmtime_r(&time_real
.tv_sec
, &tm
);
989 /* rfc-3339 format */
990 strftime(timebuf
, sizeof(timebuf
), "%Y-%m-%dT%H:%M:%S", &tm
);
991 buflen
= strlen(timebuf
);
992 ts_dot
= timebuf
+ buflen
;
994 /* microseconds and appends Z */
995 snprintfrr(ts_dot
, sizeof(timebuf
) - buflen
, ".%06luZ",
996 (unsigned long)time_real
.tv_usec
);
998 return yang_data_new(xpath
, timebuf
);
1001 const char *yang_nexthop_type2str(uint32_t ntype
)
1004 case NEXTHOP_TYPE_IFINDEX
:
1007 case NEXTHOP_TYPE_IPV4
:
1010 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1011 return "ip4-ifindex";
1013 case NEXTHOP_TYPE_IPV6
:
1016 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1017 return "ip6-ifindex";
1019 case NEXTHOP_TYPE_BLACKHOLE
:
1029 const char *yang_afi_safi_value2identity(afi_t afi
, safi_t safi
)
1031 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1032 return "frr-routing:ipv4-unicast";
1033 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
1034 return "frr-routing:ipv6-unicast";
1035 if (afi
== AFI_IP
&& safi
== SAFI_MULTICAST
)
1036 return "frr-routing:ipv4-multicast";
1037 if (afi
== AFI_IP6
&& safi
== SAFI_MULTICAST
)
1038 return "frr-routing:ipv6-multicast";
1039 if (afi
== AFI_IP
&& safi
== SAFI_MPLS_VPN
)
1040 return "frr-routing:l3vpn-ipv4-unicast";
1041 if (afi
== AFI_IP6
&& safi
== SAFI_MPLS_VPN
)
1042 return "frr-routing:l3vpn-ipv6-unicast";
1043 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
1044 return "frr-routing:l2vpn-evpn";
1045 if (afi
== AFI_IP
&& safi
== SAFI_LABELED_UNICAST
)
1046 return "frr-routing:ipv4-labeled-unicast";
1047 if (afi
== AFI_IP6
&& safi
== SAFI_LABELED_UNICAST
)
1048 return "frr-routing:ipv6-labeled-unicast";
1049 if (afi
== AFI_IP
&& safi
== SAFI_FLOWSPEC
)
1050 return "frr-routing:ipv4-flowspec";
1051 if (afi
== AFI_IP6
&& safi
== SAFI_FLOWSPEC
)
1052 return "frr-routing:ipv6-flowspec";
1057 void yang_afi_safi_identity2value(const char *key
, afi_t
*afi
, safi_t
*safi
)
1059 if (strmatch(key
, "frr-routing:ipv4-unicast")) {
1061 *safi
= SAFI_UNICAST
;
1062 } else if (strmatch(key
, "frr-routing:ipv6-unicast")) {
1064 *safi
= SAFI_UNICAST
;
1065 } else if (strmatch(key
, "frr-routing:ipv4-multicast")) {
1067 *safi
= SAFI_MULTICAST
;
1068 } else if (strmatch(key
, "frr-routing:ipv6-multicast")) {
1070 *safi
= SAFI_MULTICAST
;
1071 } else if (strmatch(key
, "frr-routing:l3vpn-ipv4-unicast")) {
1073 *safi
= SAFI_MPLS_VPN
;
1074 } else if (strmatch(key
, "frr-routing:l3vpn-ipv6-unicast")) {
1076 *safi
= SAFI_MPLS_VPN
;
1077 } else if (strmatch(key
, "frr-routing:ipv4-labeled-unicast")) {
1079 *safi
= SAFI_LABELED_UNICAST
;
1080 } else if (strmatch(key
, "frr-routing:ipv6-labeled-unicast")) {
1082 *safi
= SAFI_LABELED_UNICAST
;
1083 } else if (strmatch(key
, "frr-routing:l2vpn-evpn")) {
1086 } else if (strmatch(key
, "frr-routing:ipv4-flowspec")) {
1088 *safi
= SAFI_FLOWSPEC
;
1089 } else if (strmatch(key
, "frr-routing:ipv6-flowspec")) {
1091 *safi
= SAFI_FLOWSPEC
;
1094 *safi
= SAFI_UNSPEC
;