]> git.proxmox.com Git - mirror_frr.git/blob - pathd/path_nb_config.c
Merge pull request #8353 from opensourcerouting/llvm-20210327
[mirror_frr.git] / pathd / path_nb_config.c
1 /*
2 * Copyright (C) 2020 NetDEF, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; see the file COPYING; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <zebra.h>
20 #include <lib_errors.h>
21
22 #include "northbound.h"
23 #include "libfrr.h"
24
25 #include "pathd/path_zebra.h"
26 #include "pathd/path_nb.h"
27
28 /*
29 * XPath: /frr-pathd:pathd
30 */
31 void pathd_apply_finish(struct nb_cb_apply_finish_args *args)
32 {
33 srte_apply_changes();
34 }
35
36 /*
37 * XPath: /frr-pathd:pathd/srte/segment-list
38 */
39 int pathd_srte_segment_list_create(struct nb_cb_create_args *args)
40 {
41 struct srte_segment_list *segment_list;
42 const char *name;
43
44 if (args->event != NB_EV_APPLY)
45 return NB_OK;
46
47 name = yang_dnode_get_string(args->dnode, "./name");
48 segment_list = srte_segment_list_add(name);
49 nb_running_set_entry(args->dnode, segment_list);
50 SET_FLAG(segment_list->flags, F_SEGMENT_LIST_NEW);
51
52 return NB_OK;
53 }
54
55 int pathd_srte_segment_list_destroy(struct nb_cb_destroy_args *args)
56 {
57 struct srte_segment_list *segment_list;
58
59 if (args->event != NB_EV_APPLY)
60 return NB_OK;
61
62 segment_list = nb_running_unset_entry(args->dnode);
63 SET_FLAG(segment_list->flags, F_SEGMENT_LIST_DELETED);
64
65 return NB_OK;
66 }
67
68 /*
69 * XPath: /frr-pathd:pathd/srte/segment-list/protocol-origin
70 */
71 int pathd_srte_segment_list_protocol_origin_modify(
72 struct nb_cb_modify_args *args)
73 {
74 struct srte_segment_list *segment_list;
75
76 if (args->event != NB_EV_APPLY)
77 return NB_OK;
78
79 segment_list = nb_running_get_entry(args->dnode, NULL, true);
80 segment_list->protocol_origin = yang_dnode_get_enum(args->dnode, NULL);
81 SET_FLAG(segment_list->flags, F_SEGMENT_LIST_MODIFIED);
82
83 return NB_OK;
84 }
85
86 /*
87 * XPath: /frr-pathd:pathd/srte/segment-list/originator
88 */
89 int pathd_srte_segment_list_originator_modify(struct nb_cb_modify_args *args)
90 {
91 struct srte_segment_list *segment_list;
92 const char *originator;
93
94 if (args->event != NB_EV_APPLY)
95 return NB_OK;
96
97 segment_list = nb_running_get_entry(args->dnode, NULL, true);
98 originator = yang_dnode_get_string(args->dnode, NULL);
99 strlcpy(segment_list->originator, originator,
100 sizeof(segment_list->originator));
101 SET_FLAG(segment_list->flags, F_SEGMENT_LIST_MODIFIED);
102
103 return NB_OK;
104 }
105
106
107 /*
108 * XPath: /frr-pathd:pathd/srte/segment-list/segment
109 */
110 int pathd_srte_segment_list_segment_create(struct nb_cb_create_args *args)
111 {
112 struct srte_segment_list *segment_list;
113 struct srte_segment_entry *segment;
114 uint32_t index;
115
116 if (args->event != NB_EV_APPLY)
117 return NB_OK;
118
119 segment_list = nb_running_get_entry(args->dnode, NULL, true);
120 index = yang_dnode_get_uint32(args->dnode, "./index");
121 segment = srte_segment_entry_add(segment_list, index);
122 nb_running_set_entry(args->dnode, segment);
123 SET_FLAG(segment_list->flags, F_SEGMENT_LIST_MODIFIED);
124
125 return NB_OK;
126 }
127
128 int pathd_srte_segment_list_segment_destroy(struct nb_cb_destroy_args *args)
129 {
130 struct srte_segment_entry *segment;
131
132 if (args->event != NB_EV_APPLY)
133 return NB_OK;
134
135 segment = nb_running_unset_entry(args->dnode);
136 SET_FLAG(segment->segment_list->flags, F_SEGMENT_LIST_MODIFIED);
137
138 srte_segment_entry_del(segment);
139
140 return NB_OK;
141 }
142
143 /*
144 * XPath: /frr-pathd:pathd/srte/segment-list/segment/sid-value
145 */
146 int pathd_srte_segment_list_segment_sid_value_modify(
147 struct nb_cb_modify_args *args)
148 {
149 mpls_label_t sid_value;
150 struct srte_segment_entry *segment;
151
152 if (args->event != NB_EV_APPLY)
153 return NB_OK;
154
155 segment = nb_running_get_entry(args->dnode, NULL, true);
156 sid_value = yang_dnode_get_uint32(args->dnode, NULL);
157 segment->sid_value = sid_value;
158 SET_FLAG(segment->segment_list->flags, F_SEGMENT_LIST_MODIFIED);
159
160 return NB_OK;
161 }
162
163 int pathd_srte_segment_list_segment_sid_value_destroy(
164 struct nb_cb_destroy_args *args)
165 {
166 struct srte_segment_entry *segment;
167
168 if (args->event != NB_EV_APPLY)
169 return NB_OK;
170
171 segment = nb_running_get_entry(args->dnode, NULL, true);
172 segment->sid_value = MPLS_LABEL_NONE;
173 SET_FLAG(segment->segment_list->flags, F_SEGMENT_LIST_MODIFIED);
174
175 return NB_OK;
176 }
177
178
179 int pathd_srte_segment_list_segment_nai_destroy(struct nb_cb_destroy_args *args)
180 {
181 struct srte_segment_entry *segment;
182
183 if (args->event != NB_EV_APPLY)
184 return NB_OK;
185
186 segment = nb_running_get_entry(args->dnode, NULL, true);
187 segment->nai_type = SRTE_SEGMENT_NAI_TYPE_NONE;
188 segment->nai_local_addr.ipa_type = IPADDR_NONE;
189 segment->nai_local_iface = 0;
190 segment->nai_remote_addr.ipa_type = IPADDR_NONE;
191 segment->nai_remote_iface = 0;
192
193 return NB_OK;
194 }
195
196 void pathd_srte_segment_list_segment_nai_apply_finish(
197 struct nb_cb_apply_finish_args *args)
198 {
199 struct srte_segment_entry *segment;
200 enum srte_segment_nai_type type;
201 struct ipaddr local_addr, remote_addr;
202 uint32_t local_iface = 0, remote_iface = 0;
203 uint8_t algo = 0, local_prefix_len = 0;
204 const char *algo_buf, *local_prefix_len_buf;
205
206 segment = nb_running_get_entry(args->dnode, NULL, true);
207 type = yang_dnode_get_enum(args->dnode, "./type");
208
209 yang_dnode_get_ip(&local_addr, args->dnode, "./local-address");
210
211 switch (type) {
212 case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE:
213 case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE:
214 break;
215 case SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY:
216 case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY:
217 yang_dnode_get_ip(&remote_addr, args->dnode,
218 "./remote-address");
219 break;
220 case SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY:
221 yang_dnode_get_ip(&remote_addr, args->dnode,
222 "./remote-address");
223 local_iface =
224 yang_dnode_get_uint32(args->dnode, "./local-interface");
225 remote_iface = yang_dnode_get_uint32(args->dnode,
226 "./remote-interface");
227 break;
228 case SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM:
229 algo_buf = yang_dnode_get_string(args->dnode, "./algorithm");
230 algo = atoi(algo_buf);
231 local_prefix_len_buf = yang_dnode_get_string(
232 args->dnode, "./local-prefix-len");
233 local_prefix_len = atoi(local_prefix_len_buf);
234 break;
235 case SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE:
236 local_iface =
237 yang_dnode_get_uint32(args->dnode, "./local-interface");
238 local_prefix_len_buf = yang_dnode_get_string(
239 args->dnode, "./local-prefix-len");
240 local_prefix_len = atoi(local_prefix_len_buf);
241 break;
242 default:
243 break;
244 }
245
246 zlog_debug(" Segment list name (%d) index (%s) ", segment->index,
247 segment->segment_list->name);
248 if (srte_segment_entry_set_nai(segment, type, &local_addr, local_iface,
249 &remote_addr, remote_iface, algo,
250 local_prefix_len))
251 SET_FLAG(segment->segment_list->flags,
252 F_SEGMENT_LIST_SID_CONFLICT);
253 }
254
255 /*
256 * XPath: /frr-pathd:pathd/srte/policy
257 */
258 int pathd_srte_policy_create(struct nb_cb_create_args *args)
259 {
260 struct srte_policy *policy;
261 uint32_t color;
262 struct ipaddr endpoint;
263
264 if (args->event != NB_EV_APPLY)
265 return NB_OK;
266
267 color = yang_dnode_get_uint32(args->dnode, "./color");
268 yang_dnode_get_ip(&endpoint, args->dnode, "./endpoint");
269 policy = srte_policy_add(color, &endpoint);
270
271 nb_running_set_entry(args->dnode, policy);
272 SET_FLAG(policy->flags, F_POLICY_NEW);
273
274 return NB_OK;
275 }
276
277 int pathd_srte_policy_destroy(struct nb_cb_destroy_args *args)
278 {
279 struct srte_policy *policy;
280
281 if (args->event != NB_EV_APPLY)
282 return NB_OK;
283
284 policy = nb_running_unset_entry(args->dnode);
285 SET_FLAG(policy->flags, F_POLICY_DELETED);
286
287 return NB_OK;
288 }
289
290 /*
291 * XPath: /frr-pathd:pathd/srte/policy/name
292 */
293 int pathd_srte_policy_name_modify(struct nb_cb_modify_args *args)
294 {
295 struct srte_policy *policy;
296 const char *name;
297
298 if (args->event != NB_EV_APPLY && args->event != NB_EV_VALIDATE)
299 return NB_OK;
300
301 policy = nb_running_get_entry(args->dnode, NULL, true);
302
303 if (args->event == NB_EV_VALIDATE) {
304 /* the policy name is fixed after setting it once */
305 if (strlen(policy->name) > 0) {
306 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
307 "The SR Policy name is fixed!");
308 return NB_ERR_RESOURCE;
309 } else
310 return NB_OK;
311 }
312
313 name = yang_dnode_get_string(args->dnode, NULL);
314 strlcpy(policy->name, name, sizeof(policy->name));
315 SET_FLAG(policy->flags, F_POLICY_MODIFIED);
316
317 return NB_OK;
318 }
319
320 int pathd_srte_policy_name_destroy(struct nb_cb_destroy_args *args)
321 {
322 struct srte_policy *policy;
323
324 if (args->event != NB_EV_APPLY)
325 return NB_OK;
326
327 policy = nb_running_get_entry(args->dnode, NULL, true);
328 policy->name[0] = '\0';
329 SET_FLAG(policy->flags, F_POLICY_MODIFIED);
330
331 return NB_OK;
332 }
333
334 /*
335 * XPath: /frr-pathd:pathd/srte/policy/binding-sid
336 */
337 int pathd_srte_policy_binding_sid_modify(struct nb_cb_modify_args *args)
338 {
339 struct srte_policy *policy;
340 mpls_label_t binding_sid;
341
342 binding_sid = yang_dnode_get_uint32(args->dnode, NULL);
343
344 switch (args->event) {
345 case NB_EV_VALIDATE:
346 break;
347 case NB_EV_PREPARE:
348 if (path_zebra_request_label(binding_sid) < 0)
349 return NB_ERR_RESOURCE;
350 break;
351 case NB_EV_ABORT:
352 break;
353 case NB_EV_APPLY:
354 policy = nb_running_get_entry(args->dnode, NULL, true);
355 srte_policy_update_binding_sid(policy, binding_sid);
356 SET_FLAG(policy->flags, F_POLICY_MODIFIED);
357 break;
358 }
359
360 return NB_OK;
361 }
362
363 int pathd_srte_policy_binding_sid_destroy(struct nb_cb_destroy_args *args)
364 {
365 struct srte_policy *policy;
366
367 if (args->event != NB_EV_APPLY)
368 return NB_OK;
369
370 policy = nb_running_get_entry(args->dnode, NULL, true);
371 srte_policy_update_binding_sid(policy, MPLS_LABEL_NONE);
372 SET_FLAG(policy->flags, F_POLICY_MODIFIED);
373
374 return NB_OK;
375 }
376
377 /*
378 * XPath: /frr-pathd:pathd/srte/policy/candidate-path
379 */
380 int pathd_srte_policy_candidate_path_create(struct nb_cb_create_args *args)
381 {
382 struct srte_policy *policy;
383 struct srte_candidate *candidate;
384 uint32_t preference;
385
386 if (args->event != NB_EV_APPLY)
387 return NB_OK;
388
389 policy = nb_running_get_entry(args->dnode, NULL, true);
390 preference = yang_dnode_get_uint32(args->dnode, "./preference");
391 candidate = srte_candidate_add(policy, preference);
392 nb_running_set_entry(args->dnode, candidate);
393 SET_FLAG(candidate->flags, F_CANDIDATE_NEW);
394
395 return NB_OK;
396 }
397
398 int pathd_srte_policy_candidate_path_destroy(struct nb_cb_destroy_args *args)
399 {
400 struct srte_candidate *candidate;
401
402 if (args->event != NB_EV_APPLY)
403 return NB_OK;
404
405 candidate = nb_running_unset_entry(args->dnode);
406 SET_FLAG(candidate->flags, F_CANDIDATE_DELETED);
407
408 return NB_OK;
409 }
410
411 /*
412 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/name
413 */
414 int pathd_srte_policy_candidate_path_name_modify(struct nb_cb_modify_args *args)
415 {
416 struct srte_candidate *candidate;
417 const char *name;
418 char xpath[XPATH_MAXLEN];
419 char xpath_buf[XPATH_MAXLEN - 3];
420
421 if (args->event != NB_EV_APPLY && args->event != NB_EV_VALIDATE)
422 return NB_OK;
423
424 /* the candidate name is fixed after setting it once, this is checked
425 * here */
426 if (args->event == NB_EV_VALIDATE) {
427 /* first get the precise path to the candidate path */
428 yang_dnode_get_path(args->dnode, xpath_buf, sizeof(xpath_buf));
429 snprintf(xpath, sizeof(xpath), "%s%s", xpath_buf, "/..");
430
431 candidate = nb_running_get_entry_non_rec(NULL, xpath, false);
432
433 /* then check if it exists and if the name was provided */
434 if (candidate && strlen(candidate->name) > 0) {
435 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
436 "The candidate name is fixed!");
437 return NB_ERR_RESOURCE;
438 } else
439 return NB_OK;
440 }
441
442 candidate = nb_running_get_entry(args->dnode, NULL, true);
443
444 name = yang_dnode_get_string(args->dnode, NULL);
445 strlcpy(candidate->name, name, sizeof(candidate->name));
446 SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
447
448 return NB_OK;
449 }
450
451
452 static int affinity_filter_modify(struct nb_cb_modify_args *args,
453 enum affinity_filter_type type)
454 {
455 uint32_t filter;
456 struct srte_candidate *candidate;
457
458 if (args->event != NB_EV_APPLY)
459 return NB_OK;
460
461 assert(args->context != NULL);
462 candidate = nb_running_get_entry(args->dnode, NULL, true);
463 filter = yang_dnode_get_uint32(args->dnode, NULL);
464 srte_candidate_set_affinity_filter(candidate, type, filter);
465
466 return NB_OK;
467 }
468
469 static int affinity_filter_destroy(struct nb_cb_destroy_args *args,
470 enum affinity_filter_type type)
471 {
472 struct srte_candidate *candidate;
473
474 if (args->event != NB_EV_APPLY)
475 return NB_OK;
476
477 assert(args->context != NULL);
478 candidate = nb_running_get_entry(args->dnode, NULL, true);
479 srte_candidate_unset_affinity_filter(candidate, type);
480
481 return NB_OK;
482 }
483
484 /*
485 * XPath:
486 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/affinity/exclude-any
487 */
488
489 int pathd_srte_policy_candidate_path_exclude_any_modify(
490 struct nb_cb_modify_args *args)
491 {
492 return affinity_filter_modify(args, AFFINITY_FILTER_EXCLUDE_ANY);
493 }
494
495 int pathd_srte_policy_candidate_path_exclude_any_destroy(
496 struct nb_cb_destroy_args *args)
497 {
498 return affinity_filter_destroy(args, AFFINITY_FILTER_EXCLUDE_ANY);
499 }
500
501
502 /*
503 * XPath:
504 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/affinity/include-any
505 */
506 int pathd_srte_policy_candidate_path_include_any_modify(
507 struct nb_cb_modify_args *args)
508 {
509 return affinity_filter_modify(args, AFFINITY_FILTER_INCLUDE_ANY);
510 }
511
512 int pathd_srte_policy_candidate_path_include_any_destroy(
513 struct nb_cb_destroy_args *args)
514 {
515 return affinity_filter_destroy(args, AFFINITY_FILTER_INCLUDE_ANY);
516 }
517
518
519 /*
520 * XPath:
521 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/affinity/include-all
522 */
523 int pathd_srte_policy_candidate_path_include_all_modify(
524 struct nb_cb_modify_args *args)
525 {
526 return affinity_filter_modify(args, AFFINITY_FILTER_INCLUDE_ALL);
527 }
528
529 int pathd_srte_policy_candidate_path_include_all_destroy(
530 struct nb_cb_destroy_args *args)
531 {
532 return affinity_filter_destroy(args, AFFINITY_FILTER_INCLUDE_ALL);
533 }
534
535
536 /*
537 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/constraints/metrics
538 */
539 int pathd_srte_policy_candidate_path_metrics_destroy(
540 struct nb_cb_destroy_args *args)
541 {
542 struct srte_candidate *candidate;
543 enum srte_candidate_metric_type type;
544
545 if (args->event != NB_EV_APPLY)
546 return NB_OK;
547
548 assert(args->context != NULL);
549 candidate = nb_running_get_entry(args->dnode, NULL, true);
550
551 type = yang_dnode_get_enum(args->dnode, "./type");
552 srte_candidate_unset_metric(candidate, type);
553
554 return NB_OK;
555 }
556
557 void pathd_srte_policy_candidate_path_metrics_apply_finish(
558 struct nb_cb_apply_finish_args *args)
559 {
560 struct srte_candidate *candidate;
561 enum srte_candidate_metric_type type;
562 float value;
563 bool required, is_bound = false, is_computed = false;
564
565 assert(args->context != NULL);
566
567 candidate = nb_running_get_entry(args->dnode, NULL, true);
568
569 type = yang_dnode_get_enum(args->dnode, "./type");
570 value = (float)yang_dnode_get_dec64(args->dnode, "./value");
571 required = yang_dnode_get_bool(args->dnode, "./required");
572 if (yang_dnode_exists(args->dnode, "./is-bound"))
573 is_bound = yang_dnode_get_bool(args->dnode, "./is-bound");
574 if (yang_dnode_exists(args->dnode, "./is-computed"))
575 is_computed = yang_dnode_get_bool(args->dnode, "./is-computed");
576
577 srte_candidate_set_metric(candidate, type, value, required, is_bound,
578 is_computed);
579 }
580
581 /*
582 * XPath:
583 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/objective-function
584 */
585 int pathd_srte_policy_candidate_path_objfun_destroy(
586 struct nb_cb_destroy_args *args)
587 {
588 struct srte_candidate *candidate;
589
590 if (args->event != NB_EV_APPLY)
591 return NB_OK;
592
593 assert(args->context != NULL);
594
595 candidate = nb_running_get_entry(args->dnode, NULL, true);
596 srte_candidate_unset_objfun(candidate);
597
598 return NB_OK;
599 }
600
601 void pathd_srte_policy_candidate_path_objfun_apply_finish(
602 struct nb_cb_apply_finish_args *args)
603 {
604 struct srte_candidate *candidate;
605 enum objfun_type type;
606 bool required;
607
608 candidate = nb_running_get_entry(args->dnode, NULL, true);
609 required = yang_dnode_get_bool(args->dnode, "./required");
610 type = yang_dnode_get_enum(args->dnode, "./type");
611 srte_candidate_set_objfun(candidate, required, type);
612 }
613
614 /*
615 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/protocol-origin
616 */
617 int pathd_srte_policy_candidate_path_protocol_origin_modify(
618 struct nb_cb_modify_args *args)
619 {
620 struct srte_candidate *candidate;
621 enum srte_protocol_origin protocol_origin;
622
623 if (args->event != NB_EV_APPLY)
624 return NB_OK;
625
626 candidate = nb_running_get_entry(args->dnode, NULL, true);
627 protocol_origin = yang_dnode_get_enum(args->dnode, NULL);
628 candidate->protocol_origin = protocol_origin;
629 candidate->lsp->protocol_origin = protocol_origin;
630 SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
631
632 return NB_OK;
633 }
634
635 /*
636 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/originator
637 */
638 int pathd_srte_policy_candidate_path_originator_modify(
639 struct nb_cb_modify_args *args)
640 {
641 struct srte_candidate *candidate;
642 const char *originator;
643
644 if (args->event != NB_EV_APPLY)
645 return NB_OK;
646
647 candidate = nb_running_get_entry(args->dnode, NULL, true);
648 originator = yang_dnode_get_string(args->dnode, NULL);
649 strlcpy(candidate->originator, originator,
650 sizeof(candidate->originator));
651 strlcpy(candidate->lsp->originator, originator,
652 sizeof(candidate->lsp->originator));
653 SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
654
655 return NB_OK;
656 }
657
658 /*
659 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/type
660 */
661 int pathd_srte_policy_candidate_path_type_modify(struct nb_cb_modify_args *args)
662 {
663 struct srte_candidate *candidate;
664 enum srte_candidate_type type;
665 char xpath[XPATH_MAXLEN];
666 char xpath_buf[XPATH_MAXLEN - 3];
667
668 if (args->event != NB_EV_APPLY && args->event != NB_EV_VALIDATE)
669 return NB_OK;
670
671 /* the candidate type is fixed after setting it once, this is checked
672 * here */
673 if (args->event == NB_EV_VALIDATE) {
674 /* first get the precise path to the candidate path */
675 yang_dnode_get_path(args->dnode, xpath_buf, sizeof(xpath_buf));
676 snprintf(xpath, sizeof(xpath), "%s%s", xpath_buf, "/..");
677
678 candidate = nb_running_get_entry_non_rec(NULL, xpath, false);
679
680 /* then check if it exists and if the type was provided */
681 if (candidate
682 && candidate->type != SRTE_CANDIDATE_TYPE_UNDEFINED) {
683 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
684 "The candidate type is fixed!");
685 return NB_ERR_RESOURCE;
686 } else
687 return NB_OK;
688 }
689
690 candidate = nb_running_get_entry(args->dnode, NULL, true);
691
692 type = yang_dnode_get_enum(args->dnode, NULL);
693 candidate->type = type;
694 SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
695
696 return NB_OK;
697 }
698
699 /*
700 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/segment-list-name
701 */
702 int pathd_srte_policy_candidate_path_segment_list_name_modify(
703 struct nb_cb_modify_args *args)
704 {
705 struct srte_candidate *candidate;
706 const char *segment_list_name;
707
708 if (args->event != NB_EV_APPLY)
709 return NB_OK;
710
711 candidate = nb_running_get_entry(args->dnode, NULL, true);
712 segment_list_name = yang_dnode_get_string(args->dnode, NULL);
713
714 candidate->segment_list = srte_segment_list_find(segment_list_name);
715 candidate->lsp->segment_list = candidate->segment_list;
716 assert(candidate->segment_list);
717 SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
718
719 return NB_OK;
720 }
721
722 int pathd_srte_policy_candidate_path_segment_list_name_destroy(
723 struct nb_cb_destroy_args *args)
724 {
725 struct srte_candidate *candidate;
726
727 if (args->event != NB_EV_APPLY)
728 return NB_OK;
729
730 candidate = nb_running_get_entry(args->dnode, NULL, true);
731 candidate->segment_list = NULL;
732 candidate->lsp->segment_list = NULL;
733 SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
734
735 return NB_OK;
736 }
737
738 /*
739 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/constraints/bandwidth
740 */
741 void pathd_srte_policy_candidate_path_bandwidth_apply_finish(
742 struct nb_cb_apply_finish_args *args)
743 {
744 struct srte_candidate *candidate;
745 float value;
746 bool required;
747
748 assert(args->context != NULL);
749
750 candidate = nb_running_get_entry(args->dnode, NULL, true);
751 value = (float)yang_dnode_get_dec64(args->dnode, "./value");
752 required = yang_dnode_get_bool(args->dnode, "./required");
753 srte_candidate_set_bandwidth(candidate, value, required);
754 }
755
756 int pathd_srte_policy_candidate_path_bandwidth_destroy(
757 struct nb_cb_destroy_args *args)
758 {
759 struct srte_candidate *candidate;
760
761 if (args->event != NB_EV_APPLY)
762 return NB_OK;
763
764 assert(args->context != NULL);
765 candidate = nb_running_get_entry(args->dnode, NULL, true);
766 srte_candidate_unset_bandwidth(candidate);
767 return NB_OK;
768 }