]> git.proxmox.com Git - mirror_frr.git/blob - pathd/path_nb_config.c
pathd: New SR-TE policy management daemon
[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_nai_destroy(struct nb_cb_destroy_args *args)
164 {
165 struct srte_segment_entry *segment;
166
167 if (args->event != NB_EV_APPLY)
168 return NB_OK;
169
170 segment = nb_running_get_entry(args->dnode, NULL, true);
171 segment->nai_type = SRTE_SEGMENT_NAI_TYPE_NONE;
172 segment->nai_local_addr.ipa_type = IPADDR_NONE;
173 segment->nai_local_iface = 0;
174 segment->nai_remote_addr.ipa_type = IPADDR_NONE;
175 segment->nai_remote_iface = 0;
176
177 return NB_OK;
178 }
179
180 void pathd_srte_segment_list_segment_nai_apply_finish(
181 struct nb_cb_apply_finish_args *args)
182 {
183 struct srte_segment_entry *segment;
184 enum srte_segment_nai_type type;
185 struct ipaddr local_addr, remote_addr;
186 uint32_t local_iface = 0, remote_iface = 0;
187
188 segment = nb_running_get_entry(args->dnode, NULL, true);
189 type = yang_dnode_get_enum(args->dnode, "./type");
190
191 yang_dnode_get_ip(&local_addr, args->dnode, "./local-address");
192
193 switch (type) {
194 case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE:
195 case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE:
196 break;
197 case SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY:
198 case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY:
199 yang_dnode_get_ip(&remote_addr, args->dnode,
200 "./remote-address");
201 break;
202 case SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY:
203 yang_dnode_get_ip(&remote_addr, args->dnode,
204 "./remote-address");
205 local_iface =
206 yang_dnode_get_uint32(args->dnode, "./local-interface");
207 remote_iface = yang_dnode_get_uint32(args->dnode,
208 "./remote-interface");
209 break;
210 default:
211 break;
212 }
213
214 srte_segment_entry_set_nai(segment, type, &local_addr, local_iface,
215 &remote_addr, remote_iface);
216 }
217
218 /*
219 * XPath: /frr-pathd:pathd/srte/policy
220 */
221 int pathd_srte_policy_create(struct nb_cb_create_args *args)
222 {
223 struct srte_policy *policy;
224 uint32_t color;
225 struct ipaddr endpoint;
226
227 if (args->event != NB_EV_APPLY)
228 return NB_OK;
229
230 color = yang_dnode_get_uint32(args->dnode, "./color");
231 yang_dnode_get_ip(&endpoint, args->dnode, "./endpoint");
232 policy = srte_policy_add(color, &endpoint);
233
234 nb_running_set_entry(args->dnode, policy);
235 SET_FLAG(policy->flags, F_POLICY_NEW);
236
237 return NB_OK;
238 }
239
240 int pathd_srte_policy_destroy(struct nb_cb_destroy_args *args)
241 {
242 struct srte_policy *policy;
243
244 if (args->event != NB_EV_APPLY)
245 return NB_OK;
246
247 policy = nb_running_unset_entry(args->dnode);
248 SET_FLAG(policy->flags, F_POLICY_DELETED);
249
250 return NB_OK;
251 }
252
253 /*
254 * XPath: /frr-pathd:pathd/srte/policy/name
255 */
256 int pathd_srte_policy_name_modify(struct nb_cb_modify_args *args)
257 {
258 struct srte_policy *policy;
259 const char *name;
260
261 if (args->event != NB_EV_APPLY && args->event != NB_EV_VALIDATE)
262 return NB_OK;
263
264 policy = nb_running_get_entry(args->dnode, NULL, true);
265
266 if (args->event == NB_EV_VALIDATE) {
267 /* the policy name is fixed after setting it once */
268 if (strlen(policy->name) > 0) {
269 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
270 "The SR Policy name is fixed!");
271 return NB_ERR_RESOURCE;
272 } else
273 return NB_OK;
274 }
275
276 name = yang_dnode_get_string(args->dnode, NULL);
277 strlcpy(policy->name, name, sizeof(policy->name));
278 SET_FLAG(policy->flags, F_POLICY_MODIFIED);
279
280 return NB_OK;
281 }
282
283 int pathd_srte_policy_name_destroy(struct nb_cb_destroy_args *args)
284 {
285 struct srte_policy *policy;
286
287 if (args->event != NB_EV_APPLY)
288 return NB_OK;
289
290 policy = nb_running_get_entry(args->dnode, NULL, true);
291 policy->name[0] = '\0';
292 SET_FLAG(policy->flags, F_POLICY_MODIFIED);
293
294 return NB_OK;
295 }
296
297 /*
298 * XPath: /frr-pathd:pathd/srte/policy/binding-sid
299 */
300 int pathd_srte_policy_binding_sid_modify(struct nb_cb_modify_args *args)
301 {
302 struct srte_policy *policy;
303 mpls_label_t binding_sid;
304
305 policy = nb_running_get_entry(args->dnode, NULL, true);
306 binding_sid = yang_dnode_get_uint32(args->dnode, NULL);
307
308 switch (args->event) {
309 case NB_EV_VALIDATE:
310 break;
311 case NB_EV_PREPARE:
312 if (path_zebra_request_label(binding_sid) < 0)
313 return NB_ERR_RESOURCE;
314 break;
315 case NB_EV_ABORT:
316 break;
317 case NB_EV_APPLY:
318 srte_policy_update_binding_sid(policy, binding_sid);
319 SET_FLAG(policy->flags, F_POLICY_MODIFIED);
320 break;
321 }
322
323 return NB_OK;
324 }
325
326 int pathd_srte_policy_binding_sid_destroy(struct nb_cb_destroy_args *args)
327 {
328 struct srte_policy *policy;
329
330 if (args->event != NB_EV_APPLY)
331 return NB_OK;
332
333 policy = nb_running_get_entry(args->dnode, NULL, true);
334 srte_policy_update_binding_sid(policy, MPLS_LABEL_NONE);
335 SET_FLAG(policy->flags, F_POLICY_MODIFIED);
336
337 return NB_OK;
338 }
339
340 /*
341 * XPath: /frr-pathd:pathd/srte/policy/candidate-path
342 */
343 int pathd_srte_policy_candidate_path_create(struct nb_cb_create_args *args)
344 {
345 struct srte_policy *policy;
346 struct srte_candidate *candidate;
347 uint32_t preference;
348
349 if (args->event != NB_EV_APPLY)
350 return NB_OK;
351
352 policy = nb_running_get_entry(args->dnode, NULL, true);
353 preference = yang_dnode_get_uint32(args->dnode, "./preference");
354 candidate = srte_candidate_add(policy, preference);
355 nb_running_set_entry(args->dnode, candidate);
356 SET_FLAG(candidate->flags, F_CANDIDATE_NEW);
357
358 return NB_OK;
359 }
360
361 int pathd_srte_policy_candidate_path_destroy(struct nb_cb_destroy_args *args)
362 {
363 struct srte_candidate *candidate;
364
365 if (args->event != NB_EV_APPLY)
366 return NB_OK;
367
368 candidate = nb_running_unset_entry(args->dnode);
369 SET_FLAG(candidate->flags, F_CANDIDATE_DELETED);
370
371 return NB_OK;
372 }
373
374 /*
375 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/name
376 */
377 int pathd_srte_policy_candidate_path_name_modify(struct nb_cb_modify_args *args)
378 {
379 struct srte_candidate *candidate;
380 const char *name;
381 char xpath[XPATH_MAXLEN];
382 char xpath_buf[XPATH_MAXLEN - 3];
383
384 if (args->event != NB_EV_APPLY && args->event != NB_EV_VALIDATE)
385 return NB_OK;
386
387 /* the candidate name is fixed after setting it once, this is checked
388 * here */
389 if (args->event == NB_EV_VALIDATE) {
390 /* first get the precise path to the candidate path */
391 yang_dnode_get_path(args->dnode, xpath_buf, sizeof(xpath_buf));
392 snprintf(xpath, sizeof(xpath), "%s%s", xpath_buf, "/..");
393
394 candidate = nb_running_get_entry_non_rec(NULL, xpath, false);
395
396 /* then check if it exists and if the name was provided */
397 if (candidate && strlen(candidate->name) > 0) {
398 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
399 "The candidate name is fixed!");
400 return NB_ERR_RESOURCE;
401 } else
402 return NB_OK;
403 }
404
405 candidate = nb_running_get_entry(args->dnode, NULL, true);
406
407 name = yang_dnode_get_string(args->dnode, NULL);
408 strlcpy(candidate->name, name, sizeof(candidate->name));
409 SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
410
411 return NB_OK;
412 }
413
414
415 static int affinity_filter_modify(struct nb_cb_modify_args *args,
416 enum affinity_filter_type type)
417 {
418 uint32_t filter;
419 struct srte_candidate *candidate;
420
421 if (args->event != NB_EV_APPLY)
422 return NB_OK;
423
424 assert(args->context != NULL);
425 candidate = nb_running_get_entry(args->dnode, NULL, true);
426 filter = yang_dnode_get_uint32(args->dnode, NULL);
427 srte_candidate_set_affinity_filter(candidate, type, filter);
428
429 return NB_OK;
430 }
431
432 static int affinity_filter_destroy(struct nb_cb_destroy_args *args,
433 enum affinity_filter_type type)
434 {
435 struct srte_candidate *candidate;
436
437 if (args->event != NB_EV_APPLY)
438 return NB_OK;
439
440 assert(args->context != NULL);
441 candidate = nb_running_get_entry(args->dnode, NULL, true);
442 srte_candidate_unset_affinity_filter(candidate, type);
443
444 return NB_OK;
445 }
446
447 /*
448 * XPath:
449 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/affinity/exclude-any
450 */
451
452 int pathd_srte_policy_candidate_path_exclude_any_modify(
453 struct nb_cb_modify_args *args)
454 {
455 return affinity_filter_modify(args, AFFINITY_FILTER_EXCLUDE_ANY);
456 }
457
458 int pathd_srte_policy_candidate_path_exclude_any_destroy(
459 struct nb_cb_destroy_args *args)
460 {
461 return affinity_filter_destroy(args, AFFINITY_FILTER_EXCLUDE_ANY);
462 }
463
464
465 /*
466 * XPath:
467 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/affinity/include-any
468 */
469 int pathd_srte_policy_candidate_path_include_any_modify(
470 struct nb_cb_modify_args *args)
471 {
472 return affinity_filter_modify(args, AFFINITY_FILTER_INCLUDE_ANY);
473 }
474
475 int pathd_srte_policy_candidate_path_include_any_destroy(
476 struct nb_cb_destroy_args *args)
477 {
478 return affinity_filter_destroy(args, AFFINITY_FILTER_INCLUDE_ANY);
479 }
480
481
482 /*
483 * XPath:
484 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/affinity/include-all
485 */
486 int pathd_srte_policy_candidate_path_include_all_modify(
487 struct nb_cb_modify_args *args)
488 {
489 return affinity_filter_modify(args, AFFINITY_FILTER_INCLUDE_ALL);
490 }
491
492 int pathd_srte_policy_candidate_path_include_all_destroy(
493 struct nb_cb_destroy_args *args)
494 {
495 return affinity_filter_destroy(args, AFFINITY_FILTER_INCLUDE_ALL);
496 }
497
498
499 /*
500 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/constraints/metrics
501 */
502 int pathd_srte_policy_candidate_path_metrics_destroy(
503 struct nb_cb_destroy_args *args)
504 {
505 struct srte_candidate *candidate;
506 enum srte_candidate_metric_type type;
507
508 if (args->event != NB_EV_APPLY)
509 return NB_OK;
510
511 assert(args->context != NULL);
512 candidate = nb_running_get_entry(args->dnode, NULL, true);
513
514 type = yang_dnode_get_enum(args->dnode, "./type");
515 srte_candidate_unset_metric(candidate, type);
516
517 return NB_OK;
518 }
519
520 void pathd_srte_policy_candidate_path_metrics_apply_finish(
521 struct nb_cb_apply_finish_args *args)
522 {
523 struct srte_candidate *candidate;
524 enum srte_candidate_metric_type type;
525 float value;
526 bool required, is_bound = false, is_computed = false;
527
528 assert(args->context != NULL);
529
530 candidate = nb_running_get_entry(args->dnode, NULL, true);
531
532 type = yang_dnode_get_enum(args->dnode, "./type");
533 value = (float)yang_dnode_get_dec64(args->dnode, "./value");
534 required = yang_dnode_get_bool(args->dnode, "./required");
535 if (yang_dnode_exists(args->dnode, "./is-bound"))
536 is_bound = yang_dnode_get_bool(args->dnode, "./is-bound");
537 if (yang_dnode_exists(args->dnode, "./is-computed"))
538 is_computed = yang_dnode_get_bool(args->dnode, "./is-computed");
539
540 srte_candidate_set_metric(candidate, type, value, required, is_bound,
541 is_computed);
542 }
543
544 /*
545 * XPath:
546 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/objective-function
547 */
548 int pathd_srte_policy_candidate_path_objfun_destroy(
549 struct nb_cb_destroy_args *args)
550 {
551 struct srte_candidate *candidate;
552
553 if (args->event != NB_EV_APPLY)
554 return NB_OK;
555
556 assert(args->context != NULL);
557
558 candidate = nb_running_get_entry(args->dnode, NULL, true);
559 srte_candidate_unset_objfun(candidate);
560
561 return NB_OK;
562 }
563
564 void pathd_srte_policy_candidate_path_objfun_apply_finish(
565 struct nb_cb_apply_finish_args *args)
566 {
567 struct srte_candidate *candidate;
568 enum objfun_type type;
569 bool required;
570
571 candidate = nb_running_get_entry(args->dnode, NULL, true);
572 required = yang_dnode_get_bool(args->dnode, "./required");
573 type = yang_dnode_get_enum(args->dnode, "./type");
574 srte_candidate_set_objfun(candidate, required, type);
575 }
576
577 /*
578 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/protocol-origin
579 */
580 int pathd_srte_policy_candidate_path_protocol_origin_modify(
581 struct nb_cb_modify_args *args)
582 {
583 struct srte_candidate *candidate;
584 enum srte_protocol_origin protocol_origin;
585
586 if (args->event != NB_EV_APPLY)
587 return NB_OK;
588
589 candidate = nb_running_get_entry(args->dnode, NULL, true);
590 protocol_origin = yang_dnode_get_enum(args->dnode, NULL);
591 candidate->protocol_origin = protocol_origin;
592 candidate->lsp->protocol_origin = protocol_origin;
593 SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
594
595 return NB_OK;
596 }
597
598 /*
599 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/originator
600 */
601 int pathd_srte_policy_candidate_path_originator_modify(
602 struct nb_cb_modify_args *args)
603 {
604 struct srte_candidate *candidate;
605 const char *originator;
606
607 if (args->event != NB_EV_APPLY)
608 return NB_OK;
609
610 candidate = nb_running_get_entry(args->dnode, NULL, true);
611 originator = yang_dnode_get_string(args->dnode, NULL);
612 strlcpy(candidate->originator, originator,
613 sizeof(candidate->originator));
614 strlcpy(candidate->lsp->originator, originator,
615 sizeof(candidate->lsp->originator));
616 SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
617
618 return NB_OK;
619 }
620
621 /*
622 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/type
623 */
624 int pathd_srte_policy_candidate_path_type_modify(struct nb_cb_modify_args *args)
625 {
626 struct srte_candidate *candidate;
627 enum srte_candidate_type type;
628 char xpath[XPATH_MAXLEN];
629 char xpath_buf[XPATH_MAXLEN - 3];
630
631 if (args->event != NB_EV_APPLY && args->event != NB_EV_VALIDATE)
632 return NB_OK;
633
634 /* the candidate type is fixed after setting it once, this is checked
635 * here */
636 if (args->event == NB_EV_VALIDATE) {
637 /* first get the precise path to the candidate path */
638 yang_dnode_get_path(args->dnode, xpath_buf, sizeof(xpath_buf));
639 snprintf(xpath, sizeof(xpath), "%s%s", xpath_buf, "/..");
640
641 candidate = nb_running_get_entry_non_rec(NULL, xpath, false);
642
643 /* then check if it exists and if the type was provided */
644 if (candidate
645 && candidate->type != SRTE_CANDIDATE_TYPE_UNDEFINED) {
646 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE,
647 "The candidate type is fixed!");
648 return NB_ERR_RESOURCE;
649 } else
650 return NB_OK;
651 }
652
653 candidate = nb_running_get_entry(args->dnode, NULL, true);
654
655 type = yang_dnode_get_enum(args->dnode, NULL);
656 candidate->type = type;
657 SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
658
659 return NB_OK;
660 }
661
662 /*
663 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/segment-list-name
664 */
665 int pathd_srte_policy_candidate_path_segment_list_name_modify(
666 struct nb_cb_modify_args *args)
667 {
668 struct srte_candidate *candidate;
669 const char *segment_list_name;
670
671 candidate = nb_running_get_entry(args->dnode, NULL, true);
672 segment_list_name = yang_dnode_get_string(args->dnode, NULL);
673
674 if (args->event != NB_EV_APPLY)
675 return NB_OK;
676
677 candidate->segment_list = srte_segment_list_find(segment_list_name);
678 candidate->lsp->segment_list = candidate->segment_list;
679 assert(candidate->segment_list);
680 SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
681
682 return NB_OK;
683 }
684
685 int pathd_srte_policy_candidate_path_segment_list_name_destroy(
686 struct nb_cb_destroy_args *args)
687 {
688 struct srte_candidate *candidate;
689
690 if (args->event != NB_EV_APPLY)
691 return NB_OK;
692
693 candidate = nb_running_get_entry(args->dnode, NULL, true);
694 candidate->segment_list = NULL;
695 candidate->lsp->segment_list = NULL;
696 SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
697
698 return NB_OK;
699 }
700
701 /*
702 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/constraints/bandwidth
703 */
704 void pathd_srte_policy_candidate_path_bandwidth_apply_finish(
705 struct nb_cb_apply_finish_args *args)
706 {
707 struct srte_candidate *candidate;
708 float value;
709 bool required;
710
711 assert(args->context != NULL);
712
713 candidate = nb_running_get_entry(args->dnode, NULL, true);
714 value = (float)yang_dnode_get_dec64(args->dnode, "./value");
715 required = yang_dnode_get_bool(args->dnode, "./required");
716 srte_candidate_set_bandwidth(candidate, value, required);
717 }
718
719 int pathd_srte_policy_candidate_path_bandwidth_destroy(
720 struct nb_cb_destroy_args *args)
721 {
722 struct srte_candidate *candidate;
723
724 if (args->event != NB_EV_APPLY)
725 return NB_OK;
726
727 assert(args->context != NULL);
728 candidate = nb_running_get_entry(args->dnode, NULL, true);
729 srte_candidate_unset_bandwidth(candidate);
730 return NB_OK;
731 }