]> git.proxmox.com Git - mirror_frr.git/blob - lib/yang_wrappers.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[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 *type;
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;
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 }
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
206 struct 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;
210 const struct lys_type *type;
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;
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 }
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
242 int 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
264 int 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 */
281 int8_t yang_str2int8(const char *value)
282 {
283 return strtol(value, NULL, 10);
284 }
285
286 struct 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
294 int8_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
316 int8_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 */
333 int16_t yang_str2int16(const char *value)
334 {
335 return strtol(value, NULL, 10);
336 }
337
338 struct 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
346 int16_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
368 int16_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 */
385 int32_t yang_str2int32(const char *value)
386 {
387 return strtol(value, NULL, 10);
388 }
389
390 struct 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
398 int32_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
420 int32_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 */
437 int64_t yang_str2int64(const char *value)
438 {
439 return strtoll(value, NULL, 10);
440 }
441
442 struct 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
450 int64_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
472 int64_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 */
489 uint8_t yang_str2uint8(const char *value)
490 {
491 return strtoul(value, NULL, 10);
492 }
493
494 struct 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
502 uint8_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
524 uint8_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 */
541 uint16_t yang_str2uint16(const char *value)
542 {
543 return strtoul(value, NULL, 10);
544 }
545
546 struct 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
554 uint16_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
576 uint16_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 */
593 uint32_t yang_str2uint32(const char *value)
594 {
595 return strtoul(value, NULL, 10);
596 }
597
598 struct 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
606 uint32_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
628 uint32_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 */
645 uint64_t yang_str2uint64(const char *value)
646 {
647 return strtoull(value, NULL, 10);
648 }
649
650 struct 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
658 uint64_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
680 uint64_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 */
699 struct yang_data *yang_data_new_string(const char *xpath, const char *value)
700 {
701 return yang_data_new(xpath, value);
702 }
703
704 const 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
725 void 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
754 const 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
766 void 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
784 /*
785 * Derived type: ipv4.
786 */
787 void yang_str2ipv4(const char *value, struct in_addr *addr)
788 {
789 (void)inet_pton(AF_INET, value, addr);
790 }
791
792 struct yang_data *yang_data_new_ipv4(const char *xpath,
793 const struct in_addr *addr)
794 {
795 char value_str[INET_ADDRSTRLEN];
796
797 (void)inet_ntop(AF_INET, addr, value_str, sizeof(value_str));
798 return yang_data_new(xpath, value_str);
799 }
800
801 void yang_dnode_get_ipv4(struct in_addr *addr, const struct lyd_node *dnode,
802 const char *xpath_fmt, ...)
803 {
804 const struct lyd_node_leaf_list *dleaf;
805
806 assert(dnode);
807 if (xpath_fmt) {
808 va_list ap;
809 char xpath[XPATH_MAXLEN];
810
811 va_start(ap, xpath_fmt);
812 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
813 va_end(ap);
814 dnode = yang_dnode_get(dnode, xpath);
815 YANG_DNODE_GET_ASSERT(dnode, xpath);
816 }
817
818 dleaf = (const struct lyd_node_leaf_list *)dnode;
819 assert(dleaf->value_type == LY_TYPE_STRING);
820 memcpy(addr, dleaf->value.ptr, sizeof(*addr));
821 }
822
823 void yang_get_default_ipv4(struct in_addr *var, const char *xpath_fmt, ...)
824 {
825 char xpath[XPATH_MAXLEN];
826 const char *value;
827 va_list ap;
828
829 va_start(ap, xpath_fmt);
830 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
831 va_end(ap);
832
833 value = yang_get_default_value(xpath);
834 yang_str2ipv4(value, var);
835 }
836
837 /*
838 * Derived type: ipv4p.
839 */
840 void yang_str2ipv4p(const char *value, union prefixptr prefix)
841 {
842 struct prefix_ipv4 *prefix4 = prefix.p4;
843
844 (void)str2prefix_ipv4(value, prefix4);
845 apply_mask_ipv4(prefix4);
846 }
847
848 struct yang_data *yang_data_new_ipv4p(const char *xpath,
849 union prefixconstptr prefix)
850 {
851 char value_str[PREFIX2STR_BUFFER];
852
853 (void)prefix2str(prefix.p, value_str, sizeof(value_str));
854 return yang_data_new(xpath, value_str);
855 }
856
857 void yang_dnode_get_ipv4p(union prefixptr prefix, const struct lyd_node *dnode,
858 const char *xpath_fmt, ...)
859 {
860 const struct lyd_node_leaf_list *dleaf;
861 struct prefix_ipv4 *prefix4 = prefix.p4;
862
863 assert(dnode);
864 if (xpath_fmt) {
865 va_list ap;
866 char xpath[XPATH_MAXLEN];
867
868 va_start(ap, xpath_fmt);
869 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
870 va_end(ap);
871 dnode = yang_dnode_get(dnode, xpath);
872 YANG_DNODE_GET_ASSERT(dnode, xpath);
873 }
874
875 dleaf = (const struct lyd_node_leaf_list *)dnode;
876 assert(dleaf->value_type == LY_TYPE_STRING);
877 memcpy(prefix4, dleaf->value.ptr, sizeof(*prefix4));
878 }
879
880 void yang_get_default_ipv4p(union prefixptr var, const char *xpath_fmt, ...)
881 {
882 char xpath[XPATH_MAXLEN];
883 const char *value;
884 va_list ap;
885
886 va_start(ap, xpath_fmt);
887 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
888 va_end(ap);
889
890 value = yang_get_default_value(xpath);
891 yang_str2ipv4p(value, var);
892 }
893
894 /*
895 * Derived type: ipv6.
896 */
897 void yang_str2ipv6(const char *value, struct in6_addr *addr)
898 {
899 (void)inet_pton(AF_INET6, value, addr);
900 }
901
902 struct yang_data *yang_data_new_ipv6(const char *xpath,
903 const struct in6_addr *addr)
904 {
905 char value_str[INET6_ADDRSTRLEN];
906
907 (void)inet_ntop(AF_INET6, addr, value_str, sizeof(value_str));
908 return yang_data_new(xpath, value_str);
909 }
910
911 void yang_dnode_get_ipv6(struct in6_addr *addr, const struct lyd_node *dnode,
912 const char *xpath_fmt, ...)
913 {
914 const struct lyd_node_leaf_list *dleaf;
915
916 assert(dnode);
917 if (xpath_fmt) {
918 va_list ap;
919 char xpath[XPATH_MAXLEN];
920
921 va_start(ap, xpath_fmt);
922 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
923 va_end(ap);
924 dnode = yang_dnode_get(dnode, xpath);
925 YANG_DNODE_GET_ASSERT(dnode, xpath);
926 }
927
928 dleaf = (const struct lyd_node_leaf_list *)dnode;
929 assert(dleaf->value_type == LY_TYPE_STRING);
930 memcpy(addr, dleaf->value.ptr, sizeof(*addr));
931 }
932
933 void yang_get_default_ipv6(struct in6_addr *var, const char *xpath_fmt, ...)
934 {
935 char xpath[XPATH_MAXLEN];
936 const char *value;
937 va_list ap;
938
939 va_start(ap, xpath_fmt);
940 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
941 va_end(ap);
942
943 value = yang_get_default_value(xpath);
944 yang_str2ipv6(value, var);
945 }
946
947 /*
948 * Derived type: ipv6p.
949 */
950 void yang_str2ipv6p(const char *value, union prefixptr prefix)
951 {
952 struct prefix_ipv6 *prefix6 = prefix.p6;
953
954 (void)str2prefix_ipv6(value, prefix6);
955 apply_mask_ipv6(prefix6);
956 }
957
958 struct yang_data *yang_data_new_ipv6p(const char *xpath,
959 union prefixconstptr prefix)
960 {
961 char value_str[PREFIX2STR_BUFFER];
962
963 (void)prefix2str(prefix.p, value_str, sizeof(value_str));
964 return yang_data_new(xpath, value_str);
965 }
966
967 void yang_dnode_get_ipv6p(union prefixptr prefix, const struct lyd_node *dnode,
968 const char *xpath_fmt, ...)
969 {
970 const struct lyd_node_leaf_list *dleaf;
971 struct prefix_ipv6 *prefix6 = prefix.p6;
972
973 assert(dnode);
974 if (xpath_fmt) {
975 va_list ap;
976 char xpath[XPATH_MAXLEN];
977
978 va_start(ap, xpath_fmt);
979 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
980 va_end(ap);
981 dnode = yang_dnode_get(dnode, xpath);
982 YANG_DNODE_GET_ASSERT(dnode, xpath);
983 }
984
985 dleaf = (const struct lyd_node_leaf_list *)dnode;
986 assert(dleaf->value_type == LY_TYPE_STRING);
987 memcpy(prefix6, dleaf->value.ptr, sizeof(*prefix6));
988 }
989
990 void yang_get_default_ipv6p(union prefixptr var, const char *xpath_fmt, ...)
991 {
992 char xpath[XPATH_MAXLEN];
993 const char *value;
994 va_list ap;
995
996 va_start(ap, xpath_fmt);
997 vsnprintf(xpath, sizeof(xpath), xpath_fmt, ap);
998 va_end(ap);
999
1000 value = yang_get_default_value(xpath);
1001 yang_str2ipv6p(value, var);
1002 }