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"
29 static const char *yang_get_default_value(const char *xpath
)
31 const struct lys_node
*snode
;
34 snode
= ly_ctx_get_node(ly_native_ctx
, NULL
, xpath
, 0);
36 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
37 "%s: unknown data path: %s", __func__
, xpath
);
38 zlog_backtrace(LOG_ERR
);
42 value
= yang_snode_get_default(snode
);
48 #define YANG_DNODE_GET_ASSERT(dnode, xpath) \
50 if ((dnode) == NULL) { \
51 flog_err(EC_LIB_YANG_DNODE_NOT_FOUND, \
52 "%s: couldn't find %s", __func__, (xpath)); \
53 zlog_backtrace(LOG_ERR); \
59 * Primitive type: bool.
61 bool yang_str2bool(const char *value
)
63 return strmatch(value
, "true");
66 struct yang_data
*yang_data_new_bool(const char *xpath
, bool value
)
68 return yang_data_new(xpath
, (value
) ? "true" : "false");
71 bool yang_dnode_get_bool(const struct lyd_node
*dnode
, const char *xpath_fmt
,
74 const struct lyd_node_leaf_list
*dleaf
;
79 char xpath
[XPATH_MAXLEN
];
81 va_start(ap
, xpath_fmt
);
82 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
84 dnode
= yang_dnode_get(dnode
, xpath
);
85 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
88 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
89 assert(dleaf
->value_type
== LY_TYPE_BOOL
);
90 return dleaf
->value
.bln
;
93 bool yang_get_default_bool(const char *xpath_fmt
, ...)
95 char xpath
[XPATH_MAXLEN
];
99 va_start(ap
, xpath_fmt
);
100 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
103 value
= yang_get_default_value(xpath
);
104 return yang_str2bool(value
);
108 * Primitive type: dec64.
110 double yang_str2dec64(const char *xpath
, const char *value
)
114 if (sscanf(value
, "%lf", &dbl
) != 1) {
115 flog_err(EC_LIB_YANG_DATA_CONVERT
,
116 "%s: couldn't convert string to decimal64 [xpath %s]",
118 zlog_backtrace(LOG_ERR
);
125 struct yang_data
*yang_data_new_dec64(const char *xpath
, double value
)
127 char value_str
[BUFSIZ
];
129 snprintf(value_str
, sizeof(value_str
), "%lf", value
);
130 return yang_data_new(xpath
, value_str
);
133 double yang_dnode_get_dec64(const struct lyd_node
*dnode
, const char *xpath_fmt
,
136 const struct lyd_node_leaf_list
*dleaf
;
141 char xpath
[XPATH_MAXLEN
];
143 va_start(ap
, xpath_fmt
);
144 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
146 dnode
= yang_dnode_get(dnode
, xpath
);
147 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
150 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
151 assert(dleaf
->value_type
== LY_TYPE_DEC64
);
153 return lyd_dec64_to_double(dnode
);
156 double yang_get_default_dec64(const char *xpath_fmt
, ...)
158 char xpath
[XPATH_MAXLEN
];
162 va_start(ap
, xpath_fmt
);
163 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
166 value
= yang_get_default_value(xpath
);
167 return yang_str2dec64(xpath
, value
);
171 * Primitive type: enum.
173 int yang_str2enum(const char *xpath
, const char *value
)
175 const struct lys_node
*snode
;
176 const struct lys_node_leaf
*sleaf
;
177 const struct lys_type
*type
;
178 const struct lys_type_info_enums
*enums
;
180 snode
= ly_ctx_get_node(ly_native_ctx
, NULL
, xpath
, 0);
182 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
183 "%s: unknown data path: %s", __func__
, xpath
);
184 zlog_backtrace(LOG_ERR
);
188 sleaf
= (const struct lys_node_leaf
*)snode
;
190 enums
= &type
->info
.enums
;
191 while (enums
->count
== 0 && type
->der
) {
192 type
= &type
->der
->type
;
193 enums
= &type
->info
.enums
;
195 for (unsigned int i
= 0; i
< enums
->count
; i
++) {
196 const struct lys_type_enum
*enm
= &enums
->enm
[i
];
198 if (strmatch(value
, enm
->name
))
202 flog_err(EC_LIB_YANG_DATA_CONVERT
,
203 "%s: couldn't convert string to enum [xpath %s]", __func__
,
205 zlog_backtrace(LOG_ERR
);
209 struct yang_data
*yang_data_new_enum(const char *xpath
, int value
)
211 const struct lys_node
*snode
;
212 const struct lys_node_leaf
*sleaf
;
213 const struct lys_type
*type
;
214 const struct lys_type_info_enums
*enums
;
216 snode
= ly_ctx_get_node(ly_native_ctx
, NULL
, xpath
, 0);
218 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
219 "%s: unknown data path: %s", __func__
, xpath
);
220 zlog_backtrace(LOG_ERR
);
224 sleaf
= (const struct lys_node_leaf
*)snode
;
226 enums
= &type
->info
.enums
;
227 while (enums
->count
== 0 && type
->der
) {
228 type
= &type
->der
->type
;
229 enums
= &type
->info
.enums
;
231 for (unsigned int i
= 0; i
< enums
->count
; i
++) {
232 const struct lys_type_enum
*enm
= &enums
->enm
[i
];
234 if (value
== enm
->value
)
235 return yang_data_new(xpath
, enm
->name
);
238 flog_err(EC_LIB_YANG_DATA_CONVERT
,
239 "%s: couldn't convert enum to string [xpath %s]", __func__
,
241 zlog_backtrace(LOG_ERR
);
245 int yang_dnode_get_enum(const struct lyd_node
*dnode
, const char *xpath_fmt
,
248 const struct lyd_node_leaf_list
*dleaf
;
253 char xpath
[XPATH_MAXLEN
];
255 va_start(ap
, xpath_fmt
);
256 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
258 dnode
= yang_dnode_get(dnode
, xpath
);
259 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
262 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
263 assert(dleaf
->value_type
== LY_TYPE_ENUM
);
264 return dleaf
->value
.enm
->value
;
267 int yang_get_default_enum(const char *xpath_fmt
, ...)
269 char xpath
[XPATH_MAXLEN
];
273 va_start(ap
, xpath_fmt
);
274 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
277 value
= yang_get_default_value(xpath
);
278 return yang_str2enum(xpath
, value
);
282 * Primitive type: int8.
284 int8_t yang_str2int8(const char *value
)
286 return strtol(value
, NULL
, 10);
289 struct yang_data
*yang_data_new_int8(const char *xpath
, int8_t value
)
291 char value_str
[BUFSIZ
];
293 snprintf(value_str
, sizeof(value_str
), "%d", value
);
294 return yang_data_new(xpath
, value_str
);
297 int8_t yang_dnode_get_int8(const struct lyd_node
*dnode
, const char *xpath_fmt
,
300 const struct lyd_node_leaf_list
*dleaf
;
305 char xpath
[XPATH_MAXLEN
];
307 va_start(ap
, xpath_fmt
);
308 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
310 dnode
= yang_dnode_get(dnode
, xpath
);
311 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
314 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
315 assert(dleaf
->value_type
== LY_TYPE_INT8
);
316 return dleaf
->value
.int8
;
319 int8_t yang_get_default_int8(const char *xpath_fmt
, ...)
321 char xpath
[XPATH_MAXLEN
];
325 va_start(ap
, xpath_fmt
);
326 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
329 value
= yang_get_default_value(xpath
);
330 return yang_str2int8(value
);
334 * Primitive type: int16.
336 int16_t yang_str2int16(const char *value
)
338 return strtol(value
, NULL
, 10);
341 struct yang_data
*yang_data_new_int16(const char *xpath
, int16_t value
)
343 char value_str
[BUFSIZ
];
345 snprintf(value_str
, sizeof(value_str
), "%d", value
);
346 return yang_data_new(xpath
, value_str
);
349 int16_t yang_dnode_get_int16(const struct lyd_node
*dnode
,
350 const char *xpath_fmt
, ...)
352 const struct lyd_node_leaf_list
*dleaf
;
357 char xpath
[XPATH_MAXLEN
];
359 va_start(ap
, xpath_fmt
);
360 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
362 dnode
= yang_dnode_get(dnode
, xpath
);
363 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
366 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
367 assert(dleaf
->value_type
== LY_TYPE_INT16
);
368 return dleaf
->value
.int16
;
371 int16_t yang_get_default_int16(const char *xpath_fmt
, ...)
373 char xpath
[XPATH_MAXLEN
];
377 va_start(ap
, xpath_fmt
);
378 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
381 value
= yang_get_default_value(xpath
);
382 return yang_str2int16(value
);
386 * Primitive type: int32.
388 int32_t yang_str2int32(const char *value
)
390 return strtol(value
, NULL
, 10);
393 struct yang_data
*yang_data_new_int32(const char *xpath
, int32_t value
)
395 char value_str
[BUFSIZ
];
397 snprintf(value_str
, sizeof(value_str
), "%d", value
);
398 return yang_data_new(xpath
, value_str
);
401 int32_t yang_dnode_get_int32(const struct lyd_node
*dnode
,
402 const char *xpath_fmt
, ...)
404 const struct lyd_node_leaf_list
*dleaf
;
409 char xpath
[XPATH_MAXLEN
];
411 va_start(ap
, xpath_fmt
);
412 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
414 dnode
= yang_dnode_get(dnode
, xpath
);
415 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
418 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
419 assert(dleaf
->value_type
== LY_TYPE_INT32
);
420 return dleaf
->value
.int32
;
423 int32_t yang_get_default_int32(const char *xpath_fmt
, ...)
425 char xpath
[XPATH_MAXLEN
];
429 va_start(ap
, xpath_fmt
);
430 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
433 value
= yang_get_default_value(xpath
);
434 return yang_str2int32(value
);
438 * Primitive type: int64.
440 int64_t yang_str2int64(const char *value
)
442 return strtoll(value
, NULL
, 10);
445 struct yang_data
*yang_data_new_int64(const char *xpath
, int64_t value
)
447 char value_str
[BUFSIZ
];
449 snprintfrr(value_str
, sizeof(value_str
), "%" PRId64
, value
);
450 return yang_data_new(xpath
, value_str
);
453 int64_t yang_dnode_get_int64(const struct lyd_node
*dnode
,
454 const char *xpath_fmt
, ...)
456 const struct lyd_node_leaf_list
*dleaf
;
461 char xpath
[XPATH_MAXLEN
];
463 va_start(ap
, xpath_fmt
);
464 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
466 dnode
= yang_dnode_get(dnode
, xpath
);
467 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
470 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
471 assert(dleaf
->value_type
== LY_TYPE_INT64
);
472 return dleaf
->value
.int64
;
475 int64_t yang_get_default_int64(const char *xpath_fmt
, ...)
477 char xpath
[XPATH_MAXLEN
];
481 va_start(ap
, xpath_fmt
);
482 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
485 value
= yang_get_default_value(xpath
);
486 return yang_str2int64(value
);
490 * Primitive type: uint8.
492 uint8_t yang_str2uint8(const char *value
)
494 return strtoul(value
, NULL
, 10);
497 struct yang_data
*yang_data_new_uint8(const char *xpath
, uint8_t value
)
499 char value_str
[BUFSIZ
];
501 snprintf(value_str
, sizeof(value_str
), "%u", value
);
502 return yang_data_new(xpath
, value_str
);
505 uint8_t yang_dnode_get_uint8(const struct lyd_node
*dnode
,
506 const char *xpath_fmt
, ...)
508 const struct lyd_node_leaf_list
*dleaf
;
513 char xpath
[XPATH_MAXLEN
];
515 va_start(ap
, xpath_fmt
);
516 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
518 dnode
= yang_dnode_get(dnode
, xpath
);
519 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
522 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
523 assert(dleaf
->value_type
== LY_TYPE_UINT8
);
524 return dleaf
->value
.uint8
;
527 uint8_t yang_get_default_uint8(const char *xpath_fmt
, ...)
529 char xpath
[XPATH_MAXLEN
];
533 va_start(ap
, xpath_fmt
);
534 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
537 value
= yang_get_default_value(xpath
);
538 return yang_str2uint8(value
);
542 * Primitive type: uint16.
544 uint16_t yang_str2uint16(const char *value
)
546 return strtoul(value
, NULL
, 10);
549 struct yang_data
*yang_data_new_uint16(const char *xpath
, uint16_t value
)
551 char value_str
[BUFSIZ
];
553 snprintf(value_str
, sizeof(value_str
), "%u", value
);
554 return yang_data_new(xpath
, value_str
);
557 uint16_t yang_dnode_get_uint16(const struct lyd_node
*dnode
,
558 const char *xpath_fmt
, ...)
560 const struct lyd_node_leaf_list
*dleaf
;
565 char xpath
[XPATH_MAXLEN
];
567 va_start(ap
, xpath_fmt
);
568 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
570 dnode
= yang_dnode_get(dnode
, xpath
);
571 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
574 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
575 assert(dleaf
->value_type
== LY_TYPE_UINT16
);
576 return dleaf
->value
.uint16
;
579 uint16_t yang_get_default_uint16(const char *xpath_fmt
, ...)
581 char xpath
[XPATH_MAXLEN
];
585 va_start(ap
, xpath_fmt
);
586 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
589 value
= yang_get_default_value(xpath
);
590 return yang_str2uint16(value
);
594 * Primitive type: uint32.
596 uint32_t yang_str2uint32(const char *value
)
598 return strtoul(value
, NULL
, 10);
601 struct yang_data
*yang_data_new_uint32(const char *xpath
, uint32_t value
)
603 char value_str
[BUFSIZ
];
605 snprintf(value_str
, sizeof(value_str
), "%u", value
);
606 return yang_data_new(xpath
, value_str
);
609 uint32_t yang_dnode_get_uint32(const struct lyd_node
*dnode
,
610 const char *xpath_fmt
, ...)
612 const struct lyd_node_leaf_list
*dleaf
;
617 char xpath
[XPATH_MAXLEN
];
619 va_start(ap
, xpath_fmt
);
620 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
622 dnode
= yang_dnode_get(dnode
, xpath
);
623 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
626 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
627 assert(dleaf
->value_type
== LY_TYPE_UINT32
);
628 return dleaf
->value
.uint32
;
631 uint32_t yang_get_default_uint32(const char *xpath_fmt
, ...)
633 char xpath
[XPATH_MAXLEN
];
637 va_start(ap
, xpath_fmt
);
638 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
641 value
= yang_get_default_value(xpath
);
642 return yang_str2uint32(value
);
646 * Primitive type: uint64.
648 uint64_t yang_str2uint64(const char *value
)
650 return strtoull(value
, NULL
, 10);
653 struct yang_data
*yang_data_new_uint64(const char *xpath
, uint64_t value
)
655 char value_str
[BUFSIZ
];
657 snprintfrr(value_str
, sizeof(value_str
), "%" PRIu64
, value
);
658 return yang_data_new(xpath
, value_str
);
661 uint64_t yang_dnode_get_uint64(const struct lyd_node
*dnode
,
662 const char *xpath_fmt
, ...)
664 const struct lyd_node_leaf_list
*dleaf
;
669 char xpath
[XPATH_MAXLEN
];
671 va_start(ap
, xpath_fmt
);
672 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
674 dnode
= yang_dnode_get(dnode
, xpath
);
675 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
678 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
679 assert(dleaf
->value_type
== LY_TYPE_UINT64
);
680 return dleaf
->value
.uint64
;
683 uint64_t yang_get_default_uint64(const char *xpath_fmt
, ...)
685 char xpath
[XPATH_MAXLEN
];
689 va_start(ap
, xpath_fmt
);
690 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
693 value
= yang_get_default_value(xpath
);
694 return yang_str2uint64(value
);
698 * Primitive type: string.
700 * All string wrappers can be used with non-string types.
702 struct yang_data
*yang_data_new_string(const char *xpath
, const char *value
)
704 return yang_data_new(xpath
, value
);
707 const char *yang_dnode_get_string(const struct lyd_node
*dnode
,
708 const char *xpath_fmt
, ...)
710 const struct lyd_node_leaf_list
*dleaf
;
715 char xpath
[XPATH_MAXLEN
];
717 va_start(ap
, xpath_fmt
);
718 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
720 dnode
= yang_dnode_get(dnode
, xpath
);
721 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
724 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
725 return dleaf
->value_str
;
728 void yang_dnode_get_string_buf(char *buf
, size_t size
,
729 const struct lyd_node
*dnode
,
730 const char *xpath_fmt
, ...)
732 const struct lyd_node_leaf_list
*dleaf
;
737 char xpath
[XPATH_MAXLEN
];
739 va_start(ap
, xpath_fmt
);
740 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
742 dnode
= yang_dnode_get(dnode
, xpath
);
743 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
746 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
747 if (strlcpy(buf
, dleaf
->value_str
, size
) >= size
) {
748 char xpath
[XPATH_MAXLEN
];
750 yang_dnode_get_path(dnode
, xpath
, sizeof(xpath
));
751 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
752 "%s: value was truncated [xpath %s]", __func__
,
757 const char *yang_get_default_string(const char *xpath_fmt
, ...)
759 char xpath
[XPATH_MAXLEN
];
762 va_start(ap
, xpath_fmt
);
763 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
766 return yang_get_default_value(xpath
);
769 void yang_get_default_string_buf(char *buf
, size_t size
, const char *xpath_fmt
,
772 char xpath
[XPATH_MAXLEN
];
776 va_start(ap
, xpath_fmt
);
777 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
780 value
= yang_get_default_value(xpath
);
781 if (strlcpy(buf
, value
, size
) >= size
)
782 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
783 "%s: value was truncated [xpath %s]", __func__
,
788 * Primitive type: empty.
790 struct yang_data
*yang_data_new_empty(const char *xpath
)
792 return yang_data_new(xpath
, NULL
);
795 bool yang_dnode_get_empty(const struct lyd_node
*dnode
, const char *xpath_fmt
,
799 char xpath
[XPATH_MAXLEN
];
800 const struct lyd_node_leaf_list
*dleaf
;
804 va_start(ap
, xpath_fmt
);
805 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
808 dnode
= yang_dnode_get(dnode
, xpath
);
810 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
811 if (dleaf
->value_type
== LY_TYPE_EMPTY
)
819 * Derived type: IP prefix.
821 void yang_str2prefix(const char *value
, union prefixptr prefix
)
823 (void)str2prefix(value
, prefix
.p
);
824 apply_mask(prefix
.p
);
827 struct yang_data
*yang_data_new_prefix(const char *xpath
,
828 union prefixconstptr prefix
)
830 char value_str
[PREFIX2STR_BUFFER
];
832 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
833 return yang_data_new(xpath
, value_str
);
836 void yang_dnode_get_prefix(struct prefix
*prefix
, const struct lyd_node
*dnode
,
837 const char *xpath_fmt
, ...)
839 const struct lyd_node_leaf_list
*dleaf
;
844 char xpath
[XPATH_MAXLEN
];
846 va_start(ap
, xpath_fmt
);
847 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
849 dnode
= yang_dnode_get(dnode
, xpath
);
850 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
854 * Initialize prefix to avoid static analyzer complaints about
855 * uninitialized memory.
857 memset(prefix
, 0, sizeof(*prefix
));
859 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
860 assert(dleaf
->value_type
== LY_TYPE_STRING
);
861 (void)str2prefix(dleaf
->value_str
, prefix
);
864 void yang_get_default_prefix(union prefixptr 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_str2prefix(value
, var
);
879 * Derived type: ipv4.
881 void yang_str2ipv4(const char *value
, struct in_addr
*addr
)
883 (void)inet_pton(AF_INET
, value
, addr
);
886 struct yang_data
*yang_data_new_ipv4(const char *xpath
,
887 const struct in_addr
*addr
)
889 char value_str
[INET_ADDRSTRLEN
];
891 (void)inet_ntop(AF_INET
, addr
, value_str
, sizeof(value_str
));
892 return yang_data_new(xpath
, value_str
);
895 void yang_dnode_get_ipv4(struct in_addr
*addr
, const struct lyd_node
*dnode
,
896 const char *xpath_fmt
, ...)
898 const struct lyd_node_leaf_list
*dleaf
;
903 char xpath
[XPATH_MAXLEN
];
905 va_start(ap
, xpath_fmt
);
906 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
908 dnode
= yang_dnode_get(dnode
, xpath
);
909 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
912 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
913 assert(dleaf
->value_type
== LY_TYPE_STRING
);
914 (void)inet_pton(AF_INET
, dleaf
->value_str
, addr
);
917 void yang_get_default_ipv4(struct in_addr
*var
, const char *xpath_fmt
, ...)
919 char xpath
[XPATH_MAXLEN
];
923 va_start(ap
, xpath_fmt
);
924 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
927 value
= yang_get_default_value(xpath
);
928 yang_str2ipv4(value
, var
);
932 * Derived type: ipv4p.
934 void yang_str2ipv4p(const char *value
, union prefixptr prefix
)
936 struct prefix_ipv4
*prefix4
= prefix
.p4
;
938 (void)str2prefix_ipv4(value
, prefix4
);
939 apply_mask_ipv4(prefix4
);
942 struct yang_data
*yang_data_new_ipv4p(const char *xpath
,
943 union prefixconstptr prefix
)
945 char value_str
[PREFIX2STR_BUFFER
];
947 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
948 return yang_data_new(xpath
, value_str
);
951 void yang_dnode_get_ipv4p(union prefixptr prefix
, const struct lyd_node
*dnode
,
952 const char *xpath_fmt
, ...)
954 const struct lyd_node_leaf_list
*dleaf
;
955 struct prefix_ipv4
*prefix4
= prefix
.p4
;
960 char xpath
[XPATH_MAXLEN
];
962 va_start(ap
, xpath_fmt
);
963 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
965 dnode
= yang_dnode_get(dnode
, xpath
);
966 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
969 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
970 assert(dleaf
->value_type
== LY_TYPE_STRING
);
971 (void)str2prefix_ipv4(dleaf
->value_str
, prefix4
);
974 void yang_get_default_ipv4p(union prefixptr var
, const char *xpath_fmt
, ...)
976 char xpath
[XPATH_MAXLEN
];
980 va_start(ap
, xpath_fmt
);
981 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
984 value
= yang_get_default_value(xpath
);
985 yang_str2ipv4p(value
, var
);
989 * Derived type: ipv6.
991 void yang_str2ipv6(const char *value
, struct in6_addr
*addr
)
993 (void)inet_pton(AF_INET6
, value
, addr
);
996 struct yang_data
*yang_data_new_ipv6(const char *xpath
,
997 const struct in6_addr
*addr
)
999 char value_str
[INET6_ADDRSTRLEN
];
1001 (void)inet_ntop(AF_INET6
, addr
, value_str
, sizeof(value_str
));
1002 return yang_data_new(xpath
, value_str
);
1005 void yang_dnode_get_ipv6(struct in6_addr
*addr
, const struct lyd_node
*dnode
,
1006 const char *xpath_fmt
, ...)
1008 const struct lyd_node_leaf_list
*dleaf
;
1013 char xpath
[XPATH_MAXLEN
];
1015 va_start(ap
, xpath_fmt
);
1016 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
1018 dnode
= yang_dnode_get(dnode
, xpath
);
1019 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
1022 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
1023 assert(dleaf
->value_type
== LY_TYPE_STRING
);
1024 (void)inet_pton(AF_INET6
, dleaf
->value_str
, addr
);
1027 void yang_get_default_ipv6(struct in6_addr
*var
, const char *xpath_fmt
, ...)
1029 char xpath
[XPATH_MAXLEN
];
1033 va_start(ap
, xpath_fmt
);
1034 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
1037 value
= yang_get_default_value(xpath
);
1038 yang_str2ipv6(value
, var
);
1042 * Derived type: ipv6p.
1044 void yang_str2ipv6p(const char *value
, union prefixptr prefix
)
1046 struct prefix_ipv6
*prefix6
= prefix
.p6
;
1048 (void)str2prefix_ipv6(value
, prefix6
);
1049 apply_mask_ipv6(prefix6
);
1052 struct yang_data
*yang_data_new_ipv6p(const char *xpath
,
1053 union prefixconstptr prefix
)
1055 char value_str
[PREFIX2STR_BUFFER
];
1057 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
1058 return yang_data_new(xpath
, value_str
);
1061 void yang_dnode_get_ipv6p(union prefixptr prefix
, const struct lyd_node
*dnode
,
1062 const char *xpath_fmt
, ...)
1064 const struct lyd_node_leaf_list
*dleaf
;
1065 struct prefix_ipv6
*prefix6
= prefix
.p6
;
1070 char xpath
[XPATH_MAXLEN
];
1072 va_start(ap
, xpath_fmt
);
1073 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
1075 dnode
= yang_dnode_get(dnode
, xpath
);
1076 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
1079 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
1080 assert(dleaf
->value_type
== LY_TYPE_STRING
);
1081 (void)str2prefix_ipv6(dleaf
->value_str
, prefix6
);
1084 void yang_get_default_ipv6p(union prefixptr var
, const char *xpath_fmt
, ...)
1086 char xpath
[XPATH_MAXLEN
];
1090 va_start(ap
, xpath_fmt
);
1091 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
1094 value
= yang_get_default_value(xpath
);
1095 yang_str2ipv6p(value
, var
);
1101 void yang_str2ip(const char *value
, struct ipaddr
*ip
)
1103 (void)str2ipaddr(value
, ip
);
1106 struct yang_data
*yang_data_new_ip(const char *xpath
, const struct ipaddr
*addr
)
1108 size_t sz
= IS_IPADDR_V4(addr
) ? INET_ADDRSTRLEN
: INET6_ADDRSTRLEN
;
1111 ipaddr2str(addr
, value_str
, sizeof(value_str
));
1112 return yang_data_new(xpath
, value_str
);
1115 void yang_dnode_get_ip(struct ipaddr
*addr
, const struct lyd_node
*dnode
,
1116 const char *xpath_fmt
, ...)
1118 const struct lyd_node_leaf_list
*dleaf
;
1123 char xpath
[XPATH_MAXLEN
];
1125 va_start(ap
, xpath_fmt
);
1126 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
1128 dnode
= yang_dnode_get(dnode
, xpath
);
1129 YANG_DNODE_GET_ASSERT(dnode
, xpath
);
1132 dleaf
= (const struct lyd_node_leaf_list
*)dnode
;
1133 assert(dleaf
->value_type
== LY_TYPE_STRING
);
1134 (void)str2ipaddr(dleaf
->value_str
, addr
);
1137 void yang_get_default_ip(struct ipaddr
*var
, const char *xpath_fmt
, ...)
1139 char xpath
[XPATH_MAXLEN
];
1143 va_start(ap
, xpath_fmt
);
1144 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
1147 value
= yang_get_default_value(xpath
);
1148 yang_str2ip(value
, var
);
1151 struct yang_data
*yang_data_new_mac(const char *xpath
,
1152 const struct ethaddr
*mac
)
1154 char value_str
[ETHER_ADDR_STRLEN
];
1156 prefix_mac2str(mac
, value_str
, sizeof(value_str
));
1157 return yang_data_new(xpath
, value_str
);
1160 void yang_str2mac(const char *value
, struct ethaddr
*mac
)
1162 (void)prefix_str2mac(value
, mac
);
1165 struct yang_data
*yang_data_new_date_and_time(const char *xpath
, time_t time
)
1168 char timebuf
[MONOTIME_STRLEN
];
1169 struct timeval _time
, time_real
;
1173 _time
.tv_sec
= time
;
1175 monotime_to_realtime(&_time
, &time_real
);
1177 gmtime_r(&time_real
.tv_sec
, &tm
);
1179 /* rfc-3339 format */
1180 strftime(timebuf
, sizeof(timebuf
), "%Y-%m-%dT%H:%M:%S", &tm
);
1181 buflen
= strlen(timebuf
);
1182 ts_dot
= timebuf
+ buflen
;
1184 /* microseconds and appends Z */
1185 snprintfrr(ts_dot
, sizeof(timebuf
) - buflen
, ".%06luZ",
1186 (unsigned long)time_real
.tv_usec
);
1188 return yang_data_new(xpath
, timebuf
);
1191 const char *yang_nexthop_type2str(uint32_t ntype
)
1194 case NEXTHOP_TYPE_IFINDEX
:
1197 case NEXTHOP_TYPE_IPV4
:
1200 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1201 return "ip4-ifindex";
1203 case NEXTHOP_TYPE_IPV6
:
1206 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1207 return "ip6-ifindex";
1209 case NEXTHOP_TYPE_BLACKHOLE
:
1219 const char *yang_afi_safi_value2identity(afi_t afi
, safi_t safi
)
1221 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1222 return "frr-routing:ipv4-unicast";
1223 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
1224 return "frr-routing:ipv6-unicast";
1225 if (afi
== AFI_IP
&& safi
== SAFI_MULTICAST
)
1226 return "frr-routing:ipv4-multicast";
1227 if (afi
== AFI_IP6
&& safi
== SAFI_MULTICAST
)
1228 return "frr-routing:ipv6-multicast";
1229 if (afi
== AFI_IP
&& safi
== SAFI_MPLS_VPN
)
1230 return "frr-routing:l3vpn-ipv4-unicast";
1231 if (afi
== AFI_IP6
&& safi
== SAFI_MPLS_VPN
)
1232 return "frr-routing:l3vpn-ipv6-unicast";
1233 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
1234 return "frr-routing:l2vpn-evpn";
1235 if (afi
== AFI_IP
&& safi
== SAFI_LABELED_UNICAST
)
1236 return "frr-routing:ipv4-labeled-unicast";
1237 if (afi
== AFI_IP6
&& safi
== SAFI_LABELED_UNICAST
)
1238 return "frr-routing:ipv6-labeled-unicast";
1239 if (afi
== AFI_IP
&& safi
== SAFI_FLOWSPEC
)
1240 return "frr-routing:ipv4-flowspec";
1241 if (afi
== AFI_IP6
&& safi
== SAFI_FLOWSPEC
)
1242 return "frr-routing:ipv6-flowspec";
1247 void yang_afi_safi_identity2value(const char *key
, afi_t
*afi
, safi_t
*safi
)
1249 if (strmatch(key
, "frr-routing:ipv4-unicast")) {
1251 *safi
= SAFI_UNICAST
;
1252 } else if (strmatch(key
, "frr-routing:ipv6-unicast")) {
1254 *safi
= SAFI_UNICAST
;
1255 } else if (strmatch(key
, "frr-routing:ipv4-multicast")) {
1257 *safi
= SAFI_MULTICAST
;
1258 } else if (strmatch(key
, "frr-routing:ipv6-multicast")) {
1260 *safi
= SAFI_MULTICAST
;
1261 } else if (strmatch(key
, "frr-routing:l3vpn-ipv4-unicast")) {
1263 *safi
= SAFI_MPLS_VPN
;
1264 } else if (strmatch(key
, "frr-routing:l3vpn-ipv6-unicast")) {
1266 *safi
= SAFI_MPLS_VPN
;
1267 } else if (strmatch(key
, "frr-routing:ipv4-labeled-unicast")) {
1269 *safi
= SAFI_LABELED_UNICAST
;
1270 } else if (strmatch(key
, "frr-routing:ipv6-labeled-unicast")) {
1272 *safi
= SAFI_LABELED_UNICAST
;
1273 } else if (strmatch(key
, "frr-routing:l2vpn-evpn")) {
1276 } else if (strmatch(key
, "frr-routing:ipv4-flowspec")) {
1278 *safi
= SAFI_FLOWSPEC
;
1279 } else if (strmatch(key
, "frr-routing:ipv6-flowspec")) {
1281 *safi
= SAFI_FLOWSPEC
;
1284 *safi
= SAFI_UNSPEC
;