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); \
61 static inline const char *
62 yang_dnode_xpath_get_canon(const struct lyd_node
*dnode
, const char *xpath_fmt
,
65 const struct lyd_node_term
*__dleaf
=
66 (const struct lyd_node_term
*)dnode
;
69 char __xpath
[XPATH_MAXLEN
];
70 vsnprintf(__xpath
, sizeof(__xpath
), xpath_fmt
, ap
);
71 __dleaf
= (const struct lyd_node_term
*)yang_dnode_get(dnode
,
73 YANG_DNODE_GET_ASSERT(__dleaf
, __xpath
);
75 return lyd_get_value(&__dleaf
->node
);
78 static inline const struct lyd_value
*
79 yang_dnode_xpath_get_value(const struct lyd_node
*dnode
, const char *xpath_fmt
,
82 const struct lyd_node_term
*__dleaf
=
83 (const struct lyd_node_term
*)dnode
;
86 char __xpath
[XPATH_MAXLEN
];
87 vsnprintf(__xpath
, sizeof(__xpath
), xpath_fmt
, ap
);
88 __dleaf
= (const struct lyd_node_term
*)yang_dnode_get(dnode
,
90 YANG_DNODE_GET_ASSERT(__dleaf
, __xpath
);
92 const struct lyd_value
*__dvalue
= &__dleaf
->value
;
93 if (__dvalue
->realtype
->basetype
== LY_TYPE_UNION
)
94 __dvalue
= &__dvalue
->subvalue
->value
;
98 static const char *yang_get_default_value(const char *xpath
)
100 const struct lysc_node
*snode
;
103 snode
= lys_find_path(ly_native_ctx
, NULL
, xpath
, 0);
105 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
106 "%s: unknown data path: %s", __func__
, xpath
);
107 zlog_backtrace(LOG_ERR
);
111 value
= yang_snode_get_default(snode
);
118 * Primitive type: bool.
120 bool yang_str2bool(const char *value
)
122 return strmatch(value
, "true");
125 struct yang_data
*yang_data_new_bool(const char *xpath
, bool value
)
127 return yang_data_new(xpath
, (value
) ? "true" : "false");
130 bool yang_dnode_get_bool(const struct lyd_node
*dnode
, const char *xpath_fmt
,
133 const struct lyd_value
*dvalue
;
134 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
135 assert(dvalue
->realtype
->basetype
== LY_TYPE_BOOL
);
136 return dvalue
->boolean
;
139 bool yang_get_default_bool(const char *xpath_fmt
, ...)
141 char xpath
[XPATH_MAXLEN
];
145 va_start(ap
, xpath_fmt
);
146 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
149 value
= yang_get_default_value(xpath
);
150 return yang_str2bool(value
);
154 * Primitive type: dec64.
156 double yang_str2dec64(const char *xpath
, const char *value
)
160 if (sscanf(value
, "%lf", &dbl
) != 1) {
161 flog_err(EC_LIB_YANG_DATA_CONVERT
,
162 "%s: couldn't convert string to decimal64 [xpath %s]",
164 zlog_backtrace(LOG_ERR
);
171 struct yang_data
*yang_data_new_dec64(const char *xpath
, double value
)
173 char value_str
[BUFSIZ
];
175 snprintf(value_str
, sizeof(value_str
), "%lf", value
);
176 return yang_data_new(xpath
, value_str
);
179 double yang_dnode_get_dec64(const struct lyd_node
*dnode
, const char *xpath_fmt
,
182 const double denom
[19] = {1e0
, 1e-1, 1e-2, 1e-3, 1e-4,
183 1e-5, 1e-6, 1e-7, 1e-8, 1e-9,
184 1e-10, 1e-11, 1e-12, 1e-13, 1e-14,
185 1e-15, 1e-16, 1e-17, 1e-18};
186 const struct lysc_type_dec
*dectype
;
187 const struct lyd_value
*dvalue
;
189 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
190 dectype
= (const struct lysc_type_dec
*)dvalue
->realtype
;
191 assert(dectype
->basetype
== LY_TYPE_DEC64
);
192 assert(dectype
->fraction_digits
< sizeof(denom
) / sizeof(*denom
));
193 return (double)dvalue
->dec64
* denom
[dectype
->fraction_digits
];
196 double yang_get_default_dec64(const char *xpath_fmt
, ...)
198 char xpath
[XPATH_MAXLEN
];
202 va_start(ap
, xpath_fmt
);
203 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
206 value
= yang_get_default_value(xpath
);
207 return yang_str2dec64(xpath
, value
);
211 * Primitive type: enum.
213 int yang_str2enum(const char *xpath
, const char *value
)
215 const struct lysc_node
*snode
;
216 const struct lysc_node_leaf
*sleaf
;
217 const struct lysc_type_enum
*type
;
218 const struct lysc_type_bitenum_item
*enums
;
220 snode
= lys_find_path(ly_native_ctx
, NULL
, xpath
, 0);
222 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
223 "%s: unknown data path: %s", __func__
, xpath
);
224 zlog_backtrace(LOG_ERR
);
228 assert(snode
->nodetype
== LYS_LEAF
);
229 sleaf
= (const struct lysc_node_leaf
*)snode
;
230 type
= (const struct lysc_type_enum
*)sleaf
->type
;
231 assert(type
->basetype
== LY_TYPE_ENUM
);
233 unsigned int count
= LY_ARRAY_COUNT(enums
);
234 for (unsigned int i
= 0; i
< count
; i
++) {
235 if (strmatch(value
, enums
[i
].name
)) {
236 assert(CHECK_FLAG(enums
[i
].flags
, LYS_SET_VALUE
));
237 return enums
[i
].value
;
241 flog_err(EC_LIB_YANG_DATA_CONVERT
,
242 "%s: couldn't convert string to enum [xpath %s]", __func__
,
244 zlog_backtrace(LOG_ERR
);
248 struct yang_data
*yang_data_new_enum(const char *xpath
, int value
)
250 const struct lysc_node
*snode
;
251 const struct lysc_node_leaf
*sleaf
;
252 const struct lysc_type_enum
*type
;
253 const struct lysc_type_bitenum_item
*enums
;
255 snode
= lys_find_path(ly_native_ctx
, NULL
, xpath
, 0);
257 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH
,
258 "%s: unknown data path: %s", __func__
, xpath
);
259 zlog_backtrace(LOG_ERR
);
263 assert(snode
->nodetype
== LYS_LEAF
);
264 sleaf
= (const struct lysc_node_leaf
*)snode
;
265 type
= (const struct lysc_type_enum
*)sleaf
->type
;
266 assert(type
->basetype
== LY_TYPE_ENUM
);
268 unsigned int count
= LY_ARRAY_COUNT(enums
);
269 for (unsigned int i
= 0; i
< count
; i
++) {
270 if (CHECK_FLAG(enums
[i
].flags
, LYS_SET_VALUE
)
271 && value
== enums
[i
].value
)
272 return yang_data_new(xpath
, enums
[i
].name
);
275 flog_err(EC_LIB_YANG_DATA_CONVERT
,
276 "%s: couldn't convert enum to string [xpath %s]", __func__
,
278 zlog_backtrace(LOG_ERR
);
282 int yang_dnode_get_enum(const struct lyd_node
*dnode
, const char *xpath_fmt
,
285 const struct lyd_value
*dvalue
;
287 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
288 assert(dvalue
->realtype
->basetype
== LY_TYPE_ENUM
);
289 assert(dvalue
->enum_item
->flags
& LYS_SET_VALUE
);
290 return dvalue
->enum_item
->value
;
293 int yang_get_default_enum(const char *xpath_fmt
, ...)
295 char xpath
[XPATH_MAXLEN
];
299 va_start(ap
, xpath_fmt
);
300 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
303 value
= yang_get_default_value(xpath
);
304 return yang_str2enum(xpath
, value
);
308 * Primitive type: int8.
310 int8_t yang_str2int8(const char *value
)
312 return strtol(value
, NULL
, 10);
315 struct yang_data
*yang_data_new_int8(const char *xpath
, int8_t value
)
317 char value_str
[BUFSIZ
];
319 snprintf(value_str
, sizeof(value_str
), "%d", value
);
320 return yang_data_new(xpath
, value_str
);
323 int8_t yang_dnode_get_int8(const struct lyd_node
*dnode
, const char *xpath_fmt
,
326 const struct lyd_value
*dvalue
;
327 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
328 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT8
);
332 int8_t yang_get_default_int8(const char *xpath_fmt
, ...)
334 char xpath
[XPATH_MAXLEN
];
338 va_start(ap
, xpath_fmt
);
339 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
342 value
= yang_get_default_value(xpath
);
343 return yang_str2int8(value
);
347 * Primitive type: int16.
349 int16_t yang_str2int16(const char *value
)
351 return strtol(value
, NULL
, 10);
354 struct yang_data
*yang_data_new_int16(const char *xpath
, int16_t value
)
356 char value_str
[BUFSIZ
];
358 snprintf(value_str
, sizeof(value_str
), "%d", value
);
359 return yang_data_new(xpath
, value_str
);
362 int16_t yang_dnode_get_int16(const struct lyd_node
*dnode
,
363 const char *xpath_fmt
, ...)
365 const struct lyd_value
*dvalue
;
366 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
367 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT16
);
368 return dvalue
->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_value
*dvalue
;
405 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
406 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT32
);
407 return dvalue
->int32
;
410 int32_t yang_get_default_int32(const char *xpath_fmt
, ...)
412 char xpath
[XPATH_MAXLEN
];
416 va_start(ap
, xpath_fmt
);
417 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
420 value
= yang_get_default_value(xpath
);
421 return yang_str2int32(value
);
425 * Primitive type: int64.
427 int64_t yang_str2int64(const char *value
)
429 return strtoll(value
, NULL
, 10);
432 struct yang_data
*yang_data_new_int64(const char *xpath
, int64_t value
)
434 char value_str
[BUFSIZ
];
436 snprintfrr(value_str
, sizeof(value_str
), "%" PRId64
, value
);
437 return yang_data_new(xpath
, value_str
);
440 int64_t yang_dnode_get_int64(const struct lyd_node
*dnode
,
441 const char *xpath_fmt
, ...)
443 const struct lyd_value
*dvalue
;
444 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
445 assert(dvalue
->realtype
->basetype
== LY_TYPE_INT64
);
446 return dvalue
->int64
;
449 int64_t yang_get_default_int64(const char *xpath_fmt
, ...)
451 char xpath
[XPATH_MAXLEN
];
455 va_start(ap
, xpath_fmt
);
456 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
459 value
= yang_get_default_value(xpath
);
460 return yang_str2int64(value
);
464 * Primitive type: uint8.
466 uint8_t yang_str2uint8(const char *value
)
468 return strtoul(value
, NULL
, 10);
471 struct yang_data
*yang_data_new_uint8(const char *xpath
, uint8_t value
)
473 char value_str
[BUFSIZ
];
475 snprintf(value_str
, sizeof(value_str
), "%u", value
);
476 return yang_data_new(xpath
, value_str
);
479 uint8_t yang_dnode_get_uint8(const struct lyd_node
*dnode
,
480 const char *xpath_fmt
, ...)
482 const struct lyd_value
*dvalue
;
483 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
484 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT8
);
485 return dvalue
->uint8
;
488 uint8_t yang_get_default_uint8(const char *xpath_fmt
, ...)
490 char xpath
[XPATH_MAXLEN
];
494 va_start(ap
, xpath_fmt
);
495 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
498 value
= yang_get_default_value(xpath
);
499 return yang_str2uint8(value
);
503 * Primitive type: uint16.
505 uint16_t yang_str2uint16(const char *value
)
507 return strtoul(value
, NULL
, 10);
510 struct yang_data
*yang_data_new_uint16(const char *xpath
, uint16_t value
)
512 char value_str
[BUFSIZ
];
514 snprintf(value_str
, sizeof(value_str
), "%u", value
);
515 return yang_data_new(xpath
, value_str
);
518 uint16_t yang_dnode_get_uint16(const struct lyd_node
*dnode
,
519 const char *xpath_fmt
, ...)
521 const struct lyd_value
*dvalue
;
522 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
523 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT16
);
524 return dvalue
->uint16
;
527 uint16_t yang_get_default_uint16(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_str2uint16(value
);
542 * Primitive type: uint32.
544 uint32_t yang_str2uint32(const char *value
)
546 return strtoul(value
, NULL
, 10);
549 struct yang_data
*yang_data_new_uint32(const char *xpath
, uint32_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 uint32_t yang_dnode_get_uint32(const struct lyd_node
*dnode
,
558 const char *xpath_fmt
, ...)
560 const struct lyd_value
*dvalue
;
561 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
562 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT32
);
563 return dvalue
->uint32
;
566 uint32_t yang_get_default_uint32(const char *xpath_fmt
, ...)
568 char xpath
[XPATH_MAXLEN
];
572 va_start(ap
, xpath_fmt
);
573 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
576 value
= yang_get_default_value(xpath
);
577 return yang_str2uint32(value
);
581 * Primitive type: uint64.
583 uint64_t yang_str2uint64(const char *value
)
585 return strtoull(value
, NULL
, 10);
588 struct yang_data
*yang_data_new_uint64(const char *xpath
, uint64_t value
)
590 char value_str
[BUFSIZ
];
592 snprintfrr(value_str
, sizeof(value_str
), "%" PRIu64
, value
);
593 return yang_data_new(xpath
, value_str
);
596 uint64_t yang_dnode_get_uint64(const struct lyd_node
*dnode
,
597 const char *xpath_fmt
, ...)
599 const struct lyd_value
*dvalue
;
600 dvalue
= YANG_DNODE_XPATH_GET_VALUE(dnode
, xpath_fmt
);
601 assert(dvalue
->realtype
->basetype
== LY_TYPE_UINT64
);
602 return dvalue
->uint64
;
605 uint64_t yang_get_default_uint64(const char *xpath_fmt
, ...)
607 char xpath
[XPATH_MAXLEN
];
611 va_start(ap
, xpath_fmt
);
612 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
615 value
= yang_get_default_value(xpath
);
616 return yang_str2uint64(value
);
620 * Primitive type: string.
622 * All string wrappers can be used with non-string types.
624 struct yang_data
*yang_data_new_string(const char *xpath
, const char *value
)
626 return yang_data_new(xpath
, value
);
629 const char *yang_dnode_get_string(const struct lyd_node
*dnode
,
630 const char *xpath_fmt
, ...)
632 return YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
635 void yang_dnode_get_string_buf(char *buf
, size_t size
,
636 const struct lyd_node
*dnode
,
637 const char *xpath_fmt
, ...)
639 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
640 if (strlcpy(buf
, canon
, size
) >= size
) {
641 char xpath
[XPATH_MAXLEN
];
643 yang_dnode_get_path(dnode
, xpath
, sizeof(xpath
));
644 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
645 "%s: value was truncated [xpath %s]", __func__
,
650 const char *yang_get_default_string(const char *xpath_fmt
, ...)
652 char xpath
[XPATH_MAXLEN
];
655 va_start(ap
, xpath_fmt
);
656 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
659 return yang_get_default_value(xpath
);
662 void yang_get_default_string_buf(char *buf
, size_t size
, const char *xpath_fmt
,
665 char xpath
[XPATH_MAXLEN
];
669 va_start(ap
, xpath_fmt
);
670 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
673 value
= yang_get_default_value(xpath
);
674 if (strlcpy(buf
, value
, size
) >= size
)
675 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
676 "%s: value was truncated [xpath %s]", __func__
,
681 * Primitive type: binary.
683 struct yang_data
*yang_data_new_binary(const char *xpath
, const char *value
,
687 struct base64_encodestate s
;
690 struct yang_data
*data
;
692 value_str
= (char *)malloc(len
* 2);
693 base64_init_encodestate(&s
);
694 cnt
= base64_encode_block(value
, len
, value_str
, &s
);
696 cnt
= base64_encode_blockend(c
, &s
);
699 data
= yang_data_new(xpath
, value_str
);
704 size_t yang_dnode_get_binary_buf(char *buf
, size_t size
,
705 const struct lyd_node
*dnode
,
706 const char *xpath_fmt
, ...)
714 struct base64_decodestate s
;
716 canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
717 cannon_len
= strlen(canon
);
718 decode_len
= cannon_len
;
719 value_str
= (char *)malloc(decode_len
);
720 base64_init_decodestate(&s
);
721 cnt
= base64_decode_block(canon
, cannon_len
, value_str
, &s
);
723 ret_len
= size
> cnt
? cnt
: size
;
724 memcpy(buf
, value_str
, ret_len
);
726 char xpath
[XPATH_MAXLEN
];
728 yang_dnode_get_path(dnode
, xpath
, sizeof(xpath
));
729 flog_warn(EC_LIB_YANG_DATA_TRUNCATED
,
730 "%s: value was truncated [xpath %s]", __func__
,
739 * Primitive type: empty.
741 struct yang_data
*yang_data_new_empty(const char *xpath
)
743 return yang_data_new(xpath
, NULL
);
746 bool yang_dnode_get_empty(const struct lyd_node
*dnode
, const char *xpath_fmt
,
750 char xpath
[XPATH_MAXLEN
];
751 const struct lyd_node_term
*dleaf
;
755 va_start(ap
, xpath_fmt
);
756 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
759 dnode
= yang_dnode_get(dnode
, xpath
);
761 dleaf
= (const struct lyd_node_term
*)dnode
;
762 if (dleaf
->value
.realtype
->basetype
== LY_TYPE_EMPTY
)
770 * Derived type: IP prefix.
772 void yang_str2prefix(const char *value
, union prefixptr prefix
)
774 (void)str2prefix(value
, prefix
.p
);
775 apply_mask(prefix
.p
);
778 struct yang_data
*yang_data_new_prefix(const char *xpath
,
779 union prefixconstptr prefix
)
781 char value_str
[PREFIX2STR_BUFFER
];
783 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
784 return yang_data_new(xpath
, value_str
);
787 void yang_dnode_get_prefix(struct prefix
*prefix
, const struct lyd_node
*dnode
,
788 const char *xpath_fmt
, ...)
792 * Initialize prefix to avoid static analyzer complaints about
793 * uninitialized memory.
795 memset(prefix
, 0, sizeof(*prefix
));
797 /* XXX ip_prefix is a native type now in ly2, leverage? */
798 canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
799 (void)str2prefix(canon
, prefix
);
802 void yang_get_default_prefix(union prefixptr var
, const char *xpath_fmt
, ...)
804 char xpath
[XPATH_MAXLEN
];
808 va_start(ap
, xpath_fmt
);
809 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
812 value
= yang_get_default_value(xpath
);
813 yang_str2prefix(value
, var
);
817 * Derived type: ipv4.
819 void yang_str2ipv4(const char *value
, struct in_addr
*addr
)
821 (void)inet_pton(AF_INET
, value
, addr
);
824 struct yang_data
*yang_data_new_ipv4(const char *xpath
,
825 const struct in_addr
*addr
)
827 char value_str
[INET_ADDRSTRLEN
];
829 (void)inet_ntop(AF_INET
, addr
, value_str
, sizeof(value_str
));
830 return yang_data_new(xpath
, value_str
);
833 void yang_dnode_get_ipv4(struct in_addr
*addr
, const struct lyd_node
*dnode
,
834 const char *xpath_fmt
, ...)
836 /* XXX libyang2 IPv4 address is a native type now in ly2 */
837 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
838 (void)inet_pton(AF_INET
, canon
, addr
);
841 void yang_get_default_ipv4(struct in_addr
*var
, const char *xpath_fmt
, ...)
843 char xpath
[XPATH_MAXLEN
];
847 va_start(ap
, xpath_fmt
);
848 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
851 value
= yang_get_default_value(xpath
);
852 yang_str2ipv4(value
, var
);
856 * Derived type: ipv4p.
858 void yang_str2ipv4p(const char *value
, union prefixptr prefix
)
860 struct prefix_ipv4
*prefix4
= prefix
.p4
;
862 (void)str2prefix_ipv4(value
, prefix4
);
863 apply_mask_ipv4(prefix4
);
866 struct yang_data
*yang_data_new_ipv4p(const char *xpath
,
867 union prefixconstptr prefix
)
869 char value_str
[PREFIX2STR_BUFFER
];
871 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
872 return yang_data_new(xpath
, value_str
);
875 void yang_dnode_get_ipv4p(union prefixptr prefix
, const struct lyd_node
*dnode
,
876 const char *xpath_fmt
, ...)
878 struct prefix_ipv4
*prefix4
= prefix
.p4
;
879 /* XXX libyang2: ipv4/6 address is a native type now in ly2 */
880 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
881 (void)str2prefix_ipv4(canon
, prefix4
);
884 void yang_get_default_ipv4p(union prefixptr var
, const char *xpath_fmt
, ...)
886 char xpath
[XPATH_MAXLEN
];
890 va_start(ap
, xpath_fmt
);
891 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
894 value
= yang_get_default_value(xpath
);
895 yang_str2ipv4p(value
, var
);
899 * Derived type: ipv6.
901 void yang_str2ipv6(const char *value
, struct in6_addr
*addr
)
903 (void)inet_pton(AF_INET6
, value
, addr
);
906 struct yang_data
*yang_data_new_ipv6(const char *xpath
,
907 const struct in6_addr
*addr
)
909 char value_str
[INET6_ADDRSTRLEN
];
911 (void)inet_ntop(AF_INET6
, addr
, value_str
, sizeof(value_str
));
912 return yang_data_new(xpath
, value_str
);
915 void yang_dnode_get_ipv6(struct in6_addr
*addr
, const struct lyd_node
*dnode
,
916 const char *xpath_fmt
, ...)
918 /* XXX libyang2: IPv6 address is a native type now, leverage. */
919 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
920 (void)inet_pton(AF_INET6
, canon
, addr
);
923 void yang_get_default_ipv6(struct in6_addr
*var
, const char *xpath_fmt
, ...)
925 char xpath
[XPATH_MAXLEN
];
929 va_start(ap
, xpath_fmt
);
930 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
933 value
= yang_get_default_value(xpath
);
934 yang_str2ipv6(value
, var
);
938 * Derived type: ipv6p.
940 void yang_str2ipv6p(const char *value
, union prefixptr prefix
)
942 struct prefix_ipv6
*prefix6
= prefix
.p6
;
944 (void)str2prefix_ipv6(value
, prefix6
);
945 apply_mask_ipv6(prefix6
);
948 struct yang_data
*yang_data_new_ipv6p(const char *xpath
,
949 union prefixconstptr prefix
)
951 char value_str
[PREFIX2STR_BUFFER
];
953 (void)prefix2str(prefix
.p
, value_str
, sizeof(value_str
));
954 return yang_data_new(xpath
, value_str
);
957 void yang_dnode_get_ipv6p(union prefixptr prefix
, const struct lyd_node
*dnode
,
958 const char *xpath_fmt
, ...)
960 struct prefix_ipv6
*prefix6
= prefix
.p6
;
962 /* XXX IPv6 address is a native type now in ly2 -- can we leverage? */
963 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
964 (void)str2prefix_ipv6(canon
, prefix6
);
967 void yang_get_default_ipv6p(union prefixptr var
, const char *xpath_fmt
, ...)
969 char xpath
[XPATH_MAXLEN
];
973 va_start(ap
, xpath_fmt
);
974 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
977 value
= yang_get_default_value(xpath
);
978 yang_str2ipv6p(value
, var
);
984 void yang_str2ip(const char *value
, struct ipaddr
*ip
)
986 (void)str2ipaddr(value
, ip
);
989 struct yang_data
*yang_data_new_ip(const char *xpath
, const struct ipaddr
*addr
)
991 size_t sz
= IS_IPADDR_V4(addr
) ? INET_ADDRSTRLEN
: INET6_ADDRSTRLEN
;
994 ipaddr2str(addr
, value_str
, sizeof(value_str
));
995 return yang_data_new(xpath
, value_str
);
998 void yang_dnode_get_ip(struct ipaddr
*addr
, const struct lyd_node
*dnode
,
999 const char *xpath_fmt
, ...)
1001 /* XXX IPv4 address could be a plugin type now in ly2, leverage? */
1002 const char *canon
= YANG_DNODE_XPATH_GET_CANON(dnode
, xpath_fmt
);
1003 (void)str2ipaddr(canon
, addr
);
1006 void yang_get_default_ip(struct ipaddr
*var
, const char *xpath_fmt
, ...)
1008 char xpath
[XPATH_MAXLEN
];
1012 va_start(ap
, xpath_fmt
);
1013 vsnprintf(xpath
, sizeof(xpath
), xpath_fmt
, ap
);
1016 value
= yang_get_default_value(xpath
);
1017 yang_str2ip(value
, var
);
1020 struct yang_data
*yang_data_new_mac(const char *xpath
,
1021 const struct ethaddr
*mac
)
1023 char value_str
[ETHER_ADDR_STRLEN
];
1025 prefix_mac2str(mac
, value_str
, sizeof(value_str
));
1026 return yang_data_new(xpath
, value_str
);
1029 void yang_str2mac(const char *value
, struct ethaddr
*mac
)
1031 (void)prefix_str2mac(value
, mac
);
1034 struct yang_data
*yang_data_new_date_and_time(const char *xpath
, time_t time
)
1037 char timebuf
[MONOTIME_STRLEN
];
1038 struct timeval _time
, time_real
;
1042 _time
.tv_sec
= time
;
1044 monotime_to_realtime(&_time
, &time_real
);
1046 gmtime_r(&time_real
.tv_sec
, &tm
);
1048 /* rfc-3339 format */
1049 strftime(timebuf
, sizeof(timebuf
), "%Y-%m-%dT%H:%M:%S", &tm
);
1050 buflen
= strlen(timebuf
);
1051 ts_dot
= timebuf
+ buflen
;
1053 /* microseconds and appends Z */
1054 snprintfrr(ts_dot
, sizeof(timebuf
) - buflen
, ".%06luZ",
1055 (unsigned long)time_real
.tv_usec
);
1057 return yang_data_new(xpath
, timebuf
);
1060 const char *yang_nexthop_type2str(uint32_t ntype
)
1063 case NEXTHOP_TYPE_IFINDEX
:
1066 case NEXTHOP_TYPE_IPV4
:
1069 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1070 return "ip4-ifindex";
1072 case NEXTHOP_TYPE_IPV6
:
1075 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1076 return "ip6-ifindex";
1078 case NEXTHOP_TYPE_BLACKHOLE
:
1088 const char *yang_afi_safi_value2identity(afi_t afi
, safi_t safi
)
1090 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1091 return "frr-routing:ipv4-unicast";
1092 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
)
1093 return "frr-routing:ipv6-unicast";
1094 if (afi
== AFI_IP
&& safi
== SAFI_MULTICAST
)
1095 return "frr-routing:ipv4-multicast";
1096 if (afi
== AFI_IP6
&& safi
== SAFI_MULTICAST
)
1097 return "frr-routing:ipv6-multicast";
1098 if (afi
== AFI_IP
&& safi
== SAFI_MPLS_VPN
)
1099 return "frr-routing:l3vpn-ipv4-unicast";
1100 if (afi
== AFI_IP6
&& safi
== SAFI_MPLS_VPN
)
1101 return "frr-routing:l3vpn-ipv6-unicast";
1102 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
1103 return "frr-routing:l2vpn-evpn";
1104 if (afi
== AFI_IP
&& safi
== SAFI_LABELED_UNICAST
)
1105 return "frr-routing:ipv4-labeled-unicast";
1106 if (afi
== AFI_IP6
&& safi
== SAFI_LABELED_UNICAST
)
1107 return "frr-routing:ipv6-labeled-unicast";
1108 if (afi
== AFI_IP
&& safi
== SAFI_FLOWSPEC
)
1109 return "frr-routing:ipv4-flowspec";
1110 if (afi
== AFI_IP6
&& safi
== SAFI_FLOWSPEC
)
1111 return "frr-routing:ipv6-flowspec";
1116 void yang_afi_safi_identity2value(const char *key
, afi_t
*afi
, safi_t
*safi
)
1118 if (strmatch(key
, "frr-routing:ipv4-unicast")) {
1120 *safi
= SAFI_UNICAST
;
1121 } else if (strmatch(key
, "frr-routing:ipv6-unicast")) {
1123 *safi
= SAFI_UNICAST
;
1124 } else if (strmatch(key
, "frr-routing:ipv4-multicast")) {
1126 *safi
= SAFI_MULTICAST
;
1127 } else if (strmatch(key
, "frr-routing:ipv6-multicast")) {
1129 *safi
= SAFI_MULTICAST
;
1130 } else if (strmatch(key
, "frr-routing:l3vpn-ipv4-unicast")) {
1132 *safi
= SAFI_MPLS_VPN
;
1133 } else if (strmatch(key
, "frr-routing:l3vpn-ipv6-unicast")) {
1135 *safi
= SAFI_MPLS_VPN
;
1136 } else if (strmatch(key
, "frr-routing:ipv4-labeled-unicast")) {
1138 *safi
= SAFI_LABELED_UNICAST
;
1139 } else if (strmatch(key
, "frr-routing:ipv6-labeled-unicast")) {
1141 *safi
= SAFI_LABELED_UNICAST
;
1142 } else if (strmatch(key
, "frr-routing:l2vpn-evpn")) {
1145 } else if (strmatch(key
, "frr-routing:ipv4-flowspec")) {
1147 *safi
= SAFI_FLOWSPEC
;
1148 } else if (strmatch(key
, "frr-routing:ipv6-flowspec")) {
1150 *safi
= SAFI_FLOWSPEC
;
1153 *safi
= SAFI_UNSPEC
;