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_nai_destroy(struct nb_cb_destroy_args
*args
)
165 struct srte_segment_entry
*segment
;
167 if (args
->event
!= NB_EV_APPLY
)
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;
180 void pathd_srte_segment_list_segment_nai_apply_finish(
181 struct nb_cb_apply_finish_args
*args
)
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;
188 segment
= nb_running_get_entry(args
->dnode
, NULL
, true);
189 type
= yang_dnode_get_enum(args
->dnode
, "./type");
191 yang_dnode_get_ip(&local_addr
, args
->dnode
, "./local-address");
194 case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE
:
195 case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE
:
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
,
202 case SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY
:
203 yang_dnode_get_ip(&remote_addr
, args
->dnode
,
206 yang_dnode_get_uint32(args
->dnode
, "./local-interface");
207 remote_iface
= yang_dnode_get_uint32(args
->dnode
,
208 "./remote-interface");
214 srte_segment_entry_set_nai(segment
, type
, &local_addr
, local_iface
,
215 &remote_addr
, remote_iface
);
219 * XPath: /frr-pathd:pathd/srte/policy
221 int pathd_srte_policy_create(struct nb_cb_create_args
*args
)
223 struct srte_policy
*policy
;
225 struct ipaddr endpoint
;
227 if (args
->event
!= NB_EV_APPLY
)
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
);
234 nb_running_set_entry(args
->dnode
, policy
);
235 SET_FLAG(policy
->flags
, F_POLICY_NEW
);
240 int pathd_srte_policy_destroy(struct nb_cb_destroy_args
*args
)
242 struct srte_policy
*policy
;
244 if (args
->event
!= NB_EV_APPLY
)
247 policy
= nb_running_unset_entry(args
->dnode
);
248 SET_FLAG(policy
->flags
, F_POLICY_DELETED
);
254 * XPath: /frr-pathd:pathd/srte/policy/name
256 int pathd_srte_policy_name_modify(struct nb_cb_modify_args
*args
)
258 struct srte_policy
*policy
;
261 if (args
->event
!= NB_EV_APPLY
&& args
->event
!= NB_EV_VALIDATE
)
264 policy
= nb_running_get_entry(args
->dnode
, NULL
, true);
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
;
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
);
283 int pathd_srte_policy_name_destroy(struct nb_cb_destroy_args
*args
)
285 struct srte_policy
*policy
;
287 if (args
->event
!= NB_EV_APPLY
)
290 policy
= nb_running_get_entry(args
->dnode
, NULL
, true);
291 policy
->name
[0] = '\0';
292 SET_FLAG(policy
->flags
, F_POLICY_MODIFIED
);
298 * XPath: /frr-pathd:pathd/srte/policy/binding-sid
300 int pathd_srte_policy_binding_sid_modify(struct nb_cb_modify_args
*args
)
302 struct srte_policy
*policy
;
303 mpls_label_t binding_sid
;
305 policy
= nb_running_get_entry(args
->dnode
, NULL
, true);
306 binding_sid
= yang_dnode_get_uint32(args
->dnode
, NULL
);
308 switch (args
->event
) {
312 if (path_zebra_request_label(binding_sid
) < 0)
313 return NB_ERR_RESOURCE
;
318 srte_policy_update_binding_sid(policy
, binding_sid
);
319 SET_FLAG(policy
->flags
, F_POLICY_MODIFIED
);
326 int pathd_srte_policy_binding_sid_destroy(struct nb_cb_destroy_args
*args
)
328 struct srte_policy
*policy
;
330 if (args
->event
!= NB_EV_APPLY
)
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
);
341 * XPath: /frr-pathd:pathd/srte/policy/candidate-path
343 int pathd_srte_policy_candidate_path_create(struct nb_cb_create_args
*args
)
345 struct srte_policy
*policy
;
346 struct srte_candidate
*candidate
;
349 if (args
->event
!= NB_EV_APPLY
)
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
);
361 int pathd_srte_policy_candidate_path_destroy(struct nb_cb_destroy_args
*args
)
363 struct srte_candidate
*candidate
;
365 if (args
->event
!= NB_EV_APPLY
)
368 candidate
= nb_running_unset_entry(args
->dnode
);
369 SET_FLAG(candidate
->flags
, F_CANDIDATE_DELETED
);
375 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/name
377 int pathd_srte_policy_candidate_path_name_modify(struct nb_cb_modify_args
*args
)
379 struct srte_candidate
*candidate
;
381 char xpath
[XPATH_MAXLEN
];
382 char xpath_buf
[XPATH_MAXLEN
- 3];
384 if (args
->event
!= NB_EV_APPLY
&& args
->event
!= NB_EV_VALIDATE
)
387 /* the candidate name is fixed after setting it once, this is checked
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
, "/..");
394 candidate
= nb_running_get_entry_non_rec(NULL
, xpath
, false);
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
;
405 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
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
);
415 static int affinity_filter_modify(struct nb_cb_modify_args
*args
,
416 enum affinity_filter_type type
)
419 struct srte_candidate
*candidate
;
421 if (args
->event
!= NB_EV_APPLY
)
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
);
432 static int affinity_filter_destroy(struct nb_cb_destroy_args
*args
,
433 enum affinity_filter_type type
)
435 struct srte_candidate
*candidate
;
437 if (args
->event
!= NB_EV_APPLY
)
440 assert(args
->context
!= NULL
);
441 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
442 srte_candidate_unset_affinity_filter(candidate
, type
);
449 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/affinity/exclude-any
452 int pathd_srte_policy_candidate_path_exclude_any_modify(
453 struct nb_cb_modify_args
*args
)
455 return affinity_filter_modify(args
, AFFINITY_FILTER_EXCLUDE_ANY
);
458 int pathd_srte_policy_candidate_path_exclude_any_destroy(
459 struct nb_cb_destroy_args
*args
)
461 return affinity_filter_destroy(args
, AFFINITY_FILTER_EXCLUDE_ANY
);
467 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/affinity/include-any
469 int pathd_srte_policy_candidate_path_include_any_modify(
470 struct nb_cb_modify_args
*args
)
472 return affinity_filter_modify(args
, AFFINITY_FILTER_INCLUDE_ANY
);
475 int pathd_srte_policy_candidate_path_include_any_destroy(
476 struct nb_cb_destroy_args
*args
)
478 return affinity_filter_destroy(args
, AFFINITY_FILTER_INCLUDE_ANY
);
484 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/affinity/include-all
486 int pathd_srte_policy_candidate_path_include_all_modify(
487 struct nb_cb_modify_args
*args
)
489 return affinity_filter_modify(args
, AFFINITY_FILTER_INCLUDE_ALL
);
492 int pathd_srte_policy_candidate_path_include_all_destroy(
493 struct nb_cb_destroy_args
*args
)
495 return affinity_filter_destroy(args
, AFFINITY_FILTER_INCLUDE_ALL
);
500 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/constraints/metrics
502 int pathd_srte_policy_candidate_path_metrics_destroy(
503 struct nb_cb_destroy_args
*args
)
505 struct srte_candidate
*candidate
;
506 enum srte_candidate_metric_type type
;
508 if (args
->event
!= NB_EV_APPLY
)
511 assert(args
->context
!= NULL
);
512 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
514 type
= yang_dnode_get_enum(args
->dnode
, "./type");
515 srte_candidate_unset_metric(candidate
, type
);
520 void pathd_srte_policy_candidate_path_metrics_apply_finish(
521 struct nb_cb_apply_finish_args
*args
)
523 struct srte_candidate
*candidate
;
524 enum srte_candidate_metric_type type
;
526 bool required
, is_bound
= false, is_computed
= false;
528 assert(args
->context
!= NULL
);
530 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
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");
540 srte_candidate_set_metric(candidate
, type
, value
, required
, is_bound
,
546 * /frr-pathd:pathd/srte/policy/candidate-path/constraints/objective-function
548 int pathd_srte_policy_candidate_path_objfun_destroy(
549 struct nb_cb_destroy_args
*args
)
551 struct srte_candidate
*candidate
;
553 if (args
->event
!= NB_EV_APPLY
)
556 assert(args
->context
!= NULL
);
558 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
559 srte_candidate_unset_objfun(candidate
);
564 void pathd_srte_policy_candidate_path_objfun_apply_finish(
565 struct nb_cb_apply_finish_args
*args
)
567 struct srte_candidate
*candidate
;
568 enum objfun_type type
;
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
);
578 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/protocol-origin
580 int pathd_srte_policy_candidate_path_protocol_origin_modify(
581 struct nb_cb_modify_args
*args
)
583 struct srte_candidate
*candidate
;
584 enum srte_protocol_origin protocol_origin
;
586 if (args
->event
!= NB_EV_APPLY
)
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
);
599 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/originator
601 int pathd_srte_policy_candidate_path_originator_modify(
602 struct nb_cb_modify_args
*args
)
604 struct srte_candidate
*candidate
;
605 const char *originator
;
607 if (args
->event
!= NB_EV_APPLY
)
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
);
622 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/type
624 int pathd_srte_policy_candidate_path_type_modify(struct nb_cb_modify_args
*args
)
626 struct srte_candidate
*candidate
;
627 enum srte_candidate_type type
;
628 char xpath
[XPATH_MAXLEN
];
629 char xpath_buf
[XPATH_MAXLEN
- 3];
631 if (args
->event
!= NB_EV_APPLY
&& args
->event
!= NB_EV_VALIDATE
)
634 /* the candidate type is fixed after setting it once, this is checked
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
, "/..");
641 candidate
= nb_running_get_entry_non_rec(NULL
, xpath
, false);
643 /* then check if it exists and if the type was provided */
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
;
653 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
655 type
= yang_dnode_get_enum(args
->dnode
, NULL
);
656 candidate
->type
= type
;
657 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
663 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/segment-list-name
665 int pathd_srte_policy_candidate_path_segment_list_name_modify(
666 struct nb_cb_modify_args
*args
)
668 struct srte_candidate
*candidate
;
669 const char *segment_list_name
;
671 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
672 segment_list_name
= yang_dnode_get_string(args
->dnode
, NULL
);
674 if (args
->event
!= NB_EV_APPLY
)
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
);
685 int pathd_srte_policy_candidate_path_segment_list_name_destroy(
686 struct nb_cb_destroy_args
*args
)
688 struct srte_candidate
*candidate
;
690 if (args
->event
!= NB_EV_APPLY
)
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
);
702 * XPath: /frr-pathd:pathd/srte/policy/candidate-path/constraints/bandwidth
704 void pathd_srte_policy_candidate_path_bandwidth_apply_finish(
705 struct nb_cb_apply_finish_args
*args
)
707 struct srte_candidate
*candidate
;
711 assert(args
->context
!= NULL
);
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
);
719 int pathd_srte_policy_candidate_path_bandwidth_destroy(
720 struct nb_cb_destroy_args
*args
)
722 struct srte_candidate
*candidate
;
724 if (args
->event
!= NB_EV_APPLY
)
727 assert(args
->context
!= NULL
);
728 candidate
= nb_running_get_entry(args
->dnode
, NULL
, true);
729 srte_candidate_unset_bandwidth(candidate
);