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