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