]> git.proxmox.com Git - mirror_frr.git/blob - lib/yang_wrappers.c
Merge pull request #3320 from mjstapp/fix_dp_ecmp
[mirror_frr.git] / lib / yang_wrappers.c
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
26 static 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 */
58 bool yang_str2bool(const char *value)
59 {
60 return strmatch(value, "true");
61 }
62
63 struct yang_data *yang_data_new_bool(const char *xpath, bool value)
64 {
65 return yang_data_new(xpath, (value == true) ? "true" : "false");
66 }
67
68 bool 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
90 bool 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 */
107 double 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
122 struct 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
130 double 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
153 double 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 */
170 int yang_str2enum(const char *xpath, const char *value)
171 {
172 const struct lys_node *snode;
173 const struct lys_node_leaf *sleaf;
174 const struct lys_type_info_enums *enums;
175
176 snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0);
177 if (snode == NULL) {
178 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
179 "%s: unknown data path: %s", __func__, xpath);
180 zlog_backtrace(LOG_ERR);
181 abort();
182 }
183
184 sleaf = (const struct lys_node_leaf *)snode;
185 enums = &sleaf->type.info.enums;
186 for (unsigned int i = 0; i < enums->count; i++) {
187 const struct lys_type_enum *enm = &enums->enm[i];
188
189 if (strmatch(value, enm->name))
190 return enm->value;
191 }
192
193 flog_err(EC_LIB_YANG_DATA_CONVERT,
194 "%s: couldn't convert string to enum [xpath %s]", __func__,
195 xpath);
196 zlog_backtrace(LOG_ERR);
197 abort();
198 }
199
200 struct yang_data *yang_data_new_enum(const char *xpath, int value)
201 {
202 const struct lys_node *snode;
203 const struct lys_node_leaf *sleaf;
204 const struct lys_type *type;
205 const struct lys_type_info_enums *enums;
206
207 snode = ly_ctx_get_node(ly_native_ctx, NULL, xpath, 0);
208 if (snode == NULL) {
209 flog_err(EC_LIB_YANG_UNKNOWN_DATA_PATH,
210 "%s: unknown data path: %s", __func__, xpath);
211 zlog_backtrace(LOG_ERR);
212 abort();
213 }
214
215 sleaf = (const struct lys_node_leaf *)snode;
216 type = &sleaf->type;
217 enums = &type->info.enums;
218 while (enums->count == 0 && type->der) {
219 type = &type->der->type;
220 enums = &type->info.enums;
221 }
222 for (unsigned int i = 0; i < enums->count; i++) {
223 const struct lys_type_enum *enm = &enums->enm[i];
224
225 if (value == enm->value)
226 return yang_data_new(xpath, enm->name);
227 }
228
229 flog_err(EC_LIB_YANG_DATA_CONVERT,
230 "%s: couldn't convert enum to string [xpath %s]", __func__,
231 xpath);
232 zlog_backtrace(LOG_ERR);
233 abort();
234 }
235
236 int yang_dnode_get_enum(const struct lyd_node *dnode, const char *xpath_fmt,
237 ...)
238 {
239 const struct lyd_node_leaf_list *dleaf;
240
241 assert(dnode);
242 if (xpath_fmt) {
243 va_list ap;
244 char xpath[XPATH_MAXLEN];
245
246 va_start(ap, xpath_fmt);
247 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
248 va_end(ap);
249 dnode = yang_dnode_get(dnode, xpath);
250 YANG_DNODE_GET_ASSERT(dnode, xpath);
251 }
252
253 dleaf = (const struct lyd_node_leaf_list *)dnode;
254 assert(dleaf->value_type == LY_TYPE_ENUM);
255 return dleaf->value.enm->value;
256 }
257
258 int yang_get_default_enum(const char *xpath_fmt, ...)
259 {
260 char xpath[XPATH_MAXLEN];
261 const char *value;
262 va_list ap;
263
264 va_start(ap, xpath_fmt);
265 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
266 va_end(ap);
267
268 value = yang_get_default_value(xpath);
269 return yang_str2enum(xpath, value);
270 }
271
272 /*
273 * Primitive type: int8.
274 */
275 int8_t yang_str2int8(const char *value)
276 {
277 return strtol(value, NULL, 10);
278 }
279
280 struct yang_data *yang_data_new_int8(const char *xpath, int8_t value)
281 {
282 char value_str[BUFSIZ];
283
284 snprintf(value_str, sizeof(value_str), "%d", value);
285 return yang_data_new(xpath, value_str);
286 }
287
288 int8_t yang_dnode_get_int8(const struct lyd_node *dnode, const char *xpath_fmt,
289 ...)
290 {
291 const struct lyd_node_leaf_list *dleaf;
292
293 assert(dnode);
294 if (xpath_fmt) {
295 va_list ap;
296 char xpath[XPATH_MAXLEN];
297
298 va_start(ap, xpath_fmt);
299 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
300 va_end(ap);
301 dnode = yang_dnode_get(dnode, xpath);
302 YANG_DNODE_GET_ASSERT(dnode, xpath);
303 }
304
305 dleaf = (const struct lyd_node_leaf_list *)dnode;
306 assert(dleaf->value_type == LY_TYPE_INT8);
307 return dleaf->value.int8;
308 }
309
310 int8_t yang_get_default_int8(const char *xpath_fmt, ...)
311 {
312 char xpath[XPATH_MAXLEN];
313 const char *value;
314 va_list ap;
315
316 va_start(ap, xpath_fmt);
317 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
318 va_end(ap);
319
320 value = yang_get_default_value(xpath);
321 return yang_str2int8(value);
322 }
323
324 /*
325 * Primitive type: int16.
326 */
327 int16_t yang_str2int16(const char *value)
328 {
329 return strtol(value, NULL, 10);
330 }
331
332 struct yang_data *yang_data_new_int16(const char *xpath, int16_t value)
333 {
334 char value_str[BUFSIZ];
335
336 snprintf(value_str, sizeof(value_str), "%d", value);
337 return yang_data_new(xpath, value_str);
338 }
339
340 int16_t yang_dnode_get_int16(const struct lyd_node *dnode,
341 const char *xpath_fmt, ...)
342 {
343 const struct lyd_node_leaf_list *dleaf;
344
345 assert(dnode);
346 if (xpath_fmt) {
347 va_list ap;
348 char xpath[XPATH_MAXLEN];
349
350 va_start(ap, xpath_fmt);
351 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
352 va_end(ap);
353 dnode = yang_dnode_get(dnode, xpath);
354 YANG_DNODE_GET_ASSERT(dnode, xpath);
355 }
356
357 dleaf = (const struct lyd_node_leaf_list *)dnode;
358 assert(dleaf->value_type == LY_TYPE_INT16);
359 return dleaf->value.int16;
360 }
361
362 int16_t yang_get_default_int16(const char *xpath_fmt, ...)
363 {
364 char xpath[XPATH_MAXLEN];
365 const char *value;
366 va_list ap;
367
368 va_start(ap, xpath_fmt);
369 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
370 va_end(ap);
371
372 value = yang_get_default_value(xpath);
373 return yang_str2int16(value);
374 }
375
376 /*
377 * Primitive type: int32.
378 */
379 int32_t yang_str2int32(const char *value)
380 {
381 return strtol(value, NULL, 10);
382 }
383
384 struct yang_data *yang_data_new_int32(const char *xpath, int32_t value)
385 {
386 char value_str[BUFSIZ];
387
388 snprintf(value_str, sizeof(value_str), "%d", value);
389 return yang_data_new(xpath, value_str);
390 }
391
392 int32_t yang_dnode_get_int32(const struct lyd_node *dnode,
393 const char *xpath_fmt, ...)
394 {
395 const struct lyd_node_leaf_list *dleaf;
396
397 assert(dnode);
398 if (xpath_fmt) {
399 va_list ap;
400 char xpath[XPATH_MAXLEN];
401
402 va_start(ap, xpath_fmt);
403 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
404 va_end(ap);
405 dnode = yang_dnode_get(dnode, xpath);
406 YANG_DNODE_GET_ASSERT(dnode, xpath);
407 }
408
409 dleaf = (const struct lyd_node_leaf_list *)dnode;
410 assert(dleaf->value_type == LY_TYPE_INT32);
411 return dleaf->value.int32;
412 }
413
414 int32_t yang_get_default_int32(const char *xpath_fmt, ...)
415 {
416 char xpath[XPATH_MAXLEN];
417 const char *value;
418 va_list ap;
419
420 va_start(ap, xpath_fmt);
421 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
422 va_end(ap);
423
424 value = yang_get_default_value(xpath);
425 return yang_str2int32(value);
426 }
427
428 /*
429 * Primitive type: int64.
430 */
431 int64_t yang_str2int64(const char *value)
432 {
433 return strtoll(value, NULL, 10);
434 }
435
436 struct yang_data *yang_data_new_int64(const char *xpath, int64_t value)
437 {
438 char value_str[BUFSIZ];
439
440 snprintf(value_str, sizeof(value_str), "%" PRId64, value);
441 return yang_data_new(xpath, value_str);
442 }
443
444 int64_t yang_dnode_get_int64(const struct lyd_node *dnode,
445 const char *xpath_fmt, ...)
446 {
447 const struct lyd_node_leaf_list *dleaf;
448
449 assert(dnode);
450 if (xpath_fmt) {
451 va_list ap;
452 char xpath[XPATH_MAXLEN];
453
454 va_start(ap, xpath_fmt);
455 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
456 va_end(ap);
457 dnode = yang_dnode_get(dnode, xpath);
458 YANG_DNODE_GET_ASSERT(dnode, xpath);
459 }
460
461 dleaf = (const struct lyd_node_leaf_list *)dnode;
462 assert(dleaf->value_type == LY_TYPE_INT64);
463 return dleaf->value.int64;
464 }
465
466 int64_t yang_get_default_int64(const char *xpath_fmt, ...)
467 {
468 char xpath[XPATH_MAXLEN];
469 const char *value;
470 va_list ap;
471
472 va_start(ap, xpath_fmt);
473 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
474 va_end(ap);
475
476 value = yang_get_default_value(xpath);
477 return yang_str2int64(value);
478 }
479
480 /*
481 * Primitive type: uint8.
482 */
483 uint8_t yang_str2uint8(const char *value)
484 {
485 return strtoul(value, NULL, 10);
486 }
487
488 struct yang_data *yang_data_new_uint8(const char *xpath, uint8_t value)
489 {
490 char value_str[BUFSIZ];
491
492 snprintf(value_str, sizeof(value_str), "%u", value);
493 return yang_data_new(xpath, value_str);
494 }
495
496 uint8_t yang_dnode_get_uint8(const struct lyd_node *dnode,
497 const char *xpath_fmt, ...)
498 {
499 const struct lyd_node_leaf_list *dleaf;
500
501 assert(dnode);
502 if (xpath_fmt) {
503 va_list ap;
504 char xpath[XPATH_MAXLEN];
505
506 va_start(ap, xpath_fmt);
507 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
508 va_end(ap);
509 dnode = yang_dnode_get(dnode, xpath);
510 YANG_DNODE_GET_ASSERT(dnode, xpath);
511 }
512
513 dleaf = (const struct lyd_node_leaf_list *)dnode;
514 assert(dleaf->value_type == LY_TYPE_UINT8);
515 return dleaf->value.uint8;
516 }
517
518 uint8_t yang_get_default_uint8(const char *xpath_fmt, ...)
519 {
520 char xpath[XPATH_MAXLEN];
521 const char *value;
522 va_list ap;
523
524 va_start(ap, xpath_fmt);
525 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
526 va_end(ap);
527
528 value = yang_get_default_value(xpath);
529 return yang_str2uint8(value);
530 }
531
532 /*
533 * Primitive type: uint16.
534 */
535 uint16_t yang_str2uint16(const char *value)
536 {
537 return strtoul(value, NULL, 10);
538 }
539
540 struct yang_data *yang_data_new_uint16(const char *xpath, uint16_t value)
541 {
542 char value_str[BUFSIZ];
543
544 snprintf(value_str, sizeof(value_str), "%u", value);
545 return yang_data_new(xpath, value_str);
546 }
547
548 uint16_t yang_dnode_get_uint16(const struct lyd_node *dnode,
549 const char *xpath_fmt, ...)
550 {
551 const struct lyd_node_leaf_list *dleaf;
552
553 assert(dnode);
554 if (xpath_fmt) {
555 va_list ap;
556 char xpath[XPATH_MAXLEN];
557
558 va_start(ap, xpath_fmt);
559 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
560 va_end(ap);
561 dnode = yang_dnode_get(dnode, xpath);
562 YANG_DNODE_GET_ASSERT(dnode, xpath);
563 }
564
565 dleaf = (const struct lyd_node_leaf_list *)dnode;
566 assert(dleaf->value_type == LY_TYPE_UINT16);
567 return dleaf->value.uint16;
568 }
569
570 uint16_t yang_get_default_uint16(const char *xpath_fmt, ...)
571 {
572 char xpath[XPATH_MAXLEN];
573 const char *value;
574 va_list ap;
575
576 va_start(ap, xpath_fmt);
577 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
578 va_end(ap);
579
580 value = yang_get_default_value(xpath);
581 return yang_str2uint16(value);
582 }
583
584 /*
585 * Primitive type: uint32.
586 */
587 uint32_t yang_str2uint32(const char *value)
588 {
589 return strtoul(value, NULL, 10);
590 }
591
592 struct yang_data *yang_data_new_uint32(const char *xpath, uint32_t value)
593 {
594 char value_str[BUFSIZ];
595
596 snprintf(value_str, sizeof(value_str), "%u", value);
597 return yang_data_new(xpath, value_str);
598 }
599
600 uint32_t yang_dnode_get_uint32(const struct lyd_node *dnode,
601 const char *xpath_fmt, ...)
602 {
603 const struct lyd_node_leaf_list *dleaf;
604
605 assert(dnode);
606 if (xpath_fmt) {
607 va_list ap;
608 char xpath[XPATH_MAXLEN];
609
610 va_start(ap, xpath_fmt);
611 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
612 va_end(ap);
613 dnode = yang_dnode_get(dnode, xpath);
614 YANG_DNODE_GET_ASSERT(dnode, xpath);
615 }
616
617 dleaf = (const struct lyd_node_leaf_list *)dnode;
618 assert(dleaf->value_type == LY_TYPE_UINT32);
619 return dleaf->value.uint32;
620 }
621
622 uint32_t yang_get_default_uint32(const char *xpath_fmt, ...)
623 {
624 char xpath[XPATH_MAXLEN];
625 const char *value;
626 va_list ap;
627
628 va_start(ap, xpath_fmt);
629 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
630 va_end(ap);
631
632 value = yang_get_default_value(xpath);
633 return yang_str2uint32(value);
634 }
635
636 /*
637 * Primitive type: uint64.
638 */
639 uint64_t yang_str2uint64(const char *value)
640 {
641 return strtoull(value, NULL, 10);
642 }
643
644 struct yang_data *yang_data_new_uint64(const char *xpath, uint64_t value)
645 {
646 char value_str[BUFSIZ];
647
648 snprintf(value_str, sizeof(value_str), "%" PRIu64, value);
649 return yang_data_new(xpath, value_str);
650 }
651
652 uint64_t yang_dnode_get_uint64(const struct lyd_node *dnode,
653 const char *xpath_fmt, ...)
654 {
655 const struct lyd_node_leaf_list *dleaf;
656
657 assert(dnode);
658 if (xpath_fmt) {
659 va_list ap;
660 char xpath[XPATH_MAXLEN];
661
662 va_start(ap, xpath_fmt);
663 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
664 va_end(ap);
665 dnode = yang_dnode_get(dnode, xpath);
666 YANG_DNODE_GET_ASSERT(dnode, xpath);
667 }
668
669 dleaf = (const struct lyd_node_leaf_list *)dnode;
670 assert(dleaf->value_type == LY_TYPE_UINT64);
671 return dleaf->value.uint64;
672 }
673
674 uint64_t yang_get_default_uint64(const char *xpath_fmt, ...)
675 {
676 char xpath[XPATH_MAXLEN];
677 const char *value;
678 va_list ap;
679
680 va_start(ap, xpath_fmt);
681 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
682 va_end(ap);
683
684 value = yang_get_default_value(xpath);
685 return yang_str2uint64(value);
686 }
687
688 /*
689 * Primitive type: string.
690 *
691 * All string wrappers can be used with non-string types.
692 */
693 struct yang_data *yang_data_new_string(const char *xpath, const char *value)
694 {
695 return yang_data_new(xpath, value);
696 }
697
698 const char *yang_dnode_get_string(const struct lyd_node *dnode,
699 const char *xpath_fmt, ...)
700 {
701 const struct lyd_node_leaf_list *dleaf;
702
703 assert(dnode);
704 if (xpath_fmt) {
705 va_list ap;
706 char xpath[XPATH_MAXLEN];
707
708 va_start(ap, xpath_fmt);
709 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
710 va_end(ap);
711 dnode = yang_dnode_get(dnode, xpath);
712 YANG_DNODE_GET_ASSERT(dnode, xpath);
713 }
714
715 dleaf = (const struct lyd_node_leaf_list *)dnode;
716 return dleaf->value_str;
717 }
718
719 void yang_dnode_get_string_buf(char *buf, size_t size,
720 const struct lyd_node *dnode,
721 const char *xpath_fmt, ...)
722 {
723 const struct lyd_node_leaf_list *dleaf;
724
725 assert(dnode);
726 if (xpath_fmt) {
727 va_list ap;
728 char xpath[XPATH_MAXLEN];
729
730 va_start(ap, xpath_fmt);
731 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
732 va_end(ap);
733 dnode = yang_dnode_get(dnode, xpath);
734 YANG_DNODE_GET_ASSERT(dnode, xpath);
735 }
736
737 dleaf = (const struct lyd_node_leaf_list *)dnode;
738 if (strlcpy(buf, dleaf->value_str, size) >= size) {
739 char xpath[XPATH_MAXLEN];
740
741 yang_dnode_get_path(dnode, xpath, sizeof(xpath));
742 flog_warn(EC_LIB_YANG_DATA_TRUNCATED,
743 "%s: value was truncated [xpath %s]", __func__,
744 xpath);
745 }
746 }
747
748 const char *yang_get_default_string(const char *xpath_fmt, ...)
749 {
750 char xpath[XPATH_MAXLEN];
751 va_list ap;
752
753 va_start(ap, xpath_fmt);
754 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
755 va_end(ap);
756
757 return yang_get_default_value(xpath);
758 }
759
760 void yang_get_default_string_buf(char *buf, size_t size, const char *xpath_fmt,
761 ...)
762 {
763 char xpath[XPATH_MAXLEN];
764 const char *value;
765 va_list ap;
766
767 va_start(ap, xpath_fmt);
768 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
769 va_end(ap);
770
771 value = yang_get_default_value(xpath);
772 if (strlcpy(buf, value, size) >= size)
773 flog_warn(EC_LIB_YANG_DATA_TRUNCATED,
774 "%s: value was truncated [xpath %s]", __func__,
775 xpath);
776 }
777
778 /*
779 * Derived type: ipv4.
780 */
781 void yang_str2ipv4(const char *value, struct in_addr *addr)
782 {
783 (void)inet_pton(AF_INET, value, addr);
784 }
785
786 struct yang_data *yang_data_new_ipv4(const char *xpath,
787 const struct in_addr *addr)
788 {
789 char value_str[INET_ADDRSTRLEN];
790
791 (void)inet_ntop(AF_INET, addr, value_str, sizeof(value_str));
792 return yang_data_new(xpath, value_str);
793 }
794
795 void yang_dnode_get_ipv4(struct in_addr *addr, const struct lyd_node *dnode,
796 const char *xpath_fmt, ...)
797 {
798 const struct lyd_node_leaf_list *dleaf;
799
800 assert(dnode);
801 if (xpath_fmt) {
802 va_list ap;
803 char xpath[XPATH_MAXLEN];
804
805 va_start(ap, xpath_fmt);
806 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
807 va_end(ap);
808 dnode = yang_dnode_get(dnode, xpath);
809 YANG_DNODE_GET_ASSERT(dnode, xpath);
810 }
811
812 dleaf = (const struct lyd_node_leaf_list *)dnode;
813 assert(dleaf->value_type == LY_TYPE_STRING);
814 memcpy(addr, dleaf->value.ptr, sizeof(*addr));
815 }
816
817 void yang_get_default_ipv4(struct in_addr *var, const char *xpath_fmt, ...)
818 {
819 char xpath[XPATH_MAXLEN];
820 const char *value;
821 va_list ap;
822
823 va_start(ap, xpath_fmt);
824 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
825 va_end(ap);
826
827 value = yang_get_default_value(xpath);
828 yang_str2ipv4(value, var);
829 }
830
831 /*
832 * Derived type: ipv4p.
833 */
834 void yang_str2ipv4p(const char *value, union prefixptr prefix)
835 {
836 struct prefix_ipv4 *prefix4 = prefix.p4;
837
838 (void)str2prefix_ipv4(value, prefix4);
839 apply_mask_ipv4(prefix4);
840 }
841
842 struct yang_data *yang_data_new_ipv4p(const char *xpath,
843 const union prefixptr prefix)
844 {
845 char value_str[PREFIX2STR_BUFFER];
846
847 (void)prefix2str(prefix.p, value_str, sizeof(value_str));
848 return yang_data_new(xpath, value_str);
849 }
850
851 void yang_dnode_get_ipv4p(union prefixptr prefix, const struct lyd_node *dnode,
852 const char *xpath_fmt, ...)
853 {
854 const struct lyd_node_leaf_list *dleaf;
855 struct prefix_ipv4 *prefix4 = prefix.p4;
856
857 assert(dnode);
858 if (xpath_fmt) {
859 va_list ap;
860 char xpath[XPATH_MAXLEN];
861
862 va_start(ap, xpath_fmt);
863 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
864 va_end(ap);
865 dnode = yang_dnode_get(dnode, xpath);
866 YANG_DNODE_GET_ASSERT(dnode, xpath);
867 }
868
869 dleaf = (const struct lyd_node_leaf_list *)dnode;
870 assert(dleaf->value_type == LY_TYPE_STRING);
871 memcpy(prefix4, dleaf->value.ptr, sizeof(*prefix4));
872 }
873
874 void yang_get_default_ipv4p(union prefixptr var, const char *xpath_fmt, ...)
875 {
876 char xpath[XPATH_MAXLEN];
877 const char *value;
878 va_list ap;
879
880 va_start(ap, xpath_fmt);
881 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
882 va_end(ap);
883
884 value = yang_get_default_value(xpath);
885 yang_str2ipv4p(value, var);
886 }
887
888 /*
889 * Derived type: ipv6.
890 */
891 void yang_str2ipv6(const char *value, struct in6_addr *addr)
892 {
893 (void)inet_pton(AF_INET6, value, addr);
894 }
895
896 struct yang_data *yang_data_new_ipv6(const char *xpath,
897 const struct in6_addr *addr)
898 {
899 char value_str[INET6_ADDRSTRLEN];
900
901 (void)inet_ntop(AF_INET6, addr, value_str, sizeof(value_str));
902 return yang_data_new(xpath, value_str);
903 }
904
905 void yang_dnode_get_ipv6(struct in6_addr *addr, const struct lyd_node *dnode,
906 const char *xpath_fmt, ...)
907 {
908 const struct lyd_node_leaf_list *dleaf;
909
910 assert(dnode);
911 if (xpath_fmt) {
912 va_list ap;
913 char xpath[XPATH_MAXLEN];
914
915 va_start(ap, xpath_fmt);
916 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
917 va_end(ap);
918 dnode = yang_dnode_get(dnode, xpath);
919 YANG_DNODE_GET_ASSERT(dnode, xpath);
920 }
921
922 dleaf = (const struct lyd_node_leaf_list *)dnode;
923 assert(dleaf->value_type == LY_TYPE_STRING);
924 memcpy(addr, dleaf->value.ptr, sizeof(*addr));
925 }
926
927 void yang_get_default_ipv6(struct in6_addr *var, const char *xpath_fmt, ...)
928 {
929 char xpath[XPATH_MAXLEN];
930 const char *value;
931 va_list ap;
932
933 va_start(ap, xpath_fmt);
934 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
935 va_end(ap);
936
937 value = yang_get_default_value(xpath);
938 yang_str2ipv6(value, var);
939 }
940
941 /*
942 * Derived type: ipv6p.
943 */
944 void yang_str2ipv6p(const char *value, union prefixptr prefix)
945 {
946 struct prefix_ipv6 *prefix6 = prefix.p6;
947
948 (void)str2prefix_ipv6(value, prefix6);
949 apply_mask_ipv6(prefix6);
950 }
951
952 struct yang_data *yang_data_new_ipv6p(const char *xpath,
953 const union prefixptr prefix)
954 {
955 char value_str[PREFIX2STR_BUFFER];
956
957 (void)prefix2str(prefix.p, value_str, sizeof(value_str));
958 return yang_data_new(xpath, value_str);
959 }
960
961 void yang_dnode_get_ipv6p(union prefixptr prefix, const struct lyd_node *dnode,
962 const char *xpath_fmt, ...)
963 {
964 const struct lyd_node_leaf_list *dleaf;
965 struct prefix_ipv6 *prefix6 = prefix.p6;
966
967 assert(dnode);
968 if (xpath_fmt) {
969 va_list ap;
970 char xpath[XPATH_MAXLEN];
971
972 va_start(ap, xpath_fmt);
973 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
974 va_end(ap);
975 dnode = yang_dnode_get(dnode, xpath);
976 YANG_DNODE_GET_ASSERT(dnode, xpath);
977 }
978
979 dleaf = (const struct lyd_node_leaf_list *)dnode;
980 assert(dleaf->value_type == LY_TYPE_STRING);
981 memcpy(prefix6, dleaf->value.ptr, sizeof(*prefix6));
982 }
983
984 void yang_get_default_ipv6p(union prefixptr var, const char *xpath_fmt, ...)
985 {
986 char xpath[XPATH_MAXLEN];
987 const char *value;
988 va_list ap;
989
990 va_start(ap, xpath_fmt);
991 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
992 va_end(ap);
993
994 value = yang_get_default_value(xpath);
995 yang_str2ipv6p(value, var);
996 }