]> git.proxmox.com Git - mirror_frr.git/blob - lib/northbound.h
Merge pull request #5009 from donaldsharp/interface_deletion
[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 struct nb_callbacks {
90 /*
91 * Configuration callback.
92 *
93 * A presence container, list entry, leaf-list entry or leaf of type
94 * empty has been created.
95 *
96 * For presence-containers and list entries, the callback is supposed to
97 * initialize the default values of its children (if any) from the YANG
98 * models.
99 *
100 * event
101 * The transaction phase. Refer to the documentation comments of
102 * nb_event for more details.
103 *
104 * dnode
105 * libyang data node that is being created.
106 *
107 * resource
108 * Pointer to store resource(s) allocated during the NB_EV_PREPARE
109 * phase. The same pointer can be used during the NB_EV_ABORT and
110 * NB_EV_APPLY phases to either release or make use of the allocated
111 * resource(s). It's set to NULL when the event is NB_EV_VALIDATE.
112 *
113 * Returns:
114 * - NB_OK on success.
115 * - NB_ERR_VALIDATION when a validation error occurred.
116 * - NB_ERR_RESOURCE when the callback failed to allocate a resource.
117 * - NB_ERR_INCONSISTENCY when an inconsistency was detected.
118 * - NB_ERR for other errors.
119 */
120 int (*create)(enum nb_event event, const struct lyd_node *dnode,
121 union nb_resource *resource);
122
123 /*
124 * Configuration callback.
125 *
126 * The value of a leaf has been modified.
127 *
128 * List keys don't need to implement this callback. When a list key is
129 * modified, the northbound treats this as if the list was deleted and a
130 * new one created with the updated key value.
131 *
132 * event
133 * The transaction phase. Refer to the documentation comments of
134 * nb_event for more details.
135 *
136 * dnode
137 * libyang data node that is being modified
138 *
139 * resource
140 * Pointer to store resource(s) allocated during the NB_EV_PREPARE
141 * phase. The same pointer can be used during the NB_EV_ABORT and
142 * NB_EV_APPLY phases to either release or make use of the allocated
143 * resource(s). It's set to NULL when the event is NB_EV_VALIDATE.
144 *
145 * Returns:
146 * - NB_OK on success.
147 * - NB_ERR_VALIDATION when a validation error occurred.
148 * - NB_ERR_RESOURCE when the callback failed to allocate a resource.
149 * - NB_ERR_INCONSISTENCY when an inconsistency was detected.
150 * - NB_ERR for other errors.
151 */
152 int (*modify)(enum nb_event event, const struct lyd_node *dnode,
153 union nb_resource *resource);
154
155 /*
156 * Configuration callback.
157 *
158 * A presence container, list entry, leaf-list entry or optional leaf
159 * has been deleted.
160 *
161 * The callback is supposed to delete the entire configuration object,
162 * including its children when they exist.
163 *
164 * event
165 * The transaction phase. Refer to the documentation comments of
166 * nb_event for more details.
167 *
168 * dnode
169 * libyang data node that is being deleted.
170 *
171 * Returns:
172 * - NB_OK on success.
173 * - NB_ERR_VALIDATION when a validation error occurred.
174 * - NB_ERR_INCONSISTENCY when an inconsistency was detected.
175 * - NB_ERR for other errors.
176 */
177 int (*destroy)(enum nb_event event, const struct lyd_node *dnode);
178
179 /*
180 * Configuration callback.
181 *
182 * A list entry or leaf-list entry has been moved. Only applicable when
183 * the "ordered-by user" statement is present.
184 *
185 * event
186 * The transaction phase. Refer to the documentation comments of
187 * nb_event for more details.
188 *
189 * dnode
190 * libyang data node that is being moved.
191 *
192 * Returns:
193 * - NB_OK on success.
194 * - NB_ERR_VALIDATION when a validation error occurred.
195 * - NB_ERR_INCONSISTENCY when an inconsistency was detected.
196 * - NB_ERR for other errors.
197 */
198 int (*move)(enum nb_event event, const struct lyd_node *dnode);
199
200 /*
201 * Optional configuration callback.
202 *
203 * This callback can be used to validate subsections of the
204 * configuration being committed before validating the configuration
205 * changes themselves. It's useful to perform more complex validations
206 * that depend on the relationship between multiple nodes.
207 *
208 * dnode
209 * libyang data node associated with the 'pre_validate' callback.
210 */
211 int (*pre_validate)(const struct lyd_node *dnode);
212
213 /*
214 * Optional configuration callback.
215 *
216 * The 'apply_finish' callbacks are called after all other callbacks
217 * during the apply phase (NB_EV_APPLY). These callbacks are called only
218 * under one of the following two cases:
219 * - The data node has been created or modified (but not deleted);
220 * - Any change was made within the descendants of the data node (e.g. a
221 * child leaf was modified, created or deleted).
222 *
223 * In the second case above, the 'apply_finish' callback is called only
224 * once even if multiple changes occurred within the descendants of the
225 * data node.
226 *
227 * dnode
228 * libyang data node associated with the 'apply_finish' callback.
229 */
230 void (*apply_finish)(const struct lyd_node *dnode);
231
232 /*
233 * Operational data callback.
234 *
235 * The callback function should return the value of a specific leaf,
236 * leaf-list entry or inform if a typeless value (presence containers or
237 * leafs of type empty) exists or not.
238 *
239 * xpath
240 * YANG data path of the data we want to get.
241 *
242 * list_entry
243 * Pointer to list entry (might be NULL).
244 *
245 * Returns:
246 * Pointer to newly created yang_data structure, or NULL to indicate
247 * the absence of data.
248 */
249 struct yang_data *(*get_elem)(const char *xpath,
250 const void *list_entry);
251
252 /*
253 * Operational data callback for YANG lists and leaf-lists.
254 *
255 * The callback function should return the next entry in the list or
256 * leaf-list. The 'list_entry' parameter will be NULL on the first
257 * invocation.
258 *
259 * parent_list_entry
260 * Pointer to parent list entry.
261 *
262 * list_entry
263 * Pointer to (leaf-)list entry.
264 *
265 * Returns:
266 * Pointer to the next entry in the (leaf-)list, or NULL to signal
267 * that the end of the (leaf-)list was reached.
268 */
269 const void *(*get_next)(const void *parent_list_entry,
270 const void *list_entry);
271
272 /*
273 * Operational data callback for YANG lists.
274 *
275 * The callback function should fill the 'keys' parameter based on the
276 * given list_entry. Keyless lists don't need to implement this
277 * callback.
278 *
279 * list_entry
280 * Pointer to list entry.
281 *
282 * keys
283 * Structure to be filled based on the attributes of the provided
284 * list entry.
285 *
286 * Returns:
287 * NB_OK on success, NB_ERR otherwise.
288 */
289 int (*get_keys)(const void *list_entry, struct yang_list_keys *keys);
290
291 /*
292 * Operational data callback for YANG lists.
293 *
294 * The callback function should return a list entry based on the list
295 * keys given as a parameter. Keyless lists don't need to implement this
296 * callback.
297 *
298 * parent_list_entry
299 * Pointer to parent list entry.
300 *
301 * keys
302 * Structure containing the keys of the list entry.
303 *
304 * Returns:
305 * Pointer to the list entry if found, or NULL if not found.
306 */
307 const void *(*lookup_entry)(const void *parent_list_entry,
308 const struct yang_list_keys *keys);
309
310 /*
311 * RPC and action callback.
312 *
313 * Both 'input' and 'output' are lists of 'yang_data' structures. The
314 * callback should fetch all the input parameters from the 'input' list,
315 * and add output parameters to the 'output' list if necessary.
316 *
317 * xpath
318 * XPath of the YANG RPC or action.
319 *
320 * input
321 * Read-only list of input parameters.
322 *
323 * output
324 * List of output parameters to be populated by the callback.
325 *
326 * Returns:
327 * NB_OK on success, NB_ERR otherwise.
328 */
329 int (*rpc)(const char *xpath, const struct list *input,
330 struct list *output);
331
332 /*
333 * Optional callback to show the CLI command associated to the given
334 * YANG data node.
335 *
336 * vty
337 * The vty terminal to dump the configuration to.
338 *
339 * dnode
340 * libyang data node that should be shown in the form of a CLI
341 * command.
342 *
343 * show_defaults
344 * Specify whether to display default configuration values or not.
345 * This parameter can be ignored most of the time since the
346 * northbound doesn't call this callback for default leaves or
347 * non-presence containers that contain only default child nodes.
348 * The exception are commands associated to multiple configuration
349 * nodes, in which case it might be desirable to hide one or more
350 * parts of the command when this parameter is set to false.
351 */
352 void (*cli_show)(struct vty *vty, struct lyd_node *dnode,
353 bool show_defaults);
354
355 /*
356 * Optional callback to show the CLI node end for lists or containers.
357 *
358 * vty
359 * The vty terminal to dump the configuration to.
360 *
361 * dnode
362 * libyang data node that should be shown in the form of a CLI
363 * command.
364 */
365 void (*cli_show_end)(struct vty *vty, struct lyd_node *dnode);
366 };
367
368 /*
369 * Northbound-specific data that is allocated for each schema node of the native
370 * YANG modules.
371 */
372 struct nb_node {
373 /* Back pointer to the libyang schema node. */
374 const struct lys_node *snode;
375
376 /* Data path of this YANG node. */
377 char xpath[XPATH_MAXLEN];
378
379 /* Priority - lower priorities are processed first. */
380 uint32_t priority;
381
382 /* Callbacks implemented for this node. */
383 struct nb_callbacks cbs;
384
385 /*
386 * Pointer to the parent node (disconsidering non-presence containers).
387 */
388 struct nb_node *parent;
389
390 /* Pointer to the nearest parent list, if any. */
391 struct nb_node *parent_list;
392
393 /* Flags. */
394 uint8_t flags;
395
396 #ifdef HAVE_CONFD
397 /* ConfD hash value corresponding to this YANG path. */
398 int confd_hash;
399 #endif
400 };
401 /* The YANG container or list contains only config data. */
402 #define F_NB_NODE_CONFIG_ONLY 0x01
403 /* The YANG list doesn't contain key leafs. */
404 #define F_NB_NODE_KEYLESS_LIST 0x02
405
406 struct frr_yang_module_info {
407 /* YANG module name. */
408 const char *name;
409
410 /* Northbound callbacks. */
411 const struct {
412 /* Data path of this YANG node. */
413 const char *xpath;
414
415 /* Callbacks implemented for this node. */
416 struct nb_callbacks cbs;
417
418 /* Priority - lower priorities are processed first. */
419 uint32_t priority;
420 } nodes[];
421 };
422
423 /* Northbound error codes. */
424 enum nb_error {
425 NB_OK = 0,
426 NB_ERR,
427 NB_ERR_NO_CHANGES,
428 NB_ERR_NOT_FOUND,
429 NB_ERR_LOCKED,
430 NB_ERR_VALIDATION,
431 NB_ERR_RESOURCE,
432 NB_ERR_INCONSISTENCY,
433 };
434
435 /* Default priority. */
436 #define NB_DFLT_PRIORITY (UINT32_MAX / 2)
437
438 /* Default maximum of configuration rollbacks to store. */
439 #define NB_DLFT_MAX_CONFIG_ROLLBACKS 20
440
441 /* Northbound clients. */
442 enum nb_client {
443 NB_CLIENT_NONE = 0,
444 NB_CLIENT_CLI,
445 NB_CLIENT_CONFD,
446 NB_CLIENT_SYSREPO,
447 NB_CLIENT_GRPC,
448 };
449
450 /* Northbound configuration. */
451 struct nb_config {
452 struct lyd_node *dnode;
453 uint32_t version;
454 };
455
456 /* Northbound configuration callback. */
457 struct nb_config_cb {
458 RB_ENTRY(nb_config_cb) entry;
459 enum nb_operation operation;
460 uint32_t seq;
461 char xpath[XPATH_MAXLEN];
462 const struct nb_node *nb_node;
463 const struct lyd_node *dnode;
464 };
465 RB_HEAD(nb_config_cbs, nb_config_cb);
466 RB_PROTOTYPE(nb_config_cbs, nb_config_cb, entry, nb_config_cb_compare);
467
468 /* Northbound configuration change. */
469 struct nb_config_change {
470 struct nb_config_cb cb;
471 union nb_resource resource;
472 bool prepare_ok;
473 };
474
475 /* Northbound configuration transaction. */
476 struct nb_transaction {
477 enum nb_client client;
478 char comment[80];
479 struct nb_config *config;
480 struct nb_config_cbs changes;
481 };
482
483 /* Callback function used by nb_oper_data_iterate(). */
484 typedef int (*nb_oper_data_cb)(const struct lys_node *snode,
485 struct yang_translator *translator,
486 struct yang_data *data, void *arg);
487
488 /* Iterate over direct child nodes only. */
489 #define NB_OPER_DATA_ITER_NORECURSE 0x0001
490
491 /* Hooks. */
492 DECLARE_HOOK(nb_notification_send, (const char *xpath, struct list *arguments),
493 (xpath, arguments))
494 DECLARE_HOOK(nb_client_debug_config_write, (struct vty *vty), (vty))
495 DECLARE_HOOK(nb_client_debug_set_all, (uint32_t flags, bool set), (flags, set))
496
497 /* Northbound debugging records */
498 extern struct debug nb_dbg_cbs_config;
499 extern struct debug nb_dbg_cbs_state;
500 extern struct debug nb_dbg_cbs_rpc;
501 extern struct debug nb_dbg_notif;
502 extern struct debug nb_dbg_events;
503
504 /* Global running configuration. */
505 extern struct nb_config *running_config;
506
507 /* Wrappers for the northbound callbacks. */
508 extern struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node,
509 const char *xpath,
510 const void *list_entry);
511 extern const void *nb_callback_get_next(const struct nb_node *nb_node,
512 const void *parent_list_entry,
513 const void *list_entry);
514 extern int nb_callback_get_keys(const struct nb_node *nb_node,
515 const void *list_entry,
516 struct yang_list_keys *keys);
517 extern const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
518 const void *parent_list_entry,
519 const struct yang_list_keys *keys);
520 extern int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
521 const struct list *input, struct list *output);
522
523 /*
524 * Create a northbound node for all YANG schema nodes.
525 */
526 void nb_nodes_create(void);
527
528 /*
529 * Delete all northbound nodes from all YANG schema nodes.
530 */
531 void nb_nodes_delete(void);
532
533 /*
534 * Find the northbound node corresponding to a YANG data path.
535 *
536 * xpath
537 * XPath to search for (with or without predicates).
538 *
539 * Returns:
540 * Pointer to northbound node if found, NULL otherwise.
541 */
542 extern struct nb_node *nb_node_find(const char *xpath);
543
544 /*
545 * Create a new northbound configuration.
546 *
547 * dnode
548 * Pointer to a libyang data node containing the configuration data. If NULL
549 * is given, an empty configuration will be created.
550 *
551 * Returns:
552 * Pointer to newly created northbound configuration.
553 */
554 extern struct nb_config *nb_config_new(struct lyd_node *dnode);
555
556 /*
557 * Delete a northbound configuration.
558 *
559 * config
560 * Pointer to the config that is going to be deleted.
561 */
562 extern void nb_config_free(struct nb_config *config);
563
564 /*
565 * Duplicate a northbound configuration.
566 *
567 * config
568 * Northbound configuration to duplicate.
569 *
570 * Returns:
571 * Pointer to duplicated configuration.
572 */
573 extern struct nb_config *nb_config_dup(const struct nb_config *config);
574
575 /*
576 * Merge one configuration into another.
577 *
578 * config_dst
579 * Configuration to merge to.
580 *
581 * config_src
582 * Configuration to merge config_dst with.
583 *
584 * preserve_source
585 * Specify whether config_src should be deleted or not after the merge
586 * operation.
587 *
588 * Returns:
589 * NB_OK on success, NB_ERR otherwise.
590 */
591 extern int nb_config_merge(struct nb_config *config_dst,
592 struct nb_config *config_src, bool preserve_source);
593
594 /*
595 * Replace one configuration by another.
596 *
597 * config_dst
598 * Configuration to be replaced.
599 *
600 * config_src
601 * Configuration to replace config_dst.
602 *
603 * preserve_source
604 * Specify whether config_src should be deleted or not after the replace
605 * operation.
606 */
607 extern void nb_config_replace(struct nb_config *config_dst,
608 struct nb_config *config_src,
609 bool preserve_source);
610
611 /*
612 * Edit a candidate configuration.
613 *
614 * candidate
615 * Candidate configuration to edit.
616 *
617 * nb_node
618 * Northbound node associated to the configuration being edited.
619 *
620 * operation
621 * Operation to apply.
622 *
623 * xpath
624 * XPath of the configuration node being edited.
625 *
626 * previous
627 * Previous value of the configuration node. Should be used only when the
628 * operation is NB_OP_MOVE, otherwise this parameter is ignored.
629 *
630 * data
631 * New value of the configuration node.
632 *
633 * Returns:
634 * - NB_OK on success.
635 * - NB_ERR_NOT_FOUND when the element to be deleted was not found.
636 * - NB_ERR for other errors.
637 */
638 extern int nb_candidate_edit(struct nb_config *candidate,
639 const struct nb_node *nb_node,
640 enum nb_operation operation, const char *xpath,
641 const struct yang_data *previous,
642 const struct yang_data *data);
643
644 /*
645 * Check if a candidate configuration is outdated and needs to be updated.
646 *
647 * candidate
648 * Candidate configuration to check.
649 *
650 * Returns:
651 * true if the candidate is outdated, false otherwise.
652 */
653 extern bool nb_candidate_needs_update(const struct nb_config *candidate);
654
655 /*
656 * Update a candidate configuration by rebasing the changes on top of the latest
657 * running configuration. Resolve conflicts automatically by giving preference
658 * to the changes done in the candidate configuration.
659 *
660 * candidate
661 * Candidate configuration to update.
662 *
663 * Returns:
664 * NB_OK on success, NB_ERR otherwise.
665 */
666 extern int nb_candidate_update(struct nb_config *candidate);
667
668 /*
669 * Validate a candidate configuration. Perform both YANG syntactic/semantic
670 * validation and code-level validation using the northbound callbacks.
671 *
672 * WARNING: the candidate can be modified as part of the validation process
673 * (e.g. add default nodes).
674 *
675 * candidate
676 * Candidate configuration to validate.
677 *
678 * Returns:
679 * NB_OK on success, NB_ERR_VALIDATION otherwise.
680 */
681 extern int nb_candidate_validate(struct nb_config *candidate);
682
683 /*
684 * Create a new configuration transaction but do not commit it yet. Only
685 * validate the candidate and prepare all resources required to apply the
686 * configuration changes.
687 *
688 * candidate
689 * Candidate configuration to commit.
690 *
691 * client
692 * Northbound client performing the commit.
693 *
694 * user
695 * Northbound user performing the commit (can be NULL).
696 *
697 * comment
698 * Optional comment describing the commit.
699 *
700 * transaction
701 * Output parameter providing the created transaction when one is created
702 * successfully. In this case, it must be either aborted using
703 * nb_candidate_commit_abort() or committed using
704 * nb_candidate_commit_apply().
705 *
706 * Returns:
707 * - NB_OK on success.
708 * - NB_ERR_NO_CHANGES when the candidate is identical to the running
709 * configuration.
710 * - NB_ERR_LOCKED when there's already another transaction in progress.
711 * - NB_ERR_VALIDATION when the candidate fails the validation checks.
712 * - NB_ERR_RESOURCE when the system fails to allocate resources to apply
713 * the candidate configuration.
714 * - NB_ERR for other errors.
715 */
716 extern int nb_candidate_commit_prepare(struct nb_config *candidate,
717 enum nb_client client, const void *user,
718 const char *comment,
719 struct nb_transaction **transaction);
720
721 /*
722 * Abort a previously created configuration transaction, releasing all resources
723 * allocated during the preparation phase.
724 *
725 * transaction
726 * Candidate configuration to abort. It's consumed by this function.
727 */
728 extern void nb_candidate_commit_abort(struct nb_transaction *transaction);
729
730 /*
731 * Commit a previously created configuration transaction.
732 *
733 * transaction
734 * Configuration transaction to commit. It's consumed by this function.
735 *
736 * save_transaction
737 * Specify whether the transaction should be recorded in the transactions log
738 * or not.
739 *
740 * transaction_id
741 * Optional output parameter providing the ID of the committed transaction.
742 */
743 extern void nb_candidate_commit_apply(struct nb_transaction *transaction,
744 bool save_transaction,
745 uint32_t *transaction_id);
746
747 /*
748 * Create a new transaction to commit a candidate configuration. This is a
749 * convenience function that performs the two-phase commit protocol
750 * transparently to the user. The cost is reduced flexibility, since
751 * network-wide and multi-daemon transactions require the network manager to
752 * take into account the results of the preparation phase of multiple managed
753 * entities.
754 *
755 * candidate
756 * Candidate configuration to commit. It's preserved regardless if the commit
757 * operation fails or not.
758 *
759 * client
760 * Northbound client performing the commit.
761 *
762 * user
763 * Northbound user performing the commit (can be NULL).
764 *
765 * save_transaction
766 * Specify whether the transaction should be recorded in the transactions log
767 * or not.
768 *
769 * comment
770 * Optional comment describing the commit.
771 *
772 * transaction_id
773 * Optional output parameter providing the ID of the committed transaction.
774 *
775 * Returns:
776 * - NB_OK on success.
777 * - NB_ERR_NO_CHANGES when the candidate is identical to the running
778 * configuration.
779 * - NB_ERR_LOCKED when there's already another transaction in progress.
780 * - NB_ERR_VALIDATION when the candidate fails the validation checks.
781 * - NB_ERR_RESOURCE when the system fails to allocate resources to apply
782 * the candidate configuration.
783 * - NB_ERR for other errors.
784 */
785 extern int nb_candidate_commit(struct nb_config *candidate,
786 enum nb_client client, const void *user,
787 bool save_transaction, const char *comment,
788 uint32_t *transaction_id);
789
790 /*
791 * Lock the running configuration.
792 *
793 * client
794 * Northbound client.
795 *
796 * user
797 * Northbound user (can be NULL).
798 *
799 * Returns:
800 * 0 on success, -1 when the running configuration is already locked.
801 */
802 extern int nb_running_lock(enum nb_client client, const void *user);
803
804 /*
805 * Unlock the running configuration.
806 *
807 * client
808 * Northbound client.
809 *
810 * user
811 * Northbound user (can be NULL).
812 *
813 * Returns:
814 * 0 on success, -1 when the running configuration is already unlocked or
815 * locked by another client/user.
816 */
817 extern int nb_running_unlock(enum nb_client client, const void *user);
818
819 /*
820 * Check if the running configuration is locked or not for the given
821 * client/user.
822 *
823 * client
824 * Northbound client.
825 *
826 * user
827 * Northbound user (can be NULL).
828 *
829 * Returns:
830 * 0 if the running configuration is unlocked or if the client/user owns the
831 * lock, -1 otherwise.
832 */
833 extern int nb_running_lock_check(enum nb_client client, const void *user);
834
835 /*
836 * Iterate over operational data.
837 *
838 * xpath
839 * Data path of the YANG data we want to iterate over.
840 *
841 * translator
842 * YANG module translator (might be NULL).
843 *
844 * flags
845 * NB_OPER_DATA_ITER_ flags to control how the iteration is performed.
846 *
847 * cb
848 * Function to call with each data node.
849 *
850 * arg
851 * Arbitrary argument passed as the fourth parameter in each call to 'cb'.
852 *
853 * Returns:
854 * NB_OK on success, NB_ERR otherwise.
855 */
856 extern int nb_oper_data_iterate(const char *xpath,
857 struct yang_translator *translator,
858 uint32_t flags, nb_oper_data_cb cb, void *arg);
859
860 /*
861 * Validate if the northbound operation is valid for the given node.
862 *
863 * operation
864 * Operation we want to check.
865 *
866 * snode
867 * libyang schema node we want to check.
868 *
869 * Returns:
870 * true if the operation is valid, false otherwise.
871 */
872 extern bool nb_operation_is_valid(enum nb_operation operation,
873 const struct lys_node *snode);
874
875 /*
876 * Send a YANG notification. This is a no-op unless the 'nb_notification_send'
877 * hook was registered by a northbound plugin.
878 *
879 * xpath
880 * XPath of the YANG notification.
881 *
882 * arguments
883 * Linked list containing the arguments that should be sent. This list is
884 * deleted after being used.
885 *
886 * Returns:
887 * NB_OK on success, NB_ERR otherwise.
888 */
889 extern int nb_notification_send(const char *xpath, struct list *arguments);
890
891 /*
892 * Associate a user pointer to a configuration node.
893 *
894 * This should be called by northbound 'create' callbacks in the NB_EV_APPLY
895 * phase only.
896 *
897 * dnode
898 * libyang data node - only its XPath is used.
899 *
900 * entry
901 * Arbitrary user-specified pointer.
902 */
903 extern void nb_running_set_entry(const struct lyd_node *dnode, void *entry);
904
905 /*
906 * Unset the user pointer associated to a configuration node.
907 *
908 * This should be called by northbound 'destroy' callbacks in the NB_EV_APPLY
909 * phase only.
910 *
911 * dnode
912 * libyang data node - only its XPath is used.
913 *
914 * Returns:
915 * The user pointer that was unset.
916 */
917 extern void *nb_running_unset_entry(const struct lyd_node *dnode);
918
919 /*
920 * Find the user pointer (if any) associated to a configuration node.
921 *
922 * The XPath associated to the configuration node can be provided directly or
923 * indirectly through a libyang data node.
924 *
925 * If an user point is not found, this function follows the parent nodes in the
926 * running configuration until an user pointer is found or until the root node
927 * is reached.
928 *
929 * dnode
930 * libyang data node - only its XPath is used (can be NULL if 'xpath' is
931 * provided).
932 *
933 * xpath
934 * XPath of the configuration node (can be NULL if 'dnode' is provided).
935 *
936 * abort_if_not_found
937 * When set to true, abort the program if no user pointer is found.
938 *
939 * As a rule of thumb, this parameter should be set to true in the following
940 * scenarios:
941 * - Calling this function from any northbound configuration callback during
942 * the NB_EV_APPLY phase.
943 * - Calling this function from a 'delete' northbound configuration callback
944 * during any phase.
945 *
946 * In both the above cases, the given configuration node should contain an
947 * user pointer except when there's a bug in the code, in which case it's
948 * better to abort the program right away and eliminate the need for
949 * unnecessary NULL checks.
950 *
951 * In all other cases, this parameter should be set to false and the caller
952 * should check if the function returned NULL or not.
953 *
954 * Returns:
955 * User pointer if found, NULL otherwise.
956 */
957 extern void *nb_running_get_entry(const struct lyd_node *dnode, const char *xpath,
958 bool abort_if_not_found);
959
960 /*
961 * Return a human-readable string representing a northbound event.
962 *
963 * event
964 * Northbound event.
965 *
966 * Returns:
967 * String representation of the given northbound event.
968 */
969 extern const char *nb_event_name(enum nb_event event);
970
971 /*
972 * Return a human-readable string representing a northbound operation.
973 *
974 * operation
975 * Northbound operation.
976 *
977 * Returns:
978 * String representation of the given northbound operation.
979 */
980 extern const char *nb_operation_name(enum nb_operation operation);
981
982 /*
983 * Return a human-readable string representing a northbound error.
984 *
985 * error
986 * Northbound error.
987 *
988 * Returns:
989 * String representation of the given northbound error.
990 */
991 extern const char *nb_err_name(enum nb_error error);
992
993 /*
994 * Return a human-readable string representing a northbound client.
995 *
996 * client
997 * Northbound client.
998 *
999 * Returns:
1000 * String representation of the given northbound client.
1001 */
1002 extern const char *nb_client_name(enum nb_client client);
1003
1004 /*
1005 * Initialize the northbound layer. Should be called only once during the
1006 * daemon initialization process.
1007 *
1008 * modules
1009 * Array of YANG modules to parse and initialize.
1010 *
1011 * nmodules
1012 * Size of the modules array.
1013 */
1014 extern void nb_init(struct thread_master *tm, const struct frr_yang_module_info *modules[],
1015 size_t nmodules);
1016
1017 /*
1018 * Finish the northbound layer gracefully. Should be called only when the daemon
1019 * is exiting.
1020 */
1021 extern void nb_terminate(void);
1022
1023 #ifdef __cplusplus
1024 }
1025 #endif
1026
1027 #endif /* _FRR_NORTHBOUND_H_ */