]> git.proxmox.com Git - mirror_frr.git/blob - lib/yang_wrappers.c
Merge pull request #5778 from ton31337/fix/add_doc_for_ebgp_connected_route_check
[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" : "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: IP prefix.
786 */
787 void yang_str2prefix(const char *value, union prefixptr prefix)
788 {
789 (void)str2prefix(value, prefix.p);
790 apply_mask(prefix.p);
791 }
792
793 struct 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
802 void yang_dnode_get_prefix(struct prefix *prefix, const struct lyd_node *dnode,
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
819 /*
820 * Initialize prefix to avoid static analyzer complaints about
821 * uninitialized memory.
822 */
823 memset(prefix, 0, sizeof(*prefix));
824
825 dleaf = (const struct lyd_node_leaf_list *)dnode;
826 assert(dleaf->value_type == LY_TYPE_STRING);
827 (void)str2prefix(dleaf->value_str, prefix);
828 }
829
830 void 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
844 /*
845 * Derived type: ipv4.
846 */
847 void yang_str2ipv4(const char *value, struct in_addr *addr)
848 {
849 (void)inet_pton(AF_INET, value, addr);
850 }
851
852 struct 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
861 void 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);
880 (void)inet_pton(AF_INET, dleaf->value_str, addr);
881 }
882
883 void 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 */
900 void 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
908 struct yang_data *yang_data_new_ipv4p(const char *xpath,
909 union prefixconstptr prefix)
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
917 void 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);
937 (void)str2prefix_ipv4(dleaf->value_str, prefix4);
938 }
939
940 void 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 */
957 void yang_str2ipv6(const char *value, struct in6_addr *addr)
958 {
959 (void)inet_pton(AF_INET6, value, addr);
960 }
961
962 struct 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
971 void 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);
990 (void)inet_pton(AF_INET6, dleaf->value_str, addr);
991 }
992
993 void 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 */
1010 void 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
1018 struct yang_data *yang_data_new_ipv6p(const char *xpath,
1019 union prefixconstptr prefix)
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
1027 void 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);
1047 (void)str2prefix_ipv6(dleaf->value_str, prefix6);
1048 }
1049
1050 void 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 }
1063
1064 /*
1065 * Derived type: ip.
1066 */
1067 void yang_str2ip(const char *value, struct ipaddr *ip)
1068 {
1069 (void)str2ipaddr(value, ip);
1070 }
1071
1072 struct 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
1081 void 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
1103 void 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 }