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
23 #include "lib_errors.h"
27 #include "pathd/pathd.h"
28 #include "pathd/path_zebra.h"
29 #include "pathd/path_debug.h"
30 #include "pathd/path_ted.h"
34 DEFINE_MGROUP(PATHD
, "pathd");
36 DEFINE_MTYPE_STATIC(PATHD
, PATH_SEGMENT_LIST
, "Segment List");
37 DEFINE_MTYPE_STATIC(PATHD
, PATH_SR_POLICY
, "SR Policy");
38 DEFINE_MTYPE_STATIC(PATHD
, PATH_SR_CANDIDATE
, "SR Policy candidate path");
40 DEFINE_HOOK(pathd_candidate_created
, (struct srte_candidate
* candidate
),
42 DEFINE_HOOK(pathd_candidate_updated
, (struct srte_candidate
* candidate
),
44 DEFINE_HOOK(pathd_candidate_removed
, (struct srte_candidate
* candidate
),
47 static void trigger_pathd_candidate_created(struct srte_candidate
*candidate
);
48 static void trigger_pathd_candidate_created_timer(struct thread
*thread
);
49 static void trigger_pathd_candidate_updated(struct srte_candidate
*candidate
);
50 static void trigger_pathd_candidate_updated_timer(struct thread
*thread
);
51 static void trigger_pathd_candidate_removed(struct srte_candidate
*candidate
);
53 srte_candidate_metric_name(enum srte_candidate_metric_type type
);
55 static void srte_set_metric(struct srte_metric
*metric
, float value
,
56 bool required
, bool is_bound
, bool is_computed
);
57 static void srte_unset_metric(struct srte_metric
*metric
);
60 /* Generate rb-tree of Segment List Segment instances. */
61 static inline int srte_segment_entry_compare(const struct srte_segment_entry
*a
,
62 const struct srte_segment_entry
*b
)
64 return a
->index
- b
->index
;
66 RB_GENERATE(srte_segment_entry_head
, srte_segment_entry
, entry
,
67 srte_segment_entry_compare
)
69 /* Generate rb-tree of Segment List instances. */
70 static inline int srte_segment_list_compare(const struct srte_segment_list
*a
,
71 const struct srte_segment_list
*b
)
73 return strcmp(a
->name
, b
->name
);
75 RB_GENERATE(srte_segment_list_head
, srte_segment_list
, entry
,
76 srte_segment_list_compare
)
78 struct srte_segment_list_head srte_segment_lists
=
79 RB_INITIALIZER(&srte_segment_lists
);
81 /* Generate rb-tree of Candidate Path instances. */
82 static inline int srte_candidate_compare(const struct srte_candidate
*a
,
83 const struct srte_candidate
*b
)
85 return a
->preference
- b
->preference
;
87 RB_GENERATE(srte_candidate_head
, srte_candidate
, entry
, srte_candidate_compare
)
89 /* Generate rb-tree of SR Policy instances. */
90 static inline int srte_policy_compare(const struct srte_policy
*a
,
91 const struct srte_policy
*b
)
93 return sr_policy_compare(&a
->endpoint
, &b
->endpoint
, a
->color
,
96 RB_GENERATE(srte_policy_head
, srte_policy
, entry
, srte_policy_compare
)
98 struct srte_policy_head srte_policies
= RB_INITIALIZER(&srte_policies
);
101 * Adds a segment list to pathd.
103 * @param name The name of the segment list to add
104 * @return The added segment list
106 struct srte_segment_list
*srte_segment_list_add(const char *name
)
108 struct srte_segment_list
*segment_list
;
110 segment_list
= XCALLOC(MTYPE_PATH_SEGMENT_LIST
, sizeof(*segment_list
));
111 strlcpy(segment_list
->name
, name
, sizeof(segment_list
->name
));
112 RB_INIT(srte_segment_entry_head
, &segment_list
->segments
);
113 RB_INSERT(srte_segment_list_head
, &srte_segment_lists
, segment_list
);
119 * Deletes a segment list from pathd.
121 * The given segment list structure will be freed and should not be used anymore
122 * after calling this function.
124 * @param segment_list the segment list to remove from pathd.
126 void srte_segment_list_del(struct srte_segment_list
*segment_list
)
128 struct srte_segment_entry
*segment
, *safe_seg
;
129 RB_FOREACH_SAFE (segment
, srte_segment_entry_head
,
130 &segment_list
->segments
, safe_seg
) {
131 srte_segment_entry_del(segment
);
133 RB_REMOVE(srte_segment_list_head
, &srte_segment_lists
, segment_list
);
134 XFREE(MTYPE_PATH_SEGMENT_LIST
, segment_list
);
138 * Search for a segment list by name.
140 * @param name The name of the segment list to look for
141 * @return The segment list if found, NULL otherwise
143 struct srte_segment_list
*srte_segment_list_find(const char *name
)
145 struct srte_segment_list search
;
147 strlcpy(search
.name
, name
, sizeof(search
.name
));
148 return RB_FIND(srte_segment_list_head
, &srte_segment_lists
, &search
);
152 * Adds a segment to a segment list.
154 * @param segment_list The segment list the segment should be added to
155 * @param index The index of the added segment in the segment list
156 * @return The added segment
158 struct srte_segment_entry
*
159 srte_segment_entry_add(struct srte_segment_list
*segment_list
, uint32_t index
)
161 struct srte_segment_entry
*segment
;
163 segment
= XCALLOC(MTYPE_PATH_SEGMENT_LIST
, sizeof(*segment
));
164 segment
->segment_list
= segment_list
;
165 segment
->index
= index
;
166 RB_INSERT(srte_segment_entry_head
, &segment_list
->segments
, segment
);
172 * Deletes a segment from a segment list.
174 * @param segment The segment to be removed
176 void srte_segment_entry_del(struct srte_segment_entry
*segment
)
178 RB_REMOVE(srte_segment_entry_head
, &segment
->segment_list
->segments
,
180 XFREE(MTYPE_PATH_SEGMENT_LIST
, segment
);
184 * Set the node or adjacency identifier of a segment.
186 * @param segment The segment for which the NAI should be set
187 * @param type The type of the NAI
188 * @param type The address of the node or the local address of the adjacency
189 * @param type The local interface index of the unumbered adjacency
190 * @param type The remote address of the adjacency
191 * @param type The remote interface index of the unumbered adjacency
193 int srte_segment_entry_set_nai(struct srte_segment_entry
*segment
,
194 enum srte_segment_nai_type type
,
195 struct ipaddr
*local_ip
, uint32_t local_iface
,
196 struct ipaddr
*remote_ip
, uint32_t remote_iface
,
197 uint8_t algo
, uint8_t pref_len
)
201 struct prefix pre
= {0};
203 if (!segment
|| !local_ip
|| !remote_ip
)
206 segment
->nai_type
= type
;
207 memcpy(&segment
->nai_local_addr
, local_ip
, sizeof(struct ipaddr
));
210 case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE
:
211 case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE
:
213 case SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY
:
214 case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY
:
215 memcpy(&segment
->nai_remote_addr
, remote_ip
,
216 sizeof(struct ipaddr
));
217 status
= srte_ted_do_query_type_f(segment
, local_ip
, remote_ip
);
219 case SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY
:
220 memcpy(&segment
->nai_remote_addr
, remote_ip
,
221 sizeof(struct ipaddr
));
222 segment
->nai_local_iface
= local_iface
;
223 segment
->nai_remote_iface
= remote_iface
;
225 case SRTE_SEGMENT_NAI_TYPE_IPV6_ALGORITHM
:
226 pre
.family
= AF_INET6
;
227 pre
.prefixlen
= pref_len
;
228 pre
.u
.prefix6
= local_ip
->ip
._v6_addr
;
229 segment
->nai_local_prefix_len
= pref_len
;
230 segment
->nai_algorithm
= algo
;
231 status
= srte_ted_do_query_type_c(segment
, &pre
, algo
);
233 case SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM
:
234 pre
.family
= AF_INET
;
235 pre
.prefixlen
= pref_len
;
236 pre
.u
.prefix4
= local_ip
->ip
._v4_addr
;
237 segment
->nai_local_prefix_len
= pref_len
;
238 segment
->nai_algorithm
= algo
;
239 status
= srte_ted_do_query_type_c(segment
, &pre
, algo
);
241 case SRTE_SEGMENT_NAI_TYPE_IPV6_LOCAL_IFACE
:
242 pre
.family
= AF_INET6
;
243 pre
.prefixlen
= pref_len
;
244 pre
.u
.prefix6
= local_ip
->ip
._v6_addr
;
245 segment
->nai_local_prefix_len
= pref_len
;
246 segment
->nai_local_iface
= local_iface
;
247 status
= srte_ted_do_query_type_e(segment
, &pre
, local_iface
);
249 case SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE
:
250 pre
.family
= AF_INET
;
251 pre
.prefixlen
= pref_len
;
252 pre
.u
.prefix4
= local_ip
->ip
._v4_addr
;
253 segment
->nai_local_prefix_len
= pref_len
;
254 segment
->nai_local_iface
= local_iface
;
255 status
= srte_ted_do_query_type_e(segment
, &pre
, local_iface
);
258 segment
->nai_local_addr
.ipa_type
= IPADDR_NONE
;
259 segment
->nai_local_iface
= 0;
260 segment
->nai_remote_addr
.ipa_type
= IPADDR_NONE
;
261 segment
->nai_remote_iface
= 0;
267 * Mark segment as modified depending in protocol and sid conditions
269 * @param protocol_origin Origin of the segment list
270 * @param s_list Ptr to segment list with flags,sid to modidy
271 * @param s_entry Ptr to segment entry with sid to modidy
272 * @param ted_sid The sid from ted query
275 void srte_segment_set_local_modification(struct srte_segment_list
*s_list
,
276 struct srte_segment_entry
*s_entry
,
279 if (!s_list
|| !s_entry
)
282 if (s_list
->protocol_origin
== SRTE_ORIGIN_LOCAL
283 && s_entry
->sid_value
!= ted_sid
) {
284 s_entry
->sid_value
= ted_sid
;
285 SET_FLAG(s_list
->flags
, F_SEGMENT_LIST_MODIFIED
);
290 * Add a policy to pathd.
292 * WARNING: The color 0 is a special case as it is the no-color.
294 * @param color The color of the policy.
295 * @param endpoint The IP address of the policy endpoint
296 * @return The created policy
298 struct srte_policy
*srte_policy_add(uint32_t color
, struct ipaddr
*endpoint
,
299 enum srte_protocol_origin origin
,
300 const char *originator
)
302 struct srte_policy
*policy
;
304 policy
= XCALLOC(MTYPE_PATH_SR_POLICY
, sizeof(*policy
));
305 policy
->color
= color
;
306 policy
->endpoint
= *endpoint
;
307 policy
->binding_sid
= MPLS_LABEL_NONE
;
308 policy
->protocol_origin
= origin
;
309 if (originator
!= NULL
)
310 strlcpy(policy
->originator
, originator
,
311 sizeof(policy
->originator
));
313 RB_INIT(srte_candidate_head
, &policy
->candidate_paths
);
314 RB_INSERT(srte_policy_head
, &srte_policies
, policy
);
320 * Delete a policy from pathd.
322 * The given policy structure will be freed and should never be used again
323 * after calling this function.
325 * @param policy The policy to be removed
327 void srte_policy_del(struct srte_policy
*policy
)
329 struct srte_candidate
*candidate
;
331 path_zebra_delete_sr_policy(policy
);
333 path_zebra_release_label(policy
->binding_sid
);
335 while (!RB_EMPTY(srte_candidate_head
, &policy
->candidate_paths
)) {
337 RB_ROOT(srte_candidate_head
, &policy
->candidate_paths
);
338 trigger_pathd_candidate_removed(candidate
);
339 srte_candidate_del(candidate
);
342 RB_REMOVE(srte_policy_head
, &srte_policies
, policy
);
343 XFREE(MTYPE_PATH_SR_POLICY
, policy
);
347 * Search for a policy by color and endpoint.
349 * WARNING: The color 0 is a special case as it is the no-color.
351 * @param color The color of the policy to look for
352 * @param endpoint The endpoint of the policy to look for
353 * @return The policy if found, NULL otherwise
355 struct srte_policy
*srte_policy_find(uint32_t color
, struct ipaddr
*endpoint
)
357 struct srte_policy search
;
359 search
.color
= color
;
360 search
.endpoint
= *endpoint
;
361 return RB_FIND(srte_policy_head
, &srte_policies
, &search
);
365 * After new data from igp,local and pce the segment list :
366 * Mark as invalid for origin pce if cannot be validated
367 * Updated for origin local
369 int srte_policy_update_ted_sid(void)
372 int number_of_sid_clashed
= 0;
373 struct srte_segment_list
*s_list
;
374 struct srte_segment_entry
*s_entry
;
376 if (!path_ted_is_initialized())
378 if (RB_EMPTY(srte_segment_list_head
, &srte_segment_lists
))
381 RB_FOREACH (s_list
, srte_segment_list_head
, &srte_segment_lists
) {
382 if (CHECK_FLAG(s_list
->flags
, F_SEGMENT_LIST_DELETED
))
384 RB_FOREACH (s_entry
, srte_segment_entry_head
,
387 "%s:PATHD-TED: SL: Name: %s index:(%d) sid:(%d) prefix_len:(%d) local iface:(%d) algorithm:(%d)",
388 __func__
, s_list
->name
, s_entry
->index
,
390 s_entry
->nai_local_prefix_len
,
391 s_entry
->nai_local_iface
,
392 s_entry
->nai_algorithm
);
393 struct prefix prefix_cli
= {0};
395 switch (s_entry
->nai_type
) {
396 case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY
:
397 case SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY
:
398 number_of_sid_clashed
+=
399 srte_ted_do_query_type_f(
401 &s_entry
->nai_local_addr
,
402 &s_entry
->nai_remote_addr
);
404 case SRTE_SEGMENT_NAI_TYPE_IPV6_LOCAL_IFACE
:
405 prefix_cli
.family
= AF_INET6
;
406 prefix_cli
.prefixlen
=
407 s_entry
->nai_local_prefix_len
;
408 prefix_cli
.u
.prefix6
=
409 s_entry
->nai_local_addr
.ip
._v6_addr
;
410 number_of_sid_clashed
+=
411 srte_ted_do_query_type_e(
412 s_entry
, &prefix_cli
,
413 s_entry
->nai_local_iface
);
415 case SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE
:
416 prefix_cli
.family
= AF_INET
;
417 prefix_cli
.prefixlen
=
418 s_entry
->nai_local_prefix_len
;
419 prefix_cli
.u
.prefix4
=
420 s_entry
->nai_local_addr
.ip
._v4_addr
;
421 number_of_sid_clashed
+=
422 srte_ted_do_query_type_e(
423 s_entry
, &prefix_cli
,
424 s_entry
->nai_local_iface
);
426 case SRTE_SEGMENT_NAI_TYPE_IPV6_ALGORITHM
:
427 prefix_cli
.family
= AF_INET6
;
428 prefix_cli
.prefixlen
=
429 s_entry
->nai_local_prefix_len
;
430 prefix_cli
.u
.prefix6
=
431 s_entry
->nai_local_addr
.ip
._v6_addr
;
432 number_of_sid_clashed
+=
433 srte_ted_do_query_type_c(
434 s_entry
, &prefix_cli
,
435 s_entry
->nai_algorithm
);
437 case SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM
:
438 prefix_cli
.family
= AF_INET
;
439 prefix_cli
.prefixlen
=
440 s_entry
->nai_local_prefix_len
;
441 prefix_cli
.u
.prefix4
=
442 s_entry
->nai_local_addr
.ip
._v4_addr
;
443 number_of_sid_clashed
+=
444 srte_ted_do_query_type_c(
445 s_entry
, &prefix_cli
,
446 s_entry
->nai_algorithm
);
452 if (number_of_sid_clashed
) {
453 SET_FLAG(s_list
->flags
, F_SEGMENT_LIST_SID_CONFLICT
);
454 number_of_sid_clashed
= 0;
456 UNSET_FLAG(s_list
->flags
, F_SEGMENT_LIST_SID_CONFLICT
);
458 srte_apply_changes();
464 * Update a policy binding SID.
466 * @param policy The policy for which the SID should be updated
467 * @param binding_sid The new binding SID for the given policy
469 void srte_policy_update_binding_sid(struct srte_policy
*policy
,
470 uint32_t binding_sid
)
472 if (policy
->binding_sid
!= MPLS_LABEL_NONE
)
473 path_zebra_release_label(policy
->binding_sid
);
475 policy
->binding_sid
= binding_sid
;
477 /* Reinstall the Binding-SID if necessary. */
478 if (policy
->best_candidate
)
479 path_zebra_add_sr_policy(
480 policy
, policy
->best_candidate
->lsp
->segment_list
);
484 * Gives the policy best candidate path.
486 * @param policy The policy we want the best candidate path from
487 * @return The best candidate path
489 static struct srte_candidate
*
490 srte_policy_best_candidate(const struct srte_policy
*policy
)
492 struct srte_candidate
*candidate
;
494 RB_FOREACH_REVERSE (candidate
, srte_candidate_head
,
495 &policy
->candidate_paths
) {
496 /* search for highest preference with existing segment list */
497 if (!CHECK_FLAG(candidate
->flags
, F_CANDIDATE_DELETED
)
498 && candidate
->lsp
->segment_list
499 && (!CHECK_FLAG(candidate
->lsp
->segment_list
->flags
,
500 F_SEGMENT_LIST_SID_CONFLICT
)))
507 void srte_clean_zebra(void)
509 struct srte_policy
*policy
, *safe_pol
;
511 RB_FOREACH_SAFE (policy
, srte_policy_head
, &srte_policies
, safe_pol
)
512 srte_policy_del(policy
);
516 * Apply changes defined by setting the policies, candidate paths
517 * and segment lists modification flags NEW, MODIFIED and DELETED.
519 * This allows the northbound code to delay all the side effects of adding
520 * modifying and deleting them to the end.
522 * Example of marking an object as modified:
523 * `SET_FLAG(obj->flags, F_XXX_MODIFIED)`
525 void srte_apply_changes(void)
527 struct srte_policy
*policy
, *safe_pol
;
528 struct srte_segment_list
*segment_list
, *safe_sl
;
530 RB_FOREACH_SAFE (policy
, srte_policy_head
, &srte_policies
, safe_pol
) {
531 if (CHECK_FLAG(policy
->flags
, F_POLICY_DELETED
)) {
532 srte_policy_del(policy
);
535 srte_policy_apply_changes(policy
);
536 UNSET_FLAG(policy
->flags
, F_POLICY_NEW
);
537 UNSET_FLAG(policy
->flags
, F_POLICY_MODIFIED
);
540 RB_FOREACH_SAFE (segment_list
, srte_segment_list_head
,
541 &srte_segment_lists
, safe_sl
) {
542 if (CHECK_FLAG(segment_list
->flags
, F_SEGMENT_LIST_DELETED
)) {
543 srte_segment_list_del(segment_list
);
546 UNSET_FLAG(segment_list
->flags
, F_SEGMENT_LIST_NEW
);
547 UNSET_FLAG(segment_list
->flags
, F_SEGMENT_LIST_MODIFIED
);
552 * Apply changes defined by setting the given policy and its candidate paths
553 * modification flags NEW, MODIFIED and DELETED.
555 * In moste cases `void srte_apply_changes(void)` should be used instead,
556 * this function will not handle the changes of segment lists used by the
559 * @param policy The policy changes has to be applied to.
561 void srte_policy_apply_changes(struct srte_policy
*policy
)
563 struct srte_candidate
*candidate
, *safe
;
564 struct srte_candidate
*old_best_candidate
;
565 struct srte_candidate
*new_best_candidate
;
568 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
570 /* Get old and new best candidate path. */
571 old_best_candidate
= policy
->best_candidate
;
572 new_best_candidate
= srte_policy_best_candidate(policy
);
574 if (new_best_candidate
!= old_best_candidate
) {
575 /* TODO: add debug guard. */
577 "SR-TE(%s, %u): best candidate changed from %s to %s",
578 endpoint
, policy
->color
,
579 old_best_candidate
? old_best_candidate
->name
: "none",
580 new_best_candidate
? new_best_candidate
->name
: "none");
582 if (old_best_candidate
) {
583 policy
->best_candidate
= NULL
;
584 UNSET_FLAG(old_best_candidate
->flags
, F_CANDIDATE_BEST
);
585 SET_FLAG(old_best_candidate
->flags
,
586 F_CANDIDATE_MODIFIED
);
589 * Rely on replace semantics if there's a new best
592 if (!new_best_candidate
)
593 path_zebra_delete_sr_policy(policy
);
595 if (new_best_candidate
) {
596 policy
->best_candidate
= new_best_candidate
;
597 SET_FLAG(new_best_candidate
->flags
, F_CANDIDATE_BEST
);
598 SET_FLAG(new_best_candidate
->flags
,
599 F_CANDIDATE_MODIFIED
);
601 path_zebra_add_sr_policy(
602 policy
, new_best_candidate
->lsp
->segment_list
);
604 } else if (new_best_candidate
) {
605 /* The best candidate path did not change, but some of its
606 * attributes or its segment list may have changed.
609 bool candidate_changed
= CHECK_FLAG(new_best_candidate
->flags
,
610 F_CANDIDATE_MODIFIED
);
611 bool segment_list_changed
=
612 new_best_candidate
->lsp
->segment_list
614 new_best_candidate
->lsp
->segment_list
->flags
,
615 F_SEGMENT_LIST_MODIFIED
);
617 if (candidate_changed
|| segment_list_changed
) {
618 /* TODO: add debug guard. */
619 zlog_debug("SR-TE(%s, %u): best candidate %s changed",
620 endpoint
, policy
->color
,
621 new_best_candidate
->name
);
623 path_zebra_add_sr_policy(
624 policy
, new_best_candidate
->lsp
->segment_list
);
628 RB_FOREACH_SAFE (candidate
, srte_candidate_head
,
629 &policy
->candidate_paths
, safe
) {
630 if (CHECK_FLAG(candidate
->flags
, F_CANDIDATE_DELETED
)) {
631 trigger_pathd_candidate_removed(candidate
);
632 srte_candidate_del(candidate
);
634 } else if (CHECK_FLAG(candidate
->flags
, F_CANDIDATE_NEW
)) {
635 trigger_pathd_candidate_created(candidate
);
636 } else if (CHECK_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
)) {
637 trigger_pathd_candidate_updated(candidate
);
638 } else if (candidate
->lsp
->segment_list
639 && CHECK_FLAG(candidate
->lsp
->segment_list
->flags
,
640 F_SEGMENT_LIST_MODIFIED
)) {
641 trigger_pathd_candidate_updated(candidate
);
644 UNSET_FLAG(candidate
->flags
, F_CANDIDATE_NEW
);
645 UNSET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
650 * Adds a candidate path to a policy.
652 * @param policy The policy the candidate path should be added to
653 * @param preference The preference of the candidate path to be added
654 * @return The added candidate path
656 struct srte_candidate
*srte_candidate_add(struct srte_policy
*policy
,
658 enum srte_protocol_origin origin
,
659 const char *originator
)
661 struct srte_candidate
*candidate
;
662 struct srte_lsp
*lsp
;
664 candidate
= XCALLOC(MTYPE_PATH_SR_CANDIDATE
, sizeof(*candidate
));
665 lsp
= XCALLOC(MTYPE_PATH_SR_CANDIDATE
, sizeof(*lsp
));
667 candidate
->preference
= preference
;
668 candidate
->policy
= policy
;
669 candidate
->type
= SRTE_CANDIDATE_TYPE_UNDEFINED
;
670 candidate
->discriminator
= frr_weak_random();
671 candidate
->protocol_origin
= origin
;
672 if (originator
!= NULL
) {
673 strlcpy(candidate
->originator
, originator
,
674 sizeof(candidate
->originator
));
675 lsp
->protocol_origin
= origin
;
678 if (candidate
->protocol_origin
== SRTE_ORIGIN_PCEP
679 || candidate
->protocol_origin
== SRTE_ORIGIN_BGP
) {
680 candidate
->type
= SRTE_CANDIDATE_TYPE_DYNAMIC
;
682 lsp
->candidate
= candidate
;
683 candidate
->lsp
= lsp
;
685 RB_INSERT(srte_candidate_head
, &policy
->candidate_paths
, candidate
);
691 * Deletes a candidate.
693 * The corresponding LSP will be removed alongside the candidate path.
694 * The given candidate will be freed and shouldn't be used anymore after the
695 * calling this function.
697 * @param candidate The candidate path to delete
699 void srte_candidate_del(struct srte_candidate
*candidate
)
701 struct srte_policy
*srte_policy
= candidate
->policy
;
703 RB_REMOVE(srte_candidate_head
, &srte_policy
->candidate_paths
,
706 XFREE(MTYPE_PATH_SR_CANDIDATE
, candidate
->lsp
);
707 XFREE(MTYPE_PATH_SR_CANDIDATE
, candidate
);
711 * Sets the bandwidth constraint of given candidate path.
713 * The corresponding LSP will be changed too.
715 * @param candidate The candidate path of which the bandwidth should be changed
716 * @param bandwidth The Bandwidth constraint to set to the candidate path
717 * @param required If the constraint is required (true) or only desired (false)
719 void srte_candidate_set_bandwidth(struct srte_candidate
*candidate
,
720 float bandwidth
, bool required
)
722 struct srte_policy
*policy
= candidate
->policy
;
725 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
727 "SR-TE(%s, %u): candidate %s %sconfig bandwidth set to %f B/s",
728 endpoint
, policy
->color
, candidate
->name
,
729 required
? "required " : "", bandwidth
);
730 SET_FLAG(candidate
->flags
, F_CANDIDATE_HAS_BANDWIDTH
);
731 COND_FLAG(candidate
->flags
, F_CANDIDATE_REQUIRED_BANDWIDTH
, required
);
732 candidate
->bandwidth
= bandwidth
;
734 srte_lsp_set_bandwidth(candidate
->lsp
, bandwidth
, required
);
738 * Sets the bandwidth constraint of the given LSP.
740 * The changes will not be shown as part of the running configuration.
742 * @param lsp The lsp of which the bandwidth should be changed
743 * @param bandwidth The Bandwidth constraint to set to the candidate path
744 * @param required If the constraint is required (true) or only desired (false)
746 void srte_lsp_set_bandwidth(struct srte_lsp
*lsp
, float bandwidth
,
749 struct srte_candidate
*candidate
= lsp
->candidate
;
750 struct srte_policy
*policy
= candidate
->policy
;
752 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
753 zlog_debug("SR-TE(%s, %u): candidate %s %slsp bandwidth set to %f B/s",
754 endpoint
, policy
->color
, candidate
->name
,
755 required
? "required" : "", bandwidth
);
756 SET_FLAG(lsp
->flags
, F_CANDIDATE_HAS_BANDWIDTH
);
757 COND_FLAG(lsp
->flags
, F_CANDIDATE_REQUIRED_BANDWIDTH
, required
);
758 lsp
->bandwidth
= bandwidth
;
762 * Remove a candidate path bandwidth constraint.
764 * The corresponding LSP will be changed too.
766 * @param candidate The candidate path of which the bandwidth should be removed
768 void srte_candidate_unset_bandwidth(struct srte_candidate
*candidate
)
770 struct srte_policy
*policy
= candidate
->policy
;
772 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
773 zlog_debug("SR-TE(%s, %u): candidate %s config bandwidth unset",
774 endpoint
, policy
->color
, candidate
->name
);
775 UNSET_FLAG(candidate
->flags
, F_CANDIDATE_HAS_BANDWIDTH
);
776 UNSET_FLAG(candidate
->flags
, F_CANDIDATE_REQUIRED_BANDWIDTH
);
777 candidate
->bandwidth
= 0;
778 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
779 srte_lsp_unset_bandwidth(candidate
->lsp
);
783 * Remove an LSP bandwidth constraint.
785 * The changes will not be shown as part of the running configuration.
787 * @param lsp The lsp of which the bandwidth should be changed
789 void srte_lsp_unset_bandwidth(struct srte_lsp
*lsp
)
791 struct srte_candidate
*candidate
= lsp
->candidate
;
792 struct srte_policy
*policy
= candidate
->policy
;
794 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
795 zlog_debug("SR-TE(%s, %u): candidate %s lsp bandwidth unset", endpoint
,
796 policy
->color
, candidate
->name
);
797 UNSET_FLAG(lsp
->flags
, F_CANDIDATE_HAS_BANDWIDTH
);
798 UNSET_FLAG(lsp
->flags
, F_CANDIDATE_REQUIRED_BANDWIDTH
);
799 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
804 * Sets a candidate path metric constraint.
806 * The corresponding LSP will be changed too.
808 * @param candidate The candidate path of which the metric should be changed
809 * @param type The metric type
810 * @param value The metric value
811 * @param required If the constraint is required (true) or only desired (false)
812 * @param is_bound If the metric is an indicative value or a strict upper bound
813 * @param is_computed If the metric was computed or configured
815 void srte_candidate_set_metric(struct srte_candidate
*candidate
,
816 enum srte_candidate_metric_type type
,
817 float value
, bool required
, bool is_bound
,
820 struct srte_policy
*policy
= candidate
->policy
;
822 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
824 "SR-TE(%s, %u): candidate %s %sconfig metric %s (%u) set to %f (is-bound: %s; is_computed: %s)",
825 endpoint
, policy
->color
, candidate
->name
,
826 required
? "required " : "", srte_candidate_metric_name(type
),
827 type
, value
, is_bound
? "true" : "false",
828 is_computed
? "true" : "false");
829 assert((type
> 0) && (type
<= MAX_METRIC_TYPE
));
830 srte_set_metric(&candidate
->metrics
[type
- 1], value
, required
,
831 is_bound
, is_computed
);
832 srte_lsp_set_metric(candidate
->lsp
, type
, value
, required
, is_bound
,
834 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
838 * Sets an LSP metric constraint.
840 * The changes will not be shown as part of the running configuration.
842 * @param lsp The LSP of which the metric should be changed
843 * @param type The metric type
844 * @param value The metric value
845 * @param required If the constraint is required (true) or only desired (false)
846 * @param is_bound If the metric is an indicative value or a strict upper bound
847 * @param is_computed If the metric was computed or configured
849 void srte_lsp_set_metric(struct srte_lsp
*lsp
,
850 enum srte_candidate_metric_type type
, float value
,
851 bool required
, bool is_bound
, bool is_computed
)
853 struct srte_candidate
*candidate
= lsp
->candidate
;
854 struct srte_policy
*policy
= candidate
->policy
;
856 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
858 "SR-TE(%s, %u): candidate %s %slsp metric %s (%u) set to %f (is-bound: %s; is_computed: %s)",
859 endpoint
, policy
->color
, candidate
->name
,
860 required
? "required " : "", srte_candidate_metric_name(type
),
861 type
, value
, is_bound
? "true" : "false",
862 is_computed
? "true" : "false");
863 assert((type
> 0) && (type
<= MAX_METRIC_TYPE
));
864 srte_set_metric(&lsp
->metrics
[type
- 1], value
, required
, is_bound
,
868 void srte_set_metric(struct srte_metric
*metric
, float value
, bool required
,
869 bool is_bound
, bool is_computed
)
871 SET_FLAG(metric
->flags
, F_METRIC_IS_DEFINED
);
872 COND_FLAG(metric
->flags
, F_METRIC_IS_REQUIRED
, required
);
873 COND_FLAG(metric
->flags
, F_METRIC_IS_BOUND
, is_bound
);
874 COND_FLAG(metric
->flags
, F_METRIC_IS_COMPUTED
, is_computed
);
875 metric
->value
= value
;
879 * Removes a candidate path metric constraint.
881 * The corresponding LSP will be changed too.
883 * @param candidate The candidate path from which the metric should be removed
884 * @param type The metric type
886 void srte_candidate_unset_metric(struct srte_candidate
*candidate
,
887 enum srte_candidate_metric_type type
)
889 struct srte_policy
*policy
= candidate
->policy
;
891 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
892 zlog_debug("SR-TE(%s, %u): candidate %s config metric %s (%u) unset",
893 endpoint
, policy
->color
, candidate
->name
,
894 srte_candidate_metric_name(type
), type
);
895 assert((type
> 0) && (type
<= MAX_METRIC_TYPE
));
896 srte_unset_metric(&candidate
->metrics
[type
- 1]);
897 srte_lsp_unset_metric(candidate
->lsp
, type
);
898 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
902 * Removes a candidate path metric constraint.
904 * The changes will not be shown as part of the running configuration.
906 * @param lsp The LSP from which the metric should be removed
907 * @param type The metric type
909 void srte_lsp_unset_metric(struct srte_lsp
*lsp
,
910 enum srte_candidate_metric_type type
)
912 struct srte_candidate
*candidate
= lsp
->candidate
;
913 struct srte_policy
*policy
= candidate
->policy
;
915 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
916 zlog_debug("SR-TE(%s, %u): candidate %s lsp metric %s (%u) unset",
917 endpoint
, policy
->color
, candidate
->name
,
918 srte_candidate_metric_name(type
), type
);
919 assert((type
> 0) && (type
<= MAX_METRIC_TYPE
));
920 srte_unset_metric(&lsp
->metrics
[type
- 1]);
923 void srte_unset_metric(struct srte_metric
*metric
)
925 UNSET_FLAG(metric
->flags
, F_METRIC_IS_DEFINED
);
926 UNSET_FLAG(metric
->flags
, F_METRIC_IS_BOUND
);
927 UNSET_FLAG(metric
->flags
, F_METRIC_IS_COMPUTED
);
932 * Sets a candidate path objective function.
934 * @param candidate The candidate path of which the OF should be changed
935 * @param required If the constraint is required (true) or only desired (false)
936 * @param type The objective function type
938 void srte_candidate_set_objfun(struct srte_candidate
*candidate
, bool required
,
939 enum objfun_type type
)
941 struct srte_policy
*policy
= candidate
->policy
;
943 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
945 candidate
->objfun
= type
;
946 SET_FLAG(candidate
->flags
, F_CANDIDATE_HAS_OBJFUN
);
947 COND_FLAG(candidate
->flags
, F_CANDIDATE_REQUIRED_OBJFUN
, required
);
948 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
949 zlog_debug("SR-TE(%s, %u): candidate %s %sobjective function set to %s",
950 endpoint
, policy
->color
, candidate
->name
,
951 required
? "required " : "", objfun_type_name(type
));
955 * Removed the objective function constraint from a candidate path.
957 * @param candidate The candidate path from which the OF should be removed
959 void srte_candidate_unset_objfun(struct srte_candidate
*candidate
)
961 struct srte_policy
*policy
= candidate
->policy
;
963 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
965 UNSET_FLAG(candidate
->flags
, F_CANDIDATE_HAS_OBJFUN
);
966 UNSET_FLAG(candidate
->flags
, F_CANDIDATE_REQUIRED_OBJFUN
);
967 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
968 candidate
->objfun
= OBJFUN_UNDEFINED
;
970 "SR-TE(%s, %u): candidate %s objective functions preferences unset",
971 endpoint
, policy
->color
, candidate
->name
);
974 static uint32_t filter_type_to_flag(enum affinity_filter_type type
)
977 case AFFINITY_FILTER_EXCLUDE_ANY
:
978 return F_CANDIDATE_HAS_EXCLUDE_ANY
;
979 case AFFINITY_FILTER_INCLUDE_ANY
:
980 return F_CANDIDATE_HAS_INCLUDE_ANY
;
981 case AFFINITY_FILTER_INCLUDE_ALL
:
982 return F_CANDIDATE_HAS_INCLUDE_ALL
;
988 static const char *filter_type_name(enum affinity_filter_type type
)
991 case AFFINITY_FILTER_EXCLUDE_ANY
:
992 return "exclude-any";
993 case AFFINITY_FILTER_INCLUDE_ANY
:
994 return "include-any";
995 case AFFINITY_FILTER_INCLUDE_ALL
:
996 return "include-all";
1003 * Sets a candidate path affinity filter constraint.
1005 * @param candidate The candidate path of which the constraint should be changed
1006 * @param type The affinity constraint type to set
1007 * @param filter The bitmask filter of the constraint
1009 void srte_candidate_set_affinity_filter(struct srte_candidate
*candidate
,
1010 enum affinity_filter_type type
,
1013 struct srte_policy
*policy
= candidate
->policy
;
1015 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
1017 assert(type
> AFFINITY_FILTER_UNDEFINED
);
1018 assert(type
<= MAX_AFFINITY_FILTER_TYPE
);
1019 SET_FLAG(candidate
->flags
, filter_type_to_flag(type
));
1020 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
1021 candidate
->affinity_filters
[type
- 1] = filter
;
1023 "SR-TE(%s, %u): candidate %s affinity filter %s set to 0x%08x",
1024 endpoint
, policy
->color
, candidate
->name
,
1025 filter_type_name(type
), filter
);
1029 * Removes a candidate path affinity filter constraint.
1031 * @param candidate The candidate path from which the constraint should be
1033 * @param type The affinity constraint type to remove
1035 void srte_candidate_unset_affinity_filter(struct srte_candidate
*candidate
,
1036 enum affinity_filter_type type
)
1038 struct srte_policy
*policy
= candidate
->policy
;
1040 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
1042 assert(type
> AFFINITY_FILTER_UNDEFINED
);
1043 assert(type
<= MAX_AFFINITY_FILTER_TYPE
);
1044 UNSET_FLAG(candidate
->flags
, filter_type_to_flag(type
));
1045 SET_FLAG(candidate
->flags
, F_CANDIDATE_MODIFIED
);
1046 candidate
->affinity_filters
[type
- 1] = 0;
1047 zlog_debug("SR-TE(%s, %u): candidate %s affinity filter %s unset",
1048 endpoint
, policy
->color
, candidate
->name
,
1049 filter_type_name(type
));
1053 * Searches for a candidate path of the given policy.
1055 * @param policy The policy to search for candidate path
1056 * @param preference The preference of the candidate path you are looking for
1057 * @return The candidate path if found, NULL otherwise
1059 struct srte_candidate
*srte_candidate_find(struct srte_policy
*policy
,
1060 uint32_t preference
)
1062 struct srte_candidate search
;
1064 search
.preference
= preference
;
1065 return RB_FIND(srte_candidate_head
, &policy
->candidate_paths
, &search
);
1069 * Searches for a an entry of a given segment list.
1071 * @param segment_list The segment list to search for the entry
1072 * @param index The index of the entry you are looking for
1073 * @return The segment list entry if found, NULL otherwise.
1075 struct srte_segment_entry
*
1076 srte_segment_entry_find(struct srte_segment_list
*segment_list
, uint32_t index
)
1078 struct srte_segment_entry search
;
1080 search
.index
= index
;
1081 return RB_FIND(srte_segment_entry_head
, &segment_list
->segments
,
1086 * Updates a candidate status.
1088 * @param candidate The candidate of which the status should be updated
1089 * @param status The new candidate path status
1091 void srte_candidate_status_update(struct srte_candidate
*candidate
, int status
)
1093 struct srte_policy
*policy
= candidate
->policy
;
1095 ipaddr2str(&policy
->endpoint
, endpoint
, sizeof(endpoint
));
1096 zlog_debug("SR-TE(%s, %u): zebra updated status to %d", endpoint
,
1097 policy
->color
, status
);
1099 case ZEBRA_SR_POLICY_DOWN
:
1100 switch (policy
->status
) {
1101 /* If the policy is GOING_UP, and zebra faild
1102 to install it, we wait for zebra to retry */
1103 /* TODO: Add some timeout after which we would
1104 get is back to DOWN and remove the
1106 case SRTE_POLICY_STATUS_GOING_UP
:
1107 case SRTE_POLICY_STATUS_DOWN
:
1110 zlog_debug("SR-TE(%s, %u): policy is DOWN", endpoint
,
1112 policy
->status
= SRTE_POLICY_STATUS_DOWN
;
1116 case ZEBRA_SR_POLICY_UP
:
1117 switch (policy
->status
) {
1118 case SRTE_POLICY_STATUS_UP
:
1121 zlog_debug("SR-TE(%s, %u): policy is UP", endpoint
,
1123 policy
->status
= SRTE_POLICY_STATUS_UP
;
1129 trigger_pathd_candidate_updated(candidate
);
1133 * Flags the segment lists from give originator for removal.
1135 * The function srte_apply_changes must be called afterward for
1136 * the segment list to be removed.
1138 * @param originator The originator tag of the segment list to be marked
1139 * @param force If the unset should be forced regardless of the originator
1141 void srte_candidate_unset_segment_list(const char *originator
, bool force
)
1143 if (originator
== NULL
) {
1145 "Cannot unset segment list because originator is NULL");
1149 zlog_debug("Unset segment lists for originator %s", originator
);
1151 /* Iterate the policies, then iterate each policy's candidate path
1152 * to check the candidate path's segment list originator */
1153 struct srte_policy
*policy
;
1154 RB_FOREACH (policy
, srte_policy_head
, &srte_policies
) {
1155 zlog_debug("Unset segment lists checking policy %s",
1157 struct srte_candidate
*candidate
;
1158 RB_FOREACH (candidate
, srte_candidate_head
,
1159 &policy
->candidate_paths
) {
1160 zlog_debug("Unset segment lists checking candidate %s",
1162 if (candidate
->lsp
== NULL
) {
1166 /* The candidate->lsp->segment_list is operational data,
1167 * configured by the PCE. We dont want to modify the
1168 * candidate->segment_list,
1169 * which is configuration data. */
1170 struct srte_segment_list
*segment_list
=
1171 candidate
->lsp
->segment_list
;
1172 if (segment_list
== NULL
) {
1176 if (segment_list
->protocol_origin
1177 == SRTE_ORIGIN_LOCAL
) {
1179 "Cannot unset segment list %s because it was created locally",
1180 segment_list
->name
);
1184 /* In the case of last pce,we force the unset
1185 * because we don't have pce by prefix (TODO) is all
1187 if (strncmp(segment_list
->originator
, originator
,
1188 sizeof(segment_list
->originator
))
1191 zlog_debug("Unset segment list %s",
1192 segment_list
->name
);
1193 SET_FLAG(segment_list
->flags
,
1194 F_SEGMENT_LIST_DELETED
);
1195 SET_FLAG(candidate
->flags
,
1196 F_CANDIDATE_MODIFIED
);
1197 candidate
->lsp
->segment_list
= NULL
;
1204 * Gives a string representation of given protocol origin enum.
1206 * @param origin The enum you want a string representation of
1207 * @return The string representation of given enum
1209 const char *srte_origin2str(enum srte_protocol_origin origin
)
1212 case SRTE_ORIGIN_PCEP
:
1214 case SRTE_ORIGIN_BGP
:
1216 case SRTE_ORIGIN_LOCAL
:
1223 void pathd_shutdown(void)
1225 path_ted_teardown();
1230 void trigger_pathd_candidate_created(struct srte_candidate
*candidate
)
1232 /* The hook is called asynchronously to let the PCEP module
1233 time to send a response to the PCE before receiving any updates from
1234 pathd. In addition, a minimum amount of time need to pass before
1235 the hook is called to prevent the hook to be called multiple times
1236 from changing the candidate by hand with the console */
1237 if (candidate
->hook_timer
!= NULL
)
1239 thread_add_timer(master
, trigger_pathd_candidate_created_timer
,
1240 (void *)candidate
, HOOK_DELAY
, &candidate
->hook_timer
);
1243 void trigger_pathd_candidate_created_timer(struct thread
*thread
)
1245 struct srte_candidate
*candidate
= THREAD_ARG(thread
);
1246 candidate
->hook_timer
= NULL
;
1247 hook_call(pathd_candidate_created
, candidate
);
1250 void trigger_pathd_candidate_updated(struct srte_candidate
*candidate
)
1252 /* The hook is called asynchronously to let the PCEP module
1253 time to send a response to the PCE before receiving any updates from
1254 pathd. In addition, a minimum amount of time need to pass before
1255 the hook is called to prevent the hook to be called multiple times
1256 from changing the candidate by hand with the console */
1257 if (candidate
->hook_timer
!= NULL
)
1259 thread_add_timer(master
, trigger_pathd_candidate_updated_timer
,
1260 (void *)candidate
, HOOK_DELAY
, &candidate
->hook_timer
);
1263 void trigger_pathd_candidate_updated_timer(struct thread
*thread
)
1265 struct srte_candidate
*candidate
= THREAD_ARG(thread
);
1266 candidate
->hook_timer
= NULL
;
1267 hook_call(pathd_candidate_updated
, candidate
);
1270 void trigger_pathd_candidate_removed(struct srte_candidate
*candidate
)
1272 /* The hook needs to be call synchronously, otherwise the candidate
1273 path will be already deleted when the handler is called */
1274 if (candidate
->hook_timer
!= NULL
) {
1275 thread_cancel(&candidate
->hook_timer
);
1276 candidate
->hook_timer
= NULL
;
1278 hook_call(pathd_candidate_removed
, candidate
);
1281 const char *srte_candidate_metric_name(enum srte_candidate_metric_type type
)
1284 case SRTE_CANDIDATE_METRIC_TYPE_IGP
:
1286 case SRTE_CANDIDATE_METRIC_TYPE_TE
:
1288 case SRTE_CANDIDATE_METRIC_TYPE_HC
:
1290 case SRTE_CANDIDATE_METRIC_TYPE_ABC
:
1292 case SRTE_CANDIDATE_METRIC_TYPE_LMLL
:
1294 case SRTE_CANDIDATE_METRIC_TYPE_CIGP
:
1296 case SRTE_CANDIDATE_METRIC_TYPE_CTE
:
1298 case SRTE_CANDIDATE_METRIC_TYPE_PIGP
:
1300 case SRTE_CANDIDATE_METRIC_TYPE_PTE
:
1302 case SRTE_CANDIDATE_METRIC_TYPE_PHC
:
1304 case SRTE_CANDIDATE_METRIC_TYPE_MSD
:
1306 case SRTE_CANDIDATE_METRIC_TYPE_PD
:
1308 case SRTE_CANDIDATE_METRIC_TYPE_PDV
:
1310 case SRTE_CANDIDATE_METRIC_TYPE_PL
:
1312 case SRTE_CANDIDATE_METRIC_TYPE_PPD
:
1314 case SRTE_CANDIDATE_METRIC_TYPE_PPDV
:
1316 case SRTE_CANDIDATE_METRIC_TYPE_PPL
:
1318 case SRTE_CANDIDATE_METRIC_TYPE_NAP
:
1320 case SRTE_CANDIDATE_METRIC_TYPE_NLP
:
1322 case SRTE_CANDIDATE_METRIC_TYPE_DC
:
1324 case SRTE_CANDIDATE_METRIC_TYPE_BNC
:
1331 int32_t srte_ted_do_query_type_c(struct srte_segment_entry
*entry
,
1332 struct prefix
*prefix_cli
, uint32_t algo
)
1335 uint32_t ted_sid
= MPLS_LABEL_NONE
;
1337 if (!entry
|| !prefix_cli
)
1340 if (!path_ted_is_initialized())
1343 ted_sid
= path_ted_query_type_c(prefix_cli
, algo
);
1344 if (ted_sid
== MPLS_LABEL_NONE
) {
1345 zlog_warn(" %s: PATHD-TED: SL: ERROR query C : ted-sid (%d)",
1348 zlog_debug("%s: PATHD-TED: SL: Success query C : ted-sid (%d)",
1351 if (CHECK_SID(entry
->segment_list
->protocol_origin
, ted_sid
,
1352 entry
->sid_value
)) {
1353 status
= PATH_SID_ERROR
;
1355 srte_segment_set_local_modification(entry
->segment_list
, entry
,
1360 int32_t srte_ted_do_query_type_e(struct srte_segment_entry
*entry
,
1361 struct prefix
*prefix_cli
,
1362 uint32_t local_iface
)
1365 uint32_t ted_sid
= MPLS_LABEL_NONE
;
1367 if (!entry
|| !prefix_cli
)
1370 if (!path_ted_is_initialized())
1373 ted_sid
= path_ted_query_type_e(prefix_cli
, local_iface
);
1374 if (ted_sid
== MPLS_LABEL_NONE
) {
1375 zlog_warn(" %s: PATHD-TED: SL: ERROR query E : ted-sid (%d)",
1378 zlog_debug("%s: PATHD-TED: SL: Success query E : ted-sid (%d)",
1381 if (CHECK_SID(entry
->segment_list
->protocol_origin
, ted_sid
,
1382 entry
->sid_value
)) {
1383 status
= PATH_SID_ERROR
;
1385 srte_segment_set_local_modification(entry
->segment_list
, entry
,
1390 int32_t srte_ted_do_query_type_f(struct srte_segment_entry
*entry
,
1391 struct ipaddr
*local
, struct ipaddr
*remote
)
1394 uint32_t ted_sid
= MPLS_LABEL_NONE
;
1396 if (!entry
|| !local
|| !remote
)
1399 if (!path_ted_is_initialized())
1402 ted_sid
= path_ted_query_type_f(local
, remote
);
1403 if (ted_sid
== MPLS_LABEL_NONE
) {
1404 zlog_warn("%s:SL: ERROR query F : ted-sid (%d)", __func__
,
1407 zlog_debug("%s:SL: Success query F : ted-sid (%d)", __func__
,
1410 if (CHECK_SID(entry
->segment_list
->protocol_origin
, ted_sid
,
1411 entry
->sid_value
)) {
1412 status
= PATH_SID_ERROR
;
1414 srte_segment_set_local_modification(entry
->segment_list
, entry
,