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