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
22 #include "lib/memory.h"
24 #include "lib/ipaddr.h"
27 #include "lib/prefix.h"
29 #define PATH_SID_ERROR 1
30 #define PATH_SID_NO_ERROR 0
31 #define CHECK_SID(or, ts, es) \
32 ((or == SRTE_ORIGIN_PCEP && (ts == MPLS_LABEL_NONE || es != ts)) \
33 || (or == SRTE_ORIGIN_LOCAL && ts == MPLS_LABEL_NONE))
35 DECLARE_MGROUP(PATHD
);
37 DECLARE_HOOK(pathd_srte_config_write
, (struct vty
*vty
), (vty
));
39 enum srte_protocol_origin
{
40 SRTE_ORIGIN_UNDEFINED
= 0,
43 SRTE_ORIGIN_LOCAL
= 3,
46 enum srte_policy_status
{
47 SRTE_POLICY_STATUS_UNKNOWN
= 0,
48 SRTE_POLICY_STATUS_DOWN
= 1,
49 SRTE_POLICY_STATUS_UP
= 2,
50 SRTE_POLICY_STATUS_GOING_DOWN
= 3,
51 SRTE_POLICY_STATUS_GOING_UP
= 4
54 enum srte_candidate_type
{
55 SRTE_CANDIDATE_TYPE_UNDEFINED
= 0,
56 SRTE_CANDIDATE_TYPE_EXPLICIT
= 1,
57 SRTE_CANDIDATE_TYPE_DYNAMIC
= 2,
60 enum srte_candidate_metric_type
{
62 SRTE_CANDIDATE_METRIC_TYPE_IGP
= 1,
64 SRTE_CANDIDATE_METRIC_TYPE_TE
= 2,
66 SRTE_CANDIDATE_METRIC_TYPE_HC
= 3,
67 /* Aggregate bandwidth consumption */
68 SRTE_CANDIDATE_METRIC_TYPE_ABC
= 4,
69 /* Load of the most loaded link */
70 SRTE_CANDIDATE_METRIC_TYPE_LMLL
= 5,
71 /* Cumulative IGP cost */
72 SRTE_CANDIDATE_METRIC_TYPE_CIGP
= 6,
73 /* Cumulative TE cost */
74 SRTE_CANDIDATE_METRIC_TYPE_CTE
= 7,
76 SRTE_CANDIDATE_METRIC_TYPE_PIGP
= 8,
78 SRTE_CANDIDATE_METRIC_TYPE_PTE
= 9,
79 /* P2MP hop count metric */
80 SRTE_CANDIDATE_METRIC_TYPE_PHC
= 10,
81 /* Segment-ID (SID) Depth */
82 SRTE_CANDIDATE_METRIC_TYPE_MSD
= 11,
83 /* Path Delay metric */
84 SRTE_CANDIDATE_METRIC_TYPE_PD
= 12,
85 /* Path Delay Variation metric */
86 SRTE_CANDIDATE_METRIC_TYPE_PDV
= 13,
87 /* Path Loss metric */
88 SRTE_CANDIDATE_METRIC_TYPE_PL
= 14,
89 /* P2MP Path Delay metric */
90 SRTE_CANDIDATE_METRIC_TYPE_PPD
= 15,
91 /* P2MP Path Delay variation metric */
92 SRTE_CANDIDATE_METRIC_TYPE_PPDV
= 16,
93 /* P2MP Path Loss metric */
94 SRTE_CANDIDATE_METRIC_TYPE_PPL
= 17,
95 /* Number of adaptations on a path */
96 SRTE_CANDIDATE_METRIC_TYPE_NAP
= 18,
97 /* Number of layers on a path */
98 SRTE_CANDIDATE_METRIC_TYPE_NLP
= 19,
99 /* Domain Count metric */
100 SRTE_CANDIDATE_METRIC_TYPE_DC
= 20,
101 /* Border Node Count metric */
102 SRTE_CANDIDATE_METRIC_TYPE_BNC
= 21,
104 #define MAX_METRIC_TYPE 21
106 enum srte_segment_nai_type
{
107 SRTE_SEGMENT_NAI_TYPE_NONE
= 0,
108 SRTE_SEGMENT_NAI_TYPE_IPV4_NODE
= 1,
109 SRTE_SEGMENT_NAI_TYPE_IPV6_NODE
= 2,
110 SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY
= 3,
111 SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY
= 4,
112 SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY
= 5,
113 SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY_LINK_LOCAL_ADDRESSES
= 6,
114 SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE
= 7,
115 SRTE_SEGMENT_NAI_TYPE_IPV6_LOCAL_IFACE
= 8,
116 SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM
= 9,
117 SRTE_SEGMENT_NAI_TYPE_IPV6_ALGORITHM
= 10
121 OBJFUN_UNDEFINED
= 0,
122 /* Minimum Cost Path [RFC5541] */
124 /* Minimum Load Path [RFC5541] */
126 /* Maximum residual Bandwidth Path [RFC5541] */
128 /* Minimize aggregate Bandwidth Consumption [RFC5541] */
130 /* Minimize the Load of the most loaded Link [RFC5541] */
132 /* Minimize the Cumulative Cost of a set of paths [RFC5541] */
134 /* Shortest Path Tree [RFC8306] */
136 /* Minimum Cost Tree [RFC8306] */
138 /* Minimum Packet Loss Path [RFC8233] */
140 /* Maximum Under-Utilized Path [RFC8233] */
142 /* Maximum Reserved Under-Utilized Path [RFC8233] */
144 /* Minimize the number of Transit Domains [RFC8685] */
146 /* Minimize the number of Border Nodes [RFC8685] */
148 /* Minimize the number of Common Transit Domains [RFC8685] */
150 /* Minimize the number of Shared Links [RFC8800] */
152 /* Minimize the number of Shared SRLGs [RFC8800] */
154 /* Minimize the number of Shared Nodes [RFC8800] */
157 #define MAX_OBJFUN_TYPE 17
159 enum affinity_filter_type
{
160 AFFINITY_FILTER_UNDEFINED
= 0,
161 AFFINITY_FILTER_EXCLUDE_ANY
= 1,
162 AFFINITY_FILTER_INCLUDE_ANY
= 2,
163 AFFINITY_FILTER_INCLUDE_ALL
= 3,
165 #define MAX_AFFINITY_FILTER_TYPE 3
167 struct srte_segment_list
;
169 struct srte_segment_entry
{
170 RB_ENTRY(srte_segment_entry
) entry
;
172 /* The segment list the entry belong to */
173 struct srte_segment_list
*segment_list
;
175 /* Index of the Label. */
179 mpls_label_t sid_value
;
182 enum srte_segment_nai_type nai_type
;
183 /* NAI local address when nai type is not NONE */
184 struct ipaddr nai_local_addr
;
185 /* NAI local interface when nai type is not IPv4 unnumbered adjacency */
186 uint32_t nai_local_iface
;
187 /* NAI local interface when nai type is IPv4 or IPv6 adjacency */
188 struct ipaddr nai_remote_addr
;
189 /* NAI remote interface when nai type is not IPv4 unnumbered adjacency
191 uint32_t nai_remote_iface
;
192 /* Support draft-ietf-spring-segment-routing-policy sl types queries*/
193 uint8_t nai_local_prefix_len
;
194 uint8_t nai_algorithm
;
196 RB_HEAD(srte_segment_entry_head
, srte_segment_entry
);
197 RB_PROTOTYPE(srte_segment_entry_head
, srte_segment_entry
, entry
,
198 srte_segment_entry_compare
)
200 struct srte_segment_list
{
201 RB_ENTRY(srte_segment_list
) entry
;
203 /* Name of the Segment List. */
206 /* The Protocol-Origin. */
207 enum srte_protocol_origin protocol_origin
;
213 struct srte_segment_entry_head segments
;
217 #define F_SEGMENT_LIST_NEW 0x0002
218 #define F_SEGMENT_LIST_MODIFIED 0x0004
219 #define F_SEGMENT_LIST_DELETED 0x0008
220 #define F_SEGMENT_LIST_SID_CONFLICT 0x0010
222 RB_HEAD(srte_segment_list_head
, srte_segment_list
);
223 RB_PROTOTYPE(srte_segment_list_head
, srte_segment_list
, entry
,
224 srte_segment_list_compare
)
228 #define F_METRIC_IS_DEFINED 0x0001
229 #define F_METRIC_IS_REQUIRED 0x0002
230 #define F_METRIC_IS_BOUND 0x0004
231 #define F_METRIC_IS_COMPUTED 0x0008
235 /* Runtime information about the candidate path */
237 /* Backpointer to the Candidate Path. */
238 struct srte_candidate
*candidate
;
240 /* The associated Segment List. */
241 struct srte_segment_list
*segment_list
;
243 /* The Protocol-Origin. */
244 enum srte_protocol_origin protocol_origin
;
249 /* The Discriminator */
250 uint32_t discriminator
;
255 /* Metrics LSP Values */
256 struct srte_metric metrics
[MAX_METRIC_TYPE
];
258 /* Bandwidth Configured Value */
261 /* The objective function in used */
262 enum objfun_type objfun
;
265 /* Configured candidate path */
266 struct srte_candidate
{
267 RB_ENTRY(srte_candidate
) entry
;
269 /* Backpointer to SR Policy */
270 struct srte_policy
*policy
;
272 /* The LSP associated with this candidate path. */
273 struct srte_lsp
*lsp
;
275 /* Administrative preference. */
281 /* The associated Segment List. */
282 struct srte_segment_list
*segment_list
;
284 /* The Protocol-Origin. */
285 enum srte_protocol_origin protocol_origin
;
290 /* The Discriminator */
291 uint32_t discriminator
;
293 /* The Type (explicit or dynamic) */
294 enum srte_candidate_type type
;
298 #define F_CANDIDATE_BEST 0x0001
299 #define F_CANDIDATE_NEW 0x0002
300 #define F_CANDIDATE_MODIFIED 0x0004
301 #define F_CANDIDATE_DELETED 0x0008
302 #define F_CANDIDATE_HAS_BANDWIDTH 0x0100
303 #define F_CANDIDATE_REQUIRED_BANDWIDTH 0x0200
304 #define F_CANDIDATE_HAS_OBJFUN 0x0400
305 #define F_CANDIDATE_REQUIRED_OBJFUN 0x0800
306 #define F_CANDIDATE_HAS_EXCLUDE_ANY 0x1000
307 #define F_CANDIDATE_HAS_INCLUDE_ANY 0x2000
308 #define F_CANDIDATE_HAS_INCLUDE_ALL 0x4000
310 /* Metrics Configured Values */
311 struct srte_metric metrics
[MAX_METRIC_TYPE
];
313 /* Bandwidth Configured Value */
316 /* Configured objective functions */
317 enum objfun_type objfun
;
319 /* Path constraints attribute filters */
320 uint32_t affinity_filters
[MAX_AFFINITY_FILTER_TYPE
];
322 /* Hooks delaying timer */
323 struct thread
*hook_timer
;
326 RB_HEAD(srte_candidate_head
, srte_candidate
);
327 RB_PROTOTYPE(srte_candidate_head
, srte_candidate
, entry
, srte_candidate_compare
)
330 RB_ENTRY(srte_policy
) entry
;
336 struct ipaddr endpoint
;
342 mpls_label_t binding_sid
;
344 /* The Protocol-Origin. */
345 enum srte_protocol_origin protocol_origin
;
350 /* Operational Status of the policy */
351 enum srte_policy_status status
;
353 /* Best candidate path. */
354 struct srte_candidate
*best_candidate
;
356 /* Candidate Paths */
357 struct srte_candidate_head candidate_paths
;
360 #define F_POLICY_NEW 0x0002
361 #define F_POLICY_MODIFIED 0x0004
362 #define F_POLICY_DELETED 0x0008
363 /* SRP id for PcInitiated support */
366 RB_HEAD(srte_policy_head
, srte_policy
);
367 RB_PROTOTYPE(srte_policy_head
, srte_policy
, entry
, srte_policy_compare
)
369 DECLARE_HOOK(pathd_candidate_created
, (struct srte_candidate
* candidate
),
371 DECLARE_HOOK(pathd_candidate_updated
, (struct srte_candidate
* candidate
),
373 DECLARE_HOOK(pathd_candidate_removed
, (struct srte_candidate
* candidate
),
376 extern struct srte_segment_list_head srte_segment_lists
;
377 extern struct srte_policy_head srte_policies
;
378 extern struct zebra_privs_t pathd_privs
;
380 /* master thread, defined in path_main.c */
381 extern struct thread_master
*master
;
384 struct srte_segment_list
*srte_segment_list_add(const char *name
);
385 void srte_segment_list_del(struct srte_segment_list
*segment_list
);
386 struct srte_segment_list
*srte_segment_list_find(const char *name
);
387 struct srte_segment_entry
*
388 srte_segment_entry_add(struct srte_segment_list
*segment_list
, uint32_t index
);
389 void srte_segment_entry_del(struct srte_segment_entry
*segment
);
390 int srte_segment_entry_set_nai(struct srte_segment_entry
*segment
,
391 enum srte_segment_nai_type type
,
392 struct ipaddr
*local_ip
, uint32_t local_iface
,
393 struct ipaddr
*remote_ip
, uint32_t remote_iface
,
394 uint8_t algo
, uint8_t pref_len
);
395 void srte_segment_set_local_modification(struct srte_segment_list
*s_list
,
396 struct srte_segment_entry
*s_entry
,
398 struct srte_policy
*srte_policy_add(uint32_t color
, struct ipaddr
*endpoint
,
399 enum srte_protocol_origin origin
,
400 const char *originator
);
401 void srte_policy_del(struct srte_policy
*policy
);
402 struct srte_policy
*srte_policy_find(uint32_t color
, struct ipaddr
*endpoint
);
403 int srte_policy_update_ted_sid(void);
404 void srte_policy_update_binding_sid(struct srte_policy
*policy
,
405 uint32_t binding_sid
);
406 void srte_apply_changes(void);
407 void srte_clean_zebra(void);
408 void srte_policy_apply_changes(struct srte_policy
*policy
);
409 struct srte_candidate
*srte_candidate_add(struct srte_policy
*policy
,
411 enum srte_protocol_origin origin
,
412 const char *originator
);
413 void srte_candidate_del(struct srte_candidate
*candidate
);
414 void srte_candidate_set_bandwidth(struct srte_candidate
*candidate
,
415 float bandwidth
, bool required
);
416 void srte_candidate_unset_bandwidth(struct srte_candidate
*candidate
);
417 void srte_candidate_set_metric(struct srte_candidate
*candidate
,
418 enum srte_candidate_metric_type type
,
419 float value
, bool required
, bool is_cound
,
421 void srte_candidate_unset_metric(struct srte_candidate
*candidate
,
422 enum srte_candidate_metric_type type
);
423 void srte_candidate_set_objfun(struct srte_candidate
*candidate
, bool required
,
424 enum objfun_type type
);
425 void srte_candidate_unset_objfun(struct srte_candidate
*candidate
);
426 void srte_candidate_set_affinity_filter(struct srte_candidate
*candidate
,
427 enum affinity_filter_type type
,
429 void srte_candidate_unset_affinity_filter(struct srte_candidate
*candidate
,
430 enum affinity_filter_type type
);
431 void srte_lsp_set_bandwidth(struct srte_lsp
*lsp
, float bandwidth
,
433 void srte_lsp_unset_bandwidth(struct srte_lsp
*lsp
);
434 void srte_lsp_set_metric(struct srte_lsp
*lsp
,
435 enum srte_candidate_metric_type type
, float value
,
436 bool required
, bool is_cound
, bool is_computed
);
437 void srte_lsp_unset_metric(struct srte_lsp
*lsp
,
438 enum srte_candidate_metric_type type
);
439 struct srte_candidate
*srte_candidate_find(struct srte_policy
*policy
,
440 uint32_t preference
);
441 struct srte_segment_entry
*
442 srte_segment_entry_find(struct srte_segment_list
*segment_list
, uint32_t index
);
443 void srte_candidate_status_update(struct srte_candidate
*candidate
, int status
);
444 void srte_candidate_unset_segment_list(const char *originator
, bool force
);
445 const char *srte_origin2str(enum srte_protocol_origin origin
);
446 void pathd_shutdown(void);
449 void path_cli_init(void);
453 * Search for sid based in prefix and algorithm
455 * @param Prefix The prefix to use
456 * @param algo Algorithm we want to query for
457 * @param ted_sid Sid to query
461 int32_t srte_ted_do_query_type_c(struct srte_segment_entry
*entry
,
462 struct prefix
*prefix_cli
, uint32_t algo
);
465 * Search for sid based in prefix and interface id
467 * @param Prefix The prefix to use
468 * @param local_iface The id of interface
469 * @param ted_sid Sid to query
473 int32_t srte_ted_do_query_type_e(struct srte_segment_entry
*entry
,
474 struct prefix
*prefix_cli
,
475 uint32_t local_iface
);
477 * Search for sid based in local and remote ip
479 * @param entry entry to update
480 * @param local Local addr for query
481 * @param remote Local addr for query
485 int32_t srte_ted_do_query_type_f(struct srte_segment_entry
*entry
,
486 struct ipaddr
*local
, struct ipaddr
*remote
);
487 #endif /* _FRR_PATHD_H_ */