]> git.proxmox.com Git - mirror_frr.git/blob - lib/northbound.h
Merge pull request #8262 from reubendowle/fixes/nhrp-misc-fixes
[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 /* Buffer to store human-readable error message in case of error. */
263 char *errmsg;
264
265 /* Size of errmsg. */
266 size_t errmsg_len;
267 };
268
269 /*
270 * Set of configuration callbacks that can be associated to a northbound node.
271 */
272 struct nb_callbacks {
273 /*
274 * Configuration callback.
275 *
276 * A presence container, list entry, leaf-list entry or leaf of type
277 * empty has been created.
278 *
279 * For presence-containers and list entries, the callback is supposed to
280 * initialize the default values of its children (if any) from the YANG
281 * models.
282 *
283 * args
284 * Refer to the documentation comments of nb_cb_create_args for
285 * details.
286 *
287 * Returns:
288 * - NB_OK on success.
289 * - NB_ERR_VALIDATION when a validation error occurred.
290 * - NB_ERR_RESOURCE when the callback failed to allocate a resource.
291 * - NB_ERR_INCONSISTENCY when an inconsistency was detected.
292 * - NB_ERR for other errors.
293 */
294 int (*create)(struct nb_cb_create_args *args);
295
296 /*
297 * Configuration callback.
298 *
299 * The value of a leaf has been modified.
300 *
301 * List keys don't need to implement this callback. When a list key is
302 * modified, the northbound treats this as if the list was deleted and a
303 * new one created with the updated key value.
304 *
305 * args
306 * Refer to the documentation comments of nb_cb_modify_args for
307 * details.
308 *
309 * Returns:
310 * - NB_OK on success.
311 * - NB_ERR_VALIDATION when a validation error occurred.
312 * - NB_ERR_RESOURCE when the callback failed to allocate a resource.
313 * - NB_ERR_INCONSISTENCY when an inconsistency was detected.
314 * - NB_ERR for other errors.
315 */
316 int (*modify)(struct nb_cb_modify_args *args);
317
318 /*
319 * Configuration callback.
320 *
321 * A presence container, list entry, leaf-list entry or optional leaf
322 * has been deleted.
323 *
324 * The callback is supposed to delete the entire configuration object,
325 * including its children when they exist.
326 *
327 * args
328 * Refer to the documentation comments of nb_cb_destroy_args for
329 * details.
330 *
331 * Returns:
332 * - NB_OK on success.
333 * - NB_ERR_VALIDATION when a validation error occurred.
334 * - NB_ERR_INCONSISTENCY when an inconsistency was detected.
335 * - NB_ERR for other errors.
336 */
337 int (*destroy)(struct nb_cb_destroy_args *args);
338
339 /*
340 * Configuration callback.
341 *
342 * A list entry or leaf-list entry has been moved. Only applicable when
343 * the "ordered-by user" statement is present.
344 *
345 * args
346 * Refer to the documentation comments of nb_cb_move_args for
347 * details.
348 *
349 * Returns:
350 * - NB_OK on success.
351 * - NB_ERR_VALIDATION when a validation error occurred.
352 * - NB_ERR_INCONSISTENCY when an inconsistency was detected.
353 * - NB_ERR for other errors.
354 */
355 int (*move)(struct nb_cb_move_args *args);
356
357 /*
358 * Optional configuration callback.
359 *
360 * This callback can be used to validate subsections of the
361 * configuration being committed before validating the configuration
362 * changes themselves. It's useful to perform more complex validations
363 * that depend on the relationship between multiple nodes.
364 *
365 * args
366 * Refer to the documentation comments of nb_cb_pre_validate_args for
367 * details.
368 *
369 * Returns:
370 * - NB_OK on success.
371 * - NB_ERR_VALIDATION when a validation error occurred.
372 */
373 int (*pre_validate)(struct nb_cb_pre_validate_args *args);
374
375 /*
376 * Optional configuration callback.
377 *
378 * The 'apply_finish' callbacks are called after all other callbacks
379 * during the apply phase (NB_EV_APPLY). These callbacks are called only
380 * under one of the following two cases:
381 * - The data node has been created or modified (but not deleted);
382 * - Any change was made within the descendants of the data node (e.g. a
383 * child leaf was modified, created or deleted).
384 *
385 * In the second case above, the 'apply_finish' callback is called only
386 * once even if multiple changes occurred within the descendants of the
387 * data node.
388 *
389 * args
390 * Refer to the documentation comments of nb_cb_apply_finish_args for
391 * details.
392 */
393 void (*apply_finish)(struct nb_cb_apply_finish_args *args);
394
395 /*
396 * Operational data callback.
397 *
398 * The callback function should return the value of a specific leaf,
399 * leaf-list entry or inform if a typeless value (presence containers or
400 * leafs of type empty) exists or not.
401 *
402 * args
403 * Refer to the documentation comments of nb_cb_get_elem_args for
404 * details.
405 *
406 * Returns:
407 * Pointer to newly created yang_data structure, or NULL to indicate
408 * the absence of data.
409 */
410 struct yang_data *(*get_elem)(struct nb_cb_get_elem_args *args);
411
412 /*
413 * Operational data callback for YANG lists and leaf-lists.
414 *
415 * The callback function should return the next entry in the list or
416 * leaf-list. The 'list_entry' parameter will be NULL on the first
417 * invocation.
418 *
419 * args
420 * Refer to the documentation comments of nb_cb_get_next_args for
421 * details.
422 *
423 * Returns:
424 * Pointer to the next entry in the (leaf-)list, or NULL to signal
425 * that the end of the (leaf-)list was reached.
426 */
427 const void *(*get_next)(struct nb_cb_get_next_args *args);
428
429 /*
430 * Operational data callback for YANG lists.
431 *
432 * The callback function should fill the 'keys' parameter based on the
433 * given list_entry. Keyless lists don't need to implement this
434 * callback.
435 *
436 * args
437 * Refer to the documentation comments of nb_cb_get_keys_args for
438 * details.
439 *
440 * Returns:
441 * NB_OK on success, NB_ERR otherwise.
442 */
443 int (*get_keys)(struct nb_cb_get_keys_args *args);
444
445 /*
446 * Operational data callback for YANG lists.
447 *
448 * The callback function should return a list entry based on the list
449 * keys given as a parameter. Keyless lists don't need to implement this
450 * callback.
451 *
452 * args
453 * Refer to the documentation comments of nb_cb_lookup_entry_args for
454 * details.
455 *
456 * Returns:
457 * Pointer to the list entry if found, or NULL if not found.
458 */
459 const void *(*lookup_entry)(struct nb_cb_lookup_entry_args *args);
460
461 /*
462 * RPC and action callback.
463 *
464 * Both 'input' and 'output' are lists of 'yang_data' structures. The
465 * callback should fetch all the input parameters from the 'input' list,
466 * and add output parameters to the 'output' list if necessary.
467 *
468 * args
469 * Refer to the documentation comments of nb_cb_rpc_args for details.
470 *
471 * Returns:
472 * NB_OK on success, NB_ERR otherwise.
473 */
474 int (*rpc)(struct nb_cb_rpc_args *args);
475
476 /*
477 * Optional callback to compare the data nodes when printing
478 * the CLI commands associated with them.
479 *
480 * dnode1
481 * The first data node to compare.
482 *
483 * dnode2
484 * The second data node to compare.
485 *
486 * Returns:
487 * <0 when the CLI command for the dnode1 should be printed first
488 * >0 when the CLI command for the dnode2 should be printed first
489 * 0 when there is no difference
490 */
491 int (*cli_cmp)(struct lyd_node *dnode1, struct lyd_node *dnode2);
492
493 /*
494 * Optional callback to show the CLI command associated to the given
495 * YANG data node.
496 *
497 * vty
498 * The vty terminal to dump the configuration to.
499 *
500 * dnode
501 * libyang data node that should be shown in the form of a CLI
502 * command.
503 *
504 * show_defaults
505 * Specify whether to display default configuration values or not.
506 * This parameter can be ignored most of the time since the
507 * northbound doesn't call this callback for default leaves or
508 * non-presence containers that contain only default child nodes.
509 * The exception are commands associated to multiple configuration
510 * nodes, in which case it might be desirable to hide one or more
511 * parts of the command when this parameter is set to false.
512 */
513 void (*cli_show)(struct vty *vty, struct lyd_node *dnode,
514 bool show_defaults);
515
516 /*
517 * Optional callback to show the CLI node end for lists or containers.
518 *
519 * vty
520 * The vty terminal to dump the configuration to.
521 *
522 * dnode
523 * libyang data node that should be shown in the form of a CLI
524 * command.
525 */
526 void (*cli_show_end)(struct vty *vty, struct lyd_node *dnode);
527 };
528
529 struct nb_dependency_callbacks {
530 void (*get_dependant_xpath)(const struct lyd_node *dnode, char *xpath);
531 void (*get_dependency_xpath)(const struct lyd_node *dnode, char *xpath);
532 };
533
534 /*
535 * Northbound-specific data that is allocated for each schema node of the native
536 * YANG modules.
537 */
538 struct nb_node {
539 /* Back pointer to the libyang schema node. */
540 const struct lysc_node *snode;
541
542 /* Data path of this YANG node. */
543 char xpath[XPATH_MAXLEN];
544
545 /* Priority - lower priorities are processed first. */
546 uint32_t priority;
547
548 struct nb_dependency_callbacks dep_cbs;
549
550 /* Callbacks implemented for this node. */
551 struct nb_callbacks cbs;
552
553 /*
554 * Pointer to the parent node (disconsidering non-presence containers).
555 */
556 struct nb_node *parent;
557
558 /* Pointer to the nearest parent list, if any. */
559 struct nb_node *parent_list;
560
561 /* Flags. */
562 uint8_t flags;
563
564 #ifdef HAVE_CONFD
565 /* ConfD hash value corresponding to this YANG path. */
566 int confd_hash;
567 #endif
568 };
569 /* The YANG container or list contains only config data. */
570 #define F_NB_NODE_CONFIG_ONLY 0x01
571 /* The YANG list doesn't contain key leafs. */
572 #define F_NB_NODE_KEYLESS_LIST 0x02
573
574 /*
575 * HACK: old gcc versions (< 5.x) have a bug that prevents C99 flexible arrays
576 * from working properly on shared libraries. For those compilers, use a fixed
577 * size array to work around the problem.
578 */
579 #define YANG_MODULE_MAX_NODES 2000
580
581 struct frr_yang_module_info {
582 /* YANG module name. */
583 const char *name;
584
585 /* Northbound callbacks. */
586 const struct {
587 /* Data path of this YANG node. */
588 const char *xpath;
589
590 /* Callbacks implemented for this node. */
591 struct nb_callbacks cbs;
592
593 /* Priority - lower priorities are processed first. */
594 uint32_t priority;
595 #if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
596 } nodes[YANG_MODULE_MAX_NODES + 1];
597 #else
598 } nodes[];
599 #endif
600 };
601
602 /* Northbound error codes. */
603 enum nb_error {
604 NB_OK = 0,
605 NB_ERR,
606 NB_ERR_NO_CHANGES,
607 NB_ERR_NOT_FOUND,
608 NB_ERR_LOCKED,
609 NB_ERR_VALIDATION,
610 NB_ERR_RESOURCE,
611 NB_ERR_INCONSISTENCY,
612 };
613
614 /* Default priority. */
615 #define NB_DFLT_PRIORITY (UINT32_MAX / 2)
616
617 /* Default maximum of configuration rollbacks to store. */
618 #define NB_DLFT_MAX_CONFIG_ROLLBACKS 20
619
620 /* Northbound clients. */
621 enum nb_client {
622 NB_CLIENT_NONE = 0,
623 NB_CLIENT_CLI,
624 NB_CLIENT_CONFD,
625 NB_CLIENT_SYSREPO,
626 NB_CLIENT_GRPC,
627 NB_CLIENT_PCEP,
628 };
629
630 /* Northbound context. */
631 struct nb_context {
632 /* Northbound client. */
633 enum nb_client client;
634
635 /* Northbound user (can be NULL). */
636 const void *user;
637
638 /* Client-specific data. */
639 #if 0
640 union {
641 struct {
642 } cli;
643 struct {
644 } confd;
645 struct {
646 } sysrepo;
647 struct {
648 } grpc;
649 struct {
650 } pcep;
651 } client_data;
652 #endif
653 };
654
655 /* Northbound configuration. */
656 struct nb_config {
657 struct lyd_node *dnode;
658 uint32_t version;
659 };
660
661 /* Northbound configuration callback. */
662 struct nb_config_cb {
663 RB_ENTRY(nb_config_cb) entry;
664 enum nb_operation operation;
665 uint32_t seq;
666 const struct nb_node *nb_node;
667 const struct lyd_node *dnode;
668 };
669 RB_HEAD(nb_config_cbs, nb_config_cb);
670 RB_PROTOTYPE(nb_config_cbs, nb_config_cb, entry, nb_config_cb_compare);
671
672 /* Northbound configuration change. */
673 struct nb_config_change {
674 struct nb_config_cb cb;
675 union nb_resource resource;
676 bool prepare_ok;
677 };
678
679 /* Northbound configuration transaction. */
680 struct nb_transaction {
681 struct nb_context *context;
682 char comment[80];
683 struct nb_config *config;
684 struct nb_config_cbs changes;
685 };
686
687 /* Callback function used by nb_oper_data_iterate(). */
688 typedef int (*nb_oper_data_cb)(const struct lysc_node *snode,
689 struct yang_translator *translator,
690 struct yang_data *data, void *arg);
691
692 /* Iterate over direct child nodes only. */
693 #define NB_OPER_DATA_ITER_NORECURSE 0x0001
694
695 /* Hooks. */
696 DECLARE_HOOK(nb_notification_send, (const char *xpath, struct list *arguments),
697 (xpath, arguments));
698 DECLARE_HOOK(nb_client_debug_config_write, (struct vty *vty), (vty));
699 DECLARE_HOOK(nb_client_debug_set_all, (uint32_t flags, bool set), (flags, set));
700
701 /* Northbound debugging records */
702 extern struct debug nb_dbg_cbs_config;
703 extern struct debug nb_dbg_cbs_state;
704 extern struct debug nb_dbg_cbs_rpc;
705 extern struct debug nb_dbg_notif;
706 extern struct debug nb_dbg_events;
707 extern struct debug nb_dbg_libyang;
708
709 /* Global running configuration. */
710 extern struct nb_config *running_config;
711
712 /* Wrappers for the northbound callbacks. */
713 extern struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node,
714 const char *xpath,
715 const void *list_entry);
716 extern const void *nb_callback_get_next(const struct nb_node *nb_node,
717 const void *parent_list_entry,
718 const void *list_entry);
719 extern int nb_callback_get_keys(const struct nb_node *nb_node,
720 const void *list_entry,
721 struct yang_list_keys *keys);
722 extern const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
723 const void *parent_list_entry,
724 const struct yang_list_keys *keys);
725 extern int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
726 const struct list *input, struct list *output,
727 char *errmsg, size_t errmsg_len);
728
729 /*
730 * Create a northbound node for all YANG schema nodes.
731 */
732 void nb_nodes_create(void);
733
734 /*
735 * Delete all northbound nodes from all YANG schema nodes.
736 */
737 void nb_nodes_delete(void);
738
739 /*
740 * Find the northbound node corresponding to a YANG data path.
741 *
742 * xpath
743 * XPath to search for (with or without predicates).
744 *
745 * Returns:
746 * Pointer to northbound node if found, NULL otherwise.
747 */
748 extern struct nb_node *nb_node_find(const char *xpath);
749
750 extern void nb_node_set_dependency_cbs(const char *dependency_xpath,
751 const char *dependant_xpath,
752 struct nb_dependency_callbacks *cbs);
753
754 bool nb_node_has_dependency(struct nb_node *node);
755
756 /*
757 * Create a new northbound configuration.
758 *
759 * dnode
760 * Pointer to a libyang data node containing the configuration data. If NULL
761 * is given, an empty configuration will be created.
762 *
763 * Returns:
764 * Pointer to newly created northbound configuration.
765 */
766 extern struct nb_config *nb_config_new(struct lyd_node *dnode);
767
768 /*
769 * Delete a northbound configuration.
770 *
771 * config
772 * Pointer to the config that is going to be deleted.
773 */
774 extern void nb_config_free(struct nb_config *config);
775
776 /*
777 * Duplicate a northbound configuration.
778 *
779 * config
780 * Northbound configuration to duplicate.
781 *
782 * Returns:
783 * Pointer to duplicated configuration.
784 */
785 extern struct nb_config *nb_config_dup(const struct nb_config *config);
786
787 /*
788 * Merge one configuration into another.
789 *
790 * config_dst
791 * Configuration to merge to.
792 *
793 * config_src
794 * Configuration to merge config_dst with.
795 *
796 * preserve_source
797 * Specify whether config_src should be deleted or not after the merge
798 * operation.
799 *
800 * Returns:
801 * NB_OK on success, NB_ERR otherwise.
802 */
803 extern int nb_config_merge(struct nb_config *config_dst,
804 struct nb_config *config_src, bool preserve_source);
805
806 /*
807 * Replace one configuration by another.
808 *
809 * config_dst
810 * Configuration to be replaced.
811 *
812 * config_src
813 * Configuration to replace config_dst.
814 *
815 * preserve_source
816 * Specify whether config_src should be deleted or not after the replace
817 * operation.
818 */
819 extern void nb_config_replace(struct nb_config *config_dst,
820 struct nb_config *config_src,
821 bool preserve_source);
822
823 /*
824 * Edit a candidate configuration.
825 *
826 * candidate
827 * Candidate configuration to edit.
828 *
829 * nb_node
830 * Northbound node associated to the configuration being edited.
831 *
832 * operation
833 * Operation to apply.
834 *
835 * xpath
836 * XPath of the configuration node being edited.
837 *
838 * previous
839 * Previous value of the configuration node. Should be used only when the
840 * operation is NB_OP_MOVE, otherwise this parameter is ignored.
841 *
842 * data
843 * New value of the configuration node.
844 *
845 * Returns:
846 * - NB_OK on success.
847 * - NB_ERR_NOT_FOUND when the element to be deleted was not found.
848 * - NB_ERR for other errors.
849 */
850 extern int nb_candidate_edit(struct nb_config *candidate,
851 const struct nb_node *nb_node,
852 enum nb_operation operation, const char *xpath,
853 const struct yang_data *previous,
854 const struct yang_data *data);
855
856 /*
857 * Check if a candidate configuration is outdated and needs to be updated.
858 *
859 * candidate
860 * Candidate configuration to check.
861 *
862 * Returns:
863 * true if the candidate is outdated, false otherwise.
864 */
865 extern bool nb_candidate_needs_update(const struct nb_config *candidate);
866
867 /*
868 * Update a candidate configuration by rebasing the changes on top of the latest
869 * running configuration. Resolve conflicts automatically by giving preference
870 * to the changes done in the candidate configuration.
871 *
872 * candidate
873 * Candidate configuration to update.
874 *
875 * Returns:
876 * NB_OK on success, NB_ERR otherwise.
877 */
878 extern int nb_candidate_update(struct nb_config *candidate);
879
880 /*
881 * Validate a candidate configuration. Perform both YANG syntactic/semantic
882 * validation and code-level validation using the northbound callbacks.
883 *
884 * WARNING: the candidate can be modified as part of the validation process
885 * (e.g. add default nodes).
886 *
887 * context
888 * Context of the northbound transaction.
889 *
890 * candidate
891 * Candidate configuration to validate.
892 *
893 * errmsg
894 * Buffer to store human-readable error message in case of error.
895 *
896 * errmsg_len
897 * Size of errmsg.
898 *
899 * Returns:
900 * NB_OK on success, NB_ERR_VALIDATION otherwise.
901 */
902 extern int nb_candidate_validate(struct nb_context *context,
903 struct nb_config *candidate, char *errmsg,
904 size_t errmsg_len);
905
906 /*
907 * Create a new configuration transaction but do not commit it yet. Only
908 * validate the candidate and prepare all resources required to apply the
909 * configuration changes.
910 *
911 * context
912 * Context of the northbound transaction.
913 *
914 * candidate
915 * Candidate configuration to commit.
916 *
917 * comment
918 * Optional comment describing the commit.
919 *
920 * transaction
921 * Output parameter providing the created transaction when one is created
922 * successfully. In this case, it must be either aborted using
923 * nb_candidate_commit_abort() or committed using
924 * nb_candidate_commit_apply().
925 *
926 * errmsg
927 * Buffer to store human-readable error message in case of error.
928 *
929 * errmsg_len
930 * Size of errmsg.
931 *
932 * Returns:
933 * - NB_OK on success.
934 * - NB_ERR_NO_CHANGES when the candidate is identical to the running
935 * configuration.
936 * - NB_ERR_LOCKED when there's already another transaction in progress.
937 * - NB_ERR_VALIDATION when the candidate fails the validation checks.
938 * - NB_ERR_RESOURCE when the system fails to allocate resources to apply
939 * the candidate configuration.
940 * - NB_ERR for other errors.
941 */
942 extern int nb_candidate_commit_prepare(struct nb_context *context,
943 struct nb_config *candidate,
944 const char *comment,
945 struct nb_transaction **transaction,
946 char *errmsg, size_t errmsg_len);
947
948 /*
949 * Abort a previously created configuration transaction, releasing all resources
950 * allocated during the preparation phase.
951 *
952 * transaction
953 * Candidate configuration to abort. It's consumed by this function.
954 *
955 * errmsg
956 * Buffer to store human-readable error message in case of error.
957 *
958 * errmsg_len
959 * Size of errmsg.
960 */
961 extern void nb_candidate_commit_abort(struct nb_transaction *transaction,
962 char *errmsg, size_t errmsg_len);
963
964 /*
965 * Commit a previously created configuration transaction.
966 *
967 * transaction
968 * Configuration transaction to commit. It's consumed by this function.
969 *
970 * save_transaction
971 * Specify whether the transaction should be recorded in the transactions log
972 * or not.
973 *
974 * transaction_id
975 * Optional output parameter providing the ID of the committed transaction.
976 *
977 * errmsg
978 * Buffer to store human-readable error message in case of error.
979 *
980 * errmsg_len
981 * Size of errmsg.
982 */
983 extern void nb_candidate_commit_apply(struct nb_transaction *transaction,
984 bool save_transaction,
985 uint32_t *transaction_id, char *errmsg,
986 size_t errmsg_len);
987
988 /*
989 * Create a new transaction to commit a candidate configuration. This is a
990 * convenience function that performs the two-phase commit protocol
991 * transparently to the user. The cost is reduced flexibility, since
992 * network-wide and multi-daemon transactions require the network manager to
993 * take into account the results of the preparation phase of multiple managed
994 * entities.
995 *
996 * context
997 * Context of the northbound transaction.
998 *
999 * candidate
1000 * Candidate configuration to commit. It's preserved regardless if the commit
1001 * operation fails or not.
1002 *
1003 * save_transaction
1004 * Specify whether the transaction should be recorded in the transactions log
1005 * or not.
1006 *
1007 * comment
1008 * Optional comment describing the commit.
1009 *
1010 * transaction_id
1011 * Optional output parameter providing the ID of the committed transaction.
1012 *
1013 * errmsg
1014 * Buffer to store human-readable error message in case of error.
1015 *
1016 * errmsg_len
1017 * Size of errmsg.
1018 *
1019 * Returns:
1020 * - NB_OK on success.
1021 * - NB_ERR_NO_CHANGES when the candidate is identical to the running
1022 * configuration.
1023 * - NB_ERR_LOCKED when there's already another transaction in progress.
1024 * - NB_ERR_VALIDATION when the candidate fails the validation checks.
1025 * - NB_ERR_RESOURCE when the system fails to allocate resources to apply
1026 * the candidate configuration.
1027 * - NB_ERR for other errors.
1028 */
1029 extern int nb_candidate_commit(struct nb_context *context,
1030 struct nb_config *candidate,
1031 bool save_transaction, const char *comment,
1032 uint32_t *transaction_id, char *errmsg,
1033 size_t errmsg_len);
1034
1035 /*
1036 * Lock the running configuration.
1037 *
1038 * client
1039 * Northbound client.
1040 *
1041 * user
1042 * Northbound user (can be NULL).
1043 *
1044 * Returns:
1045 * 0 on success, -1 when the running configuration is already locked.
1046 */
1047 extern int nb_running_lock(enum nb_client client, const void *user);
1048
1049 /*
1050 * Unlock the running configuration.
1051 *
1052 * client
1053 * Northbound client.
1054 *
1055 * user
1056 * Northbound user (can be NULL).
1057 *
1058 * Returns:
1059 * 0 on success, -1 when the running configuration is already unlocked or
1060 * locked by another client/user.
1061 */
1062 extern int nb_running_unlock(enum nb_client client, const void *user);
1063
1064 /*
1065 * Check if the running configuration is locked or not for the given
1066 * client/user.
1067 *
1068 * client
1069 * Northbound client.
1070 *
1071 * user
1072 * Northbound user (can be NULL).
1073 *
1074 * Returns:
1075 * 0 if the running configuration is unlocked or if the client/user owns the
1076 * lock, -1 otherwise.
1077 */
1078 extern int nb_running_lock_check(enum nb_client client, const void *user);
1079
1080 /*
1081 * Iterate over operational data.
1082 *
1083 * xpath
1084 * Data path of the YANG data we want to iterate over.
1085 *
1086 * translator
1087 * YANG module translator (might be NULL).
1088 *
1089 * flags
1090 * NB_OPER_DATA_ITER_ flags to control how the iteration is performed.
1091 *
1092 * cb
1093 * Function to call with each data node.
1094 *
1095 * arg
1096 * Arbitrary argument passed as the fourth parameter in each call to 'cb'.
1097 *
1098 * Returns:
1099 * NB_OK on success, NB_ERR otherwise.
1100 */
1101 extern int nb_oper_data_iterate(const char *xpath,
1102 struct yang_translator *translator,
1103 uint32_t flags, nb_oper_data_cb cb, void *arg);
1104
1105 /*
1106 * Validate if the northbound operation is valid for the given node.
1107 *
1108 * operation
1109 * Operation we want to check.
1110 *
1111 * snode
1112 * libyang schema node we want to check.
1113 *
1114 * Returns:
1115 * true if the operation is valid, false otherwise.
1116 */
1117 extern bool nb_operation_is_valid(enum nb_operation operation,
1118 const struct lysc_node *snode);
1119
1120 /*
1121 * Send a YANG notification. This is a no-op unless the 'nb_notification_send'
1122 * hook was registered by a northbound plugin.
1123 *
1124 * xpath
1125 * XPath of the YANG notification.
1126 *
1127 * arguments
1128 * Linked list containing the arguments that should be sent. This list is
1129 * deleted after being used.
1130 *
1131 * Returns:
1132 * NB_OK on success, NB_ERR otherwise.
1133 */
1134 extern int nb_notification_send(const char *xpath, struct list *arguments);
1135
1136 /*
1137 * Associate a user pointer to a configuration node.
1138 *
1139 * This should be called by northbound 'create' callbacks in the NB_EV_APPLY
1140 * phase only.
1141 *
1142 * dnode
1143 * libyang data node - only its XPath is used.
1144 *
1145 * entry
1146 * Arbitrary user-specified pointer.
1147 */
1148 extern void nb_running_set_entry(const struct lyd_node *dnode, void *entry);
1149
1150 /*
1151 * Move an entire tree of user pointer nodes.
1152 *
1153 * Suppose we have xpath A/B/C/D, with user pointers associated to C and D. We
1154 * need to move B to be under Z, so the new xpath is Z/B/C/D. Because user
1155 * pointers are indexed with their absolute path, We need to move all user
1156 * pointers at and below B to their new absolute paths; this function does
1157 * that.
1158 *
1159 * xpath_from
1160 * base xpath of tree to move (A/B)
1161 *
1162 * xpath_to
1163 * base xpath of new location of tree (Z/B)
1164 */
1165 extern void nb_running_move_tree(const char *xpath_from, const char *xpath_to);
1166
1167 /*
1168 * Unset the user pointer associated to a configuration node.
1169 *
1170 * This should be called by northbound 'destroy' callbacks in the NB_EV_APPLY
1171 * phase only.
1172 *
1173 * dnode
1174 * libyang data node - only its XPath is used.
1175 *
1176 * Returns:
1177 * The user pointer that was unset.
1178 */
1179 extern void *nb_running_unset_entry(const struct lyd_node *dnode);
1180
1181 /*
1182 * Find the user pointer (if any) associated to a configuration node.
1183 *
1184 * The XPath associated to the configuration node can be provided directly or
1185 * indirectly through a libyang data node.
1186 *
1187 * If an user point is not found, this function follows the parent nodes in the
1188 * running configuration until an user pointer is found or until the root node
1189 * is reached.
1190 *
1191 * dnode
1192 * libyang data node - only its XPath is used (can be NULL if 'xpath' is
1193 * provided).
1194 *
1195 * xpath
1196 * XPath of the configuration node (can be NULL if 'dnode' is provided).
1197 *
1198 * abort_if_not_found
1199 * When set to true, abort the program if no user pointer is found.
1200 *
1201 * As a rule of thumb, this parameter should be set to true in the following
1202 * scenarios:
1203 * - Calling this function from any northbound configuration callback during
1204 * the NB_EV_APPLY phase.
1205 * - Calling this function from a 'delete' northbound configuration callback
1206 * during any phase.
1207 *
1208 * In both the above cases, the given configuration node should contain an
1209 * user pointer except when there's a bug in the code, in which case it's
1210 * better to abort the program right away and eliminate the need for
1211 * unnecessary NULL checks.
1212 *
1213 * In all other cases, this parameter should be set to false and the caller
1214 * should check if the function returned NULL or not.
1215 *
1216 * Returns:
1217 * User pointer if found, NULL otherwise.
1218 */
1219 extern void *nb_running_get_entry(const struct lyd_node *dnode,
1220 const char *xpath, bool abort_if_not_found);
1221
1222 /*
1223 * Same as 'nb_running_get_entry', but doesn't search within parent nodes
1224 * recursively if an user point is not found.
1225 */
1226 extern void *nb_running_get_entry_non_rec(const struct lyd_node *dnode,
1227 const char *xpath,
1228 bool abort_if_not_found);
1229
1230 /*
1231 * Return a human-readable string representing a northbound event.
1232 *
1233 * event
1234 * Northbound event.
1235 *
1236 * Returns:
1237 * String representation of the given northbound event.
1238 */
1239 extern const char *nb_event_name(enum nb_event event);
1240
1241 /*
1242 * Return a human-readable string representing a northbound operation.
1243 *
1244 * operation
1245 * Northbound operation.
1246 *
1247 * Returns:
1248 * String representation of the given northbound operation.
1249 */
1250 extern const char *nb_operation_name(enum nb_operation operation);
1251
1252 /*
1253 * Return a human-readable string representing a northbound error.
1254 *
1255 * error
1256 * Northbound error.
1257 *
1258 * Returns:
1259 * String representation of the given northbound error.
1260 */
1261 extern const char *nb_err_name(enum nb_error error);
1262
1263 /*
1264 * Return a human-readable string representing a northbound client.
1265 *
1266 * client
1267 * Northbound client.
1268 *
1269 * Returns:
1270 * String representation of the given northbound client.
1271 */
1272 extern const char *nb_client_name(enum nb_client client);
1273
1274 /*
1275 * Validate all northbound callbacks.
1276 *
1277 * Some errors, like missing callbacks or invalid priorities, are fatal and
1278 * can't be recovered from. Other errors, like unneeded callbacks, are logged
1279 * but otherwise ignored.
1280 *
1281 * Whenever a YANG module is loaded after startup, *all* northbound callbacks
1282 * need to be validated and not only the callbacks from the newly loaded module.
1283 * This is because augmentations can change the properties of the augmented
1284 * module, making mandatory the implementation of additional callbacks.
1285 */
1286 void nb_validate_callbacks(void);
1287
1288 /*
1289 * Initialize the northbound layer. Should be called only once during the
1290 * daemon initialization process.
1291 *
1292 * modules
1293 * Array of YANG modules to parse and initialize.
1294 *
1295 * nmodules
1296 * Size of the modules array.
1297 *
1298 * db_enabled
1299 * Set this to record the transactions in the transaction log.
1300 */
1301 extern void nb_init(struct thread_master *tm,
1302 const struct frr_yang_module_info *const modules[],
1303 size_t nmodules, bool db_enabled);
1304
1305 /*
1306 * Finish the northbound layer gracefully. Should be called only when the daemon
1307 * is exiting.
1308 */
1309 extern void nb_terminate(void);
1310
1311 #ifdef __cplusplus
1312 }
1313 #endif
1314
1315 #endif /* _FRR_NORTHBOUND_H_ */