1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2018 NetDEF, Inc.
11 #include "lib_errors.h"
12 #include "northbound.h"
18 #define YANG_DNODE_XPATH_GET_VALUE(dnode, xpath_fmt) \
21 va_start(__ap, (xpath_fmt)); \
22 const struct lyd_value *__dvalue = \
23 yang_dnode_xpath_get_value(dnode, xpath_fmt, __ap); \
28 #define YANG_DNODE_XPATH_GET_CANON(dnode, xpath_fmt) \
31 va_start(__ap, (xpath_fmt)); \
32 const char *__canon = \
33 yang_dnode_xpath_get_canon(dnode, xpath_fmt, __ap); \
38 #define YANG_DNODE_GET_ASSERT(dnode, xpath) \
40 if ((dnode) == NULL) { \
41 flog_err(EC_LIB_YANG_DNODE_NOT_FOUND, \
42 "%s: couldn't find %s", __func__, (xpath)); \
43 zlog_backtrace(LOG_ERR); \
49 static inline const char *
50 yang_dnode_xpath_get_canon(const struct lyd_node
*dnode
, const char *xpath_fmt
,
53 const struct lyd_node_term
*__dleaf
=
54 (const struct lyd_node_term
*)dnode
;
57 char __xpath
[XPATH_MAXLEN
];
58 vsnprintf(__xpath
, sizeof(__xpath
), xpath_fmt
, ap
);
59 __dleaf
= (const struct lyd_node_term
*)yang_dnode_get(dnode
,
61 YANG_DNODE_GET_ASSERT(__dleaf
, __xpath
);
63 return lyd_get_value(&__dleaf
->node
);
67 static inline const struct lyd_value
*
68 yang_dnode_xpath_get_value(const struct lyd_node
*dnode
, const char *xpath_fmt
,
71 const struct lyd_node_term
*__dleaf
=
72 (const struct lyd_node_term
*)dnode
;
75 char __xpath
[XPATH_MAXLEN
];
76 vsnprintf(__xpath
, sizeof(__xpath
), xpath_fmt
, ap
);
77 __dleaf
= (const struct lyd_node_term
*)yang_dnode_get(dnode
,
79 YANG_DNODE_GET_ASSERT(__dleaf
, __xpath
);
81 const struct lyd_value
*__dvalue
= &__dleaf
->value
;
82 if (__dvalue
->realtype
->basetype
== LY_TYPE_UNION
)
83 __dvalue
= &__dvalue
->subvalue
->value
;
87 static const char *yang_get_default_value(const char *xpath
)
89 const struct lysc_node
*snode
;
92 snode
= yang_find_snode(ly_native_ctx
, xpath
, 0);
94 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
95 "%s: unknown data path: %s", __func__
, xpath
);
96 zlog_backtrace(LOG_ERR
);
100 value
= yang_snode_get_default(snode
);
107 * Primitive type: bool.
109 bool yang_str2bool(const char *value
)
111 return strmatch(value
, "true");
114 struct yang_data
*yang_data_new_bool(const char *xpath
, bool value
)
116 return yang_data_new(xpath
, (value
) ? "true" : "false");
119 bool yang_dnode_get_bool(const struct lyd_node
*dnode
, const char *xpath_fmt
,
122 const struct lyd_value
*dvalue
;
123 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
124 assert(dvalue
->realtype
->basetype
== LY_TYPE_BOOL
);
125 return dvalue
->boolean
;
128 bool yang_get_default_bool(const char *xpath_fmt
, ...)
130 char xpath
[XPATH_MAXLEN
];
134 va_start(ap
, xpath_fmt
);
135 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
138 value
= yang_get_default_value(xpath
);
139 return yang_str2bool(value
);
143 * Primitive type: dec64.
145 double yang_str2dec64(const char *xpath
, const char *value
)
149 if (sscanf(value
, "%lf", &dbl
) != 1) {
150 flog_err(EC_LIB_YANG_DATA_CONVERT
,
151 "%s: couldn't convert string to decimal64 [xpath %s]",
153 zlog_backtrace(LOG_ERR
);
160 struct yang_data
*yang_data_new_dec64(const char *xpath
, double value
)
162 char value_str
[BUFSIZ
];
164 snprintf(value_str
, sizeof(value_str
), "%lf", value
);
165 return yang_data_new(xpath
, value_str
);
168 double yang_dnode_get_dec64(const struct lyd_node
*dnode
, const char *xpath_fmt
,
171 const double denom
[19] = {1e0
, 1e-1, 1e-2, 1e-3, 1e-4,
172 1e-5, 1e-6, 1e-7, 1e-8, 1e-9,
173 1e-10, 1e-11, 1e-12, 1e-13, 1e-14,
174 1e-15, 1e-16, 1e-17, 1e-18};
175 const struct lysc_type_dec
*dectype
;
176 const struct lyd_value
*dvalue
;
178 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
179 dectype
= (const struct lysc_type_dec
*)dvalue
->realtype
;
180 assert(dectype
->basetype
== LY_TYPE_DEC64
);
181 assert(dectype
->fraction_digits
< sizeof(denom
) / sizeof(*denom
));
182 return (double)dvalue
->dec64
* denom
[dectype
->fraction_digits
];
185 double yang_get_default_dec64(const char *xpath_fmt
, ...)
187 char xpath
[XPATH_MAXLEN
];
191 va_start(ap
, xpath_fmt
);
192 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
195 value
= yang_get_default_value(xpath
);
196 return yang_str2dec64(xpath
, value
);
200 * Primitive type: enum.
202 int yang_str2enum(const char *xpath
, const char *value
)
204 const struct lysc_node
*snode
;
205 const struct lysc_node_leaf
*sleaf
;
206 const struct lysc_type_enum
*type
;
207 const struct lysc_type_bitenum_item
*enums
;
209 snode
= yang_find_snode(ly_native_ctx
, xpath
, 0);
211 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
212 "%s: unknown data path: %s", __func__
, xpath
);
213 zlog_backtrace(LOG_ERR
);
217 assert(snode
->nodetype
== LYS_LEAF
);
218 sleaf
= (const struct lysc_node_leaf
*)snode
;
219 type
= (const struct lysc_type_enum
*)sleaf
->type
;
220 assert(type
->basetype
== LY_TYPE_ENUM
);
222 unsigned int count
= LY_ARRAY_COUNT(enums
);
223 for (unsigned int i
= 0; i
< count
; i
++) {
224 if (strmatch(value
, enums
[i
].name
)) {
225 assert(CHECK_FLAG(enums
[i
].flags
, LYS_SET_VALUE
));
226 return enums
[i
].value
;
230 flog_err(EC_LIB_YANG_DATA_CONVERT
,
231 "%s: couldn't convert string to enum [xpath %s]", __func__
,
233 zlog_backtrace(LOG_ERR
);
237 struct yang_data
*yang_data_new_enum(const char *xpath
, int value
)
239 const struct lysc_node
*snode
;
240 const struct lysc_node_leaf
*sleaf
;
241 const struct lysc_type_enum
*type
;
242 const struct lysc_type_bitenum_item
*enums
;
244 snode
= yang_find_snode(ly_native_ctx
, xpath
, 0);
246 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
247 "%s: unknown data path: %s", __func__
, xpath
);
248 zlog_backtrace(LOG_ERR
);
252 assert(snode
->nodetype
== LYS_LEAF
);
253 sleaf
= (const struct lysc_node_leaf
*)snode
;
254 type
= (const struct lysc_type_enum
*)sleaf
->type
;
255 assert(type
->basetype
== LY_TYPE_ENUM
);
257 unsigned int count
= LY_ARRAY_COUNT(enums
);
258 for (unsigned int i
= 0; i
< count
; i
++) {
259 if (CHECK_FLAG(enums
[i
].flags
, LYS_SET_VALUE
)
260 && value
== enums
[i
].value
)
261 return yang_data_new(xpath
, enums
[i
].name
);
264 flog_err(EC_LIB_YANG_DATA_CONVERT
,
265 "%s: couldn't convert enum to string [xpath %s]", __func__
,
267 zlog_backtrace(LOG_ERR
);
271 int yang_dnode_get_enum(const struct lyd_node
*dnode
, const char *xpath_fmt
,
274 const struct lyd_value
*dvalue
;
276 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
277 assert(dvalue
->realtype
->basetype
== LY_TYPE_ENUM
);
278 assert(dvalue
->enum_item
->flags
& LYS_SET_VALUE
);
279 return dvalue
->enum_item
->value
;
282 int yang_get_default_enum(const char *xpath_fmt
, ...)
284 char xpath
[XPATH_MAXLEN
];
288 va_start(ap
, xpath_fmt
);
289 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
292 value
= yang_get_default_value(xpath
);
293 return yang_str2enum(xpath
, value
);
297 * Primitive type: int8.
299 int8_t yang_str2int8(const char *value
)
301 return strtol(value
, NULL
, 10);
304 struct yang_data
*yang_data_new_int8(const char *xpath
, int8_t value
)
306 char value_str
[BUFSIZ
];
308 snprintf(value_str
, sizeof(value_str
), "%d", value
);
309 return yang_data_new(xpath
, value_str
);
312 int8_t yang_dnode_get_int8(const struct lyd_node
*dnode
, const char *xpath_fmt
,
315 const struct lyd_value
*dvalue
;
316 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
317 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT8
);
321 int8_t yang_get_default_int8(const char *xpath_fmt
, ...)
323 char xpath
[XPATH_MAXLEN
];
327 va_start(ap
, xpath_fmt
);
328 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
331 value
= yang_get_default_value(xpath
);
332 return yang_str2int8(value
);
336 * Primitive type: int16.
338 int16_t yang_str2int16(const char *value
)
340 return strtol(value
, NULL
, 10);
343 struct yang_data
*yang_data_new_int16(const char *xpath
, int16_t value
)
345 char value_str
[BUFSIZ
];
347 snprintf(value_str
, sizeof(value_str
), "%d", value
);
348 return yang_data_new(xpath
, value_str
);
351 int16_t yang_dnode_get_int16(const struct lyd_node
*dnode
,
352 const char *xpath_fmt
, ...)
354 const struct lyd_value
*dvalue
;
355 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
356 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT16
);
357 return dvalue
->int16
;
360 int16_t yang_get_default_int16(const char *xpath_fmt
, ...)
362 char xpath
[XPATH_MAXLEN
];
366 va_start(ap
, xpath_fmt
);
367 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
370 value
= yang_get_default_value(xpath
);
371 return yang_str2int16(value
);
375 * Primitive type: int32.
377 int32_t yang_str2int32(const char *value
)
379 return strtol(value
, NULL
, 10);
382 struct yang_data
*yang_data_new_int32(const char *xpath
, int32_t value
)
384 char value_str
[BUFSIZ
];
386 snprintf(value_str
, sizeof(value_str
), "%d", value
);
387 return yang_data_new(xpath
, value_str
);
390 int32_t yang_dnode_get_int32(const struct lyd_node
*dnode
,
391 const char *xpath_fmt
, ...)
393 const struct lyd_value
*dvalue
;
394 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
395 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT32
);
396 return dvalue
->int32
;
399 int32_t yang_get_default_int32(const char *xpath_fmt
, ...)
401 char xpath
[XPATH_MAXLEN
];
405 va_start(ap
, xpath_fmt
);
406 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
409 value
= yang_get_default_value(xpath
);
410 return yang_str2int32(value
);
414 * Primitive type: int64.
416 int64_t yang_str2int64(const char *value
)
418 return strtoll(value
, NULL
, 10);
421 struct yang_data
*yang_data_new_int64(const char *xpath
, int64_t value
)
423 char value_str
[BUFSIZ
];
425 snprintfrr(value_str
, sizeof(value_str
), "%" PRId64
, value
);
426 return yang_data_new(xpath
, value_str
);
429 int64_t yang_dnode_get_int64(const struct lyd_node
*dnode
,
430 const char *xpath_fmt
, ...)
432 const struct lyd_value
*dvalue
;
433 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
434 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT64
);
435 return dvalue
->int64
;
438 int64_t yang_get_default_int64(const char *xpath_fmt
, ...)
440 char xpath
[XPATH_MAXLEN
];
444 va_start(ap
, xpath_fmt
);
445 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
448 value
= yang_get_default_value(xpath
);
449 return yang_str2int64(value
);
453 * Primitive type: uint8.
455 uint8_t yang_str2uint8(const char *value
)
457 return strtoul(value
, NULL
, 10);
460 struct yang_data
*yang_data_new_uint8(const char *xpath
, uint8_t value
)
462 char value_str
[BUFSIZ
];
464 snprintf(value_str
, sizeof(value_str
), "%u", value
);
465 return yang_data_new(xpath
, value_str
);
468 uint8_t yang_dnode_get_uint8(const struct lyd_node
*dnode
,
469 const char *xpath_fmt
, ...)
471 const struct lyd_value
*dvalue
;
472 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
473 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT8
);
474 return dvalue
->uint8
;
477 uint8_t yang_get_default_uint8(const char *xpath_fmt
, ...)
479 char xpath
[XPATH_MAXLEN
];
483 va_start(ap
, xpath_fmt
);
484 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
487 value
= yang_get_default_value(xpath
);
488 return yang_str2uint8(value
);
492 * Primitive type: uint16.
494 uint16_t yang_str2uint16(const char *value
)
496 return strtoul(value
, NULL
, 10);
499 struct yang_data
*yang_data_new_uint16(const char *xpath
, uint16_t value
)
501 char value_str
[BUFSIZ
];
503 snprintf(value_str
, sizeof(value_str
), "%u", value
);
504 return yang_data_new(xpath
, value_str
);
507 uint16_t yang_dnode_get_uint16(const struct lyd_node
*dnode
,
508 const char *xpath_fmt
, ...)
510 const struct lyd_value
*dvalue
;
511 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
512 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT16
);
513 return dvalue
->uint16
;
516 uint16_t yang_get_default_uint16(const char *xpath_fmt
, ...)
518 char xpath
[XPATH_MAXLEN
];
522 va_start(ap
, xpath_fmt
);
523 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
526 value
= yang_get_default_value(xpath
);
527 return yang_str2uint16(value
);
531 * Primitive type: uint32.
533 uint32_t yang_str2uint32(const char *value
)
535 return strtoul(value
, NULL
, 10);
538 struct yang_data
*yang_data_new_uint32(const char *xpath
, uint32_t value
)
540 char value_str
[BUFSIZ
];
542 snprintf(value_str
, sizeof(value_str
), "%u", value
);
543 return yang_data_new(xpath
, value_str
);
546 uint32_t yang_dnode_get_uint32(const struct lyd_node
*dnode
,
547 const char *xpath_fmt
, ...)
549 const struct lyd_value
*dvalue
;
550 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
551 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT32
);
552 return dvalue
->uint32
;
555 uint32_t yang_get_default_uint32(const char *xpath_fmt
, ...)
557 char xpath
[XPATH_MAXLEN
];
561 va_start(ap
, xpath_fmt
);
562 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
565 value
= yang_get_default_value(xpath
);
566 return yang_str2uint32(value
);
570 * Primitive type: uint64.
572 uint64_t yang_str2uint64(const char *value
)
574 return strtoull(value
, NULL
, 10);
577 struct yang_data
*yang_data_new_uint64(const char *xpath
, uint64_t value
)
579 char value_str
[BUFSIZ
];
581 snprintfrr(value_str
, sizeof(value_str
), "%" PRIu64
, value
);
582 return yang_data_new(xpath
, value_str
);
585 uint64_t yang_dnode_get_uint64(const struct lyd_node
*dnode
,
586 const char *xpath_fmt
, ...)
588 const struct lyd_value
*dvalue
;
589 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
590 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT64
);
591 return dvalue
->uint64
;
594 uint64_t yang_get_default_uint64(const char *xpath_fmt
, ...)
596 char xpath
[XPATH_MAXLEN
];
600 va_start(ap
, xpath_fmt
);
601 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
604 value
= yang_get_default_value(xpath
);
605 return yang_str2uint64(value
);
609 * Primitive type: string.
611 * All string wrappers can be used with non-string types.
613 struct yang_data
*yang_data_new_string(const char *xpath
, const char *value
)
615 return yang_data_new(xpath
, value
);
618 const char *yang_dnode_get_string(const struct lyd_node
*dnode
,
619 const char *xpath_fmt
, ...)
621 return YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
624 void yang_dnode_get_string_buf(char *buf
, size_t size
,
625 const struct lyd_node
*dnode
,
626 const char *xpath_fmt
, ...)
628 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
629 if (strlcpy(buf
, canon
, size
) >= size
) {
630 char xpath
[XPATH_MAXLEN
];
632 yang_dnode_get_path(dnode
, xpath
, sizeof(xpath
));
633 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
634 "%s: value was truncated [xpath %s]", __func__
,
639 const char *yang_get_default_string(const char *xpath_fmt
, ...)
641 char xpath
[XPATH_MAXLEN
];
644 va_start(ap
, xpath_fmt
);
645 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
648 return yang_get_default_value(xpath
);
651 void yang_get_default_string_buf(char *buf
, size_t size
, const char *xpath_fmt
,
654 char xpath
[XPATH_MAXLEN
];
658 va_start(ap
, xpath_fmt
);
659 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
662 value
= yang_get_default_value(xpath
);
663 if (strlcpy(buf
, value
, size
) >= size
)
664 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
665 "%s: value was truncated [xpath %s]", __func__
,
670 * Primitive type: binary.
672 struct yang_data
*yang_data_new_binary(const char *xpath
, const char *value
,
676 struct base64_encodestate s
;
679 struct yang_data
*data
;
681 value_str
= (char *)malloc(len
* 2);
682 base64_init_encodestate(&s
);
683 cnt
= base64_encode_block(value
, len
, value_str
, &s
);
685 cnt
= base64_encode_blockend(c
, &s
);
688 data
= yang_data_new(xpath
, value_str
);
693 size_t yang_dnode_get_binary_buf(char *buf
, size_t size
,
694 const struct lyd_node
*dnode
,
695 const char *xpath_fmt
, ...)
703 struct base64_decodestate s
;
705 canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
706 cannon_len
= strlen(canon
);
707 decode_len
= cannon_len
+ 1;
708 value_str
= (char *)malloc(decode_len
);
709 base64_init_decodestate(&s
);
710 cnt
= base64_decode_block(canon
, cannon_len
, value_str
, &s
);
712 ret_len
= size
> cnt
? cnt
: size
;
713 memcpy(buf
, value_str
, ret_len
);
715 char xpath
[XPATH_MAXLEN
];
717 yang_dnode_get_path(dnode
, xpath
, sizeof(xpath
));
718 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
719 "%s: value was truncated [xpath %s]", __func__
,
728 * Primitive type: empty.
730 struct yang_data
*yang_data_new_empty(const char *xpath
)
732 return yang_data_new(xpath
, NULL
);
735 bool yang_dnode_get_empty(const struct lyd_node
*dnode
, const char *xpath_fmt
,
739 char xpath
[XPATH_MAXLEN
];
740 const struct lyd_node_term
*dleaf
;
744 va_start(ap
, xpath_fmt
);
745 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
748 dnode
= yang_dnode_get(dnode
, xpath
);
750 dleaf
= (const struct lyd_node_term
*)dnode
;
751 if (dleaf
->value
.realtype
->basetype
== LY_TYPE_EMPTY
)
759 * Derived type: IP prefix.
761 void yang_str2prefix(const char *value
, union prefixptr prefix
)
763 (void)str2prefix(value
, prefix
.p
);
764 apply_mask(prefix
.p
);
767 struct yang_data
*yang_data_new_prefix(const char *xpath
,
768 union prefixconstptr prefix
)
770 char value_str
[PREFIX2STR_BUFFER
];
772 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
773 return yang_data_new(xpath
, value_str
);
776 void yang_dnode_get_prefix(struct prefix
*prefix
, const struct lyd_node
*dnode
,
777 const char *xpath_fmt
, ...)
781 * Initialize prefix to avoid static analyzer complaints about
782 * uninitialized memory.
784 memset(prefix
, 0, sizeof(*prefix
));
786 /* XXX ip_prefix is a native type now in ly2, leverage? */
787 canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
788 (void)str2prefix(canon
, prefix
);
791 void yang_get_default_prefix(union prefixptr var
, const char *xpath_fmt
, ...)
793 char xpath
[XPATH_MAXLEN
];
797 va_start(ap
, xpath_fmt
);
798 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
801 value
= yang_get_default_value(xpath
);
802 yang_str2prefix(value
, var
);
806 * Derived type: ipv4.
808 void yang_str2ipv4(const char *value
, struct in_addr
*addr
)
810 (void)inet_pton(AF_INET
, value
, addr
);
813 struct yang_data
*yang_data_new_ipv4(const char *xpath
,
814 const struct in_addr
*addr
)
816 char value_str
[INET_ADDRSTRLEN
];
818 (void)inet_ntop(AF_INET
, addr
, value_str
, sizeof(value_str
));
819 return yang_data_new(xpath
, value_str
);
822 void yang_dnode_get_ipv4(struct in_addr
*addr
, const struct lyd_node
*dnode
,
823 const char *xpath_fmt
, ...)
825 /* XXX libyang2 IPv4 address is a native type now in ly2 */
826 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
827 (void)inet_pton(AF_INET
, canon
, addr
);
830 void yang_get_default_ipv4(struct in_addr
*var
, const char *xpath_fmt
, ...)
832 char xpath
[XPATH_MAXLEN
];
836 va_start(ap
, xpath_fmt
);
837 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
840 value
= yang_get_default_value(xpath
);
841 yang_str2ipv4(value
, var
);
845 * Derived type: ipv4p.
847 void yang_str2ipv4p(const char *value
, union prefixptr prefix
)
849 struct prefix_ipv4
*prefix4
= prefix
.p4
;
851 (void)str2prefix_ipv4(value
, prefix4
);
852 apply_mask_ipv4(prefix4
);
855 struct yang_data
*yang_data_new_ipv4p(const char *xpath
,
856 union prefixconstptr prefix
)
858 char value_str
[PREFIX2STR_BUFFER
];
860 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
861 return yang_data_new(xpath
, value_str
);
864 void yang_dnode_get_ipv4p(union prefixptr prefix
, const struct lyd_node
*dnode
,
865 const char *xpath_fmt
, ...)
867 struct prefix_ipv4
*prefix4
= prefix
.p4
;
868 /* XXX libyang2: ipv4/6 address is a native type now in ly2 */
869 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
870 (void)str2prefix_ipv4(canon
, prefix4
);
873 void yang_get_default_ipv4p(union prefixptr var
, const char *xpath_fmt
, ...)
875 char xpath
[XPATH_MAXLEN
];
879 va_start(ap
, xpath_fmt
);
880 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
883 value
= yang_get_default_value(xpath
);
884 yang_str2ipv4p(value
, var
);
888 * Derived type: ipv6.
890 void yang_str2ipv6(const char *value
, struct in6_addr
*addr
)
892 (void)inet_pton(AF_INET6
, value
, addr
);
895 struct yang_data
*yang_data_new_ipv6(const char *xpath
,
896 const struct in6_addr
*addr
)
898 char value_str
[INET6_ADDRSTRLEN
];
900 (void)inet_ntop(AF_INET6
, addr
, value_str
, sizeof(value_str
));
901 return yang_data_new(xpath
, value_str
);
904 void yang_dnode_get_ipv6(struct in6_addr
*addr
, const struct lyd_node
*dnode
,
905 const char *xpath_fmt
, ...)
907 /* XXX libyang2: IPv6 address is a native type now, leverage. */
908 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
909 (void)inet_pton(AF_INET6
, canon
, addr
);
912 void yang_get_default_ipv6(struct in6_addr
*var
, const char *xpath_fmt
, ...)
914 char xpath
[XPATH_MAXLEN
];
918 va_start(ap
, xpath_fmt
);
919 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
922 value
= yang_get_default_value(xpath
);
923 yang_str2ipv6(value
, var
);
927 * Derived type: ipv6p.
929 void yang_str2ipv6p(const char *value
, union prefixptr prefix
)
931 struct prefix_ipv6
*prefix6
= prefix
.p6
;
933 (void)str2prefix_ipv6(value
, prefix6
);
934 apply_mask_ipv6(prefix6
);
937 struct yang_data
*yang_data_new_ipv6p(const char *xpath
,
938 union prefixconstptr prefix
)
940 char value_str
[PREFIX2STR_BUFFER
];
942 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
943 return yang_data_new(xpath
, value_str
);
946 void yang_dnode_get_ipv6p(union prefixptr prefix
, const struct lyd_node
*dnode
,
947 const char *xpath_fmt
, ...)
949 struct prefix_ipv6
*prefix6
= prefix
.p6
;
951 /* XXX IPv6 address is a native type now in ly2 -- can we leverage? */
952 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
953 (void)str2prefix_ipv6(canon
, prefix6
);
956 void yang_get_default_ipv6p(union prefixptr var
, const char *xpath_fmt
, ...)
958 char xpath
[XPATH_MAXLEN
];
962 va_start(ap
, xpath_fmt
);
963 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
966 value
= yang_get_default_value(xpath
);
967 yang_str2ipv6p(value
, var
);
973 void yang_str2ip(const char *value
, struct ipaddr
*ip
)
975 (void)str2ipaddr(value
, ip
);
978 struct yang_data
*yang_data_new_ip(const char *xpath
, const struct ipaddr
*addr
)
980 size_t sz
= IS_IPADDR_V4(addr
) ? INET_ADDRSTRLEN
: INET6_ADDRSTRLEN
;
983 ipaddr2str(addr
, value_str
, sizeof(value_str
));
984 return yang_data_new(xpath
, value_str
);
987 void yang_dnode_get_ip(struct ipaddr
*addr
, const struct lyd_node
*dnode
,
988 const char *xpath_fmt
, ...)
990 /* XXX IPv4 address could be a plugin type now in ly2, leverage? */
991 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
992 (void)str2ipaddr(canon
, addr
);
995 void yang_get_default_ip(struct ipaddr
*var
, const char *xpath_fmt
, ...)
997 char xpath
[XPATH_MAXLEN
];
1001 va_start(ap
, xpath_fmt
);
1002 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
1005 value
= yang_get_default_value(xpath
);
1006 yang_str2ip(value
, var
);
1009 struct yang_data
*yang_data_new_mac(const char *xpath
,
1010 const struct ethaddr
*mac
)
1012 char value_str
[ETHER_ADDR_STRLEN
];
1014 prefix_mac2str(mac
, value_str
, sizeof(value_str
));
1015 return yang_data_new(xpath
, value_str
);
1018 void yang_str2mac(const char *value
, struct ethaddr
*mac
)
1020 (void)prefix_str2mac(value
, mac
);
1023 struct yang_data
*yang_data_new_date_and_time(const char *xpath
, time_t time
)
1026 char timebuf
[MONOTIME_STRLEN
];
1027 struct timeval _time
, time_real
;
1031 _time
.tv_sec
= time
;
1033 monotime_to_realtime(&_time
, &time_real
);
1035 gmtime_r(&time_real
.tv_sec
, &tm
);
1037 /* rfc-3339 format */
1038 strftime(timebuf
, sizeof(timebuf
), "%Y-%m-%dT%H:%M:%S", &tm
);
1039 buflen
= strlen(timebuf
);
1040 ts_dot
= timebuf
+ buflen
;
1042 /* microseconds and appends Z */
1043 snprintfrr(ts_dot
, sizeof(timebuf
) - buflen
, ".%06luZ",
1044 (unsigned long)time_real
.tv_usec
);
1046 return yang_data_new(xpath
, timebuf
);
1049 const char *yang_nexthop_type2str(uint32_t ntype
)
1052 case NEXTHOP_TYPE_IFINDEX
:
1055 case NEXTHOP_TYPE_IPV4
:
1058 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1059 return "ip4-ifindex";
1061 case NEXTHOP_TYPE_IPV6
:
1064 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1065 return "ip6-ifindex";
1067 case NEXTHOP_TYPE_BLACKHOLE
:
1077 const char *yang_afi_safi_value2identity(afi_t afi
, safi_t safi
)
1079 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1080 return "frr-routing:ipv4-unicast";
1081 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
1082 return "frr-routing:ipv6-unicast";
1083 if (afi
== AFI_IP
&& safi
== SAFI_MULTICAST
)
1084 return "frr-routing:ipv4-multicast";
1085 if (afi
== AFI_IP6
&& safi
== SAFI_MULTICAST
)
1086 return "frr-routing:ipv6-multicast";
1087 if (afi
== AFI_IP
&& safi
== SAFI_MPLS_VPN
)
1088 return "frr-routing:l3vpn-ipv4-unicast";
1089 if (afi
== AFI_IP6
&& safi
== SAFI_MPLS_VPN
)
1090 return "frr-routing:l3vpn-ipv6-unicast";
1091 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
1092 return "frr-routing:l2vpn-evpn";
1093 if (afi
== AFI_IP
&& safi
== SAFI_LABELED_UNICAST
)
1094 return "frr-routing:ipv4-labeled-unicast";
1095 if (afi
== AFI_IP6
&& safi
== SAFI_LABELED_UNICAST
)
1096 return "frr-routing:ipv6-labeled-unicast";
1097 if (afi
== AFI_IP
&& safi
== SAFI_FLOWSPEC
)
1098 return "frr-routing:ipv4-flowspec";
1099 if (afi
== AFI_IP6
&& safi
== SAFI_FLOWSPEC
)
1100 return "frr-routing:ipv6-flowspec";
1105 void yang_afi_safi_identity2value(const char *key
, afi_t
*afi
, safi_t
*safi
)
1107 if (strmatch(key
, "frr-routing:ipv4-unicast")) {
1109 *safi
= SAFI_UNICAST
;
1110 } else if (strmatch(key
, "frr-routing:ipv6-unicast")) {
1112 *safi
= SAFI_UNICAST
;
1113 } else if (strmatch(key
, "frr-routing:ipv4-multicast")) {
1115 *safi
= SAFI_MULTICAST
;
1116 } else if (strmatch(key
, "frr-routing:ipv6-multicast")) {
1118 *safi
= SAFI_MULTICAST
;
1119 } else if (strmatch(key
, "frr-routing:l3vpn-ipv4-unicast")) {
1121 *safi
= SAFI_MPLS_VPN
;
1122 } else if (strmatch(key
, "frr-routing:l3vpn-ipv6-unicast")) {
1124 *safi
= SAFI_MPLS_VPN
;
1125 } else if (strmatch(key
, "frr-routing:ipv4-labeled-unicast")) {
1127 *safi
= SAFI_LABELED_UNICAST
;
1128 } else if (strmatch(key
, "frr-routing:ipv6-labeled-unicast")) {
1130 *safi
= SAFI_LABELED_UNICAST
;
1131 } else if (strmatch(key
, "frr-routing:l2vpn-evpn")) {
1134 } else if (strmatch(key
, "frr-routing:ipv4-flowspec")) {
1136 *safi
= SAFI_FLOWSPEC
;
1137 } else if (strmatch(key
, "frr-routing:ipv6-flowspec")) {
1139 *safi
= SAFI_FLOWSPEC
;
1142 *safi
= SAFI_UNSPEC
;