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