2 * Copyright (C) 2020 NetDEF, Inc.
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)
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
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
20 #include <lib_errors.h>
22 #include "northbound.h"
25 #include "pathd/path_zebra.h"
26 #include "pathd/path_nb.h"
29 * XPath: /frr-pathd:pathd
31 void pathd_apply_finish(struct nb_cb_apply_finish_args
*args
)
37 * XPath: /frr-pathd:pathd/srte/segment-list
39 int pathd_srte_segment_list_create(struct nb_cb_create_args
*args
)
41 struct srte_segment_list
*segment_list
;
44 if (args
->event
!= NB_EV_APPLY
)
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
);
55 int pathd_srte_segment_list_destroy(struct nb_cb_destroy_args
*args
)
57 struct srte_segment_list
*segment_list
;
59 if (args
->event
!= NB_EV_APPLY
)
62 segment_list
= nb_running_unset_entry(args
->dnode
);
63 SET_FLAG(segment_list
->flags
, F_SEGMENT_LIST_DELETED
);
69 * XPath: /frr-pathd:pathd/srte/segment-list/protocol-origin
71 int pathd_srte_segment_list_protocol_origin_modify(
72 struct nb_cb_modify_args
*args
)
74 struct srte_segment_list
*segment_list
;
76 if (args
->event
!= NB_EV_APPLY
)
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
);
87 * XPath: /frr-pathd:pathd/srte/segment-list/originator
89 int pathd_srte_segment_list_originator_modify(struct nb_cb_modify_args
*args
)
91 struct srte_segment_list
*segment_list
;
92 const char *originator
;
94 if (args
->event
!= NB_EV_APPLY
)
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
);
108 * XPath: /frr-pathd:pathd/srte/segment-list/segment
110 int pathd_srte_segment_list_segment_create(struct nb_cb_create_args
*args
)
112 struct srte_segment_list
*segment_list
;
113 struct srte_segment_entry
*segment
;
116 if (args
->event
!= NB_EV_APPLY
)
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
);
128 int pathd_srte_segment_list_segment_destroy(struct nb_cb_destroy_args
*args
)
130 struct srte_segment_entry
*segment
;
132 if (args
->event
!= NB_EV_APPLY
)
135 segment
= nb_running_unset_entry(args
->dnode
);
136 SET_FLAG(segment
->segment_list
->flags
, F_SEGMENT_LIST_MODIFIED
);
138 srte_segment_entry_del(segment
);
144 * XPath: /frr-pathd:pathd/srte/segment-list/segment/sid-value
146 int pathd_srte_segment_list_segment_sid_value_modify(
147 struct nb_cb_modify_args
*args
)
149 mpls_label_t sid_value
;
150 struct srte_segment_entry
*segment
;
152 if (args
->event
!= NB_EV_APPLY
)
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
);
163 int pathd_srte_segment_list_segment_sid_value_destroy(
164 struct nb_cb_destroy_args
*args
)
166 struct srte_segment_entry
*segment
;
168 if (args
->event
!= NB_EV_APPLY
)
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
);
179 int pathd_srte_segment_list_segment_nai_destroy(struct nb_cb_destroy_args
*args
)
181 struct srte_segment_entry
*segment
;
183 if (args
->event
!= NB_EV_APPLY
)
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;
196 void pathd_srte_segment_list_segment_nai_apply_finish(
197 struct nb_cb_apply_finish_args
*args
)
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
;
206 segment
= nb_running_get_entry(args
->dnode
, NULL
, true);
207 type
= yang_dnode_get_enum(args
->dnode
, "./type");
209 yang_dnode_get_ip(&local_addr
, args
->dnode
, "./local-address");
212 case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE
:
213 case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE
:
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
,
220 case SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY
:
221 yang_dnode_get_ip(&remote_addr
, args
->dnode
,
224 yang_dnode_get_uint32(args
->dnode
, "./local-interface");
225 remote_iface
= yang_dnode_get_uint32(args
->dnode
,
226 "./remote-interface");
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
);
235 case SRTE_SEGMENT_NAI_TYPE_IPV4_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
);
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
,
251 SET_FLAG(segment
->segment_list
->flags
,
252 F_SEGMENT_LIST_SID_CONFLICT
);
256 * XPath: /frr-pathd:pathd/srte/policy
258 int pathd_srte_policy_create(struct nb_cb_create_args
*args
)
260 struct srte_policy
*policy
;
262 struct ipaddr endpoint
;
264 if (args
->event
!= NB_EV_APPLY
)
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
, SRTE_ORIGIN_LOCAL
, NULL
);
271 nb_running_set_entry(args
->dnode
, policy
);
272 SET_FLAG(policy
->flags
, F_POLICY_NEW
);
277 int pathd_srte_policy_destroy(struct nb_cb_destroy_args
*args
)
279 struct srte_policy
*policy
;
281 if (args
->event
!= NB_EV_APPLY
)
284 policy
= nb_running_unset_entry(args
->dnode
);
285 SET_FLAG(policy
->flags
, F_POLICY_DELETED
);
291 * XPath: /frr-pathd:pathd/srte/policy/name
293 int pathd_srte_policy_name_modify(struct nb_cb_modify_args
*args
)
295 struct srte_policy
*policy
;
298 if (args
->event
!= NB_EV_APPLY
&& args
->event
!= NB_EV_VALIDATE
)
301 policy
= nb_running_get_entry(args
->dnode
, NULL
, true);
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
;
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
);
320 int pathd_srte_policy_name_destroy(struct nb_cb_destroy_args
*args
)
322 struct srte_policy
*policy
;
324 if (args
->event
!= NB_EV_APPLY
)
327 policy
= nb_running_get_entry(args
->dnode
, NULL
, true);
328 policy
->name
[0] = '\0';
329 SET_FLAG(policy
->flags
, F_POLICY_MODIFIED
);
335 * XPath: /frr-pathd:pathd/srte/policy/binding-sid
337 int pathd_srte_policy_binding_sid_modify(struct nb_cb_modify_args
*args
)
339 struct srte_policy
*policy
;
340 mpls_label_t binding_sid
;
342 binding_sid
= yang_dnode_get_uint32(args
->dnode
, NULL
);
344 switch (args
->event
) {
348 if (path_zebra_request_label(binding_sid
) < 0)
349 return NB_ERR_RESOURCE
;
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
);
363 int pathd_srte_policy_binding_sid_destroy(struct nb_cb_destroy_args
*args
)
365 struct srte_policy
*policy
;
367 if (args
->event
!= NB_EV_APPLY
)
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
);
378 * XPath: /frr-pathd:pathd/srte/policy/candidate-path
380 int pathd_srte_policy_candidate_path_create(struct nb_cb_create_args
*args
)
382 struct srte_policy
*policy
;
383 struct srte_candidate
*candidate
;
386 if (args
->event
!= NB_EV_APPLY
)
389 policy
= nb_running_get_entry(args
->dnode
, NULL
, true);
390 preference
= yang_dnode_get_uint32(args
->dnode
, "./preference");
392 srte_candidate_add(policy
, preference
, SRTE_ORIGIN_LOCAL
, NULL
);
393 nb_running_set_entry(args
->dnode
, candidate
);
394 SET_FLAG(candidate
->flags
, F_CANDIDATE_NEW
);
399 int pathd_srte_policy_candidate_path_destroy(struct nb_cb_destroy_args
*args
)
401 struct srte_candidate
*candidate
;
403 if (args
->event
!= NB_EV_APPLY
)
406 candidate
= nb_running_unset_entry(args
->dnode
);
407 SET_FLAG(candidate
->flags
, F_CANDIDATE_DELETED
);
413 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/name
415 int pathd_srte_policy_candidate_path_name_modify(struct nb_cb_modify_args
*args
)
417 struct srte_candidate
*candidate
;
419 char xpath
[XPATH_MAXLEN
];
420 char xpath_buf
[XPATH_MAXLEN
- 3];
422 if (args
->event
!= NB_EV_APPLY
&& args
->event
!= NB_EV_VALIDATE
)
425 /* the candidate name is fixed after setting it once, this is checked
427 if (args
->event
== NB_EV_VALIDATE
) {
428 /* first get the precise path to the candidate path */
429 yang_dnode_get_path(args
->dnode
, xpath_buf
, sizeof(xpath_buf
));
430 snprintf(xpath
, sizeof(xpath
), "%s%s", xpath_buf
, "/..");
432 candidate
= nb_running_get_entry_non_rec(NULL
, xpath
, false);
434 /* then check if it exists and if the name was provided */
435 if (candidate
&& strlen(candidate
->name
) > 0) {
436 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE
,
437 "The candidate name is fixed!");
438 return NB_ERR_RESOURCE
;
443 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
445 name
= yang_dnode_get_string(args
->dnode
, NULL
);
446 strlcpy(candidate
->name
, name
, sizeof(candidate
->name
));
447 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
453 static int affinity_filter_modify(struct nb_cb_modify_args
*args
,
454 enum affinity_filter_type type
)
457 struct srte_candidate
*candidate
;
459 if (args
->event
!= NB_EV_APPLY
)
462 assert(args
->context
!= NULL
);
463 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
464 filter
= yang_dnode_get_uint32(args
->dnode
, NULL
);
465 srte_candidate_set_affinity_filter(candidate
, type
, filter
);
470 static int affinity_filter_destroy(struct nb_cb_destroy_args
*args
,
471 enum affinity_filter_type type
)
473 struct srte_candidate
*candidate
;
475 if (args
->event
!= NB_EV_APPLY
)
478 assert(args
->context
!= NULL
);
479 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
480 srte_candidate_unset_affinity_filter(candidate
, type
);
487 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/affinity/exclude-any
490 int pathd_srte_policy_candidate_path_exclude_any_modify(
491 struct nb_cb_modify_args
*args
)
493 return affinity_filter_modify(args
, AFFINITY_FILTER_EXCLUDE_ANY
);
496 int pathd_srte_policy_candidate_path_exclude_any_destroy(
497 struct nb_cb_destroy_args
*args
)
499 return affinity_filter_destroy(args
, AFFINITY_FILTER_EXCLUDE_ANY
);
505 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/affinity/include-any
507 int pathd_srte_policy_candidate_path_include_any_modify(
508 struct nb_cb_modify_args
*args
)
510 return affinity_filter_modify(args
, AFFINITY_FILTER_INCLUDE_ANY
);
513 int pathd_srte_policy_candidate_path_include_any_destroy(
514 struct nb_cb_destroy_args
*args
)
516 return affinity_filter_destroy(args
, AFFINITY_FILTER_INCLUDE_ANY
);
522 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/affinity/include-all
524 int pathd_srte_policy_candidate_path_include_all_modify(
525 struct nb_cb_modify_args
*args
)
527 return affinity_filter_modify(args
, AFFINITY_FILTER_INCLUDE_ALL
);
530 int pathd_srte_policy_candidate_path_include_all_destroy(
531 struct nb_cb_destroy_args
*args
)
533 return affinity_filter_destroy(args
, AFFINITY_FILTER_INCLUDE_ALL
);
538 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/constraints/metrics
540 int pathd_srte_policy_candidate_path_metrics_destroy(
541 struct nb_cb_destroy_args
*args
)
543 struct srte_candidate
*candidate
;
544 enum srte_candidate_metric_type type
;
546 if (args
->event
!= NB_EV_APPLY
)
549 assert(args
->context
!= NULL
);
550 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
552 type
= yang_dnode_get_enum(args
->dnode
, "./type");
553 srte_candidate_unset_metric(candidate
, type
);
558 void pathd_srte_policy_candidate_path_metrics_apply_finish(
559 struct nb_cb_apply_finish_args
*args
)
561 struct srte_candidate
*candidate
;
562 enum srte_candidate_metric_type type
;
564 bool required
, is_bound
= false, is_computed
= false;
566 assert(args
->context
!= NULL
);
568 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
570 type
= yang_dnode_get_enum(args
->dnode
, "./type");
571 value
= (float)yang_dnode_get_dec64(args
->dnode
, "./value");
572 required
= yang_dnode_get_bool(args
->dnode
, "./required");
573 if (yang_dnode_exists(args
->dnode
, "./is-bound"))
574 is_bound
= yang_dnode_get_bool(args
->dnode
, "./is-bound");
575 if (yang_dnode_exists(args
->dnode
, "./is-computed"))
576 is_computed
= yang_dnode_get_bool(args
->dnode
, "./is-computed");
578 srte_candidate_set_metric(candidate
, type
, value
, required
, is_bound
,
584 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/objective-function
586 int pathd_srte_policy_candidate_path_objfun_destroy(
587 struct nb_cb_destroy_args
*args
)
589 struct srte_candidate
*candidate
;
591 if (args
->event
!= NB_EV_APPLY
)
594 assert(args
->context
!= NULL
);
596 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
597 srte_candidate_unset_objfun(candidate
);
602 void pathd_srte_policy_candidate_path_objfun_apply_finish(
603 struct nb_cb_apply_finish_args
*args
)
605 struct srte_candidate
*candidate
;
606 enum objfun_type type
;
609 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
610 required
= yang_dnode_get_bool(args
->dnode
, "./required");
611 type
= yang_dnode_get_enum(args
->dnode
, "./type");
612 srte_candidate_set_objfun(candidate
, required
, type
);
616 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/protocol-origin
618 int pathd_srte_policy_candidate_path_protocol_origin_modify(
619 struct nb_cb_modify_args
*args
)
621 struct srte_candidate
*candidate
;
622 enum srte_protocol_origin protocol_origin
;
624 if (args
->event
!= NB_EV_APPLY
)
627 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
628 protocol_origin
= yang_dnode_get_enum(args
->dnode
, NULL
);
629 candidate
->protocol_origin
= protocol_origin
;
630 candidate
->lsp
->protocol_origin
= protocol_origin
;
631 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
637 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/originator
639 int pathd_srte_policy_candidate_path_originator_modify(
640 struct nb_cb_modify_args
*args
)
642 struct srte_candidate
*candidate
;
643 const char *originator
;
645 if (args
->event
!= NB_EV_APPLY
)
648 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
649 originator
= yang_dnode_get_string(args
->dnode
, NULL
);
650 strlcpy(candidate
->originator
, originator
,
651 sizeof(candidate
->originator
));
652 strlcpy(candidate
->lsp
->originator
, originator
,
653 sizeof(candidate
->lsp
->originator
));
654 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
660 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/type
662 int pathd_srte_policy_candidate_path_type_modify(struct nb_cb_modify_args
*args
)
664 struct srte_candidate
*candidate
;
665 enum srte_candidate_type type
;
666 char xpath
[XPATH_MAXLEN
];
667 char xpath_buf
[XPATH_MAXLEN
- 3];
669 if (args
->event
!= NB_EV_APPLY
&& args
->event
!= NB_EV_VALIDATE
)
672 /* the candidate type is fixed after setting it once, this is checked
674 if (args
->event
== NB_EV_VALIDATE
) {
675 /* first get the precise path to the candidate path */
676 yang_dnode_get_path(args
->dnode
, xpath_buf
, sizeof(xpath_buf
));
677 snprintf(xpath
, sizeof(xpath
), "%s%s", xpath_buf
, "/..");
679 candidate
= nb_running_get_entry_non_rec(NULL
, xpath
, false);
681 /* then check if it exists and if the type was provided */
683 && candidate
->type
!= SRTE_CANDIDATE_TYPE_UNDEFINED
) {
684 flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE
,
685 "The candidate type is fixed!");
686 return NB_ERR_RESOURCE
;
691 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
693 type
= yang_dnode_get_enum(args
->dnode
, NULL
);
694 candidate
->type
= type
;
695 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
701 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/segment-list-name
703 int pathd_srte_policy_candidate_path_segment_list_name_modify(
704 struct nb_cb_modify_args
*args
)
706 struct srte_candidate
*candidate
;
707 const char *segment_list_name
;
709 if (args
->event
!= NB_EV_APPLY
)
712 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
713 segment_list_name
= yang_dnode_get_string(args
->dnode
, NULL
);
715 candidate
->segment_list
= srte_segment_list_find(segment_list_name
);
716 candidate
->lsp
->segment_list
= candidate
->segment_list
;
717 assert(candidate
->segment_list
);
718 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
723 int pathd_srte_policy_candidate_path_segment_list_name_destroy(
724 struct nb_cb_destroy_args
*args
)
726 struct srte_candidate
*candidate
;
728 if (args
->event
!= NB_EV_APPLY
)
731 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
732 candidate
->segment_list
= NULL
;
733 candidate
->lsp
->segment_list
= NULL
;
734 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
740 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/constraints/bandwidth
742 void pathd_srte_policy_candidate_path_bandwidth_apply_finish(
743 struct nb_cb_apply_finish_args
*args
)
745 struct srte_candidate
*candidate
;
749 assert(args
->context
!= NULL
);
751 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
752 value
= (float)yang_dnode_get_dec64(args
->dnode
, "./value");
753 required
= yang_dnode_get_bool(args
->dnode
, "./required");
754 srte_candidate_set_bandwidth(candidate
, value
, required
);
757 int pathd_srte_policy_candidate_path_bandwidth_destroy(
758 struct nb_cb_destroy_args
*args
)
760 struct srte_candidate
*candidate
;
762 if (args
->event
!= NB_EV_APPLY
)
765 assert(args
->context
!= NULL
);
766 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
767 srte_candidate_unset_bandwidth(candidate
);