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