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