]> git.proxmox.com Git - mirror_frr.git/blame - lib/yang_wrappers.c
Merge pull request #5560 from sworleys/Pim-Vrf-Hang-3
[mirror_frr.git] / lib / yang_wrappers.c
CommitLineData
1c2facd1
RW
1/*
2 * Copyright (C) 2018 NetDEF, Inc.
3 * Renato Westphal
4 *
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)
8 * any later version.
9 *
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
13 * more details.
14 *
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
18 */
19
20#include <zebra.h>
21
22#include "log.h"
23#include "lib_errors.h"
24#include "northbound.h"
25
26static const char *yang_get_default_value(const char *xpath)
27{
28 const struct lys_node *snode;
29 const char *value;
30
31 snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0);
32 if (snode == NULL) {
33 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
34 "%s: unknown data path: %s", __func__, xpath);
35 zlog_backtrace(LOG_ERR);
36 abort();
37 }
38
39 value = yang_snode_get_default(snode);
40 assert(value);
41
42 return value;
43}
44
45#define YANG_DNODE_GET_ASSERT(dnode, xpath) \
46 do { \
47 if ((dnode) == NULL) { \
48 flog_err(EC_LIB_YANG_DNODE_NOT_FOUND, \
49 "%s: couldn't find %s", __func__, (xpath)); \
50 zlog_backtrace(LOG_ERR); \
51 abort(); \
52 } \
53 } while (0)
54
55/*
56 * Primitive type: bool.
57 */
58bool yang_str2bool(const char *value)
59{
60 return strmatch(value, "true");
61}
62
63struct yang_data *yang_data_new_bool(const char *xpath, bool value)
64{
d8729f8c 65 return yang_data_new(xpath, (value) ? "true" : "false");
1c2facd1
RW
66}
67
68bool yang_dnode_get_bool(const struct lyd_node *dnode, const char *xpath_fmt,
69 ...)
70{
71 const struct lyd_node_leaf_list *dleaf;
72
73 assert(dnode);
74 if (xpath_fmt) {
75 va_list ap;
76 char xpath[XPATH_MAXLEN];
77
78 va_start(ap, xpath_fmt);
79 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
80 va_end(ap);
81 dnode = yang_dnode_get(dnode, xpath);
82 YANG_DNODE_GET_ASSERT(dnode, xpath);
83 }
84
85 dleaf = (const struct lyd_node_leaf_list *)dnode;
86 assert(dleaf->value_type == LY_TYPE_BOOL);
87 return dleaf->value.bln;
88}
89
90bool yang_get_default_bool(const char *xpath_fmt, ...)
91{
92 char xpath[XPATH_MAXLEN];
93 const char *value;
94 va_list ap;
95
96 va_start(ap, xpath_fmt);
97 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
98 va_end(ap);
99
100 value = yang_get_default_value(xpath);
101 return yang_str2bool(value);
102}
103
104/*
105 * Primitive type: dec64.
106 */
107double yang_str2dec64(const char *xpath, const char *value)
108{
109 double dbl = 0;
110
111 if (sscanf(value, "%lf", &dbl) != 1) {
112 flog_err(EC_LIB_YANG_DATA_CONVERT,
113 "%s: couldn't convert string to decimal64 [xpath %s]",
114 __func__, xpath);
115 zlog_backtrace(LOG_ERR);
116 abort();
117 }
118
119 return dbl;
120}
121
122struct yang_data *yang_data_new_dec64(const char *xpath, double value)
123{
124 char value_str[BUFSIZ];
125
126 snprintf(value_str, sizeof(value_str), "%lf", value);
127 return yang_data_new(xpath, value_str);
128}
129
130double yang_dnode_get_dec64(const struct lyd_node *dnode, const char *xpath_fmt,
131 ...)
132{
133 const struct lyd_node_leaf_list *dleaf;
134
135 assert(dnode);
136 if (xpath_fmt) {
137 va_list ap;
138 char xpath[XPATH_MAXLEN];
139
140 va_start(ap, xpath_fmt);
141 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
142 va_end(ap);
143 dnode = yang_dnode_get(dnode, xpath);
144 YANG_DNODE_GET_ASSERT(dnode, xpath);
145 }
146
147 dleaf = (const struct lyd_node_leaf_list *)dnode;
148 assert(dleaf->value_type == LY_TYPE_DEC64);
149
150 return lyd_dec64_to_double(dnode);
151}
152
153double yang_get_default_dec64(const char *xpath_fmt, ...)
154{
155 char xpath[XPATH_MAXLEN];
156 const char *value;
157 va_list ap;
158
159 va_start(ap, xpath_fmt);
160 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
161 va_end(ap);
162
163 value = yang_get_default_value(xpath);
164 return yang_str2dec64(xpath, value);
165}
166
167/*
168 * Primitive type: enum.
169 */
170int yang_str2enum(const char *xpath, const char *value)
171{
172 const struct lys_node *snode;
173 const struct lys_node_leaf *sleaf;
bb359ba2 174 const struct lys_type *type;
1c2facd1
RW
175 const struct lys_type_info_enums *enums;
176
177 snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0);
178 if (snode == NULL) {
179 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
180 "%s: unknown data path: %s", __func__, xpath);
181 zlog_backtrace(LOG_ERR);
182 abort();
183 }
184
185 sleaf = (const struct lys_node_leaf *)snode;
bb359ba2
EDP
186 type = &sleaf->type;
187 enums = &type->info.enums;
188 while (enums->count == 0 && type->der) {
189 type = &type->der->type;
190 enums = &type->info.enums;
191 }
1c2facd1
RW
192 for (unsigned int i = 0; i < enums->count; i++) {
193 const struct lys_type_enum *enm = &enums->enm[i];
194
195 if (strmatch(value, enm->name))
196 return enm->value;
197 }
198
199 flog_err(EC_LIB_YANG_DATA_CONVERT,
200 "%s: couldn't convert string to enum [xpath %s]", __func__,
201 xpath);
202 zlog_backtrace(LOG_ERR);
203 abort();
204}
205
206struct yang_data *yang_data_new_enum(const char *xpath, int value)
207{
208 const struct lys_node *snode;
209 const struct lys_node_leaf *sleaf;
42067575 210 const struct lys_type *type;
1c2facd1
RW
211 const struct lys_type_info_enums *enums;
212
213 snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0);
214 if (snode == NULL) {
215 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
216 "%s: unknown data path: %s", __func__, xpath);
217 zlog_backtrace(LOG_ERR);
218 abort();
219 }
220
221 sleaf = (const struct lys_node_leaf *)snode;
42067575
EDP
222 type = &sleaf->type;
223 enums = &type->info.enums;
224 while (enums->count == 0 && type->der) {
225 type = &type->der->type;
226 enums = &type->info.enums;
227 }
1c2facd1
RW
228 for (unsigned int i = 0; i < enums->count; i++) {
229 const struct lys_type_enum *enm = &enums->enm[i];
230
231 if (value == enm->value)
232 return yang_data_new(xpath, enm->name);
233 }
234
235 flog_err(EC_LIB_YANG_DATA_CONVERT,
236 "%s: couldn't convert enum to string [xpath %s]", __func__,
237 xpath);
238 zlog_backtrace(LOG_ERR);
239 abort();
240}
241
242int yang_dnode_get_enum(const struct lyd_node *dnode, const char *xpath_fmt,
243 ...)
244{
245 const struct lyd_node_leaf_list *dleaf;
246
247 assert(dnode);
248 if (xpath_fmt) {
249 va_list ap;
250 char xpath[XPATH_MAXLEN];
251
252 va_start(ap, xpath_fmt);
253 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
254 va_end(ap);
255 dnode = yang_dnode_get(dnode, xpath);
256 YANG_DNODE_GET_ASSERT(dnode, xpath);
257 }
258
259 dleaf = (const struct lyd_node_leaf_list *)dnode;
260 assert(dleaf->value_type == LY_TYPE_ENUM);
261 return dleaf->value.enm->value;
262}
263
264int yang_get_default_enum(const char *xpath_fmt, ...)
265{
266 char xpath[XPATH_MAXLEN];
267 const char *value;
268 va_list ap;
269
270 va_start(ap, xpath_fmt);
271 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
272 va_end(ap);
273
274 value = yang_get_default_value(xpath);
275 return yang_str2enum(xpath, value);
276}
277
278/*
279 * Primitive type: int8.
280 */
281int8_t yang_str2int8(const char *value)
282{
283 return strtol(value, NULL, 10);
284}
285
286struct yang_data *yang_data_new_int8(const char *xpath, int8_t value)
287{
288 char value_str[BUFSIZ];
289
290 snprintf(value_str, sizeof(value_str), "%d", value);
291 return yang_data_new(xpath, value_str);
292}
293
294int8_t yang_dnode_get_int8(const struct lyd_node *dnode, const char *xpath_fmt,
295 ...)
296{
297 const struct lyd_node_leaf_list *dleaf;
298
299 assert(dnode);
300 if (xpath_fmt) {
301 va_list ap;
302 char xpath[XPATH_MAXLEN];
303
304 va_start(ap, xpath_fmt);
305 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
306 va_end(ap);
307 dnode = yang_dnode_get(dnode, xpath);
308 YANG_DNODE_GET_ASSERT(dnode, xpath);
309 }
310
311 dleaf = (const struct lyd_node_leaf_list *)dnode;
312 assert(dleaf->value_type == LY_TYPE_INT8);
313 return dleaf->value.int8;
314}
315
316int8_t yang_get_default_int8(const char *xpath_fmt, ...)
317{
318 char xpath[XPATH_MAXLEN];
319 const char *value;
320 va_list ap;
321
322 va_start(ap, xpath_fmt);
323 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
324 va_end(ap);
325
326 value = yang_get_default_value(xpath);
327 return yang_str2int8(value);
328}
329
330/*
331 * Primitive type: int16.
332 */
333int16_t yang_str2int16(const char *value)
334{
335 return strtol(value, NULL, 10);
336}
337
338struct yang_data *yang_data_new_int16(const char *xpath, int16_t value)
339{
340 char value_str[BUFSIZ];
341
342 snprintf(value_str, sizeof(value_str), "%d", value);
343 return yang_data_new(xpath, value_str);
344}
345
346int16_t yang_dnode_get_int16(const struct lyd_node *dnode,
347 const char *xpath_fmt, ...)
348{
349 const struct lyd_node_leaf_list *dleaf;
350
351 assert(dnode);
352 if (xpath_fmt) {
353 va_list ap;
354 char xpath[XPATH_MAXLEN];
355
356 va_start(ap, xpath_fmt);
357 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
358 va_end(ap);
359 dnode = yang_dnode_get(dnode, xpath);
360 YANG_DNODE_GET_ASSERT(dnode, xpath);
361 }
362
363 dleaf = (const struct lyd_node_leaf_list *)dnode;
364 assert(dleaf->value_type == LY_TYPE_INT16);
365 return dleaf->value.int16;
366}
367
368int16_t yang_get_default_int16(const char *xpath_fmt, ...)
369{
370 char xpath[XPATH_MAXLEN];
371 const char *value;
372 va_list ap;
373
374 va_start(ap, xpath_fmt);
375 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
376 va_end(ap);
377
378 value = yang_get_default_value(xpath);
379 return yang_str2int16(value);
380}
381
382/*
383 * Primitive type: int32.
384 */
385int32_t yang_str2int32(const char *value)
386{
387 return strtol(value, NULL, 10);
388}
389
390struct yang_data *yang_data_new_int32(const char *xpath, int32_t value)
391{
392 char value_str[BUFSIZ];
393
394 snprintf(value_str, sizeof(value_str), "%d", value);
395 return yang_data_new(xpath, value_str);
396}
397
398int32_t yang_dnode_get_int32(const struct lyd_node *dnode,
399 const char *xpath_fmt, ...)
400{
401 const struct lyd_node_leaf_list *dleaf;
402
403 assert(dnode);
404 if (xpath_fmt) {
405 va_list ap;
406 char xpath[XPATH_MAXLEN];
407
408 va_start(ap, xpath_fmt);
409 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
410 va_end(ap);
411 dnode = yang_dnode_get(dnode, xpath);
412 YANG_DNODE_GET_ASSERT(dnode, xpath);
413 }
414
415 dleaf = (const struct lyd_node_leaf_list *)dnode;
416 assert(dleaf->value_type == LY_TYPE_INT32);
417 return dleaf->value.int32;
418}
419
420int32_t yang_get_default_int32(const char *xpath_fmt, ...)
421{
422 char xpath[XPATH_MAXLEN];
423 const char *value;
424 va_list ap;
425
426 va_start(ap, xpath_fmt);
427 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
428 va_end(ap);
429
430 value = yang_get_default_value(xpath);
431 return yang_str2int32(value);
432}
433
434/*
435 * Primitive type: int64.
436 */
437int64_t yang_str2int64(const char *value)
438{
439 return strtoll(value, NULL, 10);
440}
441
442struct yang_data *yang_data_new_int64(const char *xpath, int64_t value)
443{
444 char value_str[BUFSIZ];
445
446 snprintf(value_str, sizeof(value_str), "%" PRId64, value);
447 return yang_data_new(xpath, value_str);
448}
449
450int64_t yang_dnode_get_int64(const struct lyd_node *dnode,
451 const char *xpath_fmt, ...)
452{
453 const struct lyd_node_leaf_list *dleaf;
454
455 assert(dnode);
456 if (xpath_fmt) {
457 va_list ap;
458 char xpath[XPATH_MAXLEN];
459
460 va_start(ap, xpath_fmt);
461 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
462 va_end(ap);
463 dnode = yang_dnode_get(dnode, xpath);
464 YANG_DNODE_GET_ASSERT(dnode, xpath);
465 }
466
467 dleaf = (const struct lyd_node_leaf_list *)dnode;
468 assert(dleaf->value_type == LY_TYPE_INT64);
469 return dleaf->value.int64;
470}
471
472int64_t yang_get_default_int64(const char *xpath_fmt, ...)
473{
474 char xpath[XPATH_MAXLEN];
475 const char *value;
476 va_list ap;
477
478 va_start(ap, xpath_fmt);
479 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
480 va_end(ap);
481
482 value = yang_get_default_value(xpath);
483 return yang_str2int64(value);
484}
485
486/*
487 * Primitive type: uint8.
488 */
489uint8_t yang_str2uint8(const char *value)
490{
491 return strtoul(value, NULL, 10);
492}
493
494struct yang_data *yang_data_new_uint8(const char *xpath, uint8_t value)
495{
496 char value_str[BUFSIZ];
497
498 snprintf(value_str, sizeof(value_str), "%u", value);
499 return yang_data_new(xpath, value_str);
500}
501
502uint8_t yang_dnode_get_uint8(const struct lyd_node *dnode,
503 const char *xpath_fmt, ...)
504{
505 const struct lyd_node_leaf_list *dleaf;
506
507 assert(dnode);
508 if (xpath_fmt) {
509 va_list ap;
510 char xpath[XPATH_MAXLEN];
511
512 va_start(ap, xpath_fmt);
513 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
514 va_end(ap);
515 dnode = yang_dnode_get(dnode, xpath);
516 YANG_DNODE_GET_ASSERT(dnode, xpath);
517 }
518
519 dleaf = (const struct lyd_node_leaf_list *)dnode;
520 assert(dleaf->value_type == LY_TYPE_UINT8);
521 return dleaf->value.uint8;
522}
523
524uint8_t yang_get_default_uint8(const char *xpath_fmt, ...)
525{
526 char xpath[XPATH_MAXLEN];
527 const char *value;
528 va_list ap;
529
530 va_start(ap, xpath_fmt);
531 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
532 va_end(ap);
533
534 value = yang_get_default_value(xpath);
535 return yang_str2uint8(value);
536}
537
538/*
539 * Primitive type: uint16.
540 */
541uint16_t yang_str2uint16(const char *value)
542{
543 return strtoul(value, NULL, 10);
544}
545
546struct yang_data *yang_data_new_uint16(const char *xpath, uint16_t value)
547{
548 char value_str[BUFSIZ];
549
550 snprintf(value_str, sizeof(value_str), "%u", value);
551 return yang_data_new(xpath, value_str);
552}
553
554uint16_t yang_dnode_get_uint16(const struct lyd_node *dnode,
555 const char *xpath_fmt, ...)
556{
557 const struct lyd_node_leaf_list *dleaf;
558
559 assert(dnode);
560 if (xpath_fmt) {
561 va_list ap;
562 char xpath[XPATH_MAXLEN];
563
564 va_start(ap, xpath_fmt);
565 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
566 va_end(ap);
567 dnode = yang_dnode_get(dnode, xpath);
568 YANG_DNODE_GET_ASSERT(dnode, xpath);
569 }
570
571 dleaf = (const struct lyd_node_leaf_list *)dnode;
572 assert(dleaf->value_type == LY_TYPE_UINT16);
573 return dleaf->value.uint16;
574}
575
576uint16_t yang_get_default_uint16(const char *xpath_fmt, ...)
577{
578 char xpath[XPATH_MAXLEN];
579 const char *value;
580 va_list ap;
581
582 va_start(ap, xpath_fmt);
583 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
584 va_end(ap);
585
586 value = yang_get_default_value(xpath);
587 return yang_str2uint16(value);
588}
589
590/*
591 * Primitive type: uint32.
592 */
593uint32_t yang_str2uint32(const char *value)
594{
595 return strtoul(value, NULL, 10);
596}
597
598struct yang_data *yang_data_new_uint32(const char *xpath, uint32_t value)
599{
600 char value_str[BUFSIZ];
601
602 snprintf(value_str, sizeof(value_str), "%u", value);
603 return yang_data_new(xpath, value_str);
604}
605
606uint32_t yang_dnode_get_uint32(const struct lyd_node *dnode,
607 const char *xpath_fmt, ...)
608{
609 const struct lyd_node_leaf_list *dleaf;
610
611 assert(dnode);
612 if (xpath_fmt) {
613 va_list ap;
614 char xpath[XPATH_MAXLEN];
615
616 va_start(ap, xpath_fmt);
617 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
618 va_end(ap);
619 dnode = yang_dnode_get(dnode, xpath);
620 YANG_DNODE_GET_ASSERT(dnode, xpath);
621 }
622
623 dleaf = (const struct lyd_node_leaf_list *)dnode;
624 assert(dleaf->value_type == LY_TYPE_UINT32);
625 return dleaf->value.uint32;
626}
627
628uint32_t yang_get_default_uint32(const char *xpath_fmt, ...)
629{
630 char xpath[XPATH_MAXLEN];
631 const char *value;
632 va_list ap;
633
634 va_start(ap, xpath_fmt);
635 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
636 va_end(ap);
637
638 value = yang_get_default_value(xpath);
639 return yang_str2uint32(value);
640}
641
642/*
643 * Primitive type: uint64.
644 */
645uint64_t yang_str2uint64(const char *value)
646{
647 return strtoull(value, NULL, 10);
648}
649
650struct yang_data *yang_data_new_uint64(const char *xpath, uint64_t value)
651{
652 char value_str[BUFSIZ];
653
654 snprintf(value_str, sizeof(value_str), "%" PRIu64, value);
655 return yang_data_new(xpath, value_str);
656}
657
658uint64_t yang_dnode_get_uint64(const struct lyd_node *dnode,
659 const char *xpath_fmt, ...)
660{
661 const struct lyd_node_leaf_list *dleaf;
662
663 assert(dnode);
664 if (xpath_fmt) {
665 va_list ap;
666 char xpath[XPATH_MAXLEN];
667
668 va_start(ap, xpath_fmt);
669 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
670 va_end(ap);
671 dnode = yang_dnode_get(dnode, xpath);
672 YANG_DNODE_GET_ASSERT(dnode, xpath);
673 }
674
675 dleaf = (const struct lyd_node_leaf_list *)dnode;
676 assert(dleaf->value_type == LY_TYPE_UINT64);
677 return dleaf->value.uint64;
678}
679
680uint64_t yang_get_default_uint64(const char *xpath_fmt, ...)
681{
682 char xpath[XPATH_MAXLEN];
683 const char *value;
684 va_list ap;
685
686 va_start(ap, xpath_fmt);
687 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
688 va_end(ap);
689
690 value = yang_get_default_value(xpath);
691 return yang_str2uint64(value);
692}
693
694/*
695 * Primitive type: string.
696 *
697 * All string wrappers can be used with non-string types.
698 */
699struct yang_data *yang_data_new_string(const char *xpath, const char *value)
700{
701 return yang_data_new(xpath, value);
702}
703
704const char *yang_dnode_get_string(const struct lyd_node *dnode,
705 const char *xpath_fmt, ...)
706{
707 const struct lyd_node_leaf_list *dleaf;
708
709 assert(dnode);
710 if (xpath_fmt) {
711 va_list ap;
712 char xpath[XPATH_MAXLEN];
713
714 va_start(ap, xpath_fmt);
715 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
716 va_end(ap);
717 dnode = yang_dnode_get(dnode, xpath);
718 YANG_DNODE_GET_ASSERT(dnode, xpath);
719 }
720
721 dleaf = (const struct lyd_node_leaf_list *)dnode;
722 return dleaf->value_str;
723}
724
725void yang_dnode_get_string_buf(char *buf, size_t size,
726 const struct lyd_node *dnode,
727 const char *xpath_fmt, ...)
728{
729 const struct lyd_node_leaf_list *dleaf;
730
731 assert(dnode);
732 if (xpath_fmt) {
733 va_list ap;
734 char xpath[XPATH_MAXLEN];
735
736 va_start(ap, xpath_fmt);
737 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
738 va_end(ap);
739 dnode = yang_dnode_get(dnode, xpath);
740 YANG_DNODE_GET_ASSERT(dnode, xpath);
741 }
742
743 dleaf = (const struct lyd_node_leaf_list *)dnode;
744 if (strlcpy(buf, dleaf->value_str, size) >= size) {
745 char xpath[XPATH_MAXLEN];
746
747 yang_dnode_get_path(dnode, xpath, sizeof(xpath));
748 flog_warn(EC_LIB_YANG_DATA_TRUNCATED,
749 "%s: value was truncated [xpath %s]", __func__,
750 xpath);
751 }
752}
753
754const char *yang_get_default_string(const char *xpath_fmt, ...)
755{
756 char xpath[XPATH_MAXLEN];
757 va_list ap;
758
759 va_start(ap, xpath_fmt);
760 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
761 va_end(ap);
762
763 return yang_get_default_value(xpath);
764}
765
766void yang_get_default_string_buf(char *buf, size_t size, const char *xpath_fmt,
767 ...)
768{
769 char xpath[XPATH_MAXLEN];
770 const char *value;
771 va_list ap;
772
773 va_start(ap, xpath_fmt);
774 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
775 va_end(ap);
776
777 value = yang_get_default_value(xpath);
778 if (strlcpy(buf, value, size) >= size)
779 flog_warn(EC_LIB_YANG_DATA_TRUNCATED,
780 "%s: value was truncated [xpath %s]", __func__,
781 xpath);
782}
783
eed84494
RW
784/*
785 * Derived type: IP prefix.
786 */
787void yang_str2prefix(const char *value, union prefixptr prefix)
788{
789 (void)str2prefix(value, prefix.p);
790 apply_mask(prefix.p);
791}
792
793struct yang_data *yang_data_new_prefix(const char *xpath,
794 union prefixconstptr prefix)
795{
796 char value_str[PREFIX2STR_BUFFER];
797
798 (void)prefix2str(prefix.p, value_str, sizeof(value_str));
799 return yang_data_new(xpath, value_str);
800}
801
46fcb2df 802void yang_dnode_get_prefix(struct prefix *prefix, const struct lyd_node *dnode,
eed84494
RW
803 const char *xpath_fmt, ...)
804{
805 const struct lyd_node_leaf_list *dleaf;
806
807 assert(dnode);
808 if (xpath_fmt) {
809 va_list ap;
810 char xpath[XPATH_MAXLEN];
811
812 va_start(ap, xpath_fmt);
813 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
814 va_end(ap);
815 dnode = yang_dnode_get(dnode, xpath);
816 YANG_DNODE_GET_ASSERT(dnode, xpath);
817 }
818
46fcb2df
RZ
819 /*
820 * Initialize prefix to avoid static analyzer complaints about
821 * uninitialized memory.
822 */
823 memset(prefix, 0, sizeof(*prefix));
824
eed84494
RW
825 dleaf = (const struct lyd_node_leaf_list *)dnode;
826 assert(dleaf->value_type == LY_TYPE_STRING);
46fcb2df 827 (void)str2prefix(dleaf->value_str, prefix);
eed84494
RW
828}
829
830void yang_get_default_prefix(union prefixptr var, const char *xpath_fmt, ...)
831{
832 char xpath[XPATH_MAXLEN];
833 const char *value;
834 va_list ap;
835
836 va_start(ap, xpath_fmt);
837 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
838 va_end(ap);
839
840 value = yang_get_default_value(xpath);
841 yang_str2prefix(value, var);
842}
843
1c2facd1
RW
844/*
845 * Derived type: ipv4.
846 */
847void yang_str2ipv4(const char *value, struct in_addr *addr)
848{
849 (void)inet_pton(AF_INET, value, addr);
850}
851
852struct yang_data *yang_data_new_ipv4(const char *xpath,
853 const struct in_addr *addr)
854{
855 char value_str[INET_ADDRSTRLEN];
856
857 (void)inet_ntop(AF_INET, addr, value_str, sizeof(value_str));
858 return yang_data_new(xpath, value_str);
859}
860
861void yang_dnode_get_ipv4(struct in_addr *addr, const struct lyd_node *dnode,
862 const char *xpath_fmt, ...)
863{
864 const struct lyd_node_leaf_list *dleaf;
865
866 assert(dnode);
867 if (xpath_fmt) {
868 va_list ap;
869 char xpath[XPATH_MAXLEN];
870
871 va_start(ap, xpath_fmt);
872 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
873 va_end(ap);
874 dnode = yang_dnode_get(dnode, xpath);
875 YANG_DNODE_GET_ASSERT(dnode, xpath);
876 }
877
878 dleaf = (const struct lyd_node_leaf_list *)dnode;
879 assert(dleaf->value_type == LY_TYPE_STRING);
1b8de275 880 (void)inet_pton(AF_INET, dleaf->value_str, addr);
1c2facd1
RW
881}
882
883void yang_get_default_ipv4(struct in_addr *var, const char *xpath_fmt, ...)
884{
885 char xpath[XPATH_MAXLEN];
886 const char *value;
887 va_list ap;
888
889 va_start(ap, xpath_fmt);
890 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
891 va_end(ap);
892
893 value = yang_get_default_value(xpath);
894 yang_str2ipv4(value, var);
895}
896
897/*
898 * Derived type: ipv4p.
899 */
900void yang_str2ipv4p(const char *value, union prefixptr prefix)
901{
902 struct prefix_ipv4 *prefix4 = prefix.p4;
903
904 (void)str2prefix_ipv4(value, prefix4);
905 apply_mask_ipv4(prefix4);
906}
907
908struct yang_data *yang_data_new_ipv4p(const char *xpath,
70065793 909 union prefixconstptr prefix)
1c2facd1
RW
910{
911 char value_str[PREFIX2STR_BUFFER];
912
913 (void)prefix2str(prefix.p, value_str, sizeof(value_str));
914 return yang_data_new(xpath, value_str);
915}
916
917void yang_dnode_get_ipv4p(union prefixptr prefix, const struct lyd_node *dnode,
918 const char *xpath_fmt, ...)
919{
920 const struct lyd_node_leaf_list *dleaf;
921 struct prefix_ipv4 *prefix4 = prefix.p4;
922
923 assert(dnode);
924 if (xpath_fmt) {
925 va_list ap;
926 char xpath[XPATH_MAXLEN];
927
928 va_start(ap, xpath_fmt);
929 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
930 va_end(ap);
931 dnode = yang_dnode_get(dnode, xpath);
932 YANG_DNODE_GET_ASSERT(dnode, xpath);
933 }
934
935 dleaf = (const struct lyd_node_leaf_list *)dnode;
936 assert(dleaf->value_type == LY_TYPE_STRING);
1b8de275 937 (void)str2prefix_ipv4(dleaf->value_str, prefix4);
1c2facd1
RW
938}
939
940void yang_get_default_ipv4p(union prefixptr var, const char *xpath_fmt, ...)
941{
942 char xpath[XPATH_MAXLEN];
943 const char *value;
944 va_list ap;
945
946 va_start(ap, xpath_fmt);
947 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
948 va_end(ap);
949
950 value = yang_get_default_value(xpath);
951 yang_str2ipv4p(value, var);
952}
953
954/*
955 * Derived type: ipv6.
956 */
957void yang_str2ipv6(const char *value, struct in6_addr *addr)
958{
959 (void)inet_pton(AF_INET6, value, addr);
960}
961
962struct yang_data *yang_data_new_ipv6(const char *xpath,
963 const struct in6_addr *addr)
964{
965 char value_str[INET6_ADDRSTRLEN];
966
967 (void)inet_ntop(AF_INET6, addr, value_str, sizeof(value_str));
968 return yang_data_new(xpath, value_str);
969}
970
971void yang_dnode_get_ipv6(struct in6_addr *addr, const struct lyd_node *dnode,
972 const char *xpath_fmt, ...)
973{
974 const struct lyd_node_leaf_list *dleaf;
975
976 assert(dnode);
977 if (xpath_fmt) {
978 va_list ap;
979 char xpath[XPATH_MAXLEN];
980
981 va_start(ap, xpath_fmt);
982 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
983 va_end(ap);
984 dnode = yang_dnode_get(dnode, xpath);
985 YANG_DNODE_GET_ASSERT(dnode, xpath);
986 }
987
988 dleaf = (const struct lyd_node_leaf_list *)dnode;
989 assert(dleaf->value_type == LY_TYPE_STRING);
1b8de275 990 (void)inet_pton(AF_INET6, dleaf->value_str, addr);
1c2facd1
RW
991}
992
993void yang_get_default_ipv6(struct in6_addr *var, const char *xpath_fmt, ...)
994{
995 char xpath[XPATH_MAXLEN];
996 const char *value;
997 va_list ap;
998
999 va_start(ap, xpath_fmt);
1000 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
1001 va_end(ap);
1002
1003 value = yang_get_default_value(xpath);
1004 yang_str2ipv6(value, var);
1005}
1006
1007/*
1008 * Derived type: ipv6p.
1009 */
1010void yang_str2ipv6p(const char *value, union prefixptr prefix)
1011{
1012 struct prefix_ipv6 *prefix6 = prefix.p6;
1013
1014 (void)str2prefix_ipv6(value, prefix6);
1015 apply_mask_ipv6(prefix6);
1016}
1017
1018struct yang_data *yang_data_new_ipv6p(const char *xpath,
70065793 1019 union prefixconstptr prefix)
1c2facd1
RW
1020{
1021 char value_str[PREFIX2STR_BUFFER];
1022
1023 (void)prefix2str(prefix.p, value_str, sizeof(value_str));
1024 return yang_data_new(xpath, value_str);
1025}
1026
1027void yang_dnode_get_ipv6p(union prefixptr prefix, const struct lyd_node *dnode,
1028 const char *xpath_fmt, ...)
1029{
1030 const struct lyd_node_leaf_list *dleaf;
1031 struct prefix_ipv6 *prefix6 = prefix.p6;
1032
1033 assert(dnode);
1034 if (xpath_fmt) {
1035 va_list ap;
1036 char xpath[XPATH_MAXLEN];
1037
1038 va_start(ap, xpath_fmt);
1039 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
1040 va_end(ap);
1041 dnode = yang_dnode_get(dnode, xpath);
1042 YANG_DNODE_GET_ASSERT(dnode, xpath);
1043 }
1044
1045 dleaf = (const struct lyd_node_leaf_list *)dnode;
1046 assert(dleaf->value_type == LY_TYPE_STRING);
1b8de275 1047 (void)str2prefix_ipv6(dleaf->value_str, prefix6);
1c2facd1
RW
1048}
1049
1050void yang_get_default_ipv6p(union prefixptr var, const char *xpath_fmt, ...)
1051{
1052 char xpath[XPATH_MAXLEN];
1053 const char *value;
1054 va_list ap;
1055
1056 va_start(ap, xpath_fmt);
1057 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
1058 va_end(ap);
1059
1060 value = yang_get_default_value(xpath);
1061 yang_str2ipv6p(value, var);
1062}
b0584ad3
QY
1063
1064/*
1065 * Derived type: ip.
1066 */
1067void yang_str2ip(const char *value, struct ipaddr *ip)
1068{
1069 (void)str2ipaddr(value, ip);
1070}
1071
1072struct yang_data *yang_data_new_ip(const char *xpath, const struct ipaddr *addr)
1073{
1074 size_t sz = IS_IPADDR_V4(addr) ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN;
1075 char value_str[sz];
1076
1077 ipaddr2str(addr, value_str, sizeof(value_str));
1078 return yang_data_new(xpath, value_str);
1079}
1080
1081void yang_dnode_get_ip(struct ipaddr *addr, const struct lyd_node *dnode,
1082 const char *xpath_fmt, ...)
1083{
1084 const struct lyd_node_leaf_list *dleaf;
1085
1086 assert(dnode);
1087 if (xpath_fmt) {
1088 va_list ap;
1089 char xpath[XPATH_MAXLEN];
1090
1091 va_start(ap, xpath_fmt);
1092 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
1093 va_end(ap);
1094 dnode = yang_dnode_get(dnode, xpath);
1095 YANG_DNODE_GET_ASSERT(dnode, xpath);
1096 }
1097
1098 dleaf = (const struct lyd_node_leaf_list *)dnode;
1099 assert(dleaf->value_type == LY_TYPE_STRING);
1100 (void)str2ipaddr(dleaf->value_str, addr);
1101}
1102
1103void yang_get_default_ip(struct ipaddr *var, const char *xpath_fmt, ...)
1104{
1105 char xpath[XPATH_MAXLEN];
1106 const char *value;
1107 va_list ap;
1108
1109 va_start(ap, xpath_fmt);
1110 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
1111 va_end(ap);
1112
1113 value = yang_get_default_value(xpath);
1114 yang_str2ip(value, var);
1115}