]> git.proxmox.com Git - mirror_frr.git/blob - lib/northbound.h
Merge pull request #7220 from idryzhov/fix-clear-isis
[mirror_frr.git] / lib / northbound.h
1 /*
2 * Copyright (C) 2018 NetDEF, Inc.
3 * Renato Westphal
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef _FRR_NORTHBOUND_H_
21 #define _FRR_NORTHBOUND_H_
22
23 #include "thread.h"
24 #include "hook.h"
25 #include "linklist.h"
26 #include "openbsd-tree.h"
27 #include "yang.h"
28 #include "yang_translator.h"
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 /* Forward declaration(s). */
35 struct vty;
36 struct debug;
37
38 /* Northbound events. */
39 enum nb_event {
40 /*
41 * The configuration callback is supposed to verify that the changes are
42 * valid and can be applied.
43 */
44 NB_EV_VALIDATE,
45
46 /*
47 * The configuration callback is supposed to prepare all resources
48 * required to apply the changes.
49 */
50 NB_EV_PREPARE,
51
52 /*
53 * Transaction has failed, the configuration callback needs to release
54 * all resources previously allocated.
55 */
56 NB_EV_ABORT,
57
58 /*
59 * The configuration changes need to be applied. The changes can't be
60 * rejected at this point (errors are logged and ignored).
61 */
62 NB_EV_APPLY,
63 };
64
65 /*
66 * Northbound operations.
67 *
68 * Refer to the documentation comments of nb_callbacks for more details.
69 */
70 enum nb_operation {
71 NB_OP_CREATE,
72 NB_OP_MODIFY,
73 NB_OP_DESTROY,
74 NB_OP_MOVE,
75 NB_OP_PRE_VALIDATE,
76 NB_OP_APPLY_FINISH,
77 NB_OP_GET_ELEM,
78 NB_OP_GET_NEXT,
79 NB_OP_GET_KEYS,
80 NB_OP_LOOKUP_ENTRY,
81 NB_OP_RPC,
82 };
83
84 union nb_resource {
85 int fd;
86 void *ptr;
87 };
88
89 /*
90 * Northbound callbacks parameters.
91 */
92
93 struct nb_cb_create_args {
94 /* Context of the configuration transaction. */
95 struct nb_context *context;
96
97 /*
98 * The transaction phase. Refer to the documentation comments of
99 * nb_event for more details.
100 */
101 enum nb_event event;
102
103 /* libyang data node that is being created. */
104 const struct lyd_node *dnode;
105
106 /*
107 * Pointer to store resource(s) allocated during the NB_EV_PREPARE
108 * phase. The same pointer can be used during the NB_EV_ABORT and
109 * NB_EV_APPLY phases to either release or make use of the allocated
110 * resource(s). It's set to NULL when the event is NB_EV_VALIDATE.
111 */
112 union nb_resource *resource;
113
114 /* Buffer to store human-readable error message in case of error. */
115 char *errmsg;
116
117 /* Size of errmsg. */
118 size_t errmsg_len;
119 };
120
121 struct nb_cb_modify_args {
122 /* Context of the configuration transaction. */
123 struct nb_context *context;
124
125 /*
126 * The transaction phase. Refer to the documentation comments of
127 * nb_event for more details.
128 */
129 enum nb_event event;
130
131 /* libyang data node that is being modified. */
132 const struct lyd_node *dnode;
133
134 /*
135 * Pointer to store resource(s) allocated during the NB_EV_PREPARE
136 * phase. The same pointer can be used during the NB_EV_ABORT and
137 * NB_EV_APPLY phases to either release or make use of the allocated
138 * resource(s). It's set to NULL when the event is NB_EV_VALIDATE.
139 */
140 union nb_resource *resource;
141
142 /* Buffer to store human-readable error message in case of error. */
143 char *errmsg;
144
145 /* Size of errmsg. */
146 size_t errmsg_len;
147 };
148
149 struct nb_cb_destroy_args {
150 /* Context of the configuration transaction. */
151 struct nb_context *context;
152
153 /*
154 * The transaction phase. Refer to the documentation comments of
155 * nb_event for more details.
156 */
157 enum nb_event event;
158
159 /* libyang data node that is being deleted. */
160 const struct lyd_node *dnode;
161
162 /* Buffer to store human-readable error message in case of error. */
163 char *errmsg;
164
165 /* Size of errmsg. */
166 size_t errmsg_len;
167 };
168
169 struct nb_cb_move_args {
170 /* Context of the configuration transaction. */
171 struct nb_context *context;
172
173 /*
174 * The transaction phase. Refer to the documentation comments of
175 * nb_event for more details.
176 */
177 enum nb_event event;
178
179 /* libyang data node that is being moved. */
180 const struct lyd_node *dnode;
181
182 /* Buffer to store human-readable error message in case of error. */
183 char *errmsg;
184
185 /* Size of errmsg. */
186 size_t errmsg_len;
187 };
188
189 struct nb_cb_pre_validate_args {
190 /* Context of the configuration transaction. */
191 struct nb_context *context;
192
193 /* libyang data node associated with the 'pre_validate' callback. */
194 const struct lyd_node *dnode;
195
196 /* Buffer to store human-readable error message in case of error. */
197 char *errmsg;
198
199 /* Size of errmsg. */
200 size_t errmsg_len;
201 };
202
203 struct nb_cb_apply_finish_args {
204 /* Context of the configuration transaction. */
205 struct nb_context *context;
206
207 /* libyang data node associated with the 'apply_finish' callback. */
208 const struct lyd_node *dnode;
209
210 /* Buffer to store human-readable error message in case of error. */
211 char *errmsg;
212
213 /* Size of errmsg. */
214 size_t errmsg_len;
215 };
216
217 struct nb_cb_get_elem_args {
218 /* YANG data path of the data we want to get. */
219 const char *xpath;
220
221 /* Pointer to list entry (might be NULL). */
222 const void *list_entry;
223 };
224
225 struct nb_cb_get_next_args {
226 /* Pointer to parent list entry. */
227 const void *parent_list_entry;
228
229 /* Pointer to (leaf-)list entry. */
230 const void *list_entry;
231 };
232
233 struct nb_cb_get_keys_args {
234 /* Pointer to list entry. */
235 const void *list_entry;
236
237 /*
238 * Structure to be filled based on the attributes of the provided list
239 * entry.
240 */
241 struct yang_list_keys *keys;
242 };
243
244 struct nb_cb_lookup_entry_args {
245 /* Pointer to parent list entry. */
246 const void *parent_list_entry;
247
248 /* Structure containing the keys of the list entry. */
249 const struct yang_list_keys *keys;
250 };
251
252 struct nb_cb_rpc_args {
253 /* XPath of the YANG RPC or action. */
254 const char *xpath;
255
256 /* Read-only list of input parameters. */
257 const struct list *input;
258
259 /* List of output parameters to be populated by the callback. */
260 struct list *output;
261 };
262
263 /*
264 * Set of configuration callbacks that can be associated to a northbound node.
265 */
266 struct nb_callbacks {
267 /*
268 * Configuration callback.
269 *
270 * A presence container, list entry, leaf-list entry or leaf of type
271 * empty has been created.
272 *
273 * For presence-containers and list entries, the callback is supposed to
274 * initialize the default values of its children (if any) from the YANG
275 * models.
276 *
277 * args
278 * Refer to the documentation comments of nb_cb_create_args for
279 * details.
280 *
281 * Returns:
282 * - NB_OK on success.
283 * - NB_ERR_VALIDATION when a validation error occurred.
284 * - NB_ERR_RESOURCE when the callback failed to allocate a resource.
285 * - NB_ERR_INCONSISTENCY when an inconsistency was detected.
286 * - NB_ERR for other errors.
287 */
288 int (*create)(struct nb_cb_create_args *args);
289
290 /*
291 * Configuration callback.
292 *
293 * The value of a leaf has been modified.
294 *
295 * List keys don't need to implement this callback. When a list key is
296 * modified, the northbound treats this as if the list was deleted and a
297 * new one created with the updated key value.
298 *
299 * args
300 * Refer to the documentation comments of nb_cb_modify_args for
301 * details.
302 *
303 * Returns:
304 * - NB_OK on success.
305 * - NB_ERR_VALIDATION when a validation error occurred.
306 * - NB_ERR_RESOURCE when the callback failed to allocate a resource.
307 * - NB_ERR_INCONSISTENCY when an inconsistency was detected.
308 * - NB_ERR for other errors.
309 */
310 int (*modify)(struct nb_cb_modify_args *args);
311
312 /*
313 * Configuration callback.
314 *
315 * A presence container, list entry, leaf-list entry or optional leaf
316 * has been deleted.
317 *
318 * The callback is supposed to delete the entire configuration object,
319 * including its children when they exist.
320 *
321 * args
322 * Refer to the documentation comments of nb_cb_destroy_args for
323 * details.
324 *
325 * Returns:
326 * - NB_OK on success.
327 * - NB_ERR_VALIDATION when a validation error occurred.
328 * - NB_ERR_INCONSISTENCY when an inconsistency was detected.
329 * - NB_ERR for other errors.
330 */
331 int (*destroy)(struct nb_cb_destroy_args *args);
332
333 /*
334 * Configuration callback.
335 *
336 * A list entry or leaf-list entry has been moved. Only applicable when
337 * the "ordered-by user" statement is present.
338 *
339 * args
340 * Refer to the documentation comments of nb_cb_move_args for
341 * details.
342 *
343 * Returns:
344 * - NB_OK on success.
345 * - NB_ERR_VALIDATION when a validation error occurred.
346 * - NB_ERR_INCONSISTENCY when an inconsistency was detected.
347 * - NB_ERR for other errors.
348 */
349 int (*move)(struct nb_cb_move_args *args);
350
351 /*
352 * Optional configuration callback.
353 *
354 * This callback can be used to validate subsections of the
355 * configuration being committed before validating the configuration
356 * changes themselves. It's useful to perform more complex validations
357 * that depend on the relationship between multiple nodes.
358 *
359 * args
360 * Refer to the documentation comments of nb_cb_pre_validate_args for
361 * details.
362 *
363 * Returns:
364 * - NB_OK on success.
365 * - NB_ERR_VALIDATION when a validation error occurred.
366 */
367 int (*pre_validate)(struct nb_cb_pre_validate_args *args);
368
369 /*
370 * Optional configuration callback.
371 *
372 * The 'apply_finish' callbacks are called after all other callbacks
373 * during the apply phase (NB_EV_APPLY). These callbacks are called only
374 * under one of the following two cases:
375 * - The data node has been created or modified (but not deleted);
376 * - Any change was made within the descendants of the data node (e.g. a
377 * child leaf was modified, created or deleted).
378 *
379 * In the second case above, the 'apply_finish' callback is called only
380 * once even if multiple changes occurred within the descendants of the
381 * data node.
382 *
383 * args
384 * Refer to the documentation comments of nb_cb_apply_finish_args for
385 * details.
386 */
387 void (*apply_finish)(struct nb_cb_apply_finish_args *args);
388
389 /*
390 * Operational data callback.
391 *
392 * The callback function should return the value of a specific leaf,
393 * leaf-list entry or inform if a typeless value (presence containers or
394 * leafs of type empty) exists or not.
395 *
396 * args
397 * Refer to the documentation comments of nb_cb_get_elem_args for
398 * details.
399 *
400 * Returns:
401 * Pointer to newly created yang_data structure, or NULL to indicate
402 * the absence of data.
403 */
404 struct yang_data *(*get_elem)(struct nb_cb_get_elem_args *args);
405
406 /*
407 * Operational data callback for YANG lists and leaf-lists.
408 *
409 * The callback function should return the next entry in the list or
410 * leaf-list. The 'list_entry' parameter will be NULL on the first
411 * invocation.
412 *
413 * args
414 * Refer to the documentation comments of nb_cb_get_next_args for
415 * details.
416 *
417 * Returns:
418 * Pointer to the next entry in the (leaf-)list, or NULL to signal
419 * that the end of the (leaf-)list was reached.
420 */
421 const void *(*get_next)(struct nb_cb_get_next_args *args);
422
423 /*
424 * Operational data callback for YANG lists.
425 *
426 * The callback function should fill the 'keys' parameter based on the
427 * given list_entry. Keyless lists don't need to implement this
428 * callback.
429 *
430 * args
431 * Refer to the documentation comments of nb_cb_get_keys_args for
432 * details.
433 *
434 * Returns:
435 * NB_OK on success, NB_ERR otherwise.
436 */
437 int (*get_keys)(struct nb_cb_get_keys_args *args);
438
439 /*
440 * Operational data callback for YANG lists.
441 *
442 * The callback function should return a list entry based on the list
443 * keys given as a parameter. Keyless lists don't need to implement this
444 * callback.
445 *
446 * args
447 * Refer to the documentation comments of nb_cb_lookup_entry_args for
448 * details.
449 *
450 * Returns:
451 * Pointer to the list entry if found, or NULL if not found.
452 */
453 const void *(*lookup_entry)(struct nb_cb_lookup_entry_args *args);
454
455 /*
456 * RPC and action callback.
457 *
458 * Both 'input' and 'output' are lists of 'yang_data' structures. The
459 * callback should fetch all the input parameters from the 'input' list,
460 * and add output parameters to the 'output' list if necessary.
461 *
462 * args
463 * Refer to the documentation comments of nb_cb_rpc_args for details.
464 *
465 * Returns:
466 * NB_OK on success, NB_ERR otherwise.
467 */
468 int (*rpc)(struct nb_cb_rpc_args *args);
469
470 /*
471 * Optional callback to show the CLI command associated to the given
472 * YANG data node.
473 *
474 * vty
475 * The vty terminal to dump the configuration to.
476 *
477 * dnode
478 * libyang data node that should be shown in the form of a CLI
479 * command.
480 *
481 * show_defaults
482 * Specify whether to display default configuration values or not.
483 * This parameter can be ignored most of the time since the
484 * northbound doesn't call this callback for default leaves or
485 * non-presence containers that contain only default child nodes.
486 * The exception are commands associated to multiple configuration
487 * nodes, in which case it might be desirable to hide one or more
488 * parts of the command when this parameter is set to false.
489 */
490 void (*cli_show)(struct vty *vty, struct lyd_node *dnode,
491 bool show_defaults);
492
493 /*
494 * Optional callback to show the CLI node end for lists or containers.
495 *
496 * vty
497 * The vty terminal to dump the configuration to.
498 *
499 * dnode
500 * libyang data node that should be shown in the form of a CLI
501 * command.
502 */
503 void (*cli_show_end)(struct vty *vty, struct lyd_node *dnode);
504 };
505
506 /*
507 * Northbound-specific data that is allocated for each schema node of the native
508 * YANG modules.
509 */
510 struct nb_node {
511 /* Back pointer to the libyang schema node. */
512 const struct lys_node *snode;
513
514 /* Data path of this YANG node. */
515 char xpath[XPATH_MAXLEN];
516
517 /* Priority - lower priorities are processed first. */
518 uint32_t priority;
519
520 /* Callbacks implemented for this node. */
521 struct nb_callbacks cbs;
522
523 /*
524 * Pointer to the parent node (disconsidering non-presence containers).
525 */
526 struct nb_node *parent;
527
528 /* Pointer to the nearest parent list, if any. */
529 struct nb_node *parent_list;
530
531 /* Flags. */
532 uint8_t flags;
533
534 #ifdef HAVE_CONFD
535 /* ConfD hash value corresponding to this YANG path. */
536 int confd_hash;
537 #endif
538 };
539 /* The YANG container or list contains only config data. */
540 #define F_NB_NODE_CONFIG_ONLY 0x01
541 /* The YANG list doesn't contain key leafs. */
542 #define F_NB_NODE_KEYLESS_LIST 0x02
543
544 /*
545 * HACK: old gcc versions (< 5.x) have a bug that prevents C99 flexible arrays
546 * from working properly on shared libraries. For those compilers, use a fixed
547 * size array to work around the problem.
548 */
549 #define YANG_MODULE_MAX_NODES 1024
550
551 struct frr_yang_module_info {
552 /* YANG module name. */
553 const char *name;
554
555 /* Northbound callbacks. */
556 const struct {
557 /* Data path of this YANG node. */
558 const char *xpath;
559
560 /* Callbacks implemented for this node. */
561 struct nb_callbacks cbs;
562
563 /* Priority - lower priorities are processed first. */
564 uint32_t priority;
565 #if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
566 } nodes[YANG_MODULE_MAX_NODES + 1];
567 #else
568 } nodes[];
569 #endif
570 };
571
572 /* Northbound error codes. */
573 enum nb_error {
574 NB_OK = 0,
575 NB_ERR,
576 NB_ERR_NO_CHANGES,
577 NB_ERR_NOT_FOUND,
578 NB_ERR_LOCKED,
579 NB_ERR_VALIDATION,
580 NB_ERR_RESOURCE,
581 NB_ERR_INCONSISTENCY,
582 };
583
584 /* Default priority. */
585 #define NB_DFLT_PRIORITY (UINT32_MAX / 2)
586
587 /* Default maximum of configuration rollbacks to store. */
588 #define NB_DLFT_MAX_CONFIG_ROLLBACKS 20
589
590 /* Northbound clients. */
591 enum nb_client {
592 NB_CLIENT_NONE = 0,
593 NB_CLIENT_CLI,
594 NB_CLIENT_CONFD,
595 NB_CLIENT_SYSREPO,
596 NB_CLIENT_GRPC,
597 };
598
599 /* Northbound context. */
600 struct nb_context {
601 /* Northbound client. */
602 enum nb_client client;
603
604 /* Northbound user (can be NULL). */
605 const void *user;
606
607 /* Client-specific data. */
608 #if 0
609 union {
610 struct {
611 } cli;
612 struct {
613 } confd;
614 struct {
615 } sysrepo;
616 struct {
617 } grpc;
618 } client_data;
619 #endif
620 };
621
622 /* Northbound configuration. */
623 struct nb_config {
624 struct lyd_node *dnode;
625 uint32_t version;
626 };
627
628 /* Northbound configuration callback. */
629 struct nb_config_cb {
630 RB_ENTRY(nb_config_cb) entry;
631 enum nb_operation operation;
632 uint32_t seq;
633 const struct nb_node *nb_node;
634 const struct lyd_node *dnode;
635 };
636 RB_HEAD(nb_config_cbs, nb_config_cb);
637 RB_PROTOTYPE(nb_config_cbs, nb_config_cb, entry, nb_config_cb_compare);
638
639 /* Northbound configuration change. */
640 struct nb_config_change {
641 struct nb_config_cb cb;
642 union nb_resource resource;
643 bool prepare_ok;
644 };
645
646 /* Northbound configuration transaction. */
647 struct nb_transaction {
648 struct nb_context *context;
649 char comment[80];
650 struct nb_config *config;
651 struct nb_config_cbs changes;
652 };
653
654 /* Callback function used by nb_oper_data_iterate(). */
655 typedef int (*nb_oper_data_cb)(const struct lys_node *snode,
656 struct yang_translator *translator,
657 struct yang_data *data, void *arg);
658
659 /* Iterate over direct child nodes only. */
660 #define NB_OPER_DATA_ITER_NORECURSE 0x0001
661
662 /* Hooks. */
663 DECLARE_HOOK(nb_notification_send, (const char *xpath, struct list *arguments),
664 (xpath, arguments))
665 DECLARE_HOOK(nb_client_debug_config_write, (struct vty *vty), (vty))
666 DECLARE_HOOK(nb_client_debug_set_all, (uint32_t flags, bool set), (flags, set))
667
668 /* Northbound debugging records */
669 extern struct debug nb_dbg_cbs_config;
670 extern struct debug nb_dbg_cbs_state;
671 extern struct debug nb_dbg_cbs_rpc;
672 extern struct debug nb_dbg_notif;
673 extern struct debug nb_dbg_events;
674
675 /* Global running configuration. */
676 extern struct nb_config *running_config;
677
678 /* Wrappers for the northbound callbacks. */
679 extern struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node,
680 const char *xpath,
681 const void *list_entry);
682 extern const void *nb_callback_get_next(const struct nb_node *nb_node,
683 const void *parent_list_entry,
684 const void *list_entry);
685 extern int nb_callback_get_keys(const struct nb_node *nb_node,
686 const void *list_entry,
687 struct yang_list_keys *keys);
688 extern const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
689 const void *parent_list_entry,
690 const struct yang_list_keys *keys);
691 extern int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
692 const struct list *input, struct list *output);
693
694 /*
695 * Create a northbound node for all YANG schema nodes.
696 */
697 void nb_nodes_create(void);
698
699 /*
700 * Delete all northbound nodes from all YANG schema nodes.
701 */
702 void nb_nodes_delete(void);
703
704 /*
705 * Find the northbound node corresponding to a YANG data path.
706 *
707 * xpath
708 * XPath to search for (with or without predicates).
709 *
710 * Returns:
711 * Pointer to northbound node if found, NULL otherwise.
712 */
713 extern struct nb_node *nb_node_find(const char *xpath);
714
715 /*
716 * Create a new northbound configuration.
717 *
718 * dnode
719 * Pointer to a libyang data node containing the configuration data. If NULL
720 * is given, an empty configuration will be created.
721 *
722 * Returns:
723 * Pointer to newly created northbound configuration.
724 */
725 extern struct nb_config *nb_config_new(struct lyd_node *dnode);
726
727 /*
728 * Delete a northbound configuration.
729 *
730 * config
731 * Pointer to the config that is going to be deleted.
732 */
733 extern void nb_config_free(struct nb_config *config);
734
735 /*
736 * Duplicate a northbound configuration.
737 *
738 * config
739 * Northbound configuration to duplicate.
740 *
741 * Returns:
742 * Pointer to duplicated configuration.
743 */
744 extern struct nb_config *nb_config_dup(const struct nb_config *config);
745
746 /*
747 * Merge one configuration into another.
748 *
749 * config_dst
750 * Configuration to merge to.
751 *
752 * config_src
753 * Configuration to merge config_dst with.
754 *
755 * preserve_source
756 * Specify whether config_src should be deleted or not after the merge
757 * operation.
758 *
759 * Returns:
760 * NB_OK on success, NB_ERR otherwise.
761 */
762 extern int nb_config_merge(struct nb_config *config_dst,
763 struct nb_config *config_src, bool preserve_source);
764
765 /*
766 * Replace one configuration by another.
767 *
768 * config_dst
769 * Configuration to be replaced.
770 *
771 * config_src
772 * Configuration to replace config_dst.
773 *
774 * preserve_source
775 * Specify whether config_src should be deleted or not after the replace
776 * operation.
777 */
778 extern void nb_config_replace(struct nb_config *config_dst,
779 struct nb_config *config_src,
780 bool preserve_source);
781
782 /*
783 * Edit a candidate configuration.
784 *
785 * candidate
786 * Candidate configuration to edit.
787 *
788 * nb_node
789 * Northbound node associated to the configuration being edited.
790 *
791 * operation
792 * Operation to apply.
793 *
794 * xpath
795 * XPath of the configuration node being edited.
796 *
797 * previous
798 * Previous value of the configuration node. Should be used only when the
799 * operation is NB_OP_MOVE, otherwise this parameter is ignored.
800 *
801 * data
802 * New value of the configuration node.
803 *
804 * Returns:
805 * - NB_OK on success.
806 * - NB_ERR_NOT_FOUND when the element to be deleted was not found.
807 * - NB_ERR for other errors.
808 */
809 extern int nb_candidate_edit(struct nb_config *candidate,
810 const struct nb_node *nb_node,
811 enum nb_operation operation, const char *xpath,
812 const struct yang_data *previous,
813 const struct yang_data *data);
814
815 /*
816 * Check if a candidate configuration is outdated and needs to be updated.
817 *
818 * candidate
819 * Candidate configuration to check.
820 *
821 * Returns:
822 * true if the candidate is outdated, false otherwise.
823 */
824 extern bool nb_candidate_needs_update(const struct nb_config *candidate);
825
826 /*
827 * Update a candidate configuration by rebasing the changes on top of the latest
828 * running configuration. Resolve conflicts automatically by giving preference
829 * to the changes done in the candidate configuration.
830 *
831 * candidate
832 * Candidate configuration to update.
833 *
834 * Returns:
835 * NB_OK on success, NB_ERR otherwise.
836 */
837 extern int nb_candidate_update(struct nb_config *candidate);
838
839 /*
840 * Validate a candidate configuration. Perform both YANG syntactic/semantic
841 * validation and code-level validation using the northbound callbacks.
842 *
843 * WARNING: the candidate can be modified as part of the validation process
844 * (e.g. add default nodes).
845 *
846 * context
847 * Context of the northbound transaction.
848 *
849 * candidate
850 * Candidate configuration to validate.
851 *
852 * errmsg
853 * Buffer to store human-readable error message in case of error.
854 *
855 * errmsg_len
856 * Size of errmsg.
857 *
858 * Returns:
859 * NB_OK on success, NB_ERR_VALIDATION otherwise.
860 */
861 extern int nb_candidate_validate(struct nb_context *context,
862 struct nb_config *candidate, char *errmsg,
863 size_t errmsg_len);
864
865 /*
866 * Create a new configuration transaction but do not commit it yet. Only
867 * validate the candidate and prepare all resources required to apply the
868 * configuration changes.
869 *
870 * context
871 * Context of the northbound transaction.
872 *
873 * candidate
874 * Candidate configuration to commit.
875 *
876 * comment
877 * Optional comment describing the commit.
878 *
879 * transaction
880 * Output parameter providing the created transaction when one is created
881 * successfully. In this case, it must be either aborted using
882 * nb_candidate_commit_abort() or committed using
883 * nb_candidate_commit_apply().
884 *
885 * errmsg
886 * Buffer to store human-readable error message in case of error.
887 *
888 * errmsg_len
889 * Size of errmsg.
890 *
891 * Returns:
892 * - NB_OK on success.
893 * - NB_ERR_NO_CHANGES when the candidate is identical to the running
894 * configuration.
895 * - NB_ERR_LOCKED when there's already another transaction in progress.
896 * - NB_ERR_VALIDATION when the candidate fails the validation checks.
897 * - NB_ERR_RESOURCE when the system fails to allocate resources to apply
898 * the candidate configuration.
899 * - NB_ERR for other errors.
900 */
901 extern int nb_candidate_commit_prepare(struct nb_context *context,
902 struct nb_config *candidate,
903 const char *comment,
904 struct nb_transaction **transaction,
905 char *errmsg, size_t errmsg_len);
906
907 /*
908 * Abort a previously created configuration transaction, releasing all resources
909 * allocated during the preparation phase.
910 *
911 * transaction
912 * Candidate configuration to abort. It's consumed by this function.
913 *
914 * errmsg
915 * Buffer to store human-readable error message in case of error.
916 *
917 * errmsg_len
918 * Size of errmsg.
919 */
920 extern void nb_candidate_commit_abort(struct nb_transaction *transaction,
921 char *errmsg, size_t errmsg_len);
922
923 /*
924 * Commit a previously created configuration transaction.
925 *
926 * transaction
927 * Configuration transaction to commit. It's consumed by this function.
928 *
929 * save_transaction
930 * Specify whether the transaction should be recorded in the transactions log
931 * or not.
932 *
933 * transaction_id
934 * Optional output parameter providing the ID of the committed transaction.
935 *
936 * errmsg
937 * Buffer to store human-readable error message in case of error.
938 *
939 * errmsg_len
940 * Size of errmsg.
941 */
942 extern void nb_candidate_commit_apply(struct nb_transaction *transaction,
943 bool save_transaction,
944 uint32_t *transaction_id, char *errmsg,
945 size_t errmsg_len);
946
947 /*
948 * Create a new transaction to commit a candidate configuration. This is a
949 * convenience function that performs the two-phase commit protocol
950 * transparently to the user. The cost is reduced flexibility, since
951 * network-wide and multi-daemon transactions require the network manager to
952 * take into account the results of the preparation phase of multiple managed
953 * entities.
954 *
955 * context
956 * Context of the northbound transaction.
957 *
958 * candidate
959 * Candidate configuration to commit. It's preserved regardless if the commit
960 * operation fails or not.
961 *
962 * save_transaction
963 * Specify whether the transaction should be recorded in the transactions log
964 * or not.
965 *
966 * comment
967 * Optional comment describing the commit.
968 *
969 * transaction_id
970 * Optional output parameter providing the ID of the committed transaction.
971 *
972 * errmsg
973 * Buffer to store human-readable error message in case of error.
974 *
975 * errmsg_len
976 * Size of errmsg.
977 *
978 * Returns:
979 * - NB_OK on success.
980 * - NB_ERR_NO_CHANGES when the candidate is identical to the running
981 * configuration.
982 * - NB_ERR_LOCKED when there's already another transaction in progress.
983 * - NB_ERR_VALIDATION when the candidate fails the validation checks.
984 * - NB_ERR_RESOURCE when the system fails to allocate resources to apply
985 * the candidate configuration.
986 * - NB_ERR for other errors.
987 */
988 extern int nb_candidate_commit(struct nb_context *context,
989 struct nb_config *candidate,
990 bool save_transaction, const char *comment,
991 uint32_t *transaction_id, char *errmsg,
992 size_t errmsg_len);
993
994 /*
995 * Lock the running configuration.
996 *
997 * client
998 * Northbound client.
999 *
1000 * user
1001 * Northbound user (can be NULL).
1002 *
1003 * Returns:
1004 * 0 on success, -1 when the running configuration is already locked.
1005 */
1006 extern int nb_running_lock(enum nb_client client, const void *user);
1007
1008 /*
1009 * Unlock the running configuration.
1010 *
1011 * client
1012 * Northbound client.
1013 *
1014 * user
1015 * Northbound user (can be NULL).
1016 *
1017 * Returns:
1018 * 0 on success, -1 when the running configuration is already unlocked or
1019 * locked by another client/user.
1020 */
1021 extern int nb_running_unlock(enum nb_client client, const void *user);
1022
1023 /*
1024 * Check if the running configuration is locked or not for the given
1025 * client/user.
1026 *
1027 * client
1028 * Northbound client.
1029 *
1030 * user
1031 * Northbound user (can be NULL).
1032 *
1033 * Returns:
1034 * 0 if the running configuration is unlocked or if the client/user owns the
1035 * lock, -1 otherwise.
1036 */
1037 extern int nb_running_lock_check(enum nb_client client, const void *user);
1038
1039 /*
1040 * Iterate over operational data.
1041 *
1042 * xpath
1043 * Data path of the YANG data we want to iterate over.
1044 *
1045 * translator
1046 * YANG module translator (might be NULL).
1047 *
1048 * flags
1049 * NB_OPER_DATA_ITER_ flags to control how the iteration is performed.
1050 *
1051 * cb
1052 * Function to call with each data node.
1053 *
1054 * arg
1055 * Arbitrary argument passed as the fourth parameter in each call to 'cb'.
1056 *
1057 * Returns:
1058 * NB_OK on success, NB_ERR otherwise.
1059 */
1060 extern int nb_oper_data_iterate(const char *xpath,
1061 struct yang_translator *translator,
1062 uint32_t flags, nb_oper_data_cb cb, void *arg);
1063
1064 /*
1065 * Validate if the northbound operation is valid for the given node.
1066 *
1067 * operation
1068 * Operation we want to check.
1069 *
1070 * snode
1071 * libyang schema node we want to check.
1072 *
1073 * Returns:
1074 * true if the operation is valid, false otherwise.
1075 */
1076 extern bool nb_operation_is_valid(enum nb_operation operation,
1077 const struct lys_node *snode);
1078
1079 /*
1080 * Send a YANG notification. This is a no-op unless the 'nb_notification_send'
1081 * hook was registered by a northbound plugin.
1082 *
1083 * xpath
1084 * XPath of the YANG notification.
1085 *
1086 * arguments
1087 * Linked list containing the arguments that should be sent. This list is
1088 * deleted after being used.
1089 *
1090 * Returns:
1091 * NB_OK on success, NB_ERR otherwise.
1092 */
1093 extern int nb_notification_send(const char *xpath, struct list *arguments);
1094
1095 /*
1096 * Associate a user pointer to a configuration node.
1097 *
1098 * This should be called by northbound 'create' callbacks in the NB_EV_APPLY
1099 * phase only.
1100 *
1101 * dnode
1102 * libyang data node - only its XPath is used.
1103 *
1104 * entry
1105 * Arbitrary user-specified pointer.
1106 */
1107 extern void nb_running_set_entry(const struct lyd_node *dnode, void *entry);
1108
1109 /*
1110 * Move an entire tree of user pointer nodes.
1111 *
1112 * Suppose we have xpath A/B/C/D, with user pointers associated to C and D. We
1113 * need to move B to be under Z, so the new xpath is Z/B/C/D. Because user
1114 * pointers are indexed with their absolute path, We need to move all user
1115 * pointers at and below B to their new absolute paths; this function does
1116 * that.
1117 *
1118 * xpath_from
1119 * base xpath of tree to move (A/B)
1120 *
1121 * xpath_to
1122 * base xpath of new location of tree (Z/B)
1123 */
1124 extern void nb_running_move_tree(const char *xpath_from, const char *xpath_to);
1125
1126 /*
1127 * Unset the user pointer associated to a configuration node.
1128 *
1129 * This should be called by northbound 'destroy' callbacks in the NB_EV_APPLY
1130 * phase only.
1131 *
1132 * dnode
1133 * libyang data node - only its XPath is used.
1134 *
1135 * Returns:
1136 * The user pointer that was unset.
1137 */
1138 extern void *nb_running_unset_entry(const struct lyd_node *dnode);
1139
1140 /*
1141 * Find the user pointer (if any) associated to a configuration node.
1142 *
1143 * The XPath associated to the configuration node can be provided directly or
1144 * indirectly through a libyang data node.
1145 *
1146 * If an user point is not found, this function follows the parent nodes in the
1147 * running configuration until an user pointer is found or until the root node
1148 * is reached.
1149 *
1150 * dnode
1151 * libyang data node - only its XPath is used (can be NULL if 'xpath' is
1152 * provided).
1153 *
1154 * xpath
1155 * XPath of the configuration node (can be NULL if 'dnode' is provided).
1156 *
1157 * abort_if_not_found
1158 * When set to true, abort the program if no user pointer is found.
1159 *
1160 * As a rule of thumb, this parameter should be set to true in the following
1161 * scenarios:
1162 * - Calling this function from any northbound configuration callback during
1163 * the NB_EV_APPLY phase.
1164 * - Calling this function from a 'delete' northbound configuration callback
1165 * during any phase.
1166 *
1167 * In both the above cases, the given configuration node should contain an
1168 * user pointer except when there's a bug in the code, in which case it's
1169 * better to abort the program right away and eliminate the need for
1170 * unnecessary NULL checks.
1171 *
1172 * In all other cases, this parameter should be set to false and the caller
1173 * should check if the function returned NULL or not.
1174 *
1175 * Returns:
1176 * User pointer if found, NULL otherwise.
1177 */
1178 extern void *nb_running_get_entry(const struct lyd_node *dnode,
1179 const char *xpath, bool abort_if_not_found);
1180
1181 /*
1182 * Same as 'nb_running_get_entry', but doesn't search within parent nodes
1183 * recursively if an user point is not found.
1184 */
1185 extern void *nb_running_get_entry_non_rec(const struct lyd_node *dnode,
1186 const char *xpath,
1187 bool abort_if_not_found);
1188
1189 /*
1190 * Return a human-readable string representing a northbound event.
1191 *
1192 * event
1193 * Northbound event.
1194 *
1195 * Returns:
1196 * String representation of the given northbound event.
1197 */
1198 extern const char *nb_event_name(enum nb_event event);
1199
1200 /*
1201 * Return a human-readable string representing a northbound operation.
1202 *
1203 * operation
1204 * Northbound operation.
1205 *
1206 * Returns:
1207 * String representation of the given northbound operation.
1208 */
1209 extern const char *nb_operation_name(enum nb_operation operation);
1210
1211 /*
1212 * Return a human-readable string representing a northbound error.
1213 *
1214 * error
1215 * Northbound error.
1216 *
1217 * Returns:
1218 * String representation of the given northbound error.
1219 */
1220 extern const char *nb_err_name(enum nb_error error);
1221
1222 /*
1223 * Return a human-readable string representing a northbound client.
1224 *
1225 * client
1226 * Northbound client.
1227 *
1228 * Returns:
1229 * String representation of the given northbound client.
1230 */
1231 extern const char *nb_client_name(enum nb_client client);
1232
1233 /*
1234 * Initialize the northbound layer. Should be called only once during the
1235 * daemon initialization process.
1236 *
1237 * modules
1238 * Array of YANG modules to parse and initialize.
1239 *
1240 * nmodules
1241 * Size of the modules array.
1242 *
1243 * db_enabled
1244 * Set this to record the transactions in the transaction log.
1245 */
1246 extern void nb_init(struct thread_master *tm,
1247 const struct frr_yang_module_info *const modules[],
1248 size_t nmodules, bool db_enabled);
1249
1250 /*
1251 * Finish the northbound layer gracefully. Should be called only when the daemon
1252 * is exiting.
1253 */
1254 extern void nb_terminate(void);
1255
1256 #ifdef __cplusplus
1257 }
1258 #endif
1259
1260 #endif /* _FRR_NORTHBOUND_H_ */