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
24 #include "lib_errors.h"
25 #include "northbound.h"
31 #define YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt) \
34 va_start(__ap, (xpath_fmt)); \
35 const struct lyd_value *__dvalue = \
36 yang_dnode_xpath_get_value(dnode, xpath_fmt, __ap); \
41 #define YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt) \
44 va_start(__ap, (xpath_fmt)); \
45 const char *__canon = \
46 yang_dnode_xpath_get_canon(dnode, xpath_fmt, __ap); \
51 #define YANG_DNODE_GET_ASSERT(dnode, xpath) \
53 if ((dnode) == NULL) { \
54 flog_err(EC_LIB_YANG_DNODE_NOT_FOUND, \
55 "%s: couldn't find %s", __func__, (xpath)); \
56 zlog_backtrace(LOG_ERR); \
62 static inline const char *
63 yang_dnode_xpath_get_canon(const struct lyd_node
*dnode
, const char *xpath_fmt
,
66 const struct lyd_node_term
*__dleaf
=
67 (const struct lyd_node_term
*)dnode
;
70 char __xpath
[XPATH_MAXLEN
];
71 vsnprintf(__xpath
, sizeof(__xpath
), xpath_fmt
, ap
);
72 __dleaf
= (const struct lyd_node_term
*)yang_dnode_get(dnode
,
74 YANG_DNODE_GET_ASSERT(__dleaf
, __xpath
);
76 return lyd_get_value(&__dleaf
->node
);
80 static inline const struct lyd_value
*
81 yang_dnode_xpath_get_value(const struct lyd_node
*dnode
, const char *xpath_fmt
,
84 const struct lyd_node_term
*__dleaf
=
85 (const struct lyd_node_term
*)dnode
;
88 char __xpath
[XPATH_MAXLEN
];
89 vsnprintf(__xpath
, sizeof(__xpath
), xpath_fmt
, ap
);
90 __dleaf
= (const struct lyd_node_term
*)yang_dnode_get(dnode
,
92 YANG_DNODE_GET_ASSERT(__dleaf
, __xpath
);
94 const struct lyd_value
*__dvalue
= &__dleaf
->value
;
95 if (__dvalue
->realtype
->basetype
== LY_TYPE_UNION
)
96 __dvalue
= &__dvalue
->subvalue
->value
;
100 static const char *yang_get_default_value(const char *xpath
)
102 const struct lysc_node
*snode
;
105 snode
= lys_find_path(ly_native_ctx
, NULL
, xpath
, 0);
107 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
108 "%s: unknown data path: %s", __func__
, xpath
);
109 zlog_backtrace(LOG_ERR
);
113 value
= yang_snode_get_default(snode
);
120 * Primitive type: bool.
122 bool yang_str2bool(const char *value
)
124 return strmatch(value
, "true");
127 struct yang_data
*yang_data_new_bool(const char *xpath
, bool value
)
129 return yang_data_new(xpath
, (value
) ? "true" : "false");
132 bool yang_dnode_get_bool(const struct lyd_node
*dnode
, const char *xpath_fmt
,
135 const struct lyd_value
*dvalue
;
136 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
137 assert(dvalue
->realtype
->basetype
== LY_TYPE_BOOL
);
138 return dvalue
->boolean
;
141 bool yang_get_default_bool(const char *xpath_fmt
, ...)
143 char xpath
[XPATH_MAXLEN
];
147 va_start(ap
, xpath_fmt
);
148 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
151 value
= yang_get_default_value(xpath
);
152 return yang_str2bool(value
);
156 * Primitive type: dec64.
158 double yang_str2dec64(const char *xpath
, const char *value
)
162 if (sscanf(value
, "%lf", &dbl
) != 1) {
163 flog_err(EC_LIB_YANG_DATA_CONVERT
,
164 "%s: couldn't convert string to decimal64 [xpath %s]",
166 zlog_backtrace(LOG_ERR
);
173 struct yang_data
*yang_data_new_dec64(const char *xpath
, double value
)
175 char value_str
[BUFSIZ
];
177 snprintf(value_str
, sizeof(value_str
), "%lf", value
);
178 return yang_data_new(xpath
, value_str
);
181 double yang_dnode_get_dec64(const struct lyd_node
*dnode
, const char *xpath_fmt
,
184 const double denom
[19] = {1e0
, 1e-1, 1e-2, 1e-3, 1e-4,
185 1e-5, 1e-6, 1e-7, 1e-8, 1e-9,
186 1e-10, 1e-11, 1e-12, 1e-13, 1e-14,
187 1e-15, 1e-16, 1e-17, 1e-18};
188 const struct lysc_type_dec
*dectype
;
189 const struct lyd_value
*dvalue
;
191 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
192 dectype
= (const struct lysc_type_dec
*)dvalue
->realtype
;
193 assert(dectype
->basetype
== LY_TYPE_DEC64
);
194 assert(dectype
->fraction_digits
< sizeof(denom
) / sizeof(*denom
));
195 return (double)dvalue
->dec64
* denom
[dectype
->fraction_digits
];
198 double yang_get_default_dec64(const char *xpath_fmt
, ...)
200 char xpath
[XPATH_MAXLEN
];
204 va_start(ap
, xpath_fmt
);
205 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
208 value
= yang_get_default_value(xpath
);
209 return yang_str2dec64(xpath
, value
);
213 * Primitive type: enum.
215 int yang_str2enum(const char *xpath
, const char *value
)
217 const struct lysc_node
*snode
;
218 const struct lysc_node_leaf
*sleaf
;
219 const struct lysc_type_enum
*type
;
220 const struct lysc_type_bitenum_item
*enums
;
222 snode
= lys_find_path(ly_native_ctx
, NULL
, xpath
, 0);
224 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
225 "%s: unknown data path: %s", __func__
, xpath
);
226 zlog_backtrace(LOG_ERR
);
230 assert(snode
->nodetype
== LYS_LEAF
);
231 sleaf
= (const struct lysc_node_leaf
*)snode
;
232 type
= (const struct lysc_type_enum
*)sleaf
->type
;
233 assert(type
->basetype
== LY_TYPE_ENUM
);
235 unsigned int count
= LY_ARRAY_COUNT(enums
);
236 for (unsigned int i
= 0; i
< count
; i
++) {
237 if (strmatch(value
, enums
[i
].name
)) {
238 assert(CHECK_FLAG(enums
[i
].flags
, LYS_SET_VALUE
));
239 return enums
[i
].value
;
243 flog_err(EC_LIB_YANG_DATA_CONVERT
,
244 "%s: couldn't convert string to enum [xpath %s]", __func__
,
246 zlog_backtrace(LOG_ERR
);
250 struct yang_data
*yang_data_new_enum(const char *xpath
, int value
)
252 const struct lysc_node
*snode
;
253 const struct lysc_node_leaf
*sleaf
;
254 const struct lysc_type_enum
*type
;
255 const struct lysc_type_bitenum_item
*enums
;
257 snode
= lys_find_path(ly_native_ctx
, NULL
, xpath
, 0);
259 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
260 "%s: unknown data path: %s", __func__
, xpath
);
261 zlog_backtrace(LOG_ERR
);
265 assert(snode
->nodetype
== LYS_LEAF
);
266 sleaf
= (const struct lysc_node_leaf
*)snode
;
267 type
= (const struct lysc_type_enum
*)sleaf
->type
;
268 assert(type
->basetype
== LY_TYPE_ENUM
);
270 unsigned int count
= LY_ARRAY_COUNT(enums
);
271 for (unsigned int i
= 0; i
< count
; i
++) {
272 if (CHECK_FLAG(enums
[i
].flags
, LYS_SET_VALUE
)
273 && value
== enums
[i
].value
)
274 return yang_data_new(xpath
, enums
[i
].name
);
277 flog_err(EC_LIB_YANG_DATA_CONVERT
,
278 "%s: couldn't convert enum to string [xpath %s]", __func__
,
280 zlog_backtrace(LOG_ERR
);
284 int yang_dnode_get_enum(const struct lyd_node
*dnode
, const char *xpath_fmt
,
287 const struct lyd_value
*dvalue
;
289 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
290 assert(dvalue
->realtype
->basetype
== LY_TYPE_ENUM
);
291 assert(dvalue
->enum_item
->flags
& LYS_SET_VALUE
);
292 return dvalue
->enum_item
->value
;
295 int yang_get_default_enum(const char *xpath_fmt
, ...)
297 char xpath
[XPATH_MAXLEN
];
301 va_start(ap
, xpath_fmt
);
302 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
305 value
= yang_get_default_value(xpath
);
306 return yang_str2enum(xpath
, value
);
310 * Primitive type: int8.
312 int8_t yang_str2int8(const char *value
)
314 return strtol(value
, NULL
, 10);
317 struct yang_data
*yang_data_new_int8(const char *xpath
, int8_t value
)
319 char value_str
[BUFSIZ
];
321 snprintf(value_str
, sizeof(value_str
), "%d", value
);
322 return yang_data_new(xpath
, value_str
);
325 int8_t yang_dnode_get_int8(const struct lyd_node
*dnode
, const char *xpath_fmt
,
328 const struct lyd_value
*dvalue
;
329 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
330 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT8
);
334 int8_t yang_get_default_int8(const char *xpath_fmt
, ...)
336 char xpath
[XPATH_MAXLEN
];
340 va_start(ap
, xpath_fmt
);
341 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
344 value
= yang_get_default_value(xpath
);
345 return yang_str2int8(value
);
349 * Primitive type: int16.
351 int16_t yang_str2int16(const char *value
)
353 return strtol(value
, NULL
, 10);
356 struct yang_data
*yang_data_new_int16(const char *xpath
, int16_t value
)
358 char value_str
[BUFSIZ
];
360 snprintf(value_str
, sizeof(value_str
), "%d", value
);
361 return yang_data_new(xpath
, value_str
);
364 int16_t yang_dnode_get_int16(const struct lyd_node
*dnode
,
365 const char *xpath_fmt
, ...)
367 const struct lyd_value
*dvalue
;
368 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
369 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT16
);
370 return dvalue
->int16
;
373 int16_t yang_get_default_int16(const char *xpath_fmt
, ...)
375 char xpath
[XPATH_MAXLEN
];
379 va_start(ap
, xpath_fmt
);
380 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
383 value
= yang_get_default_value(xpath
);
384 return yang_str2int16(value
);
388 * Primitive type: int32.
390 int32_t yang_str2int32(const char *value
)
392 return strtol(value
, NULL
, 10);
395 struct yang_data
*yang_data_new_int32(const char *xpath
, int32_t value
)
397 char value_str
[BUFSIZ
];
399 snprintf(value_str
, sizeof(value_str
), "%d", value
);
400 return yang_data_new(xpath
, value_str
);
403 int32_t yang_dnode_get_int32(const struct lyd_node
*dnode
,
404 const char *xpath_fmt
, ...)
406 const struct lyd_value
*dvalue
;
407 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
408 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT32
);
409 return dvalue
->int32
;
412 int32_t yang_get_default_int32(const char *xpath_fmt
, ...)
414 char xpath
[XPATH_MAXLEN
];
418 va_start(ap
, xpath_fmt
);
419 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
422 value
= yang_get_default_value(xpath
);
423 return yang_str2int32(value
);
427 * Primitive type: int64.
429 int64_t yang_str2int64(const char *value
)
431 return strtoll(value
, NULL
, 10);
434 struct yang_data
*yang_data_new_int64(const char *xpath
, int64_t value
)
436 char value_str
[BUFSIZ
];
438 snprintfrr(value_str
, sizeof(value_str
), "%" PRId64
, value
);
439 return yang_data_new(xpath
, value_str
);
442 int64_t yang_dnode_get_int64(const struct lyd_node
*dnode
,
443 const char *xpath_fmt
, ...)
445 const struct lyd_value
*dvalue
;
446 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
447 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT64
);
448 return dvalue
->int64
;
451 int64_t yang_get_default_int64(const char *xpath_fmt
, ...)
453 char xpath
[XPATH_MAXLEN
];
457 va_start(ap
, xpath_fmt
);
458 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
461 value
= yang_get_default_value(xpath
);
462 return yang_str2int64(value
);
466 * Primitive type: uint8.
468 uint8_t yang_str2uint8(const char *value
)
470 return strtoul(value
, NULL
, 10);
473 struct yang_data
*yang_data_new_uint8(const char *xpath
, uint8_t value
)
475 char value_str
[BUFSIZ
];
477 snprintf(value_str
, sizeof(value_str
), "%u", value
);
478 return yang_data_new(xpath
, value_str
);
481 uint8_t yang_dnode_get_uint8(const struct lyd_node
*dnode
,
482 const char *xpath_fmt
, ...)
484 const struct lyd_value
*dvalue
;
485 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
486 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT8
);
487 return dvalue
->uint8
;
490 uint8_t yang_get_default_uint8(const char *xpath_fmt
, ...)
492 char xpath
[XPATH_MAXLEN
];
496 va_start(ap
, xpath_fmt
);
497 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
500 value
= yang_get_default_value(xpath
);
501 return yang_str2uint8(value
);
505 * Primitive type: uint16.
507 uint16_t yang_str2uint16(const char *value
)
509 return strtoul(value
, NULL
, 10);
512 struct yang_data
*yang_data_new_uint16(const char *xpath
, uint16_t value
)
514 char value_str
[BUFSIZ
];
516 snprintf(value_str
, sizeof(value_str
), "%u", value
);
517 return yang_data_new(xpath
, value_str
);
520 uint16_t yang_dnode_get_uint16(const struct lyd_node
*dnode
,
521 const char *xpath_fmt
, ...)
523 const struct lyd_value
*dvalue
;
524 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
525 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT16
);
526 return dvalue
->uint16
;
529 uint16_t yang_get_default_uint16(const char *xpath_fmt
, ...)
531 char xpath
[XPATH_MAXLEN
];
535 va_start(ap
, xpath_fmt
);
536 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
539 value
= yang_get_default_value(xpath
);
540 return yang_str2uint16(value
);
544 * Primitive type: uint32.
546 uint32_t yang_str2uint32(const char *value
)
548 return strtoul(value
, NULL
, 10);
551 struct yang_data
*yang_data_new_uint32(const char *xpath
, uint32_t value
)
553 char value_str
[BUFSIZ
];
555 snprintf(value_str
, sizeof(value_str
), "%u", value
);
556 return yang_data_new(xpath
, value_str
);
559 uint32_t yang_dnode_get_uint32(const struct lyd_node
*dnode
,
560 const char *xpath_fmt
, ...)
562 const struct lyd_value
*dvalue
;
563 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
564 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT32
);
565 return dvalue
->uint32
;
568 uint32_t yang_get_default_uint32(const char *xpath_fmt
, ...)
570 char xpath
[XPATH_MAXLEN
];
574 va_start(ap
, xpath_fmt
);
575 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
578 value
= yang_get_default_value(xpath
);
579 return yang_str2uint32(value
);
583 * Primitive type: uint64.
585 uint64_t yang_str2uint64(const char *value
)
587 return strtoull(value
, NULL
, 10);
590 struct yang_data
*yang_data_new_uint64(const char *xpath
, uint64_t value
)
592 char value_str
[BUFSIZ
];
594 snprintfrr(value_str
, sizeof(value_str
), "%" PRIu64
, value
);
595 return yang_data_new(xpath
, value_str
);
598 uint64_t yang_dnode_get_uint64(const struct lyd_node
*dnode
,
599 const char *xpath_fmt
, ...)
601 const struct lyd_value
*dvalue
;
602 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
603 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT64
);
604 return dvalue
->uint64
;
607 uint64_t yang_get_default_uint64(const char *xpath_fmt
, ...)
609 char xpath
[XPATH_MAXLEN
];
613 va_start(ap
, xpath_fmt
);
614 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
617 value
= yang_get_default_value(xpath
);
618 return yang_str2uint64(value
);
622 * Primitive type: string.
624 * All string wrappers can be used with non-string types.
626 struct yang_data
*yang_data_new_string(const char *xpath
, const char *value
)
628 return yang_data_new(xpath
, value
);
631 const char *yang_dnode_get_string(const struct lyd_node
*dnode
,
632 const char *xpath_fmt
, ...)
634 return YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
637 void yang_dnode_get_string_buf(char *buf
, size_t size
,
638 const struct lyd_node
*dnode
,
639 const char *xpath_fmt
, ...)
641 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
642 if (strlcpy(buf
, canon
, size
) >= size
) {
643 char xpath
[XPATH_MAXLEN
];
645 yang_dnode_get_path(dnode
, xpath
, sizeof(xpath
));
646 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
647 "%s: value was truncated [xpath %s]", __func__
,
652 const char *yang_get_default_string(const char *xpath_fmt
, ...)
654 char xpath
[XPATH_MAXLEN
];
657 va_start(ap
, xpath_fmt
);
658 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
661 return yang_get_default_value(xpath
);
664 void yang_get_default_string_buf(char *buf
, size_t size
, const char *xpath_fmt
,
667 char xpath
[XPATH_MAXLEN
];
671 va_start(ap
, xpath_fmt
);
672 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
675 value
= yang_get_default_value(xpath
);
676 if (strlcpy(buf
, value
, size
) >= size
)
677 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
678 "%s: value was truncated [xpath %s]", __func__
,
683 * Primitive type: binary.
685 struct yang_data
*yang_data_new_binary(const char *xpath
, const char *value
,
689 struct base64_encodestate s
;
692 struct yang_data
*data
;
694 value_str
= (char *)malloc(len
* 2);
695 base64_init_encodestate(&s
);
696 cnt
= base64_encode_block(value
, len
, value_str
, &s
);
698 cnt
= base64_encode_blockend(c
, &s
);
701 data
= yang_data_new(xpath
, value_str
);
706 size_t yang_dnode_get_binary_buf(char *buf
, size_t size
,
707 const struct lyd_node
*dnode
,
708 const char *xpath_fmt
, ...)
716 struct base64_decodestate s
;
718 canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
719 cannon_len
= strlen(canon
);
720 decode_len
= cannon_len
+ 1;
721 value_str
= (char *)malloc(decode_len
);
722 base64_init_decodestate(&s
);
723 cnt
= base64_decode_block(canon
, cannon_len
, value_str
, &s
);
725 ret_len
= size
> cnt
? cnt
: size
;
726 memcpy(buf
, value_str
, ret_len
);
728 char xpath
[XPATH_MAXLEN
];
730 yang_dnode_get_path(dnode
, xpath
, sizeof(xpath
));
731 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
732 "%s: value was truncated [xpath %s]", __func__
,
741 * Primitive type: empty.
743 struct yang_data
*yang_data_new_empty(const char *xpath
)
745 return yang_data_new(xpath
, NULL
);
748 bool yang_dnode_get_empty(const struct lyd_node
*dnode
, const char *xpath_fmt
,
752 char xpath
[XPATH_MAXLEN
];
753 const struct lyd_node_term
*dleaf
;
757 va_start(ap
, xpath_fmt
);
758 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
761 dnode
= yang_dnode_get(dnode
, xpath
);
763 dleaf
= (const struct lyd_node_term
*)dnode
;
764 if (dleaf
->value
.realtype
->basetype
== LY_TYPE_EMPTY
)
772 * Derived type: IP prefix.
774 void yang_str2prefix(const char *value
, union prefixptr prefix
)
776 (void)str2prefix(value
, prefix
.p
);
777 apply_mask(prefix
.p
);
780 struct yang_data
*yang_data_new_prefix(const char *xpath
,
781 union prefixconstptr prefix
)
783 char value_str
[PREFIX2STR_BUFFER
];
785 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
786 return yang_data_new(xpath
, value_str
);
789 void yang_dnode_get_prefix(struct prefix
*prefix
, const struct lyd_node
*dnode
,
790 const char *xpath_fmt
, ...)
794 * Initialize prefix to avoid static analyzer complaints about
795 * uninitialized memory.
797 memset(prefix
, 0, sizeof(*prefix
));
799 /* XXX ip_prefix is a native type now in ly2, leverage? */
800 canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
801 (void)str2prefix(canon
, prefix
);
804 void yang_get_default_prefix(union prefixptr var
, const char *xpath_fmt
, ...)
806 char xpath
[XPATH_MAXLEN
];
810 va_start(ap
, xpath_fmt
);
811 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
814 value
= yang_get_default_value(xpath
);
815 yang_str2prefix(value
, var
);
819 * Derived type: ipv4.
821 void yang_str2ipv4(const char *value
, struct in_addr
*addr
)
823 (void)inet_pton(AF_INET
, value
, addr
);
826 struct yang_data
*yang_data_new_ipv4(const char *xpath
,
827 const struct in_addr
*addr
)
829 char value_str
[INET_ADDRSTRLEN
];
831 (void)inet_ntop(AF_INET
, addr
, value_str
, sizeof(value_str
));
832 return yang_data_new(xpath
, value_str
);
835 void yang_dnode_get_ipv4(struct in_addr
*addr
, const struct lyd_node
*dnode
,
836 const char *xpath_fmt
, ...)
838 /* XXX libyang2 IPv4 address is a native type now in ly2 */
839 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
840 (void)inet_pton(AF_INET
, canon
, addr
);
843 void yang_get_default_ipv4(struct in_addr
*var
, const char *xpath_fmt
, ...)
845 char xpath
[XPATH_MAXLEN
];
849 va_start(ap
, xpath_fmt
);
850 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
853 value
= yang_get_default_value(xpath
);
854 yang_str2ipv4(value
, var
);
858 * Derived type: ipv4p.
860 void yang_str2ipv4p(const char *value
, union prefixptr prefix
)
862 struct prefix_ipv4
*prefix4
= prefix
.p4
;
864 (void)str2prefix_ipv4(value
, prefix4
);
865 apply_mask_ipv4(prefix4
);
868 struct yang_data
*yang_data_new_ipv4p(const char *xpath
,
869 union prefixconstptr prefix
)
871 char value_str
[PREFIX2STR_BUFFER
];
873 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
874 return yang_data_new(xpath
, value_str
);
877 void yang_dnode_get_ipv4p(union prefixptr prefix
, const struct lyd_node
*dnode
,
878 const char *xpath_fmt
, ...)
880 struct prefix_ipv4
*prefix4
= prefix
.p4
;
881 /* XXX libyang2: ipv4/6 address is a native type now in ly2 */
882 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
883 (void)str2prefix_ipv4(canon
, prefix4
);
886 void yang_get_default_ipv4p(union prefixptr var
, const char *xpath_fmt
, ...)
888 char xpath
[XPATH_MAXLEN
];
892 va_start(ap
, xpath_fmt
);
893 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
896 value
= yang_get_default_value(xpath
);
897 yang_str2ipv4p(value
, var
);
901 * Derived type: ipv6.
903 void yang_str2ipv6(const char *value
, struct in6_addr
*addr
)
905 (void)inet_pton(AF_INET6
, value
, addr
);
908 struct yang_data
*yang_data_new_ipv6(const char *xpath
,
909 const struct in6_addr
*addr
)
911 char value_str
[INET6_ADDRSTRLEN
];
913 (void)inet_ntop(AF_INET6
, addr
, value_str
, sizeof(value_str
));
914 return yang_data_new(xpath
, value_str
);
917 void yang_dnode_get_ipv6(struct in6_addr
*addr
, const struct lyd_node
*dnode
,
918 const char *xpath_fmt
, ...)
920 /* XXX libyang2: IPv6 address is a native type now, leverage. */
921 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
922 (void)inet_pton(AF_INET6
, canon
, addr
);
925 void yang_get_default_ipv6(struct in6_addr
*var
, const char *xpath_fmt
, ...)
927 char xpath
[XPATH_MAXLEN
];
931 va_start(ap
, xpath_fmt
);
932 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
935 value
= yang_get_default_value(xpath
);
936 yang_str2ipv6(value
, var
);
940 * Derived type: ipv6p.
942 void yang_str2ipv6p(const char *value
, union prefixptr prefix
)
944 struct prefix_ipv6
*prefix6
= prefix
.p6
;
946 (void)str2prefix_ipv6(value
, prefix6
);
947 apply_mask_ipv6(prefix6
);
950 struct yang_data
*yang_data_new_ipv6p(const char *xpath
,
951 union prefixconstptr prefix
)
953 char value_str
[PREFIX2STR_BUFFER
];
955 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
956 return yang_data_new(xpath
, value_str
);
959 void yang_dnode_get_ipv6p(union prefixptr prefix
, const struct lyd_node
*dnode
,
960 const char *xpath_fmt
, ...)
962 struct prefix_ipv6
*prefix6
= prefix
.p6
;
964 /* XXX IPv6 address is a native type now in ly2 -- can we leverage? */
965 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
966 (void)str2prefix_ipv6(canon
, prefix6
);
969 void yang_get_default_ipv6p(union prefixptr var
, const char *xpath_fmt
, ...)
971 char xpath
[XPATH_MAXLEN
];
975 va_start(ap
, xpath_fmt
);
976 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
979 value
= yang_get_default_value(xpath
);
980 yang_str2ipv6p(value
, var
);
986 void yang_str2ip(const char *value
, struct ipaddr
*ip
)
988 (void)str2ipaddr(value
, ip
);
991 struct yang_data
*yang_data_new_ip(const char *xpath
, const struct ipaddr
*addr
)
993 size_t sz
= IS_IPADDR_V4(addr
) ? INET_ADDRSTRLEN
: INET6_ADDRSTRLEN
;
996 ipaddr2str(addr
, value_str
, sizeof(value_str
));
997 return yang_data_new(xpath
, value_str
);
1000 void yang_dnode_get_ip(struct ipaddr
*addr
, const struct lyd_node
*dnode
,
1001 const char *xpath_fmt
, ...)
1003 /* XXX IPv4 address could be a plugin type now in ly2, leverage? */
1004 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
1005 (void)str2ipaddr(canon
, addr
);
1008 void yang_get_default_ip(struct ipaddr
*var
, const char *xpath_fmt
, ...)
1010 char xpath
[XPATH_MAXLEN
];
1014 va_start(ap
, xpath_fmt
);
1015 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
1018 value
= yang_get_default_value(xpath
);
1019 yang_str2ip(value
, var
);
1022 struct yang_data
*yang_data_new_mac(const char *xpath
,
1023 const struct ethaddr
*mac
)
1025 char value_str
[ETHER_ADDR_STRLEN
];
1027 prefix_mac2str(mac
, value_str
, sizeof(value_str
));
1028 return yang_data_new(xpath
, value_str
);
1031 void yang_str2mac(const char *value
, struct ethaddr
*mac
)
1033 (void)prefix_str2mac(value
, mac
);
1036 struct yang_data
*yang_data_new_date_and_time(const char *xpath
, time_t time
)
1039 char timebuf
[MONOTIME_STRLEN
];
1040 struct timeval _time
, time_real
;
1044 _time
.tv_sec
= time
;
1046 monotime_to_realtime(&_time
, &time_real
);
1048 gmtime_r(&time_real
.tv_sec
, &tm
);
1050 /* rfc-3339 format */
1051 strftime(timebuf
, sizeof(timebuf
), "%Y-%m-%dT%H:%M:%S", &tm
);
1052 buflen
= strlen(timebuf
);
1053 ts_dot
= timebuf
+ buflen
;
1055 /* microseconds and appends Z */
1056 snprintfrr(ts_dot
, sizeof(timebuf
) - buflen
, ".%06luZ",
1057 (unsigned long)time_real
.tv_usec
);
1059 return yang_data_new(xpath
, timebuf
);
1062 const char *yang_nexthop_type2str(uint32_t ntype
)
1065 case NEXTHOP_TYPE_IFINDEX
:
1068 case NEXTHOP_TYPE_IPV4
:
1071 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1072 return "ip4-ifindex";
1074 case NEXTHOP_TYPE_IPV6
:
1077 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1078 return "ip6-ifindex";
1080 case NEXTHOP_TYPE_BLACKHOLE
:
1090 const char *yang_afi_safi_value2identity(afi_t afi
, safi_t safi
)
1092 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1093 return "frr-routing:ipv4-unicast";
1094 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
1095 return "frr-routing:ipv6-unicast";
1096 if (afi
== AFI_IP
&& safi
== SAFI_MULTICAST
)
1097 return "frr-routing:ipv4-multicast";
1098 if (afi
== AFI_IP6
&& safi
== SAFI_MULTICAST
)
1099 return "frr-routing:ipv6-multicast";
1100 if (afi
== AFI_IP
&& safi
== SAFI_MPLS_VPN
)
1101 return "frr-routing:l3vpn-ipv4-unicast";
1102 if (afi
== AFI_IP6
&& safi
== SAFI_MPLS_VPN
)
1103 return "frr-routing:l3vpn-ipv6-unicast";
1104 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
1105 return "frr-routing:l2vpn-evpn";
1106 if (afi
== AFI_IP
&& safi
== SAFI_LABELED_UNICAST
)
1107 return "frr-routing:ipv4-labeled-unicast";
1108 if (afi
== AFI_IP6
&& safi
== SAFI_LABELED_UNICAST
)
1109 return "frr-routing:ipv6-labeled-unicast";
1110 if (afi
== AFI_IP
&& safi
== SAFI_FLOWSPEC
)
1111 return "frr-routing:ipv4-flowspec";
1112 if (afi
== AFI_IP6
&& safi
== SAFI_FLOWSPEC
)
1113 return "frr-routing:ipv6-flowspec";
1118 void yang_afi_safi_identity2value(const char *key
, afi_t
*afi
, safi_t
*safi
)
1120 if (strmatch(key
, "frr-routing:ipv4-unicast")) {
1122 *safi
= SAFI_UNICAST
;
1123 } else if (strmatch(key
, "frr-routing:ipv6-unicast")) {
1125 *safi
= SAFI_UNICAST
;
1126 } else if (strmatch(key
, "frr-routing:ipv4-multicast")) {
1128 *safi
= SAFI_MULTICAST
;
1129 } else if (strmatch(key
, "frr-routing:ipv6-multicast")) {
1131 *safi
= SAFI_MULTICAST
;
1132 } else if (strmatch(key
, "frr-routing:l3vpn-ipv4-unicast")) {
1134 *safi
= SAFI_MPLS_VPN
;
1135 } else if (strmatch(key
, "frr-routing:l3vpn-ipv6-unicast")) {
1137 *safi
= SAFI_MPLS_VPN
;
1138 } else if (strmatch(key
, "frr-routing:ipv4-labeled-unicast")) {
1140 *safi
= SAFI_LABELED_UNICAST
;
1141 } else if (strmatch(key
, "frr-routing:ipv6-labeled-unicast")) {
1143 *safi
= SAFI_LABELED_UNICAST
;
1144 } else if (strmatch(key
, "frr-routing:l2vpn-evpn")) {
1147 } else if (strmatch(key
, "frr-routing:ipv4-flowspec")) {
1149 *safi
= SAFI_FLOWSPEC
;
1150 } else if (strmatch(key
, "frr-routing:ipv6-flowspec")) {
1152 *safi
= SAFI_FLOWSPEC
;
1155 *safi
= SAFI_UNSPEC
;