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