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