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