Difference between revisions of "Yuma Developer Manual"
Line 1: | Line 1: | ||
+ | <center>'''Yuma Developer Manual'''</center> |
||
− | There are additions to the set of API functions (e.g. val_get_leafref_targval, val_set_cplxval_obj, val_add_meta) in ver. 2.5. Will be published ASAP after the switch to MediaWiki formated manual is complete. |
||
+ | |||
− | ver. 2.2 PDF http://www.yumaworks.com/wp-content/themes/Yuma/images/pdf/yuma-dev-manual.pdf |
||
+ | <center>YANG-Based Unified Modular Automation Tools</center> |
||
+ | |||
+ | |||
+ | <center>Server Instrumentation Library Development</center> |
||
+ | |||
+ | |||
+ | <center>Version 2.2</center> |
||
+ | |||
+ | |||
+ | <center>Last Updated: 2012-07-24</center> |
||
+ | |||
+ | |||
+ | == <center>'''Table of Contents'''</center> == |
||
+ | 1 Preface4 |
||
+ | |||
+ | 1.1 Legal Statements4 |
||
+ | |||
+ | 1.2 Additional Resources4 |
||
+ | |||
+ | 1.2.1 WEB Sites4 |
||
+ | |||
+ | 1.2.2 Mailing Lists5 |
||
+ | |||
+ | 1.3 Conventions Used in this Document5 |
||
+ | |||
+ | 2 Software Overview6 |
||
+ | |||
+ | 2.1 Introduction6 |
||
+ | |||
+ | 2.1.1 Intended Audience6 |
||
+ | |||
+ | 2.1.2 What does Yuma Do?6 |
||
+ | |||
+ | 2.1.3 What is a Yuma Root?7 |
||
+ | |||
+ | 2.1.4 Searching Yuma Roots8 |
||
+ | |||
+ | 2.1.5 What is a SIL?9 |
||
+ | |||
+ | 2.1.6 Auto-generated SIL Files9 |
||
+ | |||
+ | 2.1.7 Basic Development Steps10 |
||
+ | |||
+ | 2.2 Yuma Source Files11 |
||
+ | |||
+ | 2.2.1 src/ncx Directory11 |
||
+ | |||
+ | 2.2.2 src/platform Directory13 |
||
+ | |||
+ | 2.2.3 src/agt Directory13 |
||
+ | |||
+ | 2.2.4 src/mgr Directory14 |
||
+ | |||
+ | 2.2.5 src/subsys Directory15 |
||
+ | |||
+ | 2.2.6 src/netconfd Directory15 |
||
+ | |||
+ | 2.2.7 src/yangcli Directory15 |
||
+ | |||
+ | 2.2.8 src/yangdiff Directory16 |
||
+ | |||
+ | 2.2.9 src/yangdump Directory16 |
||
+ | |||
+ | 2.3 Server Design17 |
||
+ | |||
+ | 2.3.1 YANG Native Operation18 |
||
+ | |||
+ | 2.3.2 YANG Object Tree19 |
||
+ | |||
+ | 2.3.3 YANG Data Tree20 |
||
+ | |||
+ | 2.3.4 Service Layering21 |
||
+ | |||
+ | 2.3.5 Session Control Block22 |
||
+ | |||
+ | 2.3.6 Server Message Flows22 |
||
+ | |||
+ | 2.3.7 Main ncxserver Loop24 |
||
+ | |||
+ | 2.3.8 SIL Callback Functions25 |
||
+ | |||
+ | 2.4 Server Operation26 |
||
+ | |||
+ | 2.4.1 Initialization26 |
||
+ | |||
+ | 2.4.2 Loading Modules and SIL Code27 |
||
+ | |||
+ | 2.4.3 Core Module Initialization28 |
||
+ | |||
+ | 2.4.4 Startup Configuration Processing28 |
||
+ | |||
+ | <nowiki>2.4.5 Process an Incoming <rpc> Request</nowiki>29 |
||
+ | |||
+ | 2.4.6 Edit the Database30 |
||
+ | |||
+ | 2.4.7 Save the Database31 |
||
+ | |||
+ | 2.5 Built-in Server Modules31 |
||
+ | |||
+ | 2.5.1 ietf-inet-types.yang32 |
||
+ | |||
+ | 2.5.2 ietf-netconf-monitoring.yang32 |
||
+ | |||
+ | 2.5.3 ietf-with-defaults.yang32 |
||
+ | |||
+ | 2.5.4 ietf-yang-types.yang32 |
||
+ | |||
+ | 2.5.5 nc-notifications.yang32 |
||
+ | |||
+ | 2.5.6 notifications.yang32 |
||
+ | |||
+ | 2.5.7 yuma-app-common.yang33 |
||
+ | |||
+ | 2.5.8 yuma-interfaces.yang33 |
||
+ | |||
+ | 2.5.9 yuma-mysession.yang33 |
||
+ | |||
+ | 2.5.10 yuma-nacm.yang33 |
||
+ | |||
+ | 2.5.11 yuma-ncx.yang33 |
||
+ | |||
+ | 2.5.12 yuma-netconf.yang33 |
||
+ | |||
+ | 2.5.13 yuma-proc.yang33 |
||
+ | |||
+ | 2.5.14 yuma-system.yang34 |
||
+ | |||
+ | 2.5.15 yuma-time-filter.yang 34 |
||
+ | |||
+ | 2.5.16 yuma-types.yang34 |
||
+ | |||
+ | 3 YANG Objects and Data Nodes34 |
||
+ | |||
+ | 3.1 Object Definition Tree34 |
||
+ | |||
+ | 3.1.1 Object Node Types34 |
||
+ | |||
+ | 3.1.2 Object Node Template (obj_template_t)35 |
||
+ | |||
+ | 3.1.3 obj_template_t Access Functions37 |
||
+ | |||
+ | 3.2 Data Tree39 |
||
+ | |||
+ | 3.2.1 Data Node Types40 |
||
+ | |||
+ | 3.2.2 Yuma Data Node Edit Variables (val_editvars_t)42 |
||
+ | |||
+ | 3.2.3 Yuma Data Nodes (val_value_t)43 |
||
+ | |||
+ | 3.2.4 val_value_t Access Macros46 |
||
+ | |||
+ | 3.2.5 val_value_t Access Functions47 |
||
+ | |||
+ | 3.2.6 SIL Utility Functions52 |
||
+ | |||
+ | 4 SIL External Interface53 |
||
+ | |||
+ | 4.1 Stage 1 Initialization53 |
||
+ | |||
+ | 4.2 Stage 2 Initialization56 |
||
+ | |||
+ | 4.3 Cleanup57 |
||
+ | |||
+ | 5 SIL Callback Interface58 |
||
+ | |||
+ | 5.1 RPC Operation Interface59 |
||
+ | |||
+ | 5.1.1 RPC Callback Initialization59 |
||
+ | |||
+ | 5.1.2 RPC Message Header59 |
||
+ | |||
+ | 5.1.3 SIL Support Functions For RPC Operations62 |
||
+ | |||
+ | 5.1.4 RPC Validate Callback Function63 |
||
+ | |||
+ | 5.1.5 RPC Invoke Callback Function66 |
||
+ | |||
+ | 5.1.6 RPC Post Reply Callback Function69 |
||
+ | |||
+ | 5.2 Database Operations70 |
||
+ | |||
+ | 5.2.1 Database Template (cfg_template_t)71 |
||
+ | |||
+ | 5.2.2 Database Access Functions72 |
||
+ | |||
+ | 5.2.3 Database Callback Initialization and Cleanup73 |
||
+ | |||
+ | 5.2.4 Example SIL Database Edit Callback Function75 |
||
+ | |||
+ | 5.2.5 Database Edit Validate Callback Phase77 |
||
+ | |||
+ | 5.2.6 Database Edit Apply Callback Phase78 |
||
+ | |||
+ | 5.2.7 Database Edit Commit Callback Phase78 |
||
+ | |||
+ | 5.2.8 Database Edit Rollback Callback Phase78 |
||
+ | |||
+ | 5.2.9 Database Virtual Node Get Callback Function79 |
||
+ | |||
+ | 5.3 Notifications81 |
||
+ | |||
+ | 5.3.1 Notification Send Function81 |
||
+ | |||
+ | 5.4 Periodic Timer Service82 |
||
+ | |||
+ | 5.4.1 Timer Callback Function82 |
||
+ | |||
+ | 5.4.2 Timer Access Functions83 |
||
+ | |||
+ | 5.4.3 Example Timer Callback Function84 |
||
+ | |||
+ | 6 Server Callback Examples84 |
||
+ | |||
+ | 6.1 YANG84 |
||
+ | |||
+ | 6.2 Edit Operations85 |
||
+ | |||
+ | 6.2.1 Create an XPO container85 |
||
+ | |||
+ | 6.2.2 Create a Profile87 |
||
+ | |||
+ | 6.2.3 Create a Stream Connection88 |
||
+ | |||
+ | 6.2.4 Delete an XPO Container91 |
||
+ | |||
+ | 6.2.5 Delete a Profile93 |
||
+ | |||
+ | 6.2.6 Delete a Stream Connection94 |
||
+ | |||
+ | 7 Development Environment94 |
||
+ | |||
+ | 7.1 Programs and Libraries Needed94 |
||
+ | |||
+ | 7.2 SIL Makefile95 |
||
+ | |||
+ | 7.2.1 Target Platforms96 |
||
+ | |||
+ | 7.2.2 Build Targets96 |
||
+ | |||
+ | 7.2.3 Command Line Build Options96 |
||
+ | |||
+ | 7.2.4 Example SIL Makefile97 |
||
+ | |||
+ | 7.3 Automation Control101 |
||
+ | |||
+ | 7.3.1 Built-in YANG Language Extensions102 |
||
+ | |||
+ | 7.3.2 SIL Language Extension Access Functions103= Preface = |
||
+ | == Legal Statements == |
||
+ | Copyright 2009 – 2012, Andy Bierman, All Rights Reserved. |
||
+ | |||
+ | == Additional Resources == |
||
+ | This document assumes you have successfully set up the software as described in the printed document: |
||
+ | |||
+ | Yuma<sup> </sup>Installation Guide |
||
+ | |||
+ | Yuma Quickstart Guide |
||
+ | |||
+ | |||
+ | Other documentation includes: |
||
+ | |||
+ | Yuma User Manual |
||
+ | |||
+ | Yuma<sup> </sup>netconfd Manual |
||
+ | |||
+ | Yuma<sup> </sup>yangcli Manual |
||
+ | |||
+ | Yuma<sup> </sup>yangdiff Manual |
||
+ | |||
+ | |||
+ | To obtain additional support you may join the yuma-users group on sourceforge.net and send email to this e-mail address: |
||
+ | |||
+ | yuma-users@lists.sourceforge.net |
||
+ | |||
+ | |||
+ | The SourceForge.net Support Page for Yuma can be found at this WEB page: |
||
+ | |||
+ | http://sourceforge.net/projects/yuma/support |
||
+ | |||
+ | |||
+ | There are several sources of free information and tools for use with YANG and/or NETCONF. |
||
+ | |||
+ | The following section lists the resources available at this time. |
||
+ | |||
+ | === WEB Sites === |
||
+ | * '''Netconf Central''' |
||
+ | ** [http://www.netconfcentral.org/ http://www.netconfcentral.org/] |
||
+ | ** Yuma Home Page |
||
+ | *** Free information on NETCONF and YANG, tutorials, on-line YANG module validation and documentation database |
||
+ | * '''Yuma SourceFource OpenSource Project''' |
||
+ | ** [http://sourceforge.net/projects/yuma/ http://sourceforge.net/projects/yuma/] |
||
+ | *** Download Yuma source and binaries; project forums and help |
||
+ | * '''Yang Central''' |
||
+ | ** [http://www.yang-central.org/ http://www.yang-central.org] |
||
+ | ** Free information and tutorials on YANG, free YANG tools for download |
||
+ | * '''NETCONF Working Group Wiki Page''' |
||
+ | ** [http://trac.tools.ietf.org/wg/netconf/trac/wiki http://trac.tools.ietf.org/wg/netconf/trac/wiki] |
||
+ | ** Free information on NETCONF standardization activities and NETCONF implementations |
||
+ | * '''NETCONF WG Status Page''' |
||
+ | ** http://tools.ietf.org/wg/netconf/ |
||
+ | ** IETF Internet draft status for NETCONF documents |
||
+ | * '''libsmi Home Page''' |
||
+ | ** [http://www.ibr.cs.tu-bs.de/projects/libsmi/ http://www.ibr.cs.tu-bs.de/projects/libsmi/] |
||
+ | ** Free tools such as smidump, to convert SMIv2 to YANG |
||
+ | * '''YumaWorks''' |
||
+ | ** [http://www.yumaworks.com/ http://www.yumaworks.com] |
||
+ | ** Offers support, training, and consulting for Yuma. |
||
+ | ** Offers YumaPro, a professional version of Yuma that includes concurrency, external database support, sub-agent support, multiple northbound interfaces, and more. API compatible with Yuma. Availability: September, 2012. Licensed. |
||
+ | |||
+ | === Mailing Lists === |
||
+ | * '''NETCONF Working Group''' |
||
+ | ** http://www.ietf.org/html.charters/netconf-charter.html |
||
+ | ** Technical issues related to the NETCONF protocol are discussed on the NETCONF WG mailing list. Refer to the instructions on the WEB page for joining the mailing list. |
||
+ | * '''NETMOD Working Group''' |
||
+ | ** [http://www.ietf.org/html.charters/netmod-charter.html http://www.ietf.org/html.charters/netmod-charter.html] |
||
+ | ** Technical issues related to the YANG language and YANG data types are discussed on the NETMOD WG mailing list. Refer to the instructions on the WEB page for joining the mailing list. |
||
+ | |||
+ | == Conventions Used in this Document == |
||
+ | The following formatting conventions are used throughout this document: |
||
+ | |||
+ | <center>'''Documentation Conventions'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Convention</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| '''--foo''' |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| CLI parameter foo |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| '''<nowiki><foo></nowiki>''' |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XML parameter foo |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| '''foo''' |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| '''yangcli''' command or parameter |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| '''$FOO''' |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Environment variable FOO |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| '''$$foo''' |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| '''yangcli''' global variable foo |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| some text |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Example command or PDU |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| some text |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Plain text |
||
+ | |||
+ | |} |
||
+ | = Software Overview = |
||
+ | [[Image:]] |
||
+ | |||
+ | == Introduction == |
||
+ | Refer to section 3 of the Yuma User Manual for a complete introduction to Yuma Tools. |
||
+ | |||
+ | This section focuses on the software development aspects of NETCONF, YANG, and the '''netconfd''' server. |
||
+ | |||
+ | === Intended Audience === |
||
+ | This document is intended for developers of server instrumentation library software, which can be used with the programs in the Yuma suite. It covers the design and operation of the '''netconfd''' server, and the development of server instrumentation library code, intended for use with the '''netconfd''' server. |
||
+ | |||
+ | === What does Yuma Do? === |
||
+ | The Yuma Tools suite provides automated support for development and usage of network management information. Refer to the Yuma User Guide for an introduction to the YANG data modeling language and the NETCONF protocol. |
||
+ | |||
+ | This section describes the Yuma development environment and the basic tasks that a software developer needs to perform, in order to integrate YANG module instrumentation into a device. |
||
+ | |||
+ | This manual contains the following information: |
||
+ | |||
+ | * Yuma Development Environment |
||
+ | * Yuma Runtime Environment |
||
+ | * Yuma Source Code Overview |
||
+ | * Yuma Server Instrumentation Library Development Guide |
||
+ | |||
+ | Yuma Tools programs are written in the C programming language, using the 'gnu99' C standard, and should be easily integrated into any operating system or embedded device that supports the Gnu C compiler. |
||
+ | |||
+ | |||
+ | === What is a Yuma Root? === |
||
+ | [[Image:]] |
||
+ | |||
+ | The Yuma Tools programs will search for some types of files in default locations |
||
+ | |||
+ | * '''YANG Modules''': The 'modules' sub-directory is used as the root of the YANG module library. |
||
+ | * '''Client Scripts''': The yangcli program looks in the 'scripts' sub-directory for user scripts. |
||
+ | * '''Program Data''': The yangcli and netconfd programs look for saved data structures in the 'data' sub-directory. |
||
+ | |||
+ | === Searching Yuma Roots === |
||
+ | [[Image:]] |
||
+ | |||
+ | '''1) $HOME Directory''' |
||
+ | |||
+ | The first Yuma root checked when searching for files is the directory identified by the $HOME environment variable. If a ''''$HOME/modules'''', ''''$HOME/data''''. and/or ''''$HOME/scripts'''' directory exists, then it will be checked for the specified file(s). |
||
+ | |||
+ | |||
+ | '''2) The $YUMA_HOME Directory''' |
||
+ | |||
+ | The second Yuma root checked when searching for files is the directory identified by the $YUMA_HOME environment variable. This is usually set to private work directory, but a shared directory could be used as well. If a ''''$YUMA_HOME/modules'''', ''''$YUMA_HOME/data''''. and/or ''''$YUMA_HOME/scripts'''' directory exists, then it will be checked for the specified file(s). |
||
+ | |||
+ | |||
+ | '''3) The $YUMA_INSTALL Directory''' |
||
+ | |||
+ | The last Yuma root checked when searching for files is the directory identified by the $YUMA_INSTALL environment variable. If it is not set, then the default value of '/'''usr/share/yuma'''' is used instead. This is usually set to the public directory where all users should find the default modules. If a ''''$YUMA_INSTALL/modules'''', ''''$YUMA_INSTALL/data''''. and/or ''''$YUMA_INSTALL/scripts'''' directory exists, then it will be checked for the specified file(s). |
||
+ | |||
+ | === What is a SIL? === |
||
+ | A SIL is a Server Instrumentation Library. It contains the 'glue code' that binds YANG content (managed by the '''netconfd''' server), to your networking device, which implements the specific behavior, as defined by the YANG module statements. |
||
+ | |||
+ | The '''netconfd''' server handles all aspects of the NETCONF protocol operation, except data model semantics that are contained in description statements. The server uses YANG files directly, loaded at boot-time or run-time, to manage all NETCONF content, operations, and notifications. |
||
+ | |||
+ | Callback functions are used to hook device and data model specific behavior to database objects and RPC operations. The '''yangdump''' program is used to generate the initialization, cleanup, and 'empty' callback functions for a particular YANG module. The callback functions are then completed (by you), as required by the YANG module semantics. This code is then compiled as a shared library and made available to the '''netconfd''' server. The 'load' command (via CLI, configuration file, protocol operation) is used (by the operator) to activate the YANG module and its SIL. |
||
+ | |||
+ | |||
+ | === Auto-generated SIL Files === |
||
+ | The SIL code for a YANG module can be generated with the '''make_sil_dir '''script described in the next section. This script can generate 'combined' SIL files or 'split' SIL files (if the –split parameter is present). |
||
+ | |||
+ | |||
+ | A split SIL module for ''foo.yang'' would be generated using the following files: |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>File name</center> |
||
+ | ! <center>Type</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| u_foo.c |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| User SIL |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| User-provided server instrumentation code for the 'foo' module. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| u_foo.h |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| User SIL |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| User-provided external definitions for the 'foo' module. Should not edit! |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| y_foo.c |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| Yuma SIL |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yuma server glue code for the 'foo' module. Do not edit! |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| y_foo.h |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| Yuma SIL |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yuma server external definitions for the 'foo' module. Do not edit! |
||
+ | |||
+ | |} |
||
+ | A combined SIL module for ''foo.yang'' would be generated using the following files: |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>File name</center> |
||
+ | ! <center>Type</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| foo.c |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| Combined Yuma and User SIL |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| User-provided server instrumentation code for the 'foo' module. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| foo.h |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| Combined Yuma and User SIL |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| User-provided external definitions for the 'foo' module. Should not edit! |
||
+ | |||
+ | |} |
||
+ | === Basic Development Steps === |
||
+ | The steps needed to create server instrumentation for use within Yuma are as follows: |
||
+ | |||
+ | * '''Create the YANG module data model '''definition, or use an existing YANG module. |
||
+ | |||
+ | * |
||
+ | ** Validate the YANG module with the '''yangdump''' program and make sure it does not contain any errors. All warnings should also be examined to determine if they indicate data modeling bugs or not. |
||
+ | ** Example toaster.yang |
||
+ | * Make sure the '''$YUMA_HOME''' environment variable is defined, and pointing to your Yuma development tree. |
||
+ | * '''Create a SIL development subtree''' |
||
+ | |||
+ | * |
||
+ | ** Generate the directory structure and the Makefile with the '''make_sil_dir''' script, installed in the''' /usr/bin''' directory. This step will also call '''yangdump''' to generate the initial H and C files file the SIL. |
||
+ | ** Example: mydir> '''make_sil_dir –split test''' |
||
+ | * '''Use your text editor to fill in the device-specific instrumentation '''for each object, RPC method, and notification. (In this example, edit '''test/src/u_test.c''') Almost all possible NETCONF-specific code is either handled in the central stack, or generated automatically. so this code is responsible for implementing the semantics of the YANG data model. |
||
+ | * '''Compile your code''' |
||
+ | ** Use the 'make' command in the SIL 'src' directory. This should generate a library file in the SIL 'lib' directory. |
||
+ | ** Example: mydir/test/src> '''make''' |
||
+ | * '''Install the SIL library so it is available to the netconfd server.''' |
||
+ | ** Use the 'make install' command in the SIL 'src' directory. |
||
+ | ** Example: mydir/test/src> '''sudo''' '''make install''' |
||
+ | * '''Run the netconfd server''' (or build it again if linking with static libraries) |
||
+ | * '''Load the new module''' |
||
+ | ** Be sure to add a 'load' command to the configuration file if the module should be loaded upon each reboot. |
||
+ | ** yangcli Example: load test |
||
+ | * The '''netconfd''' server will load the specified YANG module and the SIL and make it available to all sessions. |
||
+ | |||
+ | == Yuma Source Files == |
||
+ | This section describes the files that are contained in the '''yuma-source''' package. |
||
+ | |||
+ | The important C include files are copied into '''/usr/include/yuma''' when the '''yuma-dev''' package is installed. The full set of installation sources is installed in '''/usr/share/yuma/src''', if the''' yuma-source''' package is installed. Yuma tools will check the''' $YUMA_HOME/src''' sub-tree before checking this default installation location. This allows a working copy of the Yuma sources to be used instead of the installation copy, in case it has been modified for a particular embedded system (for example). |
||
+ | |||
+ | This section lists the files that are included within the''' netconf/src''' directory. |
||
+ | |||
+ | === src/ncx Directory === |
||
+ | This directory contains the code that is used to build the''' libncx.so''' binary shared library that is used by all Yuma Tools programs. It handles many of the core NETCONF/YANG data structure support, including all of the YANG/YIN, XML, and XPath processing. The following table describes the purpose of each file. Refer to the actual include file (e.g., ncx.h in /usr/include/yuma) for more details on each external function in each C source module. |
||
+ | |||
+ | <center>'''src/ncx C Modules'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>C Module</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| b64 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Encoding and decoding the YANG binary data type. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| blob |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Encoding and decoding the SQL BLOB data type. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| bobhash |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implementation of the BOB hash function. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cap |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| NETCONF capability definitions and support functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| NETCONF database data structures and configuration locking support. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cli |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| CLI parameter parsing data driven by YANG definitions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| conf |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Text .conf file encoding and decoding, data driven by YANG definitions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| def_reg |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Hash-driven definition registry for quick lookup support of some data structures. Contains back-pointers to the actual data. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| dlq |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Double linked queue support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ext |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG extension data structure support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| grp |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG grouping data structure support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| help |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Automatic help text, data-driven by YANG definitions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| log |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| System logging support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ncx_appinfo |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yuma Netconf Extensions (NCX) support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ncx |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG module data structure support, and some utilities |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ncx_feature |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG feature and if-feature statement data structure support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ncx_list |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Support for the '''ncx_list_t''' data structure, used for YANG bits and '''ncx:xsdlist''' data types. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ncxmod |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| File Management: Controls finding and searching for YANG/YIN files, data files, and script files |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ncx_num |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yuma''' ncx_num_t''' data structure support. Used for processing value nodes and XPath numbers. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ncx_str |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yuma''' '''string support. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yuma object '''(obj_template_t)''' data structure access |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_help |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Automated object help support used with help module |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| op |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| NETCONF operations definitions and support functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>NETCONF <rpc> and <rpc-reply> data structures and support functions</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_err |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>NETCONF <rpc-error> data structures and support functions.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| runstack |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Script execution stack support for yangcli scripts |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| send_buff |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| NETCONF send buffer function |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ses |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| NETCONF session data structures and session access functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ses_msg |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Message buffering support for NETCONF sessions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| status |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Error code definitions and error support functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| tk |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Token chain data structures used for parsing YANG, XPath and other syntaxes. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| top |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Top-level XML node registration support. <nowiki>The <rpc> and <hello> elements are registered by the server. </nowiki><nowiki>The <hello>, <rpc-reply> , and <notification> elements are registered by the client.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| tstamp |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Time and date stamp support functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| typ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG typedef data structures and access functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yuma value tree data structures and access functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_util |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| High-level utilities for some common SIL tasks related to the value tree. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| var |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| User variable support, used by '''yangcli''' and (TBD) XPath |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xml_msg |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XML message data structures and support functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xmlns |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XML Namespace registry |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xml_util |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XML parse and utility functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xml_val |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| High level support functions for constructing XML-ready '''val_value_t '''data structures |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xml_wr |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XML output support functions and access-control protected message generation support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xpath1 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XPath 1.0 implementation |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xpath |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XPath data structures and support functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xpath_wr |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Support for generating XPath expression content within an XML instance document |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xpath_yang |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Special YANG XPath construct support, such as path expressions and instance identifiers |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yang |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG definitions and general support functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yang_ext |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG parsing and validation of the extension statement |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yang_grp |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG parsing and validation of the grouping statement |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yang_obj |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG parsing and validation of the rpc, notification, and data definition statements |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yang_parse |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Top level YANG parse and validation support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yang_typ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG typedef and type statement support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yin |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG to YIN mapping definitions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yinyang |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YIN to YANG translation |
||
+ | |||
+ | |} |
||
+ | === src/platform Directory === |
||
+ | This directory contains platform support include files and Makefile support files. It is used by all Yuma C modules to provide an insulating layer between Yuma programs and the hardware platform that is used. For example the '''m__getMem, m__getObj''', and '''m__freeMem''' macros are used instead of '''malloc''' and '''free''' functions directly. |
||
+ | |||
+ | The following table describes the files that are contained in this directory: |
||
+ | |||
+ | <center>'''src/platform Files'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>File</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| curversion.h |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| File generated during the build process to get the SVNVERSION number |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| platform.profile |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Included by Makefiles for build support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| platform.profile.cmn |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Included by Makefiles for build support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| platform.profile.depend |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Included by Makefiles for dependency generation support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| procdefs.h |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Platform definitions. Contains basic data types and macros used throughout the Yuma code. All C files include this file before any other Yuma files. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| setversion.sh |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Shell script to generate the curversion.h file |
||
+ | |||
+ | |} |
||
+ | === src/agt Directory === |
||
+ | This directory contains the NETCONF server implementation and built-in module SIL code. A static library called '''libagt.a''' is built and statically linked within the '''netconfd''' program. |
||
+ | |||
+ | The following table describes the C modules contained in this directory: |
||
+ | |||
+ | |||
+ | <center>'''src/agt C Modules'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>C Module</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_acm |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| NETCONF access control implementation. Contains the '''yuma-nacm''' module SIL callback functions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Server initialization and cleanup control points. Also contains the '''agt_profile_t''' data structure. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_cap |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Server capabilities. <nowiki>Generates the server <capabilities> element content.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_cb |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| SIL callback support functions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_cli |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Server CLI and .conf file control functions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_connect |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Handles the internal <ncx-connect> message sent from the </nowiki>'''netconf-subsystem''' to the '''netconfd''' server. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_hello |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Handles the incoming client <hello> message and generates the </nowiki><nowiki>server <hello> message.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_if |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yuma Interfaces module implementation. Contains the '''yuma-interfaces '''module SIL callback functions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_ncx |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| NETCONF protocol operation implementation. Contains the '''yuma-netconf '''module SIL callback functions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_ncxserver |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements the ncxserver loop, handling the IO between the server NETCONF sessions and the '''netconf-subsystem''' thin client program. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_not |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| NETCONF Notifications implementation. Contains the '''notifications '''and''' nc-notifications''' modules SIL callback functions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_proc |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| '''/proc '''system monitoring implementation. Contains the '''yuma-proc''' module SIL callback functions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_rpc |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| NETCONF RPC operation handler |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_rpcerr |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>NETCONF <rpc-error> generation</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_ses |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| NETCONF session support and implementation of the Yuma Session extensions. Contains the '''yuma-mysession''' module SIL callback functions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_signal |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Server signal handling support |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_state |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Standard NETCONF monitoring implementation. Contains the''' ietf-netconf-monitoring''' SIL callback functions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_sys |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Server system monitoring and notification generation. Contains the '''yuma-system''' module SIL callback functions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_timer |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| SIL periodic timer callback support functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_top |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Server registration and dispatch of top-level XML messages |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_tree |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Subtree filtering implementation |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_util |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| SIL callback utilities |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_val |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Server validation, commit, and rollback support for NETCONF database operations |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_val_parse |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Incoming <rpc> and <config> content parse and complete YANG constraint validation</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_xml |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Server XML processing interface to '''ncx/xml_util''' functions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_xpath |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XPath filtering implementation |
||
+ | |||
+ | |} |
||
+ | === src/mgr Directory === |
||
+ | This module contains the NETCONF client support code. It handles all the basic NETCONF details so a simple internal API can be used by NETCONF applications such as '''yangcli'''. A static library called '''libmgr.a''' is built and statically linked within the '''yangcli''' program. |
||
+ | |||
+ | The following table describes the C modules contained in this directory: |
||
+ | |||
+ | |||
+ | <center>'''src/mgr C Modules'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>C Module</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| mgr |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Client initialization and cleanup control points. Also contains manager session control block data structure support functions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| mgr_cap |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Generate the client NETCONF <capabilities> element content</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| mgr_hello |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Handles the incoming server <hello> message and generates the client <hello> message.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| mgr_io |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Handles SSH server IO support for client NETCONF sessions |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| mgr_not |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Handles incoming server <notification> messages</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| mgr_rpc |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Generate <rpc> messages going to the NETCONF server and process incoming <rpc-reply> messages from the NETCONF server.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| mgr_ses |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Handles all aspects of client NETCONF sessions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| mgr_signal |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Client signal handler |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| mgr_top |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Client registration and dispatch of top-level XML messages |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| mgr_val_parse |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Incoming <rpc-reply>, <notification>, and <config> content parse and complete YANG constraint validation.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| mgr_xml |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Client XML processing interface to '''ncx/xml_util''' functions |
||
+ | |||
+ | |} |
||
+ | === src/subsys Directory === |
||
+ | This directory contains the '''netconf-subsystem''' program. This is a thin-client application that just transfers input and output between the SSH server and the NETCONF server. It contains one C source module called '''netconf-subsystem'''. This is a stand-alone binary that is part of the '''yuma-server''' package. It is installed in the '''/usr/sbin/ '''directory. |
||
+ | |||
+ | === src/netconfd Directory === |
||
+ | This directory contains the '''netconfd''' program, which implements the NETCONF server. It contains one C module called '''netconfd''', which defines the NETCONF server 'main' function. This is a stand-alone binary that is part of the '''yuma-server''' package. It is installed in the '''/usr/sbin/ '''directory. |
||
+ | |||
+ | === src/yangcli Directory === |
||
+ | This directory contains the '''yangcli''' program, which is the Yuma NETCONF client program. This is a stand-alone binary that is part of the '''yuma-client''' package. It is installed in the '''/usr/bin/ '''directory. |
||
+ | |||
+ | The following table describes the C modules contained in this directory: |
||
+ | |||
+ | |||
+ | <center>'''src/yangcli C Modules'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>C Module</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangcli |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| NETCONF client program, provides interactive and script-based CLI, based on YANG modules. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangcli_autoload |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Uses the server capabilities from the <hello> message to automatically load any missing YANG modules from the server, and apply all features and deviations.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yang_autolock |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Provides protocol exchange support for the high-level get-locks and release-locks commands |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangcli_cmd |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Main local command processor |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangcli_list |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements yangcli 'list' command |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangcli_save |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements yangcli 'save' command |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangcli_show |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements yangcli 'show' command |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangcli_tab |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements context-sensitive tab word completion |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangcli_util |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Utilities used by other yangcli C modules |
||
+ | |||
+ | |} |
||
+ | === src/yangdiff Directory === |
||
+ | This directory contains the '''yangdiff''' program, which is the Yuma YANG module compare program. This is a stand-alone binary that is part of the '''yuma-client''' package. It is installed in the '''/usr/bin/ '''directory. |
||
+ | |||
+ | The following table describes the C modules contained in this directory: |
||
+ | |||
+ | |||
+ | <center>'''src/yangdiff'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>C Module</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangdiff |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG module semantic compare program |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangdiff_grp |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements semantic diff for YANG grouping statement |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangdiff_obj |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements semantic diff for YANG data definition statements |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangdiff_typ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements semantic diff for YANG typedef and type statements |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangdiff_util |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Utilities used by the other '''yangdiff''' C modules |
||
+ | |||
+ | |} |
||
+ | === src/yangdump Directory === |
||
+ | This directory contains the '''yangdump''' program, which is the Yuma YANG compiler program. This is a stand-alone binary that is part of the '''yuma-client''' package. It is installed in the '''/usr/bin/ '''directory. |
||
+ | |||
+ | The following table describes the C modules contained in this directory: |
||
+ | |||
+ | |||
+ | <center>'''src/yangdump C Modules'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>C Module</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| c |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements SIL C file generation |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| c_util |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Utilities used for SIL code generation |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| h |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements SIL H file generation |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| html |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements YANG to HTML translation |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| sql |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements SQL generation for YANG module WEB Docs |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xsd |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements YANG to XSD translation |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xsd_typ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements YANG typedef/type statement to XSD simpleType and complexType statements |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xsd_yang |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG to XSD translation utilities |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangdump |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG module compiler |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangdump_util |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Utilities used by all yangdump C modules |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| yangyin |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Implements YANG to YIN translation |
||
+ | |||
+ | |} |
||
+ | == Server Design == |
||
+ | This section describes the basic design used in the '''netconfd''' server. |
||
+ | |||
+ | |||
+ | [[Image:]] |
||
+ | |||
+ | |||
+ | '''Initialization:''' |
||
+ | |||
+ | The '''netconfd''' server will process the YANG modules, CLI parameters, config file parameters, and startup device NETCONF database, then wait for NETCONF sessions. |
||
+ | |||
+ | '''ncxserver Loop:''' |
||
+ | |||
+ | The SSH2 server will listen for incoming connections which request the 'netconf' subsystem. |
||
+ | |||
+ | When a new session request is received, the '''netconf-subsystem''' program is called, which opens a local connection to the '''netconfd''' server, via the ncxserver loop. <nowiki>NETCONF <rpc> requests are processed by the internal NETCONF stack. </nowiki>The module-specific callback functions (blue boxes) can be loaded into the system at build-time or run-time. This is the device instrumentation code, also called a server implementation library (SIL). For example, for '''libtoaster''', this is the code that controls the toaster hardware. |
||
+ | |||
+ | '''Cleanup''': |
||
+ | |||
+ | <nowiki>If the <shutdown> or <reboot> operations are invoked, then the server will cleanup. </nowiki>For a reboot, the init cycle is started again, instead of exiting the program. |
||
+ | |||
+ | === YANG Native Operation === |
||
+ | [[Image:]] |
||
+ | |||
+ | Yuma uses YANG source modules directly to implement NETCONF protocol operations automatically within the server. The same YANG parser is used by all Yuma programs. It is located in the 'ncx' source directory (libncx.so). There are several different parsing modes, which is set by the application. |
||
+ | |||
+ | In the 'server mode', the descriptive statements, such as 'description' and 'reference' are discarded upon input. Only the machine-readable statements are saved. All possible database validation, filtering, processing, initialization, NV-storage, and error processing is done, based on these machine readable statements. |
||
+ | |||
+ | For example, in order to set the platform-specific default value for some leaf, instead of hard-coded it into the server instrumentation, the default is stored in YANG data instead. The YANG file can be altered, either directly (by editing) or indirectly (via deviation statements), and the new or altered default value specified there. |
||
+ | |||
+ | In addition, range statements, patterns, XPath expressions, and all other machine-readable statements are all processed automatically, so the YANG statements themselves are like server source code. |
||
+ | |||
+ | YANG also allows vendor and platform-specific deviations to be specified, which are like generic patches to the common YANG module for whatever purpose needed. YANG also allows annotations to be defined and added to YANG modules, which are specified with the 'extension' statement. Yuma uses some extensions to control some automation features, but any module can define extensions, and module instrumentation code can access these annotation during server operation, to control device behavior. |
||
+ | |||
+ | There are CLI parameters that can be used to control parser behavior such as warning suppression, and protocol behavior related to the YANG content, such as XML order enforcement and NETCONF protocol operation support. These parameters are stored in the server profile, which can be customized for each platform. |
||
+ | |||
+ | === YANG Object Tree === |
||
+ | [[Image:]] |
||
+ | |||
+ | The YANG statements found in a module are converted to internal data structures. |
||
+ | |||
+ | For NETCONF and database operations, a single tree of '''obj_template_t '''data''' '''structures is maintained by the server. This tree represents all the NETCONF data that is supported by the server. It does not represent any actual data structure instances. It just defines the data instances that are allowed to exist on the server. |
||
+ | |||
+ | |||
+ | '''Raw YANG vs. Cooked YANG:''' |
||
+ | |||
+ | Some of the nodes in this tree represent the exact YANG statements that the data modeler has used, such as 'augment', 'refine', and 'uses', but these nodes are not used directly in the object tree. They exist in the object tree, but they are processed to produce a final set of YANG data statements, translated into 'cooked' nodes in the object tree. If any deviation statements are used by server implementation of a YANG data node (to change it to match the actual platform implementation of the data node), then these are also 'patched' into the cooked YANG nodes in the object tree. |
||
+ | |||
+ | |||
+ | === YANG Data Tree === |
||
+ | [[Image:]] |
||
+ | |||
+ | A YANG data tree represents the instances of 1 or more of the objects in the object tree. |
||
+ | |||
+ | Each NETCONF database is a separate data tree. A data tree is constructed for each incoming message as well. The server has automated functions to process the data tree, based on the desired NETCONF operation and the object tree node corresponding to each data node. |
||
+ | |||
+ | Every NETCONF node (including database nodes) are distinguished with XML Qualified Names (QName). The YANG module namespace is used as the XML namespace, and the YANG identifier is used as the XML local name. |
||
+ | |||
+ | Each data node contains a pointer back to its object tree schema node. The value tree is comprised of the '''val_value_t '''structure. Only real data is actually stored in the value tree. For example, there are no data tree nodes for choices and cases. These are conceptual layers, not real layers, within the data tree. |
||
+ | |||
+ | |||
+ | The NETCONF server engine accesses individual SIL callback functions through the data tree and object tree. Each data node contains a pointer to its corresponding object node. |
||
+ | |||
+ | Each data node may have several different callback functions stored in the object tree node. Usually, the actual configuration value is stored in the database, However, '''virtual data nodes''' are also supported. These are simply placeholder nodes within the data tree, and usually used for non-configuration nodes, such as counters. Instead of using a static value stored in the data node, a callback function is used to retrieve the instrumentation value each time it is accessed. |
||
+ | |||
+ | === Service Layering === |
||
+ | All of the major server functions are supported by service layers in the 'agt' or 'ncx' libraries: |
||
+ | |||
+ | * '''Memory management''': macros in '''platform/procdefs.h''' are used instead of using direct heap functions. The macros '''m__getMem '''or '''m__getObj '''are used by Yuma code to allocate memory. Both of these functions increment a global counter called '''malloc_count'''. The macro''' m__free''' is used to delete all malloced memory. This macro increments a global counter called '''free_count'''. When a Yuma program exists, it checks if '''malloc_count''' equals '''free_count''', and if not, generates an error message. If this occurs, the '''MEMTRACE=1''' parameter can be added to the make command to activate 'mtrace' debugging. |
||
+ | * '''Queue management''': APIs in '''ncx/dlq.h''' are used for all double-linked queue management. |
||
+ | * '''XML namespaces''': XML namespaces (including YANG module namespaces) are managed with functions in''' ncx/xmlns.h'''. An internal 'namespace ID is used internally instead of the actual URI. |
||
+ | * '''XML parsing''': XML input processing is found in '''ncx/xml_util.h''' data structures and functions. |
||
+ | * '''XML message processing''': XML message support is found in '''ncx/xml_msg.h''' data structures and functions. |
||
+ | * '''XML message writing with access control''': XML message generation is controlled through API functions located in '''ncx/xml_wr.h'''. High level (value tree output) and low-level (individual tag output) XML output functions are provided, which hide all namespace, indentation, and other details. Access control is integrated into XML message output to enforce the configured data access policies uniformly for all RPC operations and notifications. The access control model cannot be bypassed by any dynamically loaded module server instrumentation code. |
||
+ | * '''XPath Services''': All NETCONF XPath filtering, and all YANG XPath-based constraint validation, is handled with common data structures and API functions. The XPath 1.0 implementation is native to the server, and uses the object and value trees directly to generate XPath results for NETCONF and YANG purposes. NETCONF uses XPath differently than XSLT, and libxml2 XPath processing is memory intensive. These functions are located in '''ncx/xpath.h''', '''ncx/xpath1.h''', and '''ncx/xpath_yang.h'''. <nowiki>XPath filtered <get> responses are generated in </nowiki>'''agt/agt_xpath.c'''. |
||
+ | * '''Logging service''': Encapsulates server output to a log file or to the standard output, filtered by a configurable log level. Located in '''ncx/log.h'''. In addition, the macro '''SET_ERROR()''' in '''ncx/status.h '''is used to report programming errors to the log. |
||
+ | * '''Session management''': All server activity is associated with a session. The session control block and API functions are located in '''ncx/ses.h'''. All input, output, access control, and protocol operation support is controlled through the session control block (ses_cb_t). |
||
+ | * '''Timer service''': A periodic timer service is available to SIL modules for performing background maintenance within the main service loop. These functions are located in '''agt/agt_timer.h'''. |
||
+ | * '''Connection management''': All TCP connections to the netconfd server are controlled through a main service loop, located in '''agt/agt_ncxserver.c'''. It is expected that the 'select' loop in this file will be replaced in embedded systems. <nowiki>The default netconfd server actually listens for local <ncx-connect> connections on an </nowiki>AF_LOCAL socket. The openSSH server listens for connections on port 830 (or other configured TCP ports), and the netconf-subsystem thin client acts as a conduit between the SSH server and the '''netconfd''' server. |
||
+ | * '''Database management''': All configuration databases use a common configuration template, defined in '''ncx/cfg.h'''. Locking and other generic database functions are handled in this module. The actual manipulation of the value tree is handled by API functions in '''ncx/val.h''', '''ncx/val_util.h, agt/agt_val_parse.h, '''and '''agt/agt_val.h'''. |
||
+ | * '''NETCONF operations''': All standard NETCONF RPC callback functions are located in '''agt/agt_ncx.c'''. All operations are completely automated, so there is no server instrumentation APIs in this file. |
||
+ | * '''NETCONF request processing''': <nowiki>All <rpc> requests and replies use common data structures and APIs, found in </nowiki>'''ncx/rpc.h''' and''' agt/agt_rpc.h'''. Automated reply generation, automatic filter processing, and message state data is contained in the RPC message control block. |
||
+ | * '''NETCONF error reporting:'''<nowiki> All <rpc-error> elements use common data structures defined in ncx/rpc_err,h and agt/agt_rpcerr.h. </nowiki>Most errors are handled automatically, but 'description statement' semantics need to be enforced by the SIL callback functions. These functions use the API functions in '''agt/agt_util.h'''<nowiki> (such as agt_record_error) to generate data structures that will be translated to the proper <rpc-error> contents when a reply is sent.</nowiki> |
||
+ | * '''YANG module library management:''' All YANG modules are loaded into a common data structure (ncx_module_t) located in ncx/ncxtypes.h. The API functions in''' ncx/ncxmod.h '''(such as ncxmod_load_module) are used to locate YANG modules, parse them, and store the internal data structures in a central library. Multiple versions of the same module can be loaded at once, as required by YANG. |
||
+ | |||
+ | === Session Control Block === |
||
+ | Once a NETCONF session is started, it is assigned a session control block for the life of the session. All NETCONF and system activity in driven through this interface, so the '''ncxserver''' loop can be replaced in an embedded system. |
||
+ | |||
+ | Each session control block (ses_scb_t) controls the input and output for one session, which is associated with one SSH user name. Access control (see yuma-nacm.yang) is enforced within the context of a session control block. Unauthorized return data is automatically removed from the response. <nowiki>Unauthorized <rpc> or database write requests are automatically rejected with an 'access-denied' error-tag.</nowiki> |
||
+ | |||
+ | The user preferences for each session are also stored in this data structure. <nowiki>They are initially derived from the server default values, but can be altered with the <set-my-session> operation and retrieved with the <get-my-session> operation.</nowiki> |
||
+ | |||
+ | === Server Message Flows === |
||
+ | [[Image:]] |
||
+ | |||
+ | The '''netconfd''' server provides the following type of components: |
||
+ | |||
+ | * NETCONF session management |
||
+ | * NETCONF/YANG database management |
||
+ | * NETCONF/YANG protocol operations |
||
+ | * Access control configuration and enforcement |
||
+ | * RPC error reporting |
||
+ | * Notification subscription management |
||
+ | * Default data retrieval processing |
||
+ | * Database editing |
||
+ | * Database validation |
||
+ | * Subtree and XPath retrieval filtering |
||
+ | * Dynamic and static capability management |
||
+ | * Conditional object management (if-feature, when) |
||
+ | * Memory management |
||
+ | * Logging management |
||
+ | * Timer services |
||
+ | |||
+ | All NETCONF and YANG protocol operation details are handled automatically within the '''netconfd''' server. All database locking and editing is also handled by the server. There are callback functions available at different points of the processing model for your module specific instrumentation code to process each server request, and/or generate notifications. Everything except the 'description statement' semantics are usually handled |
||
+ | |||
+ | The server instrumentation stub files associated with the data model semantics are generated automatically with the '''yangdump''' program. The developer fills in server callback functions to activate the networking device behavior represented by each YANG data model. |
||
+ | |||
+ | === Main ncxserver Loop === |
||
+ | [[Image:]] |
||
+ | |||
+ | The '''ncxserver''' loop does very little, and it is designed to be replaced in an embedded server that has its own SSH server: |
||
+ | |||
+ | * A client request to start an SSH session results in an SSH channel being established to an instance of the '''netconf-subsystem''' program. |
||
+ | * The '''netconf-subsystem '''<nowiki>program will open a local socket (/tmp/ncxserver.sock) and send a proprietary <ncxconnect> message to the netconfd server, which is listening on this local socket with a select loop (in agt_ncxserver.c).</nowiki> |
||
+ | * <nowiki>When a valid <ncxconnect> message is received by </nowiki>'''netconfd''', a new NETCONF session is created. |
||
+ | * <nowiki>After sending the <ncxconnect> message, the </nowiki>'''netconf-subsystem '''program goes into 'transfer mode', and simply passes input from the SSH channel to the '''netconfd''' server, and passes output from the '''netconfd''' server to the SSH server. |
||
+ | * The '''ncxserver''' loop simply waits for input on the open connections, with a quick timeout. Each timeout, the server checks if a reboot, shutdown, signal, or other event occurred that needs attention. |
||
+ | * Notifications may also be sent during the timeout check, if any events are queued for processing. The '''--max-burst''' configuration parameter controls the number of notifications sent to each notification subscription, during this timeout check. |
||
+ | * <nowiki>Input <rpc> messages are buffered, and when a complete message is received (based on the NETCONF End-of-Message marker), it is processed by the server and any instrumentation module callback functions that are affected by the request.</nowiki> |
||
+ | |||
+ | When the agt_ncxserver_run function in agt/agt_ncxserver.c is replaced within an embedded system, the replacement code must handle the following tasks: |
||
+ | |||
+ | * Call '''agt_ses_new_session''' in '''agt/agt_ses.c''' when a new NETCONF session starts. |
||
+ | * Call '''ses_accept_input''' in '''ncx/ses.c''' with the correct session control block when NETCONF data is received. |
||
+ | * Call '''agt_ses_process_first_ready''' in '''agt/agt_ses.c''' after input is received. This should be called repeatedly until all serialized NETCONF messages have been processed. |
||
+ | * Call '''agt_ses_kill_session''' in '''agt/agt_ses.c''' when the NETCONF session is terminated. |
||
+ | * The following functions are used for sending NETCONF responses, if responses are buffered instead of sent directly (streamed). |
||
+ | ** '''ses_msg_send_buffs''' in '''ncx/ses_msg.c''' is used to output any queued send buffers. |
||
+ | * The following functions need to be called periodically: |
||
+ | ** '''agt_shutdown_requested''' in '''agt/agt_util.c''' to check if the server should terminate or reboot |
||
+ | ** '''agt_ses_check_timeouts''' in '''agt/agt_ses.c'''<nowiki> to check for idle sessions or sessions stuck waiting for a NETCONF <hello> message.</nowiki> |
||
+ | ** '''agt_timer_handler''' in '''agt/agt_timer.c''' to process server and SIL periodic callback functions. |
||
+ | ** '''send_some_notifications '''in '''agt/agt_ncxserver.c''' to process some outgoing notifications. |
||
+ | |||
+ | === SIL Callback Functions === |
||
+ | [[Image:]] |
||
+ | |||
+ | * Top Level: The top-level incoming messages are registered, not hard-wired, in the server message processing design. The '''agt_ncxserve'''r module accepts <nowiki>the <ncxconnect> message from </nowiki>'''netconf-subsystem'''. The '''agt_rpc'''<nowiki> module accepts the NETCONF <rpc> message. </nowiki>Additional messages can be supported by the server using the '''top_register_node''' function. |
||
+ | * All RPC operations are implemented in a data-driven fashion by the server. Each NETCONF operation is handled by a separate function in '''agt_ncx.c'''. Any proprietary operation can be automatically supported, using the '''agt_rpc_register_method''' function. |
||
+ | ** Note: Once the YANG module is loaded into the server, all RPC operations defined in the module are available. If no SIL code is found, these will be dummy 'no-op' functions. This mode can be used to provide some server simulation capability for client applications under development. |
||
+ | * All database operations are performed in a structured manner, using special database access callback functions. Not all database nodes need callback functions. One callback function can be used for each 'phase', or the same function can be used for multiple phases. The '''agt_cb_register_callback''' function in''' agt/agt_cb.c''' is used by SIL code to hook into NETCONF database operations. |
||
+ | |||
+ | == Server Operation == |
||
+ | This section briefly describes the server internal behavior for some basic NETCONF operations. |
||
+ | |||
+ | === Initialization === |
||
+ | The file '''netconfd/netconfd.c''' contains the initial 'main' function that is used to start the server. |
||
+ | |||
+ | * The common services support for most core data structures is located in 'libncx.so'. The ''''ncx_init'''' function is called to setup these data structures. This function also calls the bootstrap_cli function in ncx/ncx.c, which processes some key configuration parameters that need to be set right away, such as the logging parameters and the module search path. |
||
+ | * Most of the actual server code is located in the 'agt' directory. The ''''agt_init1'''' function is called to initialize core server functions. The configuration parameters are processed, and the server profile is completed. |
||
+ | ** The''' agt_profile_t '''data structure in agt/agt.h is used to contain all the vendor-related boot-time options, such as the database target (candidate or running). The''' init_server_profile''' function can be edited if the Yuma default values are not desired. This will insure the proper factory defaults for server behavior are used, even if no configuration parameters are provided. |
||
+ | * The function '''init_server_profile''' in '''agt/agt.c''' is used to set the factory defaults for the server behavior. |
||
+ | |||
+ | The '''agt_init1''' function also loads the core NETCONF protocol, '''netconfd''' CLI, and YANG data type modules. |
||
+ | |||
+ | * Note: '''netconfd''' uses '''yuma-netconf.yang''', not '''ietf-netconf.yang''' to support a data-driven implementation. The only difference is that the yuma version adds some data structures and extensions (such as ncx:root), to automate processing of all NETCONF messages. |
||
+ | |||
+ | After the core definition modules are loaded successfully, the''' agt_cli_process_input''' function in '''agt/agt_cli.c''' is called to process any command line and/or configuration file parameters that have been entered. |
||
+ | |||
+ | * Note: Any defaults set in the G module definitions will be added to the CLI parameter set. The '''val_set_by_default''' function in '''ncx/val.c''' can be used to check if the node is set by the server to the YANG default value. If not set, and the node has the YANG default value, then the client set this value explicitly. This is different than the '''val_is_default''' function in '''ncx/val.c''', which just checks if the node contains the YANG default value. |
||
+ | |||
+ | All the configuration parameters are saved, and those that can be processed right away are handled. The '''agt_cli_get_valset''' function in '''agt/agt_cli.c''' can be used to retrieve the entire set of load-time configuration parameters. |
||
+ | |||
+ | === Loading Modules and SIL Code === |
||
+ | YANG modules and their associated device instrumentation can be loaded dynamically with the '''--module''' configuration parameter. Some examples are shown below: |
||
+ | |||
+ | |||
+ | module=foo |
||
+ | module=bar |
||
+ | module=baz@2009-01-05 |
||
+ | module=~/mymodules/myfoo.yang |
||
+ | |||
+ | |||
+ | * The '''ncxmod_find_sil_file''' function in '''ncx/ncxmod.c''' is used to find the library code associated with the each module name. The following search sequence is followed: |
||
+ | ** Check the '''$YUMA_HOME/target/lib''' directory |
||
+ | ** Check each directory in the '''$YUMA_RUNPATH''' environment variable or '''--runpath''' configuration variable. |
||
+ | ** Check the''' /usr/lib/yuma''' directory |
||
+ | * If the module parameter contains any sub-directories or a file extension, then it is treated as a file, and the module search path will not be used. Instead the absolute or relative file specification will be used. |
||
+ | * If the first term starts with an environment variable or the tilde (~) character, and will be expanded first |
||
+ | * If the 'at sign' (@) followed by a revision date is present, then that exact revision will be loaded. |
||
+ | * If no file extension or directories are specified, then the module search path is checked for YANG and YIN files that match. The first match will be used, which may not be the newest, depending on the actual search path sequence. |
||
+ | * The '''$YUMA_MODPATH''' environment variable or '''--modpath''' configuration parameter can be used to configure one or more directory sub-trees to be searched. |
||
+ | * The '''$YUMA_HOME''' environment variable or '''--yuma-home''' configuration parameter can be used to specify the Yuma project tree to use if nothing is found in the currect directory or the module search path. |
||
+ | * The '''$YUMA_INSTALL''' environment variable or default Yuma install location (/usr/share/yuma/modules) will be used as a last resort to find a YANG or YIN file. |
||
+ | |||
+ | The server processes''' --module''' parameters by first checking if a dynamic library can be found which has an 'soname' that matches the module name. If so, then the SIL phase 1 initialization function is called, and that function is expected to call the ncxmod_load_module function. |
||
+ | |||
+ | |||
+ | If no SIL file can be found for the module, then the server will load the YANG module anyway, and support database operations for the module, for provisioning purposes. Any RPC operations defined in the module will also be accepted (depending on access control settings), but the action will not actually be performed. <nowiki>Only the input parameters will be checked, and <or> or some <rpc-error> returned.</nowiki> |
||
+ | |||
+ | === Core Module Initialization === |
||
+ | The '''agt_init2''' function in '''agt/agt.c''' is called after the configuration parameters have been collected. |
||
+ | |||
+ | * |
||
+ | ** Initialize the core server code modules |
||
+ | ** Static device-specific modules can be added to the agt_init2 function after the core modules have been initialized |
||
+ | ** Any 'module' parameters found in the CLI or server configuration file are processed. |
||
+ | ** The '''agt_cap_set_modules''' function in '''agt/agt_cap.c''' is called to set the initial module capabilities for the '''ietf-netconf-monitoring''' module |
||
+ | |||
+ | === Startup Configuration Processing === |
||
+ | After the static and dynamic server modules are loaded, the '''--startup''' (or '''--no-startup''') parameter is processed by '''agt_init2''' in '''agt/agt.c''': |
||
+ | |||
+ | * If the --startup parameter is used and includes any sub-directories, it is treated as a file and must be found, as specified. |
||
+ | * Otherwise, the '''$YUMA_DATAPATH '''environment variable or''' --datapath''' configuration parameter can be used to determine where to find the startup configuration file. |
||
+ | * If neither the '''--startup''' or '''--no-startup''' configuration parameter is present, then the data search path will be used to find the default '''startup-cfg.xml''' |
||
+ | * The '''$YUMA_HOME''' environment variable or --yuma-home configuration parameter is checked if no file is found in the data search path. The '''$YUMA_HOME/data''' directory is checked if this parameter is set. |
||
+ | * The '''$YUMA_INSTALL''' environment variable or default location (/etc/yuma/) is checked next, if the startup configuration is still not found. |
||
+ | |||
+ | It is a fatal error if a startup config is specified and it cannot be found. |
||
+ | |||
+ | As the startup configuration is loaded, any SIL callbacks that have been registered will be invoked for the association data present in the startup configuration file.. The edit operation will be OP_EDITOP_LOAD during this callback. |
||
+ | |||
+ | After the startup configuration is loaded into the running configuration database, all the stage 2 initialization routines are called. These are needed for modules which add read-only data nodes to the tree containing the running configuration. SIL modules may also use their 'init2' function to create factory default configuration nodes (which can be saved for the next reboot). |
||
+ | |||
+ | === Process an Incoming <rpc> Request === |
||
+ | [[Image:]] |
||
+ | |||
+ | * '''PARSE Phase:''' The incoming buffer is converted to a stream of XML nodes, using the '''xmlTextReader''' functions from '''libxml2'''. The agt_val_parse function is used to convert the stream of XML nodes to a '''val_value_t''' structure, representing the incoming request according to the YANG definition for the RPC operation. An '''rpc_msg_t''' structure is also built for the request. |
||
+ | * '''VALIDATE Phase: '''If a message is parsed correctly,''' '''then the incoming message is validated according to the YANG machine-readable constraints. Any description statement constraints need to be checked with a callback function. The''' agt_rpc_register_method''' function in '''agt/agt_rpc.c''' is used to register callback functions. |
||
+ | * '''INVOKE Phase: '''If the message is validated correctly, then the invoke callback is executed. This is usually the only required callback function. Without it, the RPC operation has no affect. This callback will set fields in the '''rpc_msg_t'''<nowiki> header that will allow the server to construct or stream the <rpc-reply> message back to the client.</nowiki> |
||
+ | * '''REPLY Phase: '''<nowiki>Unless some catastrophic error occurs, the server will generate an <rpc-reply> response. </nowiki><nowiki>If any <rpc-error> elements are needed, they are generated first. </nowiki>If there is any response data to send, that is generated or streamed (via callback function provided earlier) at this time. Any unauthorized data (according to to the '''yuma-nacm.yang''' module configuration) will be silently dropped from the message payload. <nowiki>If there were no errors and no data to send, then an <ok> resonse is generated.</nowiki> |
||
+ | * '''POST_REPLY Phase: '''After the response has been sent, a rarely-used callback function can be invoked to cleanup any memory allocation or other data-model related tasks. For example, if the''' rpc_user1''' or '''rpc_user2''' pointers in the message header contain allocated memory then they need to be freed at this time. |
||
+ | |||
+ | === Edit the Database === |
||
+ | [[Image:]] |
||
+ | |||
+ | * '''Validate Phase:''' The server will determine the edit operation and the actual nodes in the target database (candidate or running) that will be affected by the operation. All of the machine-readable YANG statements which apply to the affected node(s) are tested against the incoming PDU and the target database. If there are no errors, the server will search for a SIL validate callback function for the affected node(s). If the SIL code has registered a database callback function for the node or its local ancestors, it will be invoked. This SIL callback function usually checks additional constraints that are contained in the YANG description statements for the database objects. |
||
+ | * '''Test-Apply and Apply Phase:''' If the validate phase completes without errors, then the requested changes are applied to the target database. If the target database is the running configuration, or if the edit-config 'test-option' parameter is set to 'test-then-set' (the default if '''--with-validate'''<nowiki>=true), then the test-apply phase is executed first. </nowiki>This is essentially the same as the real apply phase, except that changes are made to a copy of the target database. Once all objects have been altered as requested, the entire test database is validated, including all cross-referential integrity tests. If this test completes without any errors, then the procedure is repeated on the real target database. |
||
+ | ** Note: This phase is used for the internal data tree manipulation and validation only. It is not used to alter device behavior. Resources may need to be reserved during the SIL apply callback, but the database changes are not activated at this time. |
||
+ | * '''Commit or Rollback Phase:''' If the validate and apply phases complete without errors, then then the server will search for SIL commit callback functions for the affected node(s) in the target database. This SIL callback phase is used to apply the changes to the device and/or network. It is only called when a commit procedure is attempted. <nowiki>This can be due to a <commit> operation, or an <edit-config> or <copy-config> operation on the running database.</nowiki> |
||
+ | ** Note: If there are errors during the commit phase, then the backup configuration will be applied, and the server will search for a SIL callback to invoke with a 'rollback operation'. The same procedure is used for confirmed commit operations which timeout or canceled by the client. |
||
+ | |||
+ | === Save the Database === |
||
+ | The following bullets describe how the server saves configuration changes to non-volatile storage: |
||
+ | |||
+ | * If the '''--with-startup=true''' parameter is used, then the server will support the :startup capability. <nowiki>In this case, the <copy-config> command needs to be used to cause the running configuration to be saved.</nowiki> |
||
+ | * If the '''--with-startup=false''' parameter is used, then the server will not support the :startup capability. In this case, the database will be saved each time the running configuration is changed. |
||
+ | * <nowiki>The <copy-config> or <commit> operations will cause the startup configuration file to be saved, even if nothing has changed. </nowiki>This allows an operator to replace a corrupted or missing startup configuration file at any time. |
||
+ | * The database is saved with the '''agt_ncx_cfg_save '''function in '''agt/agt_ncx.c.''' |
||
+ | * The '''with-defaults''' 'explicit' mode is used during the save operation to filter the database contents. |
||
+ | ** Any values that have been set by the client will be saved in NV-storage. |
||
+ | ** Any value set by the server to a YANG default value will not be saved in the database. |
||
+ | ** If the server create a node that does not have a YANG default value (e.g., containers, lists, keys), then this node will be saved in NV storage. |
||
+ | * If the '''--startup=filespec''' parameter is used, then the server will save the database by overwriting that file. The file will be renamed to backup-cfg.xml first. |
||
+ | * If the '''--no-startup''' parameter is used, or no startup file is specified and no default is found, then the server will create a file called 'startup-cfg.xml', in the following manner: |
||
+ | ** If the '''$YUMA_HOME''' variable is set, the configuration will be saved in '''$YUMA_HOME/data/startup-cfg.xml'''. |
||
+ | ** Otherwise, the configuration will be saved in''' $HOME/.yuma'''/'''startup-cfg.xml.''' |
||
+ | * <nowiki>The database is saved as an XML instance document, using the <config> element in the NETCONF 'base' namespace as the root element. </nowiki><nowiki>Each top-level YANG module supported by the server, which contains some explicit configuration data, will be saved as a child node of the <nc:config> element. </nowiki>There is no particular order to the top-level data model elements. |
||
+ | |||
+ | == Built-in Server Modules == |
||
+ | There are several YANG modules which are implemented within the server, and not loaded at run-time like a dynamic SIL module. Some of them are NETCONF standard modules and some are Yuma extension modules. |
||
+ | |||
+ | === ietf-inet-types.yang === |
||
+ | This module contains the standard YANG Internet address types. These types are available for commonly used management object types. A YANG module author should check this module first, before creating any new data types with the YANG typedef statement. |
||
+ | |||
+ | There are no accessible objects in this module, so there are no SIL callback functions. The YANG data-types are supported within the Yuma engine core modules, such as '''ncx/val.c '''and '''ncx/xml_wr.c.''' |
||
+ | |||
+ | === ietf-netconf-monitoring.yang === |
||
+ | The standard NETCONF Monitoring module is used to examine the capabilities, current state, and statistics related to the NETCONF server. The entire module is supported. |
||
+ | |||
+ | This module is also used to retrieve the actual YANG or YIN files (or URLs for them) that the server is using. <nowiki>Clients can use the <get-schema> RPC operation to retrieve the YANG or YIN files listed in the </nowiki>'''/netconf-state/schemas''' subtree. <nowiki>A client will normally check the <hello> message from the server for module capabilities, and use its own local copy of a server YANG module, if it can. </nowiki><nowiki>If not, then the <get-schema> function can be used to retrieve the YANG module.</nowiki> |
||
+ | |||
+ | The '''agt/agt_state.c''' contains the SIL callback functions for this module. |
||
+ | |||
+ | === ietf-with-defaults.yang === |
||
+ | <nowiki>The standard <with-defaults> extension to some NETCONF operations is defined in this module. </nowiki><nowiki>This parameter is added to the <get>, <get-config>, and <copy-config> operations to let the client control how 'default leafs' are returned by the server. </nowiki>The Yuma server can be configured to use any of the default handling styles (report-all, trim, or explicit). The filtering of default nodes is handled automatically by the server support functions in '''agt/agt_util.c''', and the XML write functions in''' ncx/xml_wr.c.''' |
||
+ | |||
+ | === ietf-yang-types.yang === |
||
+ | This module contains the standard YANG general user data types. These types are available for commonly used derived types. A YANG module author should check this module first, before creating any new data types with the YANG typedef statement. |
||
+ | |||
+ | There are no accessible objects in this module, so there are no SIL callback functions. The YANG data-types are supported within the Yuma engine core modules, such as '''ncx/val.c''' and '''ncx/xml_wr.c.''' |
||
+ | |||
+ | === nc-notifications.yang === |
||
+ | This module is defined in RFC 5277, the NETCONF Notifications specification. <nowiki>It contains the <replayComplete> and <notificationComplete> notification event definitions.</nowiki> |
||
+ | |||
+ | The file '''agt/agt_not.c''' contains the SIL support code for this module. |
||
+ | |||
+ | === notifications.yang === |
||
+ | This module is defined in RFC 5277, the NETCONF Notifications specification. All of this RFC is supported in the server. <nowiki>This module contains the <create-subscription> RPC operation. </nowiki>The notification replay feature is controlled with the '''--eventlog-size''' configuration parameter. <nowiki>The <create-subscription> operation is fully supported, including </nowiki>XPath and subtree filters. The '''yuma-nacm''' module can be used to control what notification events a user is allowed to receive. <nowiki>The <create-subscription> filter allows the client to select which notification events it wants to receive.</nowiki> |
||
+ | |||
+ | The file''' agt/agt_not.c '''contains the SIL callback functions for this modules. |
||
+ | |||
+ | === yuma-app-common.yang === |
||
+ | This module contains some common groupings of CLI parameters supported by some or all Yuma programs. Each program with CLI parameters defines its own module of CLI parameters (using the ncx:cli extension). The program name is used for the YANG module name as well (e.g., yangdump.yang or netconfd.yang). |
||
+ | |||
+ | The SIL callback functions for the common groupings in this module are found in '''ncx/val_util.c''', such as the '''val_set_feature_parms''' function. |
||
+ | |||
+ | === yuma-interfaces.yang === |
||
+ | This module contains the Yuma interfaces table, which is just a skeleton configuration list, plus some basic interface counters. This module is intended to provide an example for embedded developers to replace this module with their own interfaces table. The Yuma table uses information in some files found in Unix systems which support the '''/proc/net/dev''' system file. |
||
+ | |||
+ | The file '''agt/agt_if.c''' contains the SIL callback functions for this module. |
||
+ | |||
+ | === yuma-mysession.yang === |
||
+ | <nowiki>This module provides the Yuma proprietary <get-my-session> and <set-my-session> RPC operations. </nowiki>These are used by the client to set some session output preferences, such as the desired line length, indentation amount, and defaults handling behavior. |
||
+ | |||
+ | The file '''agt/agt_ses.c''' contains the SIL callback functions for this module. |
||
+ | |||
+ | === yuma-nacm.yang === |
||
+ | This module contains the Yuma NETCONF Access Control Model implementation. It provides all user-configurable access control settings and also provides API functions to check if a specific access request should be allowed or not. |
||
+ | |||
+ | The file '''agt/agt_acm.c''' contains the SIL callback functions for this module. |
||
+ | |||
+ | === yuma-ncx.yang === |
||
+ | This module provides the YANG language extension statements that are used by Yuma programs to automate certain parts of the NETCONF protocol, document generation, code generation, etc. |
||
+ | |||
+ | There are no SIL callback functions for this module. There are support functions within the '''src/ncx''' directory that include the '''obj_set_ncx_flags''' function in '''ncx/obj.c''' |
||
+ | |||
+ | === yuma-netconf.yang === |
||
+ | The NETCONF protocol operations, message structures, and error information are all data-driven, based on the YANG statements in the''' yuma-netconf.yang''' module. The ietf-netconf.yang module is not used at this time because it does not contain the complete set of YANG statements needed. The yuma-netconf.yang version is a super-set of the IETF version. Only one YANG module can be associated with an XML namespace in Yuma. In a future version, the extra data structures will be moved to an annotation module. |
||
+ | |||
+ | The file '''agt/agt_ncx.c''' contains the SIL callback functions for this module. |
||
+ | |||
+ | This module is not advertised in the server capabilities. It is only used internally within the server. |
||
+ | |||
+ | === yuma-proc.yang === |
||
+ | This module provides some Unix '''/proc''' file-system data, in nested XML format. This module will not load if the files '''/proc/meminfo''' and '''/proc/cpuinfo''' are not found. |
||
+ | |||
+ | The file '''agt/agt_proc.c''' contains the SIL callback functions for this module. |
||
+ | |||
+ | === yuma-system.yang === |
||
+ | This module contains the Yuma '''/system''' data structure, providing basic server information, unix 'uname' data, and all the Yuma proprietary notification event definitions. |
||
+ | |||
+ | The file '''agt/agt_sys.c''' contains the SIL callback functions for this module. |
||
+ | |||
+ | === yuma-time-filter.yang === |
||
+ | This module contains the Yuma '''last-modified''' leaf, which extends the standard '''/netconf-state/datastores/datastore '''structure in '''ietf-netconf-monitoring.yang,''' with the database last-modified timestamp. <nowiki>The standard <get> and <get-config> operations are augmented with the </nowiki>'''if-modified-since''' leaf, to allow all-or-none filtering of the configuration, based on its modification timestamp. |
||
+ | |||
+ | The file '''agt/agt_sys.c''' contains the SIL callback functions for this module. |
||
+ | |||
+ | === yuma-types.yang === |
||
+ | This module provides some common data types that are used by other Yuma YANG modules. |
||
+ | |||
+ | There are no SIL callback functions for this module. |
||
+ | |||
+ | = YANG Objects and Data Nodes = |
||
+ | This section describes the basic design of the YANG object tree and the corresponding data tree that represents instances of various object nodes that the client or the server can create. |
||
+ | |||
+ | == Object Definition Tree == |
||
+ | The object tree is a tree representation of all the YANG module rpc, data definition, and notification statements. It starts with a 'root' container. This is defined with a YANG container statement which has an''' ncx:root '''extension statement within it. <nowiki>The <config> parameter within the <edit-config> operation is an example of an object node which is treated as a root container. </nowiki><nowiki>Each configuration database maintained by the server (e.g., <candidate> and <running>) has a root container value node as its top-level object.</nowiki> |
||
+ | |||
+ | A root container does not have any child nodes defined in it within the YANG file. However, the Yuma tools will treat this special container as if any top-level YANG data node is allowed to be a child node of the 'root' container type. |
||
+ | |||
+ | === Object Node Types === |
||
+ | There are 14 different YANG object node types, and a discriminated union of sub-data structures contains fields common to each sub-type. Object templates are defined in ncx/obj.h. |
||
+ | |||
+ | |||
+ | <center>'''YANG Object Types'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | | style="border-top:0.05pt solid #000000;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| <center>'''object type'''</center> |
||
+ | | style="border:0.05pt solid #000000;padding:0.0382in;"| <center>'''description'''</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_ANYXML |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG '''anyxml''' data node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_CONTAINER |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG presence or non-presence '''container.''' |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_CONTAINER + ncx:root |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| If the ncx:root extension is present within a container definition, then the object represents a NETCONF database '''root'''. No child nodes |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_LEAF |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG '''leaf''' data node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_LEAF_LIST |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG''' leaf-list''' data node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_LIST |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG '''list''' data node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_CHOICE |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG '''choice''' schema node. The only children allowed are case objects. |
||
+ | |||
+ | This object does not have instances in the data tree. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_CASE |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG '''case''' schema node. This object does not have instances in the data tree. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_USES |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG '''uses''' schema node. The contents of the grouping it represents will be expanded into object tree. It is saved in the object tree even during operation, in order for the expanded objects to share common data. This object does not have instances in the data tree. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_REFINE |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG '''refine''' statement. It is used to alter the grouping contents during the expansion of a uses statement. This object is only allowed to be a child of a uses statement. It does not have instances in the data tree. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_AUGMENT |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG '''augment''' statement. It is used to add additional objects to an existing data structure. This object is only allowed to be a child of a uses statement or a child of a 'root' container. It does not have instances in the data tree, however any children of the augment node will generate object nodes that have instances in the data tree. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_RPC |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG '''rpc''' statement. <nowiki>It is used to define new <rpc> operations. </nowiki>This object will only appear as a child of a 'root' container. It does not have instances in the data tree. Only 'rpcio' nodes are allowed to be children of an RPC node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_RPCIO |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG '''input '''or''' output''' statement. <nowiki>It is used to define new <rpc> operations. </nowiki>This object will only appear as a child of an RPC node. It does not have instances in the data tree. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_NOTIF |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This object represents a YANG '''notification''' statement. <nowiki>It is used to define new <notification> event types. </nowiki>This object will only appear as a child of a 'root' container. It does not have instances in the data tree. |
||
+ | |||
+ | |} |
||
+ | === Object Node Template (obj_template_t) === |
||
+ | The following typedef is used to represent an object tree node: |
||
+ | |||
+ | |||
+ | /* One YANG data-def-stmt */ |
||
+ | typedef struct obj_template_t_ { |
||
+ | dlq_hdr_t qhdr; |
||
+ | obj_type_t objtype; |
||
+ | uint32 flags; /* see OBJ_FL_* definitions */ |
||
+ | ncx_error_t tkerr; |
||
+ | grp_template_t *grp; /* non-NULL == in a grp.datadefQ */ |
||
+ | |||
+ | /* 4 back pointers */ |
||
+ | struct obj_template_t_ *parent; |
||
+ | struct obj_template_t_ *usesobj; |
||
+ | struct obj_template_t_ *augobj; |
||
+ | struct xpath_pcb_t_ <nowiki>*when; </nowiki> /* optional when clause */ |
||
+ | dlq_hdr_t metadataQ; /* Q of obj_metadata_t */ |
||
+ | dlq_hdr_t appinfoQ; /* Q of ncx_appinfo_t */ |
||
+ | dlq_hdr_t iffeatureQ; /* Q of ncx_iffeature_t */ |
||
+ | |||
+ | /* cbset is agt_rpc_cbset_t for RPC or agt_cb_fnset_t for OBJ */ |
||
+ | void <nowiki>*cbset; </nowiki> |
||
+ | |||
+ | /* object namespace ID assigned at runtime |
||
+ | <nowiki>* this can be changed over and over as a</nowiki> |
||
+ | <nowiki>* uses statement is expanded. </nowiki> The final |
||
+ | <nowiki>* expansion into a real object will leave</nowiki> |
||
+ | <nowiki>* the correct value in place</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | xmlns_id_t nsid; |
||
+ | |||
+ | union def_ { |
||
+ | obj_container_t <nowiki>*container;</nowiki> |
||
+ | obj_leaf_t <nowiki>*leaf;</nowiki> |
||
+ | obj_leaflist_t <nowiki>*leaflist;</nowiki> |
||
+ | obj_list_t <nowiki>*list;</nowiki> |
||
+ | obj_choice_t <nowiki>*choic;</nowiki> |
||
+ | obj_case_t <nowiki>*cas;</nowiki> |
||
+ | obj_uses_t <nowiki>*uses;</nowiki> |
||
+ | obj_refine_t <nowiki>*refine;</nowiki> |
||
+ | obj_augment_t <nowiki>*augment;</nowiki> |
||
+ | obj_rpc_t <nowiki>*rpc;</nowiki> |
||
+ | obj_rpcio_t <nowiki>*rpcio;</nowiki> |
||
+ | obj_notif_t <nowiki>*notif;</nowiki> |
||
+ | } def; |
||
+ | |||
+ | } obj_template_t; |
||
+ | |||
+ | The following table highlights the fields within the obj_template_t data structure: |
||
+ | |||
+ | |||
+ | <center>'''obj_template_t Fields'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Field</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| qhdr |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Queue header to allow the object template to be stored in a child queue |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| objtype |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| enumeration to identify which variant of the 'def' union is present |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| flags |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal state and properties |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| tkerr |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Error message information |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| grp |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| back-pointer to parent group if this is a top-level data node within a grouping |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| parent |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Parent node if any |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| usesobj |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Back pointer to uses object if this is a top-level data node within an expanded grouping |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| augobj |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Back pointer to augment object if this is a top-level data node within an expanded augment |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| when |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XPath structure for YANG when statement |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| metadataQ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Queue of obj_template_t for any XML attributes (ncx:metadata) defined for this object node |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| appinfoQ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Queue of ncx_appinfo_t for any YANG extensions found defined within the object, that were not collected within a deeper appinfoQ (e.g., within a type statement) |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| iffeatureQ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Queue of ncx_iffeature_t for any if-feature statements found within this object node |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cbset |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Set of server callback functions for this object node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| nsid |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Object node namespace ID assigned by xmlns.c |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| def |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Union of object type specific nodes containing the rest of the YANG statements. Note that the server discards all descriptive statements such as description, reference, contact,. |
||
+ | |||
+ | |} |
||
+ | === obj_template_t Access Functions === |
||
+ | The file '''ncx/obj.h''' contains many API functions so that object properties do not have to be accessed directly. The following table highlights the most commonly used functions. Refer to the H file for a complete definition of each API function. |
||
+ | |||
+ | |||
+ | <center>'''obj_template_t Access Functions'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Function</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_find_template |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Find a top-level object template within a module |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_find_child |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Find the specified child node within a complex object template . Skips over any nodes without names (augment, uses, etc.) |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_first_child |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the first child node within a complex object template . Skips over any nodes without names. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_next_child |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the next child node after the current specified child. Skips over any nodes without names. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_first_child_deep |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the first child node within a complex object template . Skips over any nodes without names, and also any choice and case nodes. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_next_child_deep |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the next child node after the current specified child. Skips over any nodes without names, and also any choice and case nodes. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_find_case |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Find the specified case object child node within the specific complex object node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_find_type |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if a typ_template_t in the obj typedefQ hierarchy. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_find_grouping |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if a grp_template_t in the obj typedefQ hierarchy. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_find_key |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Find a specific key component by key leaf identifier name |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_first_key |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the first obj_key_t struct for the specified list object type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_next_key |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the next obj_key_t struct for the specified list object type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_gen_object_id |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Allocate and generate the YANG object ID for an object node |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_name |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the object name string |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_has_name |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object has a name field |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_has_text_content |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object has text content |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_status |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the YANG status for the object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_description |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the YANG description statement for an object. Note that the server will always return a NULL pointer. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_reference |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the YANG reference statement for an object. Note that the server will always return a NULL pointer. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_config_flag |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the YANG config statement value for an object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_typestr |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the name string for the type of an object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_default |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the YANG default value for an object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_default_case |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the name of the default case for a choice object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_typdef |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the internal type definition for the leaf or leaf-list object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_basetype |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the internal base type enumeration for an object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_mod_prefix |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the module prefix for an object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_mod_name |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the module name containing an object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_mod_version |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the module revision date for the module containing an object. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_nsid |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the internal XML namespace ID for an object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_min_elements |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the YANG min-elements value for a list or leaf-list object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_max_elements |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the YANG max-elements value for a list or leaf-list object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_units |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the YANG units field for a leaf or leaf-list object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_parent |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the parent object node for an object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_presence_string |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the YANG presence statement for a container object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_child_count |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the number of child nodes for a complex object. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_get_fraction_digits |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the YANG fraction-digits statement for a decimal64 leaf or leaf-list object |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_leafy |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object is a leaf or leaf-list type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_mandatory |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object is YANG mandatory |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_mandatory_when |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object is YANG mandatory, but first check if any when statements are FALSE first |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_cloned |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object is expanded from a grouping or augment statement |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_data_db |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object is defined within a YANG database definition |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_in_rpc |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object is defined within an RPC statement |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_in_notif |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object is defined within a notification statement |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_hidden |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if object contains the ncx:hidden extension |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_root |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if object contains the ncx:root extension |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_password |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if object contains the ncx:password extension |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_cli |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if object contains the ncx:cli extension |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_abstract |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if object contains the ncx:abstract extension |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_xpath_string |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object is a leaf or leaf-list containing an XPath string |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_schema_instance_string |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object is a leaf or leaf-list containing a schema instance identifier string |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_secure |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if object contains the nacm:secure extension |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_very_secure |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if object contains the nacm:very-secure extension |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_system_ordered |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the list or leaf-list object is system ordered; FALSE if it is user ordered |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_np_container |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object is a YANG non presence container |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_is_enabled |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the object is enabled; FALSE if any if-feature, when-stmt, or deviation-stmt has removed the object from the system. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_sort_children |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Rearrange any child nodes in YANG schema order |
||
+ | |||
+ | |} |
||
+ | == Data Tree == |
||
+ | A Yuma data tree is a representation of some subset of all possible object instances that a server is maintaining within a configuration database or other structure. |
||
+ | |||
+ | Each data tree starts with a 'root' container, and any child nodes represent top-level YANG module data nodes that exist within the server. |
||
+ | |||
+ | Each configuration database maintains its own copy (and version) of the data tree. There is only one object tree, however, and all data trees use the same object tree for reference. |
||
+ | |||
+ | Not all object types have a corresponding node within a data tree. Only 'real' data nodes are present. Object nodes that are used as meta-data to organize the object tree (e.g., choice, augment) are not present. The following table lists the object types and whether each one is found in a data tree. |
||
+ | |||
+ | |||
+ | <center>'''Object Types in the Data Tree'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Object Type</center> |
||
+ | ! <center>Found In Data Tree?</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_ANYXML |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yes |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_CONTAINER |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yes |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_CONTAINER (ncx:root) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yes |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_LEAF |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yes |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_LEAF_LIST |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yes |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_LIST |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Yes |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_CHOICE |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| No |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_CASE |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| No |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_USES |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| No |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_REFINE |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| No |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_AUGMENT |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| No |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_RPC |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| No |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_RPCIO |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| No |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| OBJ_TYP_NOTIF |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| No |
||
+ | |||
+ | |} |
||
+ | === Data Node Types === |
||
+ | The '''ncx_btype_t''' enumeration in '''ncx/ncxtypes.h''' is used within each '''val_value_t''' to quickly identify which variant of the data node structure is being used. |
||
+ | |||
+ | The following table describes the different enumeration values: |
||
+ | |||
+ | |||
+ | <center>'''Yuma Data Types (ncx_btype_t)'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Data Type</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_NONE |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| No type has been set yet. The val_new_value() function has been called but no specific init function has been called to set the base type. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_ANY |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The node is a YANG 'anyxml' node. When the client or server parses an 'anyxml' object, it will be converted to containers and strings. This type should not be used directly. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_BITS |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'bits' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_ENUM |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'enumeration' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_EMPTY |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'empty' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_BOOLEAN |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'boolean' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_INT8 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'int8' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_INT16 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'int16' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_INT32 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'int32' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_INT64 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'int64' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_UINT8 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'uint8' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_UINT16 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'uint16' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_UINT32 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'uint32' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_UINT64 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'uint64' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_DECIMAL64 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'decimal64' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_FLOAT64 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Hidden double type, used just for XPath. If the HAS_FLOAT #define is false, then this type will be implemented as a string, not a double. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_STRING |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'string' type. There are also some Yuma extensions that are used with this data type for special strings. The server needs to know if a string contains XML prefixes or not, and there are several flavors to automatate processing of each one correctly. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_BINARY |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'binary' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_INSTANCE_ID |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'instance-identifier' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_UNION |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'union' data type. This is a meta-type. When the client or server parses a value, it will resolve the union to one of the data types defined within the union. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_LEAFREF |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'leafref' data type. This is a meta-type. The client or server will resolve this data type to the type of the actual 'pointed-at' leaf that is being referenced. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_IDREF |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG 'identityref' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_SLIST |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XSD list data type (ncx:xsdlist extension) |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_CONTAINER |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG container |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_CHOICE |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG choice. This is a meta-type and placeholder. It does not appear in the data tree. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_CASE |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG case. This is a meta-type and placeholder. It does not appear in the data tree. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_LIST |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG list |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_EXTERN |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal 'external' data type, used in yangcli. It indicates that the content is actually in an external file. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NCX_BT_INTERN |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal 'buffer' data type, used in yangcli. The content is actually stored verbatim in an internal buffer. |
||
+ | |||
+ | |} |
||
+ | === Yuma Data Node Edit Variables (val_editvars_t) === |
||
+ | There is a temporary data structure which is attached to a data node while editing operations are in progress, called '''val_editvars_t'''. <nowiki>This structure is used by the functions in agt/agt_val.c to manipulate the value tree nodes during an <edit-config>, <copy-config>, <load-config>, or <commit> operation.</nowiki> |
||
+ | |||
+ | The SIL callback functions may wish to refer to the fields in this data structure. There is also a SIL cookie field to allow data to be transferred from one callback stage to the later stages. For example, if an edit operation caused the device instrumentation to reserve some memory, then this cookie could store that pointer. |
||
+ | |||
+ | The following typedef is used to define the val_editvars_t structure: |
||
+ | |||
+ | |||
+ | /* one set of edit-in-progress variables for one value node */ |
||
+ | typedef struct val_editvars_t_ { |
||
+ | /* these fields are only used in modified values before they are |
||
+ | <nowiki>* actually added to the config database (TBD: move into struct)</nowiki> |
||
+ | <nowiki>* curparent == parent of curnode for merge</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | struct val_value_t_ <nowiki>*curparent; </nowiki> |
||
+ | op_editop_t editop; /* effective edit operation */ |
||
+ | op_insertop_t insertop; /* YANG insert operation */ |
||
+ | xmlChar <nowiki>*insertstr; </nowiki> /* saved value or key attr */ |
||
+ | struct xpath_pcb_t_ *insertxpcb; /* key attr for insert */ |
||
+ | struct val_value_t_ *insertval; /* back-ptr */ |
||
+ | boolean iskey; /* T: key, F: value */ |
||
+ | boolean operset; /* nc:operation here */ |
||
+ | void <nowiki>*pcookie; </nowiki> /* user pointer cookie */ |
||
+ | int icookie; /* user integer cookie */ |
||
+ | } val_editvars_t; |
||
+ | |||
+ | The following fields within the val_editvars_t are highlighted: |
||
+ | |||
+ | <center>'''val_editvars_t Fields'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Field</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| curparent |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| A 'new' node will use this field to remember the parent of the 'current' value. This is needed to support the YANG insert operation. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| editop |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The effective edit operation for this node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| insertop |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The YANG insert operation, if any. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| insertstr |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The YANG 'value' or 'key' attribute value string, used to support the YANG insert operation. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| insertxpcb |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XPath parser control block for the insert 'key' expression, if needed. Used to support the YANG insert operation. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| insertval |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Back pointer to the value node to insert ahead of, or behind, if needed. Used to support the 'before' and 'after' modes of the YANG insert operation. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| iskey |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| TRUE if this is a key leaf. FALSE otherwise. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| operset |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| TRUE if there was an nc:operation attribute found in this node; FALSE if the 'editop' is derived from its parent. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| pcookie |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| SIL user pointer cookie. Not used by the server. Reserved for SIL callback code. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| icookie |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| SIL user integer cookie. Not used by the server. Reserved for SIL callback code. |
||
+ | |||
+ | |} |
||
+ | === Yuma Data Nodes (val_value_t) === |
||
+ | The '''val_value_t'''<nowiki> data structure is used to maintain the internal representation of all NETCONF databases, non-configuration data available with the <get> operation, all RPC operation input and output parameters, and all notification contents.</nowiki> |
||
+ | |||
+ | The following typedef is used to define a value node: |
||
+ | |||
+ | |||
+ | /* one value to match one type */ |
||
+ | typedef struct val_value_t_ { |
||
+ | dlq_hdr_t qhdr; |
||
+ | |||
+ | /* common fields */ |
||
+ | struct obj_template_t_ *obj; /* bptr to object def */ |
||
+ | typ_def_t *typdef; /* bptr to typdef if leaf */ |
||
+ | const xmlChar <nowiki>*name; </nowiki> /* back pointer to elname */ |
||
+ | xmlChar <nowiki>*dname; </nowiki> /* AND malloced name if needed */ |
||
+ | struct val_value_t_ *parent; /* back-ptr to parent if any */ |
||
+ | xmlns_id_t nsid; /* namespace ID for this node */ |
||
+ | ncx_btype_t btyp; /* base type of this value */ |
||
+ | |||
+ | uint32 flags; /* internal status flags */ |
||
+ | ncx_data_class_t dataclass; /* config or state data */ |
||
+ | |||
+ | /* YANG does not support user-defined meta-data but NCX does. |
||
+ | <nowiki>* The <edit-config>, <get> and <get-config> operations </nowiki> |
||
+ | <nowiki>* use attributes in the RPC parameters, the metaQ is still used</nowiki> |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* The ncx:metadata extension allows optional attributes</nowiki> |
||
+ | <nowiki>* to be added to object nodes for anyxml, leaf, leaf-list,</nowiki> |
||
+ | <nowiki>* list, and container nodes. </nowiki> The config property will |
||
+ | <nowiki>* be inherited from the object that contains the metadata</nowiki> |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* This is used mostly for RPC input parameters</nowiki> |
||
+ | <nowiki>* and is strongly discouraged. </nowiki> Full edit-config |
||
+ | <nowiki>* support is not provided for metdata</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | dlq_hdr_t metaQ; /* Q of val_value_t */ |
||
+ | |||
+ | /* value editing variables */ |
||
+ | val_editvars_t <nowiki>*editvars; </nowiki> /* edit-in-progress vars */ |
||
+ | status_t res; /* validationt result */ |
||
+ | |||
+ | /* Used by Agent only: |
||
+ | <nowiki>* if this field is non-NULL, then the entire value node</nowiki> |
||
+ | <nowiki>* is actually a placeholder for a dynamic read-only object</nowiki> |
||
+ | <nowiki>* and all read access is done via this callback function;</nowiki> |
||
+ | <nowiki>* the real data type is getcb_fn_t *</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | void *getcb; |
||
+ | |||
+ | /* if this field is non-NULL, then a malloced value struct |
||
+ | <nowiki>* representing the real value retrieved by </nowiki> |
||
+ | <nowiki>* val_get_virtual_value, is cached here for XPath filtering</nowiki> |
||
+ | <nowiki>* TBD: add timestamp to reuse cached entries for some time</nowiki> |
||
+ | <nowiki>* period</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | struct val_value_t_ *virtualval; |
||
+ | |||
+ | /* these fields are used for NCX_BT_LIST */ |
||
+ | struct val_index_t_ *index; /* back-ptr/flag in use as index */ |
||
+ | dlq_hdr_t indexQ; /* Q of val_index_t or ncx_filptr_t */ |
||
+ | |||
+ | /* this field is used for NCX_BT_CHOICE |
||
+ | <nowiki>* If set, the object path for this node is really:</nowiki> |
||
+ | <nowiki>* </nowiki> $this --> casobj --> casobj.parent --> $this.parent |
||
+ | <nowiki>* the OBJ_TYP_CASE and OBJ_TYP_CHOICE nodes are skipped</nowiki> |
||
+ | <nowiki>* inside an XML instance document</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | struct obj_template_t_ <nowiki>*casobj;</nowiki> |
||
+ | |||
+ | /* these fields are for NCX_BT_LEAFREF |
||
+ | <nowiki>* NCX_BT_INSTANCE_ID, or tagged ncx:xpath </nowiki> |
||
+ | <nowiki>* value stored in v union as a string</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | struct xpath_pcb_t_ <nowiki>*xpathpcb;</nowiki> |
||
+ | |||
+ | /* union of all the NCX-specific sub-types |
||
+ | <nowiki>* note that the following invisible constructs should</nowiki> |
||
+ | <nowiki>* never show up in this struct:</nowiki> |
||
+ | <nowiki>* </nowiki> NCX_BT_CHOICE |
||
+ | <nowiki>* </nowiki> NCX_BT_CASE |
||
+ | <nowiki>* </nowiki> NCX_BT_UNION |
||
+ | <nowiki>*/</nowiki> |
||
+ | union v_ { |
||
+ | /* complex types have a Q of val_value_t representing |
||
+ | * the child nodes with values |
||
+ | * NCX_BT_CONTAINER |
||
+ | * NCX_BT_LIST |
||
+ | */ |
||
+ | dlq_hdr_t childQ; |
||
+ | |||
+ | /* Numeric data types: |
||
+ | * NCX_BT_INT8, NCX_BT_INT16, |
||
+ | * NCX_BT_INT32, NCX_BT_INT64 |
||
+ | * NCX_BT_UINT8, NCX_BT_UINT16 |
||
+ | * NCX_BT_UINT32, NCX_BT_UINT64 |
||
+ | * NCX_BT_DECIMAL64, NCX_BT_FLOAT64 |
||
+ | */ |
||
+ | ncx_num_t num; |
||
+ | |||
+ | /* String data types: |
||
+ | * NCX_BT_STRING |
||
+ | * NCX_BT_INSTANCE_ID |
||
+ | */ |
||
+ | |||
+ | ncx_str_t str; |
||
+ | val_idref_t idref; |
||
+ | ncx_binary_t binary; /* NCX_BT_BINARY */ |
||
+ | ncx_list_t list; /* NCX_BT_BITS, NCX_BT_SLIST */ |
||
+ | boolean boo; /* NCX_BT_EMPTY, NCX_BT_BOOLEAN */ |
||
+ | ncx_enum_t enu; /* NCX_BT_UNION, NCX_BT_ENUM */ |
||
+ | xmlChar <nowiki>*fname; </nowiki> /* NCX_BT_EXTERN */ |
||
+ | xmlChar <nowiki>*intbuff; </nowiki> /* NCX_BT_INTERN */ |
||
+ | } v; |
||
+ | } val_value_t; |
||
+ | |||
+ | The following table highlights the fields in this data structure: |
||
+ | |||
+ | <center>'''val_value_t Fields'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Field</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| qhdr |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal queue header to allow a value node to be stored in a queue. A complex node maintains a child queue of val_value_t nodes. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Back pointer to the object template for this data node |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| typdef |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Back pointer to the typedef structure if this is a leaf or leaf-list node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| name |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Back pointer to the name string for this node |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| dname |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Malloced name string if the client or server changed the name of this node, so the object node name is not being used. This is used for anyxml processing (and other things) to allow generic objects (container, string, empty, etc.) to be used to represent the contents of an 'anyxml' node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| parent |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Back pointer to the parent of this node, if any |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| nsid |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Namespace ID for this node. This may not be the same as the object node namespace ID, e.g., anyxml child node contents will override the generic object namespace. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| btyp |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The ncx_btype_t base type enumeration for this node. This is the final resolved value, in the event the object type is not a final resolved base type. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| flags |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal flags field. Do not access directly. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| dataclass |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal config or non-config enumeration |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| metaQ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Queue of val_value_t structures that represent any meta-variables (XML attributes) found for this data node. For example, the NETCONF filter <nowiki>'type' and 'select' attributes are defined for the <filter> element in yuma-netconf.yang.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| editvars |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Pointer to the malloced edit variables structure for this data node. This node will be freed (and NULL value) when the edit variables are not in use. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| res |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal validation result status for this node during editing or parsing. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| getcb |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal server callback function pointer. Used only if this is a 'virtual' node, and the actual value node contents are generated by a SIL callback function instead of being stored in the node itself. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| virtualval |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The temporary cached virtual node value, if the getcb pointer is non-NULL. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| indexQ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Queue of internal data structures used during parsing and filtering streamed output. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| casobj |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Back pointer to the OBJ_TYP_CASE object node for this data node, if this node is a top-level child of a YANG case statement. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xpathpcb |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XPath parser control block, used if this value contains some sort of XPath string or instance-identifier. <nowiki>For example, the XML namespace ID mappings are stored, so the XML prefix map generated for the <rpc-reply> will contain and reuse the proper namespace attributes, as needed.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| v |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Union of different internal fields, depending on the 'btyp' field value. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| v.childQ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Queue of val_value_t child nodes, if this is a complex node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| v.num |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| ncx_num_t for all numeric data types |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| v.str |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Malloced string value for the string data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| v.idref |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal data structure for the YANG identityref data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| v.binary |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal data structure for the YANG binary data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| v.list |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal data structure for YANG bits and NCX xsdlist data types |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| v.boo |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| YANG boolean data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| v.enu |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal data structure for YANG enumeration data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| v.fname |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| File name for NCX 'external' data type |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| v.intbuff |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Malloced buffer for 'internal' data type |
||
+ | |||
+ | |} |
||
+ | === val_value_t Access Macros === |
||
+ | There are a set of macros defined to access the fields within a val_value_t structure. |
||
+ | |||
+ | These should be used instead of accessing the fields directly. There are also functions defined as well. These macros are provided in addition the the access functions for quick access to the actual node value. These macros must only be used when the base type ('btyp') field has been properly set and known by the SIL code. Some auto-generated SIL code uses these macros. |
||
+ | |||
+ | The following table summarized the val_value_t macros that are defined in '''ncx/val.h''': |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Macro</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_BOOL(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access value for NCX_BT_BOOLEAN |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_EMPTY(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access value for NCX_BT_EMPTY |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_DOUBLE(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access value for NCX_BT_FLOAT64 |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_STRING(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access value for NCX_BT_STRING |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_BINARY(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access value for NCX_BT_BINARY |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_ENU(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access entire '''ncx_enum_t''' structure for NCX_BT_ENUM |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_ENUM(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access enumeration integer value for NCX_BT_ENUM |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_ENUM_NAME(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access enumeration name string for NCX_BT_ENUM |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_FLAG(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Deprecated: use VAL_BOOL instead |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_LONG(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access NCX_BT_INT64 value |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_INT(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access NCX_BT_INT32 value |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_INT8(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access NCX_BT_INT8 value |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_INT16(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access NCX_BT_INT16 value |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_STR(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Deprecated: use VAL_STRING instead |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_INSTANCE_ID(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access NCX_BT_INSTANCE_ID value |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_IDREF(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access entire '''val_idref_t''' structure for NCX_BT_IDREF |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_IDREF_NSID(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access the identityref namespace ID for NCX_BT_IDREF |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_IDREF_NAME(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access the identityref name string for NCX_BT_IDREF |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_UINT(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access the NCX_BT_UINT32 value |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_UINT8(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access the NCX_BT_UINT8 value |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_UINT16(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access the NCX_BT_UINT16 value |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_ULONG(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access the NCX_BT_UINT64 value |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_DEC64(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access the '''ncx_dec64'''structure for NCX_BT_DEC64 |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_LIST(V) |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access the '''ncx_list_t '''structure for NCX_BT_LIST |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| VAL_BITS |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access the '''ncx_list_t '''structure for NCX_BT_BITS. (Same as VAL_LIST) |
||
+ | |||
+ | |} |
||
+ | === val_value_t Access Functions === |
||
+ | The file '''ncx/val.h''' contains many API functions so that object properties do not have to be accessed directly. In addition, the file ncx/val_util.h contains more (high-level) utility functions. The following table highlights the most commonly used functions. Refer to the H files for a complete definition of each API function. |
||
+ | |||
+ | |||
+ | <center>'''val_value_t Access Functions'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Function</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_new_value |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Malloc a new value node with type NCX_BT_NONE. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_init_complex |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Initialize a malloced value node as one of the complex data types. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_init_virtual |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Initialize a malloced value node as a virtual node (provide a 'get' callback function). |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_init_from_template |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Initialize a malloced value node using an object template. This is the most common form of the init function used by SIL callback functions. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| vaL-free_value |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Clean and free a malloced value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_set_name |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Set or replace the value node name. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_set_qname |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Set or replace the value node namespace ID and name. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_string_ok |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the string value is valid for the value node object type. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_string_ok_errinfo |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the string value is valid for the value node object type, and provide the error information to use if it is not OK. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_list_ok |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the list value is valid for the value node object type. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_list_ok_errinfo |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the list value is valid for the value node object type, and provide the error information to use if it is not OK. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_enum_ok |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the enumeration value is valid for the value node object type. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_enum_ok_errinfo |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the enumeration value is valid for the value node object type, and provide the error information to use if it is not OK. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_bit_ok |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the bits value is valid for the value node object type. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_idref_ok |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the identityref value is valid for the value node object type. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_parse_idref |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Convert a string to an internal QName string into its various parts and find the identity struct that is being referenced (if available). |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_simval_ok |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the smple value is valid for the value node object type. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_simval_ok_errinfo |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the simple value is valid for the value node object type, and provide the error information to use if it is not OK. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_first_meta |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the first meta-variable (XML attribute value) for a value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_next_meta |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the next meta-variable (XML attribute value) for a value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_find_meta |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Find the specified meta-variable in a value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_dump_value |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Debug function to print the contents of any value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_dump_value_ex |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Debug function to print the contents of any value node, with extended parameters to control the output. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_dump_value_max |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Debug function to print the contents of any value node, with full control of the output parameters. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_set_string |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Set a malloced value node as a generic string value. Used instead of val_init_from_template. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_set_string2 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Set a malloced value node as a specified string type. Used instead of val_init_from_template. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_set_simval |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Set a malloced value node as a specified simple type. Used instead of val_init_from_template. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_set_simval_str |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Set a malloced value node as a specified simple type. Used instead of val_init_from_template. Use a counted string value instead of a zero-terminated string value. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_make_string |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Create a complete malloced generic string value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_clone |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Clone a value node |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_clone_test |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Clone a value node with a 'test' callback function to prune certain descendant nodes during the clone procedure. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_clone_config_data |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Clone a value node but skip all the non-configuration descendant nodes. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_add_child |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Add a child value node to a parent value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_insert_child |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Insert a child value node into a specific spot into a parent value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_remove_child |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Remove a child value node from its parent. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_swap_child |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Replace a child node within its parent with a different value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_first_child_match |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Match a child node name; Used for partial command completion in yangcli. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_next_child_match |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Match the next child node name; Used for partial command completion in yangcli. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_first_child |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the first child value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_next_child |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the next child value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_find_child |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Find a specific child value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_find_next_child |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Find the next occurrence of a specified child node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_match_child |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Match a potential partial node name against the child node names, and return the first match found, if any. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_child_cnt |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the number of child nodes within a parent node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_liststr_count |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the number of strings within an NCX_BT_LIST value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_index_match |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if 2 value list nodes have the same set of key leaf values. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_compare |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Compare 2 value nodes |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_compare_ex |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Compare 2 value nodes with extra parameters. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_compare_to_string |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Compare a value node to a string value instead of another value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_sprintf_simval_nc |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Output the value node as a string into the specified buffer. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_make_sprintf_string |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Malloc a buffer and fill it with a zero-terminated string representation of the value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_resolve_scoped_name |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Find a descendant node within a value node, from a relative path expression. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_has_content |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the value node has any content; FALSE if an empty XML element could represent its value. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_has_index |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the value node is a list with a key statement. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_first_index |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the first index node for the specified list value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_next_index |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the next index node for the specified list value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_set_extern |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Set a malloced value node as an NCX_BT_EXTERN internal data type. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_set_intern |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Set a malloced value node as an NCX_BT_INTERN internal data type. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_fit_oneline |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the value node should fit on 1 display line; Sometimes a guess is made instead of determining the exact value. XML namespace declarations generated during XML output can cause this function value to sometimes be wrong. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_create_allowed |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the NETCONF create operation is allowed for the specified value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_delete_allowed |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the NETCONF delete operation is allowed for the specified value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_is_config_data |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the value node represents configuration data. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_virtual_value |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the value for a virtual node from its 'get' callback function. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_is_default |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the value node is set to its YANG default value. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_is_real |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if a value node is a real node or one of the abstract node types. |
||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_parent_nsid |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the namespace ID for the parent value node of a specified child node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_instance_count |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the number of occurrences of the specified child value node within a parent value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_need_quotes |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if the printed string representation of a value node needs quotes (because it contains some whitespace or special characters). |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_dirty_flag |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if a value node has been altered by an RPC operation, but this edit has not been finalized yet. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_nest_level |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the current numeric nest level of the specified value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_mod_name |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the module name for the specified value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_mod_prefix |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the module prefix string for the specified value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_nsid |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the namespace ID for the specified value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_change_nsid |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Change the namespace ID for the specified value node and all of its descendents. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_set_pcookie |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Set the SIL pointer cookie in the value node editvars structure. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_set_icookie |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Set the SIL integer cookie in the value node editvars structure. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_pcookie |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the SIL pointer cookie in the value node editvars structure. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_icookie |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the SIL integer cookie in the value node editvars structure. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_typdef |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the typedef structure for a leaf or leaf-list value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_move_children |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Move all the child nodes of one complex value node to another complex value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_set_canonical_order |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Re-order the descendant nodes of a value node so they are in YANG order. Does not change the relative order of system-ordered lists and leaf-lists. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_gen_index_chain |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Generate the internal key leaf lookup chain for a list value node.. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_add_defaults |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Generate the leafs that have default values. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_instance_check |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check a value node against its template to see if the correct number of descendant nodes are present. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_choice_first_set |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the first real node that is present for a conceptual choice statement. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_choice_next_set |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the next real node that is present for a conceptual choice statement. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_choice_is_set |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Return TRUE if some real data node is present for a conceptual choice statement. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_new_child_val |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Create a child node during an edit operation. Used by the server. SIL code does not need to maintain the value tree. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_gen_instance_id |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Malloc and generate the YANG instance-identifier string for the value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_check_obj_when |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if an object node has any 'when' statements, and if so, evaluate the XPath condition(s) against the value tree to determine if the object should be considered present or not. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_check_child_conditional |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if a child object node has any FALSE 'if-feature' or 'when' statements. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_is_mandatory |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the child object node is currently mandatory or optional. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_get_xpathpcb |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Access the XPath parser control block for this value node, if any. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_make_simval_obj |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Malloc and fill in a value node from an object template and a value string. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_set_simval_obj |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Fill in a value node from an object template and a value string. |
||
+ | |||
+ | |} |
||
+ | === SIL Utility Functions === |
||
+ | There are some high-level SIL callback utilities in '''agt/agt_util.h'''. These functions access the lower-level functions in libncx to provide simpler functions for common SIL tasks. |
||
+ | |||
+ | The following table highlights the functions available in this module: |
||
+ | |||
+ | |||
+ | <center>'''agt/agt_util Functions'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Function</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_get_cfg_from_parm |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| For value nodes that represent a NETCONF configuration database name (e.g., empty element named 'running'). The configuration control block for the referenced database is retrieved. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_get_inline_cfg_from_parm |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| For value nodes that represent inline NETCONF configuration data. The value node for the inline config node is retrieved. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_get_parmval |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the specified parameter name within the RPC input section, from an RPC message control block. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_record_error |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Generate a complete RPC error record to be used when the <rpc-reply> is sent.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_record_error_errinfo |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Generate a complete RPC error record to be used when the <rpc-reply> is sent, using the YANG specified error information, not the default error information.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_record_attr_error |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Generate a complete RPC error record to be used when the <rpc-reply> is sent for an XML attribute error.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_record_insert_error |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Generate a complete RPC error record to be used when the <rpc-reply> is sent for a YANG insert operation error.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_record_unique_error |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Generate a complete RPC error record to be used when the <rpc-reply> is sent for a YANG unique statement contraint error.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_check_default |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| val_nodetest_fn_t Node Test Callback function to filter out default data from streamed replies, according to the server's definition of a default node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_check_save |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| val_nodetest_fn_t Node Test Callback function to filter out data nodes that should not be saved to NV-storage. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_enable_feature |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Enable the specified YANG feature |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_disable_feature |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Disable the specified YANG feature |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_make_leaf |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Create a child value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_make_virtual_leaf |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Create a virtual value child node. Most device monitoring leafs use this function because the value is retrieved with a device-specific API, not stored in the value tree. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_init_cache |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Initialize a cached pointer to a node in a data tree. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_check_cache |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if a cached pointer to a node in a data tree needs to be updated or set to NULL. |
||
+ | |||
+ | |} |
||
+ | = SIL External Interface = |
||
+ | Each SIL has 2 initialization functions and 1 cleanup function that must be present. |
||
+ | |||
+ | * The first initialization callback function is used to set up the configuration related objects. |
||
+ | * The second initialization callback is used to setup up non-configuration objects, after the running configuration has been loaded from the startup file. |
||
+ | * The cleanup callback is used to remove all SIL data structures and unregister all callback functions. |
||
+ | |||
+ | These are the only SIL functions that the server will invoke directly. They are generated by '''yangdump''' with the '''--format'''<nowiki>=c parameter, and usually do not require any editing by the developer.</nowiki> |
||
+ | |||
+ | Most of the work done by SIL code is through callback functions for specific RPC operations and database objects. These callback functions are registered during the initialization functions. |
||
+ | |||
+ | == Stage 1 Initialization == |
||
+ | The stage 1 initialization function is the first function called in the library by the server. |
||
+ | |||
+ | If the '''netconfd''' configuration parameters include a 'load' command for the module, then this function will be called during server initialization. <nowiki>It can also be called if the <load> operation is invoked during server operation.</nowiki> |
||
+ | |||
+ | This function MUST NOT attempt to access any database. There will not be any configuration databases if this function is called during server initialization. Use the 'init2' function to adjust the running configuration. |
||
+ | |||
+ | This callback function is expected to perform the following functions: |
||
+ | |||
+ | * initialize any module static data |
||
+ | * make sure the requested module name and optional revision date parameters are correct |
||
+ | * load the requested module name and revision with '''ncxmod_load_module''' |
||
+ | * setup top-level object cache pointers (if needed) |
||
+ | * register any RPC method callbacks with '''agt_rpc_register_method''' |
||
+ | * register any database object callbacks with '''agt_cb_register_callback''' |
||
+ | * perform any device-specific and/or module-specific initialization |
||
+ | |||
+ | Name Format: |
||
+ | |||
+ | <nowiki>y_<modname>_init</nowiki> |
||
+ | |||
+ | Input: |
||
+ | |||
+ | * modname == string containing module name to load |
||
+ | * revision == string containing revision date to use <nowiki>== NULL if the operator did not specify a revision.</nowiki> |
||
+ | |||
+ | Returns: |
||
+ | |||
+ | * operation status (0 if success) |
||
+ | |||
+ | Example function generated by '''yangdump''': |
||
+ | |||
+ | |||
+ | /******************************************************************** |
||
+ | <nowiki>* FUNCTION y_toaster_init</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* initialize the toaster server instrumentation library</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* INPUTS:</nowiki> |
||
+ | <nowiki>* </nowiki> modname == requested module name |
||
+ | <nowiki>* </nowiki> revision == requested version (NULL for any) |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* RETURNS:</nowiki> |
||
+ | <nowiki>* </nowiki> error status |
||
+ | <nowiki>********************************************************************/</nowiki> |
||
+ | status_t |
||
+ | y_toaster_init ( |
||
+ | const xmlChar *modname, |
||
+ | const xmlChar *revision) |
||
+ | { |
||
+ | agt_profile_t *agt_profile; |
||
+ | status_t res; |
||
+ | |||
+ | y_toaster_init_static_vars(); |
||
+ | |||
+ | /* change if custom handling done */ |
||
+ | if (xml_strcmp(modname, y_toaster_M_toaster)) { |
||
+ | return ERR_NCX_UNKNOWN_MODULE; |
||
+ | } |
||
+ | |||
+ | if (revision && xml_strcmp(revision, y_toaster_R_toaster)) { |
||
+ | return ERR_NCX_WRONG_VERSION; |
||
+ | } |
||
+ | |||
+ | agt_profile = agt_get_profile(); |
||
+ | |||
+ | res = ncxmod_load_module( |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_R_toaster, |
||
+ | &agt_profile->agt_savedevQ, |
||
+ | &toaster_mod); |
||
+ | if (res != NO_ERR) { |
||
+ | return res; |
||
+ | } |
||
+ | |||
+ | toaster_obj = ncx_find_object( |
||
+ | toaster_mod, |
||
+ | y_toaster_N_toaster); |
||
+ | if (toaster_mod == NULL) { |
||
+ | return SET_ERROR(ERR_NCX_DEF_NOT_FOUND); |
||
+ | } |
||
+ | |||
+ | make_toast_obj = ncx_find_object( |
||
+ | toaster_mod, |
||
+ | y_toaster_N_make_toast); |
||
+ | if (toaster_mod == NULL) { |
||
+ | return SET_ERROR(ERR_NCX_DEF_NOT_FOUND); |
||
+ | } |
||
+ | |||
+ | cancel_toast_obj = ncx_find_object( |
||
+ | toaster_mod, |
||
+ | y_toaster_N_cancel_toast); |
||
+ | if (toaster_mod == NULL) { |
||
+ | return SET_ERROR(ERR_NCX_DEF_NOT_FOUND); |
||
+ | } |
||
+ | |||
+ | toastDone_obj = ncx_find_object( |
||
+ | toaster_mod, |
||
+ | y_toaster_N_toastDone); |
||
+ | if (toaster_mod == NULL) { |
||
+ | return SET_ERROR(ERR_NCX_DEF_NOT_FOUND); |
||
+ | } |
||
+ | |||
+ | res = agt_rpc_register_method( |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_make_toast, |
||
+ | AGT_RPC_PH_VALIDATE, |
||
+ | y_toaster_make_toast_validate); |
||
+ | if (res != NO_ERR) { |
||
+ | return res; |
||
+ | } |
||
+ | |||
+ | res = agt_rpc_register_method( |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_make_toast, |
||
+ | AGT_RPC_PH_INVOKE, |
||
+ | y_toaster_make_toast_invoke); |
||
+ | if (res != NO_ERR) { |
||
+ | return res; |
||
+ | } |
||
+ | |||
+ | res = agt_rpc_register_method( |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_cancel_toast, |
||
+ | AGT_RPC_PH_VALIDATE, |
||
+ | y_toaster_cancel_toast_validate); |
||
+ | if (res != NO_ERR) { |
||
+ | return res; |
||
+ | } |
||
+ | |||
+ | res = agt_rpc_register_method( |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_cancel_toast, |
||
+ | AGT_RPC_PH_INVOKE, |
||
+ | y_toaster_cancel_toast_invoke); |
||
+ | if (res != NO_ERR) { |
||
+ | return res; |
||
+ | } |
||
+ | |||
+ | res = agt_cb_register_callback( |
||
+ | y_toaster_M_toaster, |
||
+ | (const xmlChar *)"/toaster", |
||
+ | (const xmlChar *)"2009-11-20", |
||
+ | y_toaster_toaster_edit); |
||
+ | |||
+ | if (res != NO_ERR) { |
||
+ | return res; |
||
+ | } |
||
+ | |||
+ | /* put your module initialization code here */ |
||
+ | |||
+ | return res; |
||
+ | } /* y_toaster_init */ |
||
+ | |||
+ | == Stage 2 Initialization == |
||
+ | The stage 2 initialization function is the second function called in the library by the server: |
||
+ | |||
+ | * It will only be called if the stage 1 initialization is called first, and it returns 0 (NO_ERR status). |
||
+ | * This function is used to initialize any needed data structures in the running configuration, such as factory default configuration, read-only counters and status objects. |
||
+ | * It is called after the startup configuration has been loaded into the server. |
||
+ | * <nowiki>If the <load> operation is used during server operation, then this function will be called immediately after the state 1 initialization function.</nowiki> |
||
+ | |||
+ | Note that configuration data structures that are loaded during server initialization '''(load_running_config''') will be handled by the database callback functions registered during phase 1 initialization. |
||
+ | |||
+ | Any server-created configuration nodes should be created during phase 2 initialization (this function), after examining the explicitly-provided configuration data. For example, the top-level /nacm container will be created (by agt_acm.c) if it is not provided in the startup configuration. |
||
+ | |||
+ | |||
+ | This callback function is expected to perform the following functions: |
||
+ | |||
+ | * load non-configuration data structures into the server (if needed) |
||
+ | * initialize top-level data node cache pointers (if needed) |
||
+ | * load factory-default configuration data structures into the server (if needed) |
||
+ | * optionally save a cached pointer to a data tree node (such as the root node for the module). The '''agt_create_cache''' function in agt/agt_util.h is used to initialize such a module-static variable. |
||
+ | |||
+ | Name Format: |
||
+ | |||
+ | <nowiki>y_<modname>_init2</nowiki> |
||
+ | |||
+ | Returns: |
||
+ | |||
+ | * operation status (0 if success) |
||
+ | |||
+ | Example function generated by '''yangdump''': |
||
+ | |||
+ | |||
+ | /******************************************************************** |
||
+ | <nowiki>* FUNCTION y_toaster_init2</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* SIL init phase 2: non-config data structures</nowiki> |
||
+ | <nowiki>* Called after running config is loaded</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* RETURNS:</nowiki> |
||
+ | <nowiki>* </nowiki> error status |
||
+ | <nowiki>********************************************************************/</nowiki> |
||
+ | |||
+ | status_t |
||
+ | y_toaster_init2 (void) |
||
+ | { |
||
+ | status_t res; |
||
+ | |||
+ | res = NO_ERR; |
||
+ | |||
+ | toaster_val = agt_init_cache( |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_toaster, |
||
+ | &res); |
||
+ | if (res != NO_ERR) { |
||
+ | return res; |
||
+ | } |
||
+ | |||
+ | /* put your init2 code here */ |
||
+ | |||
+ | return res; |
||
+ | } /* y_toaster_init2 */ |
||
+ | |||
+ | == Cleanup == |
||
+ | The cleanup function is called during server shutdown. It is only called if the stage 1 initialization function is called. It will be called right away if either the stage 1 or stage 2 initialization functions return a non-zero error status. |
||
+ | |||
+ | This callback function is expected to perform the following functions: |
||
+ | |||
+ | * cleanup any module static data |
||
+ | * free any top-level object cache pointers (if needed) |
||
+ | * unregister any RPC method callbacks with '''agt_rpc_unregister_method''' |
||
+ | * unregister any database object callbacks with '''agt_cb_unregister_callbacks''' |
||
+ | * perform any device-specific and/or module-specific cleanup |
||
+ | |||
+ | Name Format: |
||
+ | |||
+ | <nowiki>y_<modname>_cleanup</nowiki> |
||
+ | |||
+ | Example function generated by '''yangdump''': |
||
+ | |||
+ | |||
+ | /******************************************************************** |
||
+ | <nowiki>* FUNCTION y_toaster_cleanup</nowiki> |
||
+ | <nowiki>* </nowiki> cleanup the server instrumentation library |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>********************************************************************/</nowiki> |
||
+ | void |
||
+ | y_toaster_cleanup (void) |
||
+ | { |
||
+ | agt_rpc_unregister_method( |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_make_toast); |
||
+ | |||
+ | agt_rpc_unregister_method( |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_cancel_toast); |
||
+ | |||
+ | agt_cb_unregister_callbacks( |
||
+ | y_toaster_M_toaster, |
||
+ | (const xmlChar *)"/toaster"); |
||
+ | |||
+ | /* put your cleanup code here */ |
||
+ | |||
+ | } /* y_toaster_cleanup */ |
||
+ | |||
+ | = SIL Callback Interface = |
||
+ | This section briefly describes the SIL code that a developer will need to create to handle the data-model specific details. SIL functions access internal server data structures, either directly or through utility functions. Database mechanics and XML processing are done by the server engine, not the SIL code. A more complete reference can be found in section 5. |
||
+ | |||
+ | <nowiki>When a <rpc> request is received, the NETCONF server engine will perform the following tasks before calling any SIL:</nowiki> |
||
+ | |||
+ | * parse the RPC operation element, and find its associated YANG rpc template |
||
+ | * if found, check if the session is allowed to invoke this RPC operation |
||
+ | * if the RPC is allowed, parse the rest of the XML message, using the '''rpc_template_t '''for the RPC operation to determine if the basic structure is valid. |
||
+ | * if the basic structure is valid, construct an '''rpc_msg_t''' data structure for the incoming message. |
||
+ | * check all YANG machine-readable constraints, such as must, when, if-feature, min-elements, etc. |
||
+ | * if the incoming message is completely 'YANG valid', then the server will check for an RPC validate function, and call it if found. This SIL code is only needed if there are additional system constraints to check. For example: |
||
+ | ** <nowiki>need to check if a configuration name such as <candidate/> is supported</nowiki> |
||
+ | ** need to check if a configuration database is locked by another session |
||
+ | ** need to check description statement constraints not covered by machine-readable constraints |
||
+ | ** need to check if a specific capability or feature is enabled |
||
+ | * If the validate function returns a NO_ERR status value, then the server will call the SIL invoke callback, if it is present. This SIL code should always be present, otherwise the RPC operation will have no real affect on the system. |
||
+ | * <nowiki>At this point, an <rpc-reply> is generated, based on the data in the rpc_msg_t.</nowiki> |
||
+ | ** Errors are recorded in a queue when they are detected. |
||
+ | ** The server will handle the error reply generation for all errors it detects. |
||
+ | ** For SIL detected errors, the '''agt_record_error''' function in agt/agt_util.h is usually used to save the error details. |
||
+ | ** Reply data can be generated by the SIL invoke callback function and stored in the rpc_msg_t structure. |
||
+ | ** Replay data can be streamed by the SIL code via reply callback functions. <nowiki>For example, the <get> and <get-config> operations use callback functions to deal with filters, and stream the reply by walking the target data tree.</nowiki> |
||
+ | * <nowiki>After the <rpc-reply> is sent, the server will check for an RPC post reply callback function. </nowiki>This is only needed if the SIL code allocated some per-message data structures. For example, the '''rpc_msg_t''' contains 2 SIL controlled pointers ('''rpc_user1''' and '''rpc_user2'''). The post reply callback is used by the SIL code to free these pointers, if needed. |
||
+ | |||
+ | The database edit SIL callbacks are only used for database operations that alter the database. The validate and invoke callback functions for these operations will in turn invoke the data-model specific SIL callback functions, depending on the success or failure of the edit request. |
||
+ | |||
+ | == RPC Operation Interface == |
||
+ | All RPC operations are data-driven within the server, using the YANG rpc statement for the operation and SIL callback functions. |
||
+ | |||
+ | Any new protocol operation can be added by defining a new YANG rpc statement in a module, and providing the proper SIL code. |
||
+ | |||
+ | === RPC Callback Initialization === |
||
+ | The''' agt_rpc_register_method''' function in agt/agt_rpc.h is used to provide a callback function for a specific callback phase. The same function can be used for multiple phases if desired. |
||
+ | |||
+ | |||
+ | /* Template for RPC server callbacks |
||
+ | <nowiki>* The same template is used for all RPC callback phases</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | typedef status_t |
||
+ | (*agt_rpc_method_t) (ses_cb_t *scb, |
||
+ | rpc_msg_t *msg, |
||
+ | xml_node_t *methnode); |
||
+ | |||
+ | extern status_t |
||
+ | agt_rpc_register_method (const xmlChar *module, |
||
+ | const xmlChar *method_name, |
||
+ | agt_rpc_phase_t phase, |
||
+ | agt_rpc_method_t method); |
||
+ | |||
+ | <center>'''agt_rpc_register_method'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Parameter</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| module |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The name of the module that contains the rpc statement |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| method_name |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The identifier for the rpc statement |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| phase |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| AGT_PH_VALIDATE(0): validate phaseAGT_PH_INVOKE(1): invoke phaseAGT_PH_POST_REPLY(2): post-reply phase |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| method |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The address of the callback function to register |
||
+ | |||
+ | |} |
||
+ | === RPC Message Header === |
||
+ | <nowiki>The NETCONF server will parse the incoming XML message and construct an RPC message header, which is used to maintain state and any other message-specific data during the processing of an incoming <rpc> request.</nowiki> |
||
+ | |||
+ | The '''rpc_msg_t''' data structure in ncx/rpc.h is used for this purpose. The following table summarizes the fields: |
||
+ | |||
+ | <center>'''rpc_msg_t'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Field</center> |
||
+ | ! <center>Type</center> |
||
+ | ! <center>User Mode</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| qhdr |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| dlq_hdr_t |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| none |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Queue header to store RPC messages in a queue (within the session header) |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| mhdr |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xml_msg_hdr_t |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| none |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| XML message prefix map and other data used to parse the request and generate the reply. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_in_attrs |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| xml_attrs_t * |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| readwrite |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Queue of xml_attr_t representing any XML attributes that were present in the <rpc> element. </nowiki>A callback function may add xml_attr_t structs to this queue to send in the reply. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_method |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| obj_template_t * |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| read |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Back-pointer to the object template for this RPC operation. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_agt_state |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| int |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| read |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Enum value (0, 1, 2) for the current RPC callback phase. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_err_option |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| op_errop_t |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| read |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Enum value for the <error-option> parameter. </nowiki><nowiki>This is only set if the <edit-config> operation is in progress.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_top_editop |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| op_editop_t |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| read |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Enum value for the <default-operation> parameter. </nowiki><nowiki>This is only set if the <edit-config> operation is in progress.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_input |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| val_value_t * |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| read |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Value tree representing the container of 'input' parameters for this RPC operation. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_user1 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| void * |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| readwrite |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Void pointer that can be used by the SIL functions to store their own message-specific data. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_user2 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| void * |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| readwrite |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Void pointer that can be used by the SIL functions to store their own message-specific data. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_returncode |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| uint32 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| none |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal return code used to control nested callbacks. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_data_type |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_data_t |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| write |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| For RPC operations that return data, this enumeration is set to indicate which type of data is desired. |
||
+ | |||
+ | '''RPC_DATA_STD''': <nowiki>A <data> container will be used to encapsulate any returned data, within the <rpc-reply> element.</nowiki> |
||
+ | |||
+ | '''RPC_DATA_YANG'''<nowiki>: The <rpc-reply> element will be the only container encapsulated any returned data.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_datacb |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| void * |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| write |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>For operations that return streamed data, this pointer is set to the desired callback function to use for generated the data portion of the <rpc-reply> XML response.</nowiki> |
||
+ | |||
+ | The template for this callback is '''agt_rpc_data_cb_t,''' found in agt_rpc.h |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_dataQ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| dlq_hdr_t |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| write |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| For operations that return stored data, this queue of val_value_t structures can be used to provide the response data. Each val_value_t structure will be encoded as one of the corresponding RPC output parameters. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_filter |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| op_filter_t |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| none |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal structure for optimizing subtree and XPath retrieval operations. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_need_undo |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| boolean |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| none |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Internal flag to indicate if rollback-on-error is in effect dusing an <edit-config> operation.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_undoQ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| dlq_hdr_t |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| none |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Queue of '''rpc_undo_rec_t'''<nowiki> structures, used to undo edits if rollback-on-error is in affect during an <edit-config> operation.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| rpc_auditQ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| dlq_hdr_t |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| none |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Queue of rpc_audit_rec_t structures used internally to generate database alteration notifications and audit log entries. |
||
+ | |||
+ | |} |
||
+ | The following C code represents the '''rpc_msg_t''' data structure: |
||
+ | |||
+ | |||
+ | /* NETCONF Server and Client RPC Request/Reply Message Header */ |
||
+ | typedef struct rpc_msg_t_ { |
||
+ | dlq_hdr_t qhdr; |
||
+ | |||
+ | /* generic XML message header */ |
||
+ | xml_msg_hdr_t mhdr; |
||
+ | |||
+ | /* incoming: top-level rpc element data */ |
||
+ | xml_attrs_t <nowiki>*rpc_in_attrs; </nowiki> <nowiki>/* borrowed from <rpc> elem */</nowiki> |
||
+ | |||
+ | /* incoming: |
||
+ | <nowiki>* 2nd-level method name element data, used in agt_output_filter</nowiki> |
||
+ | <nowiki>* to check get or get-config</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | struct obj_template_t_ *rpc_method; |
||
+ | |||
+ | /* incoming: SERVER RPC processing state */ |
||
+ | int rpc_agt_state; /* agt_rpc_phase_t */ |
||
+ | op_errop_t rpc_err_option; |
||
+ | op_editop_t rpc_top_editop; |
||
+ | val_value_t <nowiki>*rpc_input;</nowiki> |
||
+ | |||
+ | /* incoming: |
||
+ | <nowiki>* hooks for method routines to save context or whatever </nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | void <nowiki>*rpc_user1;</nowiki> |
||
+ | void <nowiki>*rpc_user2;</nowiki> |
||
+ | uint32 rpc_returncode; /* for nested callbacks */ |
||
+ | |||
+ | /* incoming: get method reply handling builtin |
||
+ | <nowiki>* If the rpc_datacb is non-NULL then it will be used as a</nowiki> |
||
+ | <nowiki>* callback to generate the rpc-reply inline, instead of</nowiki> |
||
+ | <nowiki>* buffering the output. </nowiki> |
||
+ | <nowiki>* The rpc_data and rpc_filter parameters are optionally used</nowiki> |
||
+ | <nowiki>* by the rpc_datacb function to generate a reply.</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | rpc_data_t rpc_data_type; /* type of data reply */ |
||
+ | |||
+ | void <nowiki>*rpc_datacb; </nowiki> /* agt_rpc_data_cb_t */ |
||
+ | dlq_hdr_t rpc_dataQ; /* data reply: Q of val_value_t */ |
||
+ | op_filter_t rpc_filter; /* backptrs for get* methods */ |
||
+ | |||
+ | /* incoming: rollback or commit phase support builtin |
||
+ | <nowiki>* As an edit-config (or other RPC) is processed, a</nowiki> |
||
+ | <nowiki>* queue of 'undo records' is collected.</nowiki> |
||
+ | <nowiki>* If the apply phase succeeds then it is discarded,</nowiki> |
||
+ | <nowiki>* otherwise if rollback-on-error is requested,</nowiki> |
||
+ | <nowiki>* it is used to undo each change that did succeed (if any)</nowiki> |
||
+ | <nowiki>* before an error occured in the apply phase.</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | boolean rpc_need_undo; /* set by edit_config_validate */ |
||
+ | dlq_hdr_t rpc_undoQ; /* Q of rpc_undo_rec_t */ |
||
+ | dlq_hdr_t rpc_auditQ; /* Q of rpc_audit_rec_t */ |
||
+ | |||
+ | } rpc_msg_t; |
||
+ | |||
+ | === SIL Support Functions For RPC Operations === |
||
+ | The file agt/agt_rpc.c contains some functions that are used by SIL callback functions. |
||
+ | |||
+ | The following table highlights the functions that may be useful to SIL developers: |
||
+ | |||
+ | |||
+ | <center>'''agt/agt_rpc.c Functions'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Function</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_rpc_register_method |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Register a SIL RPC operation callback function for 1 callback phase. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_rpc_support_method |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Tell the server that an RPC operation is supported by the system.. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_rpc_unsupport_method |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Tell the server that an RPC operation is not supported by the system.. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_rpc_unregister_method |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Remove all the SIL RPC operation callback functions for 1 RPC operation. |
||
+ | |||
+ | |} |
||
+ | === RPC Validate Callback Function === |
||
+ | [[Image:]] |
||
+ | |||
+ | |||
+ | The RPC validate callback function is optional to use. Its purpose is to validate any aspects of an RPC operation, beyond the constraints checked by the server engine. Only 1 function can register for each YANG rpc statement. The standard NETCONF operations are reserved by the server engine. There is usually zero or one of these callback functions for every 'rpc' statement in the YANG module associated with the SIL code. |
||
+ | |||
+ | It is enabled with the '''agt_rpc_register_method''' function, within the phase 1 initialization callback function. |
||
+ | |||
+ | The '''yangdump''' code generator will create this SIL callback function by default. There will C comments in the code to indicate where your additional C code should be added. |
||
+ | |||
+ | The '''val_find_child''' function is commonly used to find particular parameters within the RPC input section, which is encoded as a '''val_value_t''' tree. |
||
+ | |||
+ | The '''agt_record_error''' function is commonly used to record any parameter or other errors. In the '''libtoaster''' example, there are internal state variables ('''toaster_enabled''' and '''toaster_toasting'''), maintained by the SIL code, which are checked in addition to any provided parameters. |
||
+ | |||
+ | |||
+ | Example SIL Function Registration |
||
+ | |||
+ | |||
+ | res = agt_rpc_register_method( |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_make_toast, |
||
+ | AGT_RPC_PH_VALIDATE, |
||
+ | y_toaster_make_toast_validate); |
||
+ | if (res != NO_ERR) { |
||
+ | return res; |
||
+ | } |
||
+ | |||
+ | Example SIL Function: |
||
+ | |||
+ | |||
+ | /******************************************************************** |
||
+ | <nowiki>* FUNCTION y_toaster_make_toast_validate</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* RPC validation phase</nowiki> |
||
+ | <nowiki>* All YANG constraints have passed at this point.</nowiki> |
||
+ | <nowiki>* Add description-stmt checks in this function.</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* INPUTS:</nowiki> |
||
+ | <nowiki>* </nowiki> see agt/agt_rpc.h for details |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* RETURNS:</nowiki> |
||
+ | <nowiki>* </nowiki> error status |
||
+ | <nowiki>********************************************************************/</nowiki> |
||
+ | static status_t |
||
+ | y_toaster_make_toast_validate ( |
||
+ | ses_cb_t *scb, |
||
+ | rpc_msg_t *msg, |
||
+ | xml_node_t *methnode) |
||
+ | { |
||
+ | status_t res; |
||
+ | val_value_t *errorval; |
||
+ | const xmlChar *errorstr; |
||
+ | val_value_t *toasterDoneness_val; |
||
+ | val_value_t *toasterToastType_val; |
||
+ | uint32 toasterDoneness; |
||
+ | val_idref_t *toasterToastType; |
||
+ | |||
+ | res = NO_ERR; |
||
+ | errorval = NULL; |
||
+ | errorstr = NULL; |
||
+ | |||
+ | toasterDoneness_val = val_find_child( |
||
+ | msg->rpc_input, |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_toasterDoneness); |
||
+ | if (toasterDoneness_val != NULL && toasterDoneness_val->res == NO_ERR) { |
||
+ | toasterDoneness = VAL_UINT(toasterDoneness_val); |
||
+ | } |
||
+ | |||
+ | toasterToastType_val = val_find_child( |
||
+ | msg->rpc_input, |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_toasterToastType); |
||
+ | if (toasterToastType_val != NULL && toasterToastType_val->res == NO_ERR) { |
||
+ | toasterToastType = VAL_IDREF(toasterToastType_val); |
||
+ | } |
||
+ | |||
+ | /* added code starts here */ |
||
+ | if (toaster_enabled) { |
||
+ | /* toaster service enabled, check if in use */ |
||
+ | |||
+ | if (toaster_toasting) { |
||
+ | res = ERR_NCX_IN_USE; |
||
+ | } else { |
||
+ | /* this is where a check on bread inventory would go */ |
||
+ | |||
+ | /* this is where a check on toaster HW ready would go */ |
||
+ | } |
||
+ | } else { |
||
+ | /* toaster service disabled */ |
||
+ | res = ERR_NCX_RESOURCE_DENIED; |
||
+ | } |
||
+ | /* added code ends here */ |
||
+ | |||
+ | /* if error: set the res, errorstr, and errorval parms */ |
||
+ | if (res != NO_ERR) { |
||
+ | agt_record_error( |
||
+ | scb, |
||
+ | &msg->mhdr, |
||
+ | NCX_LAYER_OPERATION, |
||
+ | res, |
||
+ | methnode, |
||
+ | NCX_NT_STRING, |
||
+ | errorstr, |
||
+ | NCX_NT_VAL, |
||
+ | errorval); |
||
+ | } |
||
+ | |||
+ | return res; |
||
+ | |||
+ | } /* y_toaster_make_toast_validate */ |
||
+ | |||
+ | === RPC Invoke Callback Function === |
||
+ | [[Image:]] |
||
+ | |||
+ | The RPC invoke callback function is used to perform the operation requested by the client session. Only 1 function can register for each YANG rpc statement. The standard NETCONF operations are reserved by the server engine. There is usually one of these callback functions for every 'rpc' statement in the YANG module associated with the SIL code. |
||
+ | |||
+ | The RPC invoke callback function is optional to use, although if no invoke callback is provided, then the operation will have no affect. Normally, this is only the case if the module is be tested by an application developer, using '''netconfd''' as a server simulator. |
||
+ | |||
+ | It is enabled with the '''agt_rpc_register_method''' function, within the phase 1 initialization callback function. |
||
+ | |||
+ | The '''yangdump''' code generator will create this SIL callback function by default. There will C comments in the code to indicate where your additional C code should be added. |
||
+ | |||
+ | The '''val_find_child''' function is commonly used to retrieve particular parameters within the RPC input section, which is encoded as a '''val_value_t''' tree. The''' rpc_user1''' and '''rpc_user2''' cache pointers in the '''rpc_msg_t''' structure can also be used to store data in the validation phase, so it can be immediately available in the invoke phase. |
||
+ | |||
+ | The '''agt_record_error''' function is commonly used to record any internal or platform-specific errors. In the '''libtoaster''' example, if the request to create a timer callback control block fails, then an error is recorded. |
||
+ | |||
+ | <nowiki>For RPC operations that return either an <ok> or <rpc-error> response, there is nothing more required of the RPC invoke callback function.</nowiki> |
||
+ | |||
+ | <nowiki>For operations which return some data or <rpc-error>, the SIL code must do 1 of 2 additional tasks:</nowiki> |
||
+ | |||
+ | * add a '''val_value_t''' structure to the '''rpc_dataQ''' queue in the''' rpc_msg_t '''for each parameter listed in the YANG rpc 'output' section. |
||
+ | * set the rpc_datacb pointer in the rpc_msg_t structure to the address of your data reply callback function. See the '''agt_rpc_data_cb_t''' definition in agt/agt_rpc.h for more details. |
||
+ | |||
+ | Example SIL Function Registration |
||
+ | |||
+ | |||
+ | res = agt_rpc_register_method( |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_make_toast, |
||
+ | AGT_RPC_PH_INVOKE, |
||
+ | y_toaster_make_toast_invoke); |
||
+ | if (res != NO_ERR) { |
||
+ | return res; |
||
+ | } |
||
+ | |||
+ | Example SIL Function: |
||
+ | |||
+ | |||
+ | /******************************************************************** |
||
+ | <nowiki>* FUNCTION y_toaster_make_toast_invoke</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* RPC invocation phase</nowiki> |
||
+ | <nowiki>* All constraints have passed at this point.</nowiki> |
||
+ | <nowiki>* Call device instrumentation code in this function.</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* INPUTS:</nowiki> |
||
+ | <nowiki>* </nowiki> see agt/agt_rpc.h for details |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* RETURNS:</nowiki> |
||
+ | <nowiki>* </nowiki> error status |
||
+ | <nowiki>********************************************************************/</nowiki> |
||
+ | static status_t |
||
+ | y_toaster_make_toast_invoke ( |
||
+ | ses_cb_t *scb, |
||
+ | rpc_msg_t *msg, |
||
+ | xml_node_t *methnode) |
||
+ | { |
||
+ | status_t res; |
||
+ | val_value_t *toasterDoneness_val; |
||
+ | val_value_t *toasterToastType_val; |
||
+ | uint32 toasterDoneness; |
||
+ | val_idref_t *toasterToastType; |
||
+ | |||
+ | res = NO_ERR; |
||
+ | toasterDoneness = 0; |
||
+ | |||
+ | toasterDoneness_val = val_find_child( |
||
+ | msg->rpc_input, |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_toasterDoneness); |
||
+ | if (toasterDoneness_val != NULL && toasterDoneness_val->res == NO_ERR) { |
||
+ | toasterDoneness = VAL_UINT(toasterDoneness_val); |
||
+ | } |
||
+ | |||
+ | toasterToastType_val = val_find_child( |
||
+ | msg->rpc_input, |
||
+ | y_toaster_M_toaster, |
||
+ | y_toaster_N_toasterToastType); |
||
+ | if (toasterToastType_val != NULL && toasterToastType_val->res == NO_ERR) { |
||
+ | toasterToastType = VAL_IDREF(toasterToastType_val); |
||
+ | } |
||
+ | |||
+ | /* invoke your device instrumentation code here */ |
||
+ | |||
+ | /* make sure the toasterDoneness value is set */ |
||
+ | if (toasterDoneness_val == NULL) { |
||
+ | toasterDoneness = 5; /* set the default */ |
||
+ | } |
||
+ | |||
+ | /* arbitrary formula to convert toaster doneness to the |
||
+ | <nowiki>* number of seconds the toaster should be on</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | toaster_duration = toasterDoneness * 12; |
||
+ | |||
+ | /* this is where the code would go to adjust the duration |
||
+ | <nowiki>* based on the bread type</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | |||
+ | if (LOGDEBUG) { |
||
+ | log_debug("\ntoaster: starting toaster for %u seconds", |
||
+ | toaster_duration); |
||
+ | } |
||
+ | |||
+ | /* this is where the code would go to start the toaster |
||
+ | <nowiki>* heater element</nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | |||
+ | /* start a timer to toast for the specified time interval */ |
||
+ | res = agt_timer_create(toaster_duration, |
||
+ | FALSE, |
||
+ | toaster_timer_fn, |
||
+ | NULL, |
||
+ | &toaster_timer_id); |
||
+ | if (res == NO_ERR) { |
||
+ | toaster_toasting = TRUE; |
||
+ | } else { |
||
+ | agt_record_error( |
||
+ | scb, |
||
+ | &msg->mhdr, |
||
+ | NCX_LAYER_OPERATION, |
||
+ | res, |
||
+ | methnode, |
||
+ | NCX_NT_NONE, |
||
+ | NULL, |
||
+ | NCX_NT_NONE, |
||
+ | NULL); |
||
+ | } |
||
+ | /* added code ends here */ |
||
+ | |||
+ | return res; |
||
+ | |||
+ | } /* y_toaster_make_toast_invoke */ |
||
+ | |||
+ | === RPC Post Reply Callback Function === |
||
+ | [[Image:]] |
||
+ | |||
+ | The RPC post-reply callback function is used to clean up after a message has been processed. Only 1 function can register for each YANG rpc statement. The standard NETCONF operations are reserved by the server engine. <nowiki>This callback is not needed unless the SIL validate or invoke callback allocated some memory that needs to deleted after the <rpc-reply> is sent.</nowiki> |
||
+ | |||
+ | The RPC post reply callback function is optional to use. It is enabled with the '''agt_rpc_register_method''' function, within the phase 1 initialization callback function. |
||
+ | |||
+ | The '''yangdump''' code generator will not create this SIL callback function by default. |
||
+ | |||
+ | |||
+ | Example SIL Function Registration |
||
+ | |||
+ | |||
+ | res = agt_rpc_register_method( |
||
+ | y_foo_M_foo, |
||
+ | y_foo_N_command, |
||
+ | AGT_RPC_PH_POST_REPLY, |
||
+ | y_foo_command_post); |
||
+ | if (res != NO_ERR) { |
||
+ | return res; |
||
+ | } |
||
+ | |||
+ | Example SIL Function: |
||
+ | |||
+ | |||
+ | /******************************************************************** |
||
+ | <nowiki>* FUNCTION y_foo_command_post</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* RPC post reply phase</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* INPUTS:</nowiki> |
||
+ | <nowiki>* </nowiki> see agt/agt_rpc.h for details |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* RETURNS:</nowiki> |
||
+ | <nowiki>* </nowiki> error status |
||
+ | <nowiki>********************************************************************/</nowiki> |
||
+ | static status_t |
||
+ | y_foo_command_post ( |
||
+ | ses_cb_t *scb, |
||
+ | rpc_msg_t *msg, |
||
+ | xml_node_t *methnode) |
||
+ | { |
||
+ | (void)scb; |
||
+ | (void)methnode; |
||
+ | if (msg->rpc_user1 != NULL) { |
||
+ | m__free(msg->rpc_user1); |
||
+ | msg->rpc_user1 = NULL; |
||
+ | } |
||
+ | return NO_ERR; |
||
+ | } /* y_foo_command_post */ |
||
+ | |||
+ | == Database Operations == |
||
+ | The server database is designed so that the SIL callback functions do not need to really know which database model is being used by the server (e.g., target is candidate vs. running configuration). |
||
+ | |||
+ | There are three SIL database edit callback phases: |
||
+ | |||
+ | # '''Validate''': Check the parameters no matter what database is the target |
||
+ | # '''Apply''': The server will manipulate the database nodes as needed. The SIL usually has nothing to do in this phase unless internal resources need to be reserved. |
||
+ | # '''Commit or Rollback''': Depending on the result of the previous phases, either the commit or the rollback callback phase will be invoked, if and when the changes are going to be finalized in the running configuration. |
||
+ | |||
+ | The SIL code is not responsible for maintaining the value tree for any database. This is done by the server. |
||
+ | |||
+ | The SIL database edit callback code is responsible for the following tasks: |
||
+ | |||
+ | * Perform any data-model specific validation that is not already covered by a machine-readable statement, during the validation phase. |
||
+ | * Reserve any data-model specific resources for the proposed new configuration content, during the apply phase. |
||
+ | * Activate any data-model behavior changes based on the new configuration content, during the commit phase. |
||
+ | * Release any reserved resources that were previously allocated in the apply phase, during the rollback phase. |
||
+ | |||
+ | === Database Template (cfg_template_t) === |
||
+ | Every NETCONF database has a common template control block, and common set of access functions. |
||
+ | |||
+ | NETCONF databases are not separate entities like separate SQL databases. Each NETCONF database is conceptually the same database, but in different states: |
||
+ | |||
+ | * '''candidate''': A complete configuration that may contain changes that have not been applied yet. This is only available if the :candidate capability is advertised by the server. The value tree for this database contains only configuration data nodes. |
||
+ | * '''running''': The complete current server configuration. This is available on every NETCONF server. The value tree for this database contains configuration data nodes and non-configuration nodes created and maintained by the server. <nowiki>The server will maintain read-only nodes when <edit-config>, <copy-config>, or <commit> operations are performed on the running configuration. </nowiki>SIL code should not alter the data nodes within a configuration directly. This work is handled by the server. SIL callback code should only alter its own data structures, if needed. |
||
+ | * '''startup''': A complete configuration that will be used upon the next reboot of the device. This is only available if the :startup capability is advertised by the server. The value tree for this database contains only configuration data nodes. |
||
+ | |||
+ | <nowiki>NETCONF also recognized external files via the <url> parameter, if the :url capability is advertised by the server. </nowiki>These databases will be supported in a future release of the server. The NETCONF standard does not require that these external databases support the same set of protocol operations as the standard databases, listed above. A client application can reliably copy from and to an external database, but editing and filtered retrieval may not be supported. |
||
+ | |||
+ | The following typedef is used to define a NETCONF database template: |
||
+ | |||
+ | |||
+ | /* struct representing 1 configuration database */ |
||
+ | typedef struct cfg_template_t_ { |
||
+ | dlq_hdr_t qhdr; |
||
+ | ncx_cfg_t cfg_id; |
||
+ | cfg_location_t cfg_loc; |
||
+ | cfg_state_t cfg_state; |
||
+ | xmlChar <nowiki>*name;</nowiki> |
||
+ | xmlChar <nowiki>*src_url;</nowiki> |
||
+ | xmlChar <nowiki>*load_time;</nowiki> |
||
+ | xmlChar <nowiki>*lock_time;</nowiki> |
||
+ | xmlChar <nowiki>*last_ch_time;</nowiki> |
||
+ | uint32 flags; |
||
+ | ses_id_t locked_by; |
||
+ | cfg_source_t lock_src; |
||
+ | dlq_hdr_t load_errQ; /* Q of rpc_err_rec_t */ |
||
+ | val_value_t <nowiki>*root; </nowiki> /* btyp == container */ |
||
+ | } cfg_template_t; |
||
+ | |||
+ | The following table highlights the fields in the cfg_template_t data structure: |
||
+ | |||
+ | |||
+ | <center>'''cfg_template_t Fields'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Field</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| qhdr |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Queue header to allow the object template to be stored in a queue. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_id |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal configuration ID assigned to this configuration. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_loc |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Enumeration identifying the configuration source location. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_state |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Current internal configuration state. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| name |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Name string for this configuration. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| src_url |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| URL for use with 'cfg_loc' to identify the configuration source. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| load_time |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Date and time string when the configuration was loaded. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| lock_time |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Date and time string when the configuration was last locked. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| last_ch_time |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Date and time string when the configuration was last changed. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| flags |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Internal configuration flags. Do not use directly. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| locked_by |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Session ID that owns the global configuration lock, if the database is currently locked. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| lock_src |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| If the database is locked, identifies the protocol or other source that currently caused the database to be locked. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| load_errQ |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| <nowiki>Queue of rpc_err_rec_t structures that represent any <rpc-error> records that were generated when the configuration was loaded, if any.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| root |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The root of the value tree representing the entire database. |
||
+ | |||
+ | |} |
||
+ | === Database Access Functions === |
||
+ | The file '''ncx/cfg.h''' contains some high-level database access functions that may be of interest to SIL callback functions for custom RPC operations. All database access details are handled by the server if the database edit callback functions are used (associated with a particular object node supported by the server)..The following table highlights the most commonly used functions. Refer to the H file for a complete definition of each API function. |
||
+ | |||
+ | <center>'''cfg_template_t Access Functions'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Function</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_new_template |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Create a new configuration database. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_free_template |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Free a configuration database. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_get_state |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get the current internal database state. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_get_config |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get a configuration database template pointer, from a configuration name string. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_get_config_id |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get a configuration database template pointer, from a configuration ID. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_fill_candidate_from_inline |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Fill the candidate database from an internal value tree data structure. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_get_dirty_flag |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Returns TRUE if the database has changes in it that have not been saved yet. This applies to the candidate and running databases at this time. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_ok_to_lock |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the database could be successfully locked by a specific session. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_ok_to_unlock |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the database could be successfully unlocked by a specific session. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_ok_to_read |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the database is in a state where read operations are allowed. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_ok_to_write |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Check if the database could be successfully written by a specific session. Checks the global configuration lock, if any is set. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_is_global_locked |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Returns TRUE if the database is locked right now with a global lock. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_get_global_lock_info |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get some information about the current global lock on the database. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_lock |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Get a global lock on the database. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_unlock |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Release the global lock on the database. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cfg_release_locks |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Release all locks on all databases |
||
+ | |||
+ | |} |
||
+ | === Database Callback Initialization and Cleanup === |
||
+ | The file '''agt/agt_cb.h''' contains functions that a SIL developer needs to register and unregister database edit callback functions. The same callback function can be used for different phases, if desired. |
||
+ | |||
+ | The following function template definition is used for all SIL database edit callback functions: |
||
+ | |||
+ | |||
+ | /* Callback function for agent object handler |
||
+ | <nowiki>* Used to provide a callback sub-mode for</nowiki> |
||
+ | <nowiki>* a specific named object</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* INPUTS:</nowiki> |
||
+ | <nowiki>* </nowiki> scb == session control block making the request |
||
+ | <nowiki>* </nowiki> msg == incoming rpc_msg_t in progress |
||
+ | <nowiki>* </nowiki> cbtyp == reason for the callback |
||
+ | <nowiki>* </nowiki> editop == the parent edit-config operation type, which |
||
+ | <nowiki>* </nowiki> is also used for all other callbacks |
||
+ | <nowiki>* </nowiki> that operate on objects |
||
+ | <nowiki>* </nowiki> newval == container object holding the proposed changes to |
||
+ | <nowiki>* </nowiki> apply to the current config, depending on |
||
+ | <nowiki>* </nowiki> the editop value. Will not be NULL. |
||
+ | <nowiki>* </nowiki> <nowiki>curval == current container values from the <running> </nowiki> |
||
+ | <nowiki>* </nowiki> <nowiki>or <candidate> configuration, if any. Could be NULL</nowiki> |
||
+ | <nowiki>* </nowiki> for create and other operations. |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* RETURNS:</nowiki> |
||
+ | <nowiki>* </nowiki> status: |
||
+ | <nowiki>*/</nowiki> |
||
+ | typedef status_t |
||
+ | (*'''agt_cb_fn_t''') (ses_cb_t <nowiki>*scb,</nowiki> |
||
+ | rpc_msg_t *msg, |
||
+ | agt_cbtyp_t cbtyp, |
||
+ | op_editop_t editop, |
||
+ | val_value_t <nowiki>*newval,</nowiki> |
||
+ | val_value_t <nowiki>*curval);</nowiki> |
||
+ | |||
+ | <center>'''SIL Database Callback Template'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Parameter</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| scb |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The session control block making the edit request. The SIL callback code should not need this parameter except to pass to functions that need the SCB. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| msg |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Incoming RPC message in progress. The server uses some fields in this structure, and there are 2 SIL fields for the RPC callback functions. The SIL callback code should not need this parameter except to pass to functions that need the message header. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cbtyp |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Enumeration for the callback phase in progress.. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| editop |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The edit operation in effect as this node is being processed. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| newval |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Value node containing the new value for a create, merge, replace, or insert operation. The 'newval' parm may be NULL and should be ignored for a delete operation. In that case, the 'curval' pointer contains the node being deleted. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| curval |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Value node containing the current database node that corresponds to the 'newval' node, if any is available. |
||
+ | |||
+ | |} |
||
+ | A SIL database edit callback function is hooked into the server with the '''agt_cb_register_callback''' or '''agt_cb_register_callbacks''' functions, described below. The SIL code generated by yangdump uses the first function to register a single callback function for all callback phases. |
||
+ | |||
+ | |||
+ | extern status_t |
||
+ | '''agt_cb_register_callback '''(const xmlChar *modname, |
||
+ | const xmlChar *defpath, |
||
+ | const xmlChar *version, |
||
+ | const agt_cb_fn_t cbfn); |
||
+ | |||
+ | <center>'''agt_cb_register_callback'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Parameter</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| modname |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Module name string that defines this object node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| defpath |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Absolute path expression string indicating which node the callback function is for. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| version |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| If non-NULL, indicates the exact module version expected. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cbfn |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The callback function address. This function will be used for all callback phases. |
||
+ | |||
+ | |} |
||
+ | extern status_t |
||
+ | '''agt_cb_register_callbacks''' (const xmlChar *modname, |
||
+ | const xmlChar *defpath, |
||
+ | const xmlChar *version, |
||
+ | const agt_cb_fnset_t *cbfnset); |
||
+ | |||
+ | <center>'''agt_cb_register_callbacks'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Parameter</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| modname |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Module name string that defines this object node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| defpath |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Absolute path expression string indicating which node the callback function is for. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| version |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| If non-NULL, indicates the exact module version expected. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cbfnset |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The callback function set structure, fillied in with the addesses of all desired callback phases. Any NULL slots will cause that phase to be skipped. |
||
+ | |||
+ | |} |
||
+ | The '''agt_cb_unregister_callbacks''' function is called during the module cleanup. It is generated by '''yangdump''' automatically for all RPC operations. |
||
+ | |||
+ | |||
+ | extern void |
||
+ | '''agt_cb_unregister_callbacks '''(const xmlChar *modname, |
||
+ | const xmlChar *defpath); |
||
+ | |||
+ | <center>'''agt_cb_unregister_callbacks'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Parameter</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| modname |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Module name string that defines this object node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| defpath |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Absolute path expression string indicating which node the callback function is for. |
||
+ | |||
+ | |} |
||
+ | === Example SIL Database Edit Callback Function === |
||
+ | The following example code is from the '''libtoaster''' source code, available in '''yuma-dev '''and''' yuma-source '''packages. |
||
+ | |||
+ | |||
+ | /******************************************************************** |
||
+ | <nowiki>* FUNCTION y_toaster_toaster_edit</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* Edit database object callback</nowiki> |
||
+ | <nowiki>* Path: /toaster</nowiki> |
||
+ | <nowiki>* Add object instrumentation in COMMIT phase.</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* INPUTS:</nowiki> |
||
+ | <nowiki>* </nowiki> see agt/agt_cb.h for details |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* RETURNS:</nowiki> |
||
+ | <nowiki>* </nowiki> error status |
||
+ | <nowiki>********************************************************************/</nowiki> |
||
+ | |||
+ | static status_t |
||
+ | y_toaster_toaster_edit ( |
||
+ | ses_cb_t *scb, |
||
+ | rpc_msg_t *msg, |
||
+ | agt_cbtyp_t cbtyp, |
||
+ | op_editop_t editop, |
||
+ | val_value_t *newval, |
||
+ | val_value_t *curval) |
||
+ | { |
||
+ | status_t res; |
||
+ | val_value_t *errorval; |
||
+ | const xmlChar *errorstr; |
||
+ | |||
+ | res = NO_ERR; |
||
+ | errorval = NULL; |
||
+ | errorstr = NULL; |
||
+ | |||
+ | switch (cbtyp) { |
||
+ | case AGT_CB_VALIDATE: |
||
+ | /* description-stmt validation here */ |
||
+ | break; |
||
+ | case AGT_CB_APPLY: |
||
+ | /* database manipulation done here */ |
||
+ | break; |
||
+ | case AGT_CB_COMMIT: |
||
+ | /* device instrumentation done here */ |
||
+ | switch (editop) { |
||
+ | case OP_EDITOP_LOAD: |
||
+ | toaster_enabled = TRUE; |
||
+ | toaster_toasting = FALSE; |
||
+ | break; |
||
+ | case OP_EDITOP_MERGE: |
||
+ | break; |
||
+ | case OP_EDITOP_REPLACE: |
||
+ | break; |
||
+ | case OP_EDITOP_CREATE: |
||
+ | toaster_enabled = TRUE; |
||
+ | toaster_toasting = FALSE; |
||
+ | break; |
||
+ | case OP_EDITOP_DELETE: |
||
+ | toaster_enabled = FALSE; |
||
+ | if (toaster_toasting) { |
||
+ | agt_timer_delete(toaster_timer_id); |
||
+ | toaster_timer_id = 0; |
||
+ | toaster_toasting = FALSE; |
||
+ | y_toaster_toastDone_send((const xmlChar *)"error"); |
||
+ | } |
||
+ | break; |
||
+ | default: |
||
+ | res = SET_ERROR(ERR_INTERNAL_VAL); |
||
+ | } |
||
+ | |||
+ | if (res == NO_ERR) { |
||
+ | res = agt_check_cache( |
||
+ | &toaster_val, |
||
+ | newval, |
||
+ | curval, |
||
+ | editop); |
||
+ | } |
||
+ | |||
+ | if (res == NO_ERR && |
||
+ | (editop == OP_EDITOP_LOAD || editop == OP_EDITOP_CREATE)){ |
||
+ | res = y_toaster_toaster_mro(newval); |
||
+ | } |
||
+ | break; |
||
+ | case AGT_CB_ROLLBACK: |
||
+ | /* undo device instrumentation here */ |
||
+ | break; |
||
+ | default: |
||
+ | res = SET_ERROR(ERR_INTERNAL_VAL); |
||
+ | } |
||
+ | |||
+ | /* if error: set the res, errorstr, and errorval parms */ |
||
+ | if (res != NO_ERR) { |
||
+ | agt_record_error( |
||
+ | scb, |
||
+ | &msg->mhdr, |
||
+ | NCX_LAYER_CONTENT, |
||
+ | res, |
||
+ | NULL, |
||
+ | NCX_NT_STRING, |
||
+ | errorstr, |
||
+ | NCX_NT_VAL, |
||
+ | errorval); |
||
+ | } |
||
+ | |||
+ | return res; |
||
+ | |||
+ | } /* y_toaster_toaster_edit */ |
||
+ | |||
+ | === Database Edit Validate Callback Phase === |
||
+ | [[Image:]] |
||
+ | |||
+ | A SIL database validation phase callback function is responsible for checking all the 'description statement' sort of data model requirements that are not covered by any of the YANG machine-readable statements. |
||
+ | |||
+ | For example, if a 'user name' parameter needed to match an existing user name in''' /etc/passwd, '''then the SIL validation callback would call the system APIs needed to check if the 'newval' string value matched a valid user name. The server will make sure the user name is well-formed and could be a valid user name. |
||
+ | |||
+ | === Database Edit Apply Callback Phase === |
||
+ | The callback function for this phase is called when database edits are being applied to the running configuration. The resources needed for the requested operation may be reserved at this time, if needed. |
||
+ | |||
+ | === Database Edit Commit Callback Phase === |
||
+ | This callback function for this phase is called when database edits are being committed to the running configuration. The SIL callback function is expected to finalize and apply any data-model dependent system behavior at this time. |
||
+ | |||
+ | === Database Edit Rollback Callback Phase === |
||
+ | This callback function for this phase is called when database edits are being undone, after some apply phase or commit phase callback function returned an error, or a confirmed commit operation timed out. |
||
+ | |||
+ | The SIL callback function is expected to release any resources it allocated during the apply or commit phases. Usually only the commit or the rollback function will be called for a given SIL callback, but it is possible for both to be called. For example, if the 'rollback-on-error' option is in effect, and some SIL commit callback fails after your SIL commit callback succeeds, then your SIL rollback callback may be called as well. |
||
+ | |||
+ | === Database Virtual Node Get Callback Function === |
||
+ | A common SIL callback function to use is a virtual node 'get' function. A virtual node can be either a configuration or non-configuration node, but is more likely to be a non-configuration node, such as a counter or hardware status object. |
||
+ | |||
+ | The function '''agt_make_virtual_leaf''' in '''agt/agt_util.h''' is a common API used for creating a virtual leaf within an existing parent container. |
||
+ | |||
+ | The following typedef defines the '''getcb_fn_t '''template, used by all virtual callback functions. This function is responsible for filling in a value node with the current instance value. The status NO_ERR is returned if this is done successfully. |
||
+ | |||
+ | |||
+ | /* getcb_fn_t |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* Callback function for agent node get handler </nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* INPUTS:</nowiki> |
||
+ | <nowiki>* </nowiki> scb <nowiki>== session that issued the get (may be NULL)</nowiki> |
||
+ | <nowiki>* </nowiki> can be used for access control purposes |
||
+ | <nowiki>* </nowiki> cbmode == reason for the callback |
||
+ | <nowiki>* </nowiki> virval == place-holder node in the data model for |
||
+ | <nowiki>* </nowiki> this virtual value node |
||
+ | <nowiki>* </nowiki> dstval == pointer to value output struct |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* OUTPUTS:</nowiki> |
||
+ | <nowiki>* </nowiki> <nowiki>*fil may be adjusted depending on callback reason</nowiki> |
||
+ | <nowiki>* </nowiki> <nowiki>*dstval should be filled in, depending on the callback reason</nowiki> |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* RETURNS:</nowiki> |
||
+ | <nowiki>* </nowiki> status: |
||
+ | <nowiki>*/</nowiki> |
||
+ | typedef status_t |
||
+ | (*getcb_fn_t) (ses_cb_t *scb, |
||
+ | getcb_mode_t cbmode, |
||
+ | const val_value_t *virval, |
||
+ | val_value_t *dstval); |
||
+ | |||
+ | The following table describes the parameters. |
||
+ | |||
+ | <center>'''getcb_fn_t Parameters'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Parameter</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| scb |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| This is the session control block making the request, if available. This pointer may be NULL, so in the rare event this parameter is needed by the SIL callback function, it should be checked first. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cbmode |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The callback type. The only supported enumeration at this time is GETCB_GET_VALUE. Other values may be used in the future for different retrieval modes. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| virval |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The virtual value node in the data tree that is being referenced, The''' val_get_virtual_value''' function was called for this value node. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| dstval |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The destination value node that needs to be filled in. This is just an empty value node that has been malloced and then initialized with the '''val_init_from_template''' function. The SIL callback function needs to set the value properly. The '''val_set_simval''' and '''val_set_simval_obj''' functions are two API functions that can be used for this purpose. |
||
+ | |||
+ | |} |
||
+ | The following example from '''agt/agt_ses.c''' shows a SIL get callback function for the ietf-netconf-monitoring data model, which returns the 'in-sessions' counter value: |
||
+ | |||
+ | |||
+ | /******************************************************************** |
||
+ | <nowiki>* FUNCTION agt_ses_get_inSessions</nowiki> |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* <get> operation handler for the inSessions counter</nowiki> |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* INPUTS:</nowiki> |
||
+ | <nowiki>* </nowiki> see ncx/getcb.h getcb_fn_t for details |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* RETURNS:</nowiki> |
||
+ | <nowiki>* </nowiki> status |
||
+ | <nowiki>*********************************************************************/</nowiki> |
||
+ | status_t |
||
+ | agt_ses_get_inSessions (ses_cb_t *scb, |
||
+ | getcb_mode_t cbmode, |
||
+ | const val_value_t *virval, |
||
+ | val_value_t <nowiki>*dstval)</nowiki> |
||
+ | { |
||
+ | (void)scb; |
||
+ | (void)virval; |
||
+ | |||
+ | if (cbmode == GETCB_GET_VALUE) { |
||
+ | VAL_UINT(dstval) = agttotals->inSessions; |
||
+ | return NO_ERR; |
||
+ | } else { |
||
+ | return ERR_NCX_OPERATION_NOT_SUPPORTED; |
||
+ | } |
||
+ | |||
+ | } /* agt_ses_get_inSessions */ |
||
+ | |||
+ | The following example from '''agt/agt_state.c'''<nowiki> shows a complex get callback function for the same data model, which returns the entire <capabilities> element when it is requested. </nowiki>This is done by simply cloning the 'official copy' of the server capabilities that is maintained by the agt/agt_caps.c module. |
||
+ | |||
+ | |||
+ | /******************************************************************** |
||
+ | <nowiki>* FUNCTION get_caps</nowiki> |
||
+ | |||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* <get> operation handler for the capabilities NP container</nowiki> |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* INPUTS:</nowiki> |
||
+ | <nowiki>* </nowiki> see ncx/getcb.h getcb_fn_t for details |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* RETURNS:</nowiki> |
||
+ | <nowiki>* </nowiki> status |
||
+ | <nowiki>*********************************************************************/</nowiki> |
||
+ | static status_t |
||
+ | get_caps (ses_cb_t *scb, |
||
+ | getcb_mode_t cbmode, |
||
+ | val_value_t *virval, |
||
+ | val_value_t <nowiki>*dstval)</nowiki> |
||
+ | { |
||
+ | val_value_t <nowiki>*capsval;</nowiki> |
||
+ | status_t res; |
||
+ | |||
+ | (void)scb; |
||
+ | (void)virval; |
||
+ | res = NO_ERR; |
||
+ | |||
+ | if (cbmode == GETCB_GET_VALUE) { |
||
+ | capsval = val_clone(agt_cap_get_capsval()); |
||
+ | if (!capsval) { |
||
+ | return ERR_INTERNAL_MEM; |
||
+ | } else { |
||
+ | /* change the namespace to this module, |
||
+ | <nowiki>* and get rid of the netconf NSID </nowiki> |
||
+ | <nowiki>*/</nowiki> |
||
+ | val_change_nsid(capsval, statemod->nsid); |
||
+ | val_move_children(capsval, dstval); |
||
+ | val_free_value(capsval); |
||
+ | } |
||
+ | } else { |
||
+ | res = ERR_NCX_OPERATION_NOT_SUPPORTED; |
||
+ | } |
||
+ | return res; |
||
+ | |||
+ | } /* get_caps */ |
||
+ | |||
+ | == Notifications == |
||
+ | The '''yangdump''' program will automatically generate functions to queue a specific notification type for processing. It is up to the SIL callback code to invoke this function when the notification event needs to be generated. The SIL code is expected to provide the value nodes that are needed for any notification payload objects. |
||
+ | |||
+ | === Notification Send Function === |
||
+ | The function to generate a notification control block and queue it for notification replay and delivery is generated by the '''yangdump''' program. A function parameter will exist for each top-level data node defined in the YANG notification definition. |
||
+ | |||
+ | |||
+ | In the example below, the 'toastDone' notification event contains just one leaf, called the 'toastStatus'. <nowiki>There is SIL timer callback code which calls this function, and provides the final toast status, after the <make-toast> operation has been completed or canceled.</nowiki> |
||
+ | |||
+ | |||
+ | /******************************************************************** |
||
+ | <nowiki>* FUNCTION y_toaster_toastDone_send</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* Send a y_toaster_toastDone notification</nowiki> |
||
+ | <nowiki>* Called by your code when notification event occurs</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>********************************************************************/</nowiki> |
||
+ | void |
||
+ | y_toaster_toastDone_send ( |
||
+ | const xmlChar *toastStatus) |
||
+ | { |
||
+ | agt_not_msg_t *notif; |
||
+ | val_value_t *parmval; |
||
+ | status_t res; |
||
+ | |||
+ | res = NO_ERR; |
||
+ | |||
+ | if (LOGDEBUG) { |
||
+ | <nowiki>log_debug("\nGenerating <toastDone> notification");</nowiki> |
||
+ | } |
||
+ | |||
+ | notif = agt_not_new_notification(toastDone_obj); |
||
+ | if (notif == NULL) { |
||
+ | <nowiki>log_error("\nError: malloc failed, cannot send <toastDone> notification");</nowiki> |
||
+ | return; |
||
+ | } |
||
+ | |||
+ | /* add toastStatus to payload */ |
||
+ | parmval = agt_make_leaf( |
||
+ | toastDone_obj, |
||
+ | y_toaster_N_toastStatus, |
||
+ | toastStatus, |
||
+ | &res); |
||
+ | if (parmval == NULL) { |
||
+ | log_error( |
||
+ | <nowiki>"\nError: make leaf failed (%s), cannot send <toastDone> notification",</nowiki> |
||
+ | get_error_string(res)); |
||
+ | } else { |
||
+ | agt_not_add_to_payload(notif, parmval); |
||
+ | } |
||
+ | |||
+ | agt_not_queue_notification(notif); |
||
+ | |||
+ | } /* y_toaster_toastDone_send */ |
||
+ | |||
+ | == Periodic Timer Service == |
||
+ | Some SIL code may need to be called at periodic intervals to check system status, update counters, and/or perhaps send notifications. |
||
+ | |||
+ | The file '''agt/agt_timer.h''' contains the timer access function declarations. |
||
+ | |||
+ | This section provides a brief overview of the SIL timer service. |
||
+ | |||
+ | === Timer Callback Function === |
||
+ | The timer callback function is expected to do a short amount of work, and not block the running process. The function returns zero for a normal exit, and -1 if there was an error and the timer should be destroyed. |
||
+ | |||
+ | The '''agt_timer_fn_t''' template in '''agt/agt_timer.h''' is used to define the SIL timer callback function prototype. This typedef defines the callback function template expected by the server for use with the timer service: |
||
+ | |||
+ | |||
+ | /* timer callback function |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* Process the timer expired event</nowiki> |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* INPUTS:</nowiki> |
||
+ | <nowiki>* </nowiki> timer_id == timer identifier |
||
+ | <nowiki>* </nowiki> cookie == context pointer, such as a session control block, |
||
+ | <nowiki>* </nowiki> passed to agt_timer_set function (may be NULL) |
||
+ | <nowiki>*</nowiki> |
||
+ | <nowiki>* RETURNS:</nowiki> |
||
+ | <nowiki>* </nowiki> 0 == normal exit |
||
+ | <nowiki>* </nowiki> -1 == error exit, delete timer upon return |
||
+ | <nowiki>*/</nowiki> |
||
+ | typedef int (*agt_timer_fn_t) (uint32 timer_id, |
||
+ | void *cookie); |
||
+ | |||
+ | The following table describes the parameters for this callback function: |
||
+ | |||
+ | |||
+ | <center>'''SIL Timer Callback Function Parameters'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Parameter</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| timer_id |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The timer ID that was returned when the '''agt_timer_create''' function was called. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| cookie |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| The cookie parameter value that was passed to the server when the '''agt_timer_create''' function was called. |
||
+ | |||
+ | |} |
||
+ | === Timer Access Functions === |
||
+ | A SIL timer can be set up as a periodic timer or a one-time event. |
||
+ | |||
+ | The timer interval (in seconds) and the SIL timer callback function are provided when the timer is created. A timer can also be restarted if it is running, and the time interval can be changed as well. |
||
+ | |||
+ | The following table highlights the SIL timer access functions in '''agt/agt_timer.h:''' |
||
+ | |||
+ | |||
+ | <center>'''SIL Timer Access Functions'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Function</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_timer_create |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Create a SIL timer. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_timer_restart |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Restart a SIL timer |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| agt_timer_delete |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Delete a SIL timer |
||
+ | |||
+ | |} |
||
+ | === Example Timer Callback Function === |
||
+ | The following example from toaster.c simply completes the toast when the timer expires and calls the auto-generated 'toastDone' send notification function: |
||
+ | |||
+ | |||
+ | /******************************************************************** |
||
+ | <nowiki>* FUNCTION toaster_timer_fn</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* Added timeout function for toaster function</nowiki> |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* INPUTS:</nowiki> |
||
+ | <nowiki>* </nowiki> see agt/agt_timer.h |
||
+ | <nowiki>* </nowiki> |
||
+ | <nowiki>* RETURNS:</nowiki> |
||
+ | <nowiki>* </nowiki> 0 for OK; -1 to kill periodic timer |
||
+ | <nowiki>********************************************************************/</nowiki> |
||
+ | static int |
||
+ | toaster_timer_fn (uint32 timer_id, |
||
+ | void *cookie) |
||
+ | { |
||
+ | (void)timer_id; |
||
+ | (void)cookie; |
||
+ | |||
+ | /* toast is finished */ |
||
+ | toaster_toasting = FALSE; |
||
+ | toaster_timer_id = 0; |
||
+ | if (LOGDEBUG2) { |
||
+ | log_debug2("\ntoast is finished"); |
||
+ | } |
||
+ | y_toaster_toastDone_send((const xmlChar *)"done"); |
||
+ | return 0; |
||
+ | |||
+ | } /* toaster_timer_fn */ |
||
+ | |||
+ | = Server Callback Examples = |
||
+ | This section was written by Mark Pashley for the Yuma Integration Test Suite. |
||
+ | |||
+ | It is included here because it explains the details of SIL callback for several message flow examples. |
||
+ | |||
+ | This document details the SIL callbacks that are made when Yuma processes NETCONF edit queries when configured to use the candidate database configuration (--target=candidate). |
||
+ | |||
+ | == YANG == |
||
+ | The following YANG defines the configuration that is used for all of the examples within this document. |
||
+ | |||
+ | '''container xpo''' { |
||
+ | presence "Indicates that the Device Test API is available."; |
||
+ | description "Top-level container for all configuration and status objects."; |
||
+ | |||
+ | //////////////////////////////////// |
||
+ | // Start of main configuration block |
||
+ | //////////////////////////////////// |
||
+ | '''grouping connectionItem''' { |
||
+ | description "Connection container."; |
||
+ | |||
+ | leaf sourceId { |
||
+ | description "The ID of the item providing the input to the connection."; |
||
+ | type uint32; |
||
+ | } |
||
+ | |||
+ | leaf bitrate { |
||
+ | description "The maximum expected bitrate over this connection."; |
||
+ | type uint32; |
||
+ | units "bps"; |
||
+ | } |
||
+ | } |
||
+ | |||
+ | '''list profile''' { |
||
+ | key id; |
||
+ | description "Profile container."; |
||
+ | |||
+ | leaf id { |
||
+ | description "Unique ID for this profile."; |
||
+ | type uint32; |
||
+ | } |
||
+ | |||
+ | '''list streamConnection''' { |
||
+ | description "Connection between two streams."; |
||
+ | key id; |
||
+ | |||
+ | leaf id { |
||
+ | description "Connection identifier."; |
||
+ | type uint32; |
||
+ | } |
||
+ | |||
+ | uses connectionItem; |
||
+ | } |
||
+ | } |
||
+ | |||
+ | '''leaf activeProfile''' { |
||
+ | description "The number of the active profile."; |
||
+ | type uint32; |
||
+ | } |
||
+ | } |
||
+ | |||
+ | == Edit Operations == |
||
+ | The following sections identify the messages sent by the Netconf Client and the SIL callbacks that will be made. The message sequence charts do not show operations for locking and unlocking of the running and candidate configurations. |
||
+ | |||
+ | === Create an XPO container === |
||
+ | The message sequence chart below shows the expected SIL callbacks for a create xpo container operation. |
||
+ | |||
+ | [[Image:]] |
||
+ | |||
+ | # The client issues an ''rpc edit-config'' to create an xpo container: |
||
+ | |||
+ | <nowiki><?xml version="1.0" encoding="UTF-8"?></nowiki> |
||
+ | <nowiki><rpc message-id="4"</nowiki> |
||
+ | xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" |
||
+ | xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> |
||
+ | <nowiki><edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"></nowiki> |
||
+ | <nowiki><target> <candidate/> </target></nowiki> |
||
+ | <nowiki><default-operation>merge</default-operation></nowiki> |
||
+ | <nowiki><config></nowiki> |
||
+ | <nowiki><xpo xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"</nowiki> |
||
+ | nc:operation="create" |
||
+ | xmlns="http://www.ericsson.com/television/ns/xpo3/base"/> |
||
+ | <nowiki></config></nowiki> |
||
+ | <nowiki></edit-config></nowiki> |
||
+ | <nowiki></rpc></nowiki> |
||
+ | |||
+ | # Netconf executes the ''<nowiki>xpo_edit<validate></nowiki>'' callback to validate the change to the ''candidate'' configuration. |
||
+ | # Netconf executes the ''<nowiki>xpo_edit<apply></nowiki>'' callback to apply the change to the ''candidate'' configuration. |
||
+ | # The client receives an ''rpc-reply'' indicating success. |
||
+ | # The client issues an ''rpc commit'' to commit the change to the ''running'' configuration. |
||
+ | # Netconf executes the ''<nowiki>xpo_edit<validate></nowiki>'' callback to validate the change to the ''running'' configuration. |
||
+ | # Netconf executes the ''<nowiki>xpo_edit<commit create></nowiki>'' callback to perform a create operation change to the ''candidate'' configuration. |
||
+ | # The client receives an ''rpc-reply'' indicating success. |
||
+ | |||
+ | === Create a Profile === |
||
+ | The message sequence chart below shows the expected SIL callbacks for a create profile operation. |
||
+ | |||
+ | [[Image:]] |
||
+ | |||
+ | * The client issues an ''rpc edit-config'' to create a profile: |
||
+ | |||
+ | <nowiki><?xml version="1.0" encoding="UTF-8"?></nowiki> |
||
+ | <nowiki><rpc message-id="5"</nowiki> |
||
+ | xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" |
||
+ | xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> |
||
+ | <nowiki><edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"></nowiki> |
||
+ | <nowiki><target> <candidate/> </target></nowiki> |
||
+ | <nowiki><default-operation>merge</default-operation></nowiki> |
||
+ | <nowiki><config></nowiki> |
||
+ | <nowiki><xpo </nowiki> |
||
+ | xmlns="http://www.ericsson.com/television/ns/xpo3/base"> |
||
+ | <nowiki><profile xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"</nowiki> |
||
+ | <nowiki>nc:operation="create"><id>1</id></profile></xpo></nowiki> |
||
+ | <nowiki></config></nowiki> |
||
+ | <nowiki></edit-config></nowiki> |
||
+ | <nowiki></rpc></nowiki> |
||
+ | |||
+ | * Netconf executes the ''<nowiki>profile_edit<validate></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_id_edit<validate></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_edit<apply></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_id_edit<apply></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * The client receives an ''rpc-reply'' indicating success. |
||
+ | * The client issues an ''rpc commit'' to commit the change to the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_edit<apply></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_id_edit<apply></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_edit<commit create></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_id_edit< commit create ></nowiki>'' callback for the ''running'' configuration. |
||
+ | * The client receives an ''rpc-reply'' indicating success. |
||
+ | |||
+ | === Create a Stream Connection === |
||
+ | The message sequence chart below shows the expected SIL callbacks for a create profile stream connection operation. In this scenario the XPO container is empty prior to step 1. |
||
+ | |||
+ | [[Image:]] |
||
+ | |||
+ | * The client issues an ''rpc edit-config'' to create a profile stream connection. (Note the profile has not previously been created) |
||
+ | |||
+ | <nowiki><?xml version="1.0" encoding="UTF-8"?></nowiki> |
||
+ | <nowiki><rpc message-id="5"</nowiki> |
||
+ | xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" |
||
+ | xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> |
||
+ | <nowiki><edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"></nowiki> |
||
+ | <nowiki><target> <candidate/> </target></nowiki> |
||
+ | <nowiki><default-operation>merge</default-operation></nowiki> |
||
+ | <nowiki><config></nowiki> |
||
+ | <nowiki><xpo xmlns="http://www.ericsson.com/television/ns/xpo3/base"></nowiki> |
||
+ | <nowiki><profile><id>1</id></nowiki> |
||
+ | <nowiki><streamConnection xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="create"><id>1</id></nowiki> |
||
+ | <nowiki><sourceId>100</sourceId></nowiki> |
||
+ | <nowiki><bitrate>500</bitrate></nowiki> |
||
+ | <nowiki></streamConnection></nowiki> |
||
+ | <nowiki></profile></xpo></nowiki> |
||
+ | <nowiki></config></nowiki> |
||
+ | <nowiki></edit-config></nowiki> |
||
+ | <nowiki></rpc></nowiki> |
||
+ | |||
+ | * Netconf executes the ''<nowiki>profile_edit<validate></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_id_edit<validate></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_edit<validate></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_id_edit<validate></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_sourceId_edit<validate></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_bitrate_edit<validate></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_edit<apply></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_id_edit<apply></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_edit<apply></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_id_edit<apply></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_sourceId_edit<apply></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_bitrate_edit<apply></nowiki>'' callback for the ''candidate'' configuration. |
||
+ | * The client receives an ''rpc-reply'' indicating success. |
||
+ | * The client issues an ''rpc commit'' to commit the change to the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_edit<apply></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_id_edit<apply></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_edit<apply></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_id_edit<apply></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_sourceId_edit<apply></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_bitrate_edit<apply></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_edit<commit create></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_id_edit<commit create></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_edit<commit create></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_id_edit<commit create></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_sourceId_edit<commit create></nowiki>'' callback for the ''running'' configuration. |
||
+ | * Netconf executes the ''<nowiki>profile_streamConnection_bitrate_edit<commit create></nowiki>'' callback for the ''running'' configuration. |
||
+ | * The client receives an ''rpc-reply'' indicating success. |
||
+ | |||
+ | === Delete an XPO Container === |
||
+ | The message sequence chart below shows the expected SIL callbacks for a delete xpo container operation. In this scenario the XPO container is populated with at last one profile prior to step 1. |
||
+ | |||
+ | [[Image:]] |
||
+ | |||
+ | # The client issues an ''rpc edit-config'' to delete an xpo container: |
||
+ | |||
+ | <nowiki><?xml version="1.0" encoding="UTF-8"?></nowiki> |
||
+ | <nowiki><rpc message-id="10"</nowiki> |
||
+ | xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" |
||
+ | xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> |
||
+ | <nowiki><edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"></nowiki> |
||
+ | <nowiki><target> <candidate/> </target></nowiki> |
||
+ | <nowiki><default-operation>merge</default-operation></nowiki> |
||
+ | <nowiki><config></nowiki> |
||
+ | <nowiki><xpo xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"</nowiki> |
||
+ | nc:operation="delete" |
||
+ | xmlns="http://www.ericsson.com/television/ns/xpo3/base"/> |
||
+ | <nowiki></config></nowiki> |
||
+ | <nowiki></edit-config></nowiki> |
||
+ | <nowiki></rpc></nowiki> |
||
+ | |||
+ | # Netconf executes the ''<nowiki>xpo_edit<validate></nowiki>'' callback to validate the change to the ''candidate'' configuration. |
||
+ | # Netconf executes the ''<nowiki>xpo_edit<apply></nowiki>'' callback to apply the change to the ''candidate'' configuration. |
||
+ | # The client receives an ''rpc-reply'' indicating success. |
||
+ | # The client issues an ''rpc commit'' to commit the change to the ''running'' configuration. |
||
+ | # Netconf executes the ''<nowiki>xpo_edit<validate></nowiki>'' callback to validate the change to the ''running'' configuration. |
||
+ | # Netconf executes the ''<nowiki>xpo_edit<commit delete></nowiki>'' callback to perform a create operation change to the ''candidate'' configuration. |
||
+ | # The client receives an ''rpc-reply'' indicating success. |
||
+ | |||
+ | === Delete a Profile === |
||
+ | The message sequence chart below shows the expected SIL callbacks for a delete xpo profile operation. In this scenario the XPO container is populated with at last one profile prior to step 1. |
||
+ | |||
+ | [[Image:]] |
||
+ | |||
+ | # The client issues an ''rpc edit-config'' to delete a profile: |
||
+ | |||
+ | <nowiki><?xml version="1.0" encoding="UTF-8"?></nowiki> |
||
+ | <nowiki><rpc message-id="10"</nowiki> |
||
+ | xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" |
||
+ | xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> |
||
+ | <nowiki><edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"></nowiki> |
||
+ | <nowiki><target> <candidate/> </target></nowiki> |
||
+ | <nowiki><default-operation>merge</default-operation></nowiki> |
||
+ | <nowiki><config></nowiki> |
||
+ | <nowiki><xpo xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"></nowiki> |
||
+ | <nowiki><profile xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete"><id>1</id></profile></xpo></nowiki> |
||
+ | <nowiki></config></nowiki> |
||
+ | <nowiki></edit-config></nowiki> |
||
+ | <nowiki></rpc></nowiki> |
||
+ | |||
+ | # Netconf executes the ''<nowiki>xpo_profile_edit<validate></nowiki>'' callback to validate the change to the ''candidate'' configuration. |
||
+ | # Netconf executes the ''<nowiki>xpo_ profile_edit<apply></nowiki>'' callback to apply the change to the ''candidate'' configuration. |
||
+ | # The client receives an ''rpc-reply'' indicating success. |
||
+ | # The client issues an ''rpc commit'' to commit the change to the ''running'' configuration. |
||
+ | # Netconf executes the ''<nowiki>xpo_ profile_edit<validate></nowiki>'' callback to validate the change to the ''running'' configuration. |
||
+ | # Netconf executes the ''<nowiki>xpo_ profile_edit<commit delete></nowiki>'' callback to perform a create operation change to the ''candidate'' configuration. |
||
+ | # The client receives an ''rpc-reply'' indicating success. |
||
+ | |||
+ | === Delete a Stream Connection === |
||
+ | Deleting a stream connection is no different to deleting a profile. For delete operations SIL callbacks are only made for the highest level node that is being deleted. |
||
+ | |||
+ | |||
+ | = Development Environment = |
||
+ | This section describes the Yuma Tools development environment used to produce the Linux binaries. |
||
+ | |||
+ | |||
+ | == Programs and Libraries Needed == |
||
+ | There are several components used in the Yuma software development environment: |
||
+ | |||
+ | * gcc compiler and linker |
||
+ | * ldconfig and install programs |
||
+ | * GNU make program |
||
+ | * shell program, such as bash |
||
+ | * Yuma development tree: the source tree containing Yuma code, specified with the '''$YUMA_HOME''' environment variable. |
||
+ | * SIL development tree: the source tree containing server instrumentation code |
||
+ | |||
+ | The following external program is used by Yuma, and needs to be pre-installed: |
||
+ | |||
+ | * '''opensshd (needed by netconfd)''' |
||
+ | ** The SSH2 server code does not link with '''netconfd'''. Instead, the '''netconf-subsystem''' program is invoked, and local connections are made to the '''netconfd''' server from this SSH2 subsystem. |
||
+ | |||
+ | The following program is part of Yuma Tools, and needs to be installed: |
||
+ | |||
+ | * '''netconf-subsystem (needed by netconfd)''' |
||
+ | ** The thin client sub-program that is called by '''sshd''' when a new SSH2 connection to the 'netconf' sub-system is attempted. |
||
+ | *** This program will use an AF_LOCAL socket, using a proprietary '''<nowiki><ncxconnect></nowiki>''' message, to communicate with the '''netconfd''' server.. |
||
+ | *** After establishing a connection with the '''netconfd''' server, this program simply transfers SSH2 NETCONF channel data between '''sshd''' and '''netconfd'''. |
||
+ | |||
+ | The following program is part of Yuma Tools, and usually found within the Yuma development tree: |
||
+ | |||
+ | * '''netconfd''' |
||
+ | ** The NETCONF server that processes all protocol operations. |
||
+ | *** The '''agt_ncxserver''' component will listen for '''<nowiki><ncxconnect></nowiki>''' messages on the designated socket (/tmp/ncxserver.sock). If an invalid message is received, the connection will be dropped. Otherwise, the''' netconf-subsystem '''will begin passing NETCONF channel data to the netconfd server. <nowiki>The first message is expected to be a valid NETCONF <hello> PDU. </nowiki>If |
||
+ | |||
+ | The following external libraries are used by Yuma, and need to be pre-installed: |
||
+ | |||
+ | * '''ncurses (needed by yangcli)''' |
||
+ | ** character processing library needed by '''libtecla'''<nowiki>; used within </nowiki>'''yangcli''' |
||
+ | * '''libc (or glibc, needed by all applications)''' |
||
+ | ** unix system library |
||
+ | * '''libssh2 (needed by yangcli)''' |
||
+ | ** SSH2 client library, used by yangcli |
||
+ | * '''libxml2 (needed by all applications)''' |
||
+ | ** xmlTextReader XML parser |
||
+ | ** pattern support |
||
+ | |||
+ | == SIL Makefile == |
||
+ | The SIL Makefile is based on the Makefile for Yuma sources. The automake program is not used at this time. There is no ./configure script to run. There are 2 basic build steps: |
||
+ | |||
+ | # make |
||
+ | # <nowiki>[sudo] make install</nowiki> |
||
+ | |||
+ | The installation step may require root access via the '''sudo''' program, depending on the system. |
||
+ | |||
+ | === Target Platforms === |
||
+ | The following target platforms are supported: |
||
+ | |||
+ | * '''Fedora and Ubuntu''': These are the default targets and no special command line options are needed. |
||
+ | |||
+ | === Build Targets === |
||
+ | The following table describes the build targets that are supported: |
||
+ | |||
+ | |||
+ | <center>'''Yuma Build Targets'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Make Target</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| all |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Make everything. This is the default if not target is specified. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| depend |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Make the dependencies files. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| clean |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Remove the target files. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| superclean |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Remove all the dependencies and the target files. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| distclean |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Remove all the distribution files that make be installed, all the dependencies and the target files. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| test |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Make any test code. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| lint |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Run a lint program on the source files. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| install |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Install the components into the system. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| uninstall |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Remove the components from the system. |
||
+ | |||
+ | |} |
||
+ | === Command Line Build Options === |
||
+ | There are several command line options that can be used when making the Yuma source code. These may have an impact on building and linking the SIL source code. The following table describes these options: |
||
+ | |||
+ | |||
+ | <center>'''Yuma Build Parameters for 'make''''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Make Parameter</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| CYGWIN=1 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Build for the Windows Cygwin target environment. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| DEBUG=1 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Generate debug symbols for '''gdb''' debugging, and do not generate optimized binary code. The default is not to generate symbols, and instead use -O2 optimization. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ETC_PREFIX |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Build 'etc' install directory to use (default /etc) |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| LIB64=1 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Build so that SIL libraries are installed in the 'lib64' directory |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| MAC=1 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Build the software for the Mac OS X platform. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| MEMTRACE=1 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Enabled 'mtrace' memory leak debugging to identify the exact nodes which were malloced but never freed. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| NOFLOAT=1 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Defining this make flag will force the server to implement XPath numbers with a string representation instead of using the 'double' data type from the floating point library. <nowiki>This will impact the correctness of XPath expression evaluation, so this should not be done unless the <math.h> library support is not available. (Required for CYGWIN=1)</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| PREFIX=string |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Build Root path to use (default /usr) |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| RELEASE=n |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Builds release 'n' (version-release) for Ubuntu or RPM package distribution |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| STATIC=1 |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Build static libraries instead of dynamic libraries, where needed. This sometimes makes debugging simpler and faster. Embedded systems without dynamic library support need to use this make option.(Required for CYGWIN=1) |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| STATIC_SERVER |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Defining this make flag forces the server not to require or use the 'dylib' functions to dynamically load SIL libraries at run-time, without requiring ldconfig. Instead, the server will assume the server code has been modified so these SIL libraries are initialized and cleaned up statically. |
||
+ | |||
+ | |} |
||
+ | === Example SIL Makefile === |
||
+ | The script '''/usr/bin/make_sil_dir''' is used to automatically create a SIL work sub-directory tree. Support files are located in the '''/usr/share/yuma/util '''directory. |
||
+ | |||
+ | The following Makefile is for the '''libtoaster''' library, supporting the''' toaster.yang''' module: |
||
+ | |||
+ | |||
+ | <nowiki># SIL Makefile for Yuma Server Instrumentation Library</nowiki> |
||
+ | <nowiki># </nowiki> |
||
+ | |||
+ | <nowiki>############### SOURCE PROFILE ##############################</nowiki> |
||
+ | |||
+ | SUBDIR_NM=toaster |
||
+ | |||
+ | SUBDIR_CPP= |
||
+ | |||
+ | <nowiki>############### TARGET PROFILE ##############################</nowiki> |
||
+ | |||
+ | TARGET=../bin |
||
+ | |||
+ | LIB_INST=../lib |
||
+ | |||
+ | WORK_INST=$(YUMA_HOME)/target/lib |
||
+ | |||
+ | REAL_INST=$(DESTDIR)/usr/lib/yuma |
||
+ | |||
+ | <nowiki>#################### MAKE RULES ########################</nowiki> |
||
+ | |||
+ | all: sil_dummy sil_lib |
||
+ | |||
+ | <nowiki>#################### PLATFORM DEFINITIONS ############</nowiki> |
||
+ | |||
+ | ifdef YUMA_HOME |
||
+ | CINC = -I. \ |
||
+ | -I$(YUMA_HOME)/src/platform \ |
||
+ | -I$(YUMA_HOME)/src/ncx \ |
||
+ | -I$(YUMA_HOME)/src/agt \ |
||
+ | -I/usr/include \ |
||
+ | -I/usr/include/libxml2 \ |
||
+ | -I/usr/include/libxml2/libxml |
||
+ | else |
||
+ | ifdef YUMA_INSTALL |
||
+ | CINC = -I. \ |
||
+ | -I$(YUMA_INSTALL)/src/platform \ |
||
+ | -I$(YUMA_INSTALL)/src/ncx \ |
||
+ | -I$(YUMA_INSTALL)/src/agt \ |
||
+ | -I/usr/include \ |
||
+ | -I/usr/include/libxml2 \ |
||
+ | -I/usr/include/libxml2/libxml |
||
+ | else |
||
+ | CINC = -I. \ |
||
+ | -I/usr/share/yuma/src/netconf/src/platform \ |
||
+ | -I/usr/share/yuma/src/netconf/src/ncx \ |
||
+ | -I/usr/share/yuma/src/netconf/src/agt \ |
||
+ | -I/usr/include \ |
||
+ | -I/usr/include/libxml2 \ |
||
+ | -I/usr/include/libxml2/libxml |
||
+ | endif |
||
+ | endif |
||
+ | |||
+ | <nowiki># added /sw/include for MacOSX</nowiki> |
||
+ | ifdef MAC |
||
+ | <nowiki># MACOSX version</nowiki> |
||
+ | CINC +=-I/sw/include |
||
+ | CFLAGS += -DMACOSX=1 |
||
+ | endif |
||
+ | |||
+ | LBASE=../lib |
||
+ | |||
+ | ifdef DESTDIR |
||
+ | OWNER= |
||
+ | else |
||
+ | ifdef MAC |
||
+ | OWNER=-oroot |
||
+ | else |
||
+ | OWNER= --owner=root |
||
+ | endif |
||
+ | endif |
||
+ | |||
+ | <nowiki>### GCC + [LINUX or MACOSX]</nowiki> |
||
+ | |||
+ | CWARN=-Wall -Wno-long-long -Wformat-y2k -Winit-self \ |
||
+ | -Wmissing-include-dirs -Wswitch-default -Wunused-parameter \ |
||
+ | -Wextra -Wundef -Wshadow -Wpointer-arith \ |
||
+ | -Wwrite-strings -Wbad-function-cast -Wcast-qual -Wcast-align \ |
||
+ | -Waggregate-return -Wstrict-prototypes -Wold-style-definition \ |
||
+ | -Wmissing-prototypes -Wmissing-declarations \ |
||
+ | -Wpacked -Winvalid-pch \ |
||
+ | -Wredundant-decls -Wnested-externs -Winline -std=gnu99 -Werror |
||
+ | |||
+ | <nowiki># -Wunreachable-code removed due to -O3</nowiki> |
||
+ | <nowiki># -O3 changed to -O2 due to code bloat from inline functions</nowiki> |
||
+ | |||
+ | CDEFS=-DDEBUG -DLINUX -DGCC |
||
+ | |||
+ | ifndef NOFLOAT |
||
+ | CDEFS += -DHAS_FLOAT |
||
+ | endif |
||
+ | |||
+ | CFLAGS=$(CDEFS) $(CWARN) -fPIC |
||
+ | |||
+ | <nowiki># production (0) or debug (1) build</nowiki> |
||
+ | ifdef DEBUG |
||
+ | CFLAGS += -ggdb3 |
||
+ | else |
||
+ | CFLAGS += -O2 |
||
+ | endif |
||
+ | |||
+ | <nowiki># memory leak debugging mode</nowiki> |
||
+ | ifdef MEMTRACE |
||
+ | CFLAGS += -DMEMORY_DEBUG=1 |
||
+ | endif |
||
+ | |||
+ | <nowiki># free or SDK version</nowiki> |
||
+ | ifdef FREE |
||
+ | CFLAGS += -DFREE_VERSION |
||
+ | endif |
||
+ | |||
+ | ifdef RELEASE |
||
+ | CFLAGS += -DRELEASE=$(RELEASE) |
||
+ | endif |
||
+ | |||
+ | ifdef MAC |
||
+ | GRP= |
||
+ | else |
||
+ | ifdef DESTDIR |
||
+ | GRP= |
||
+ | else |
||
+ | GRP=--group=root |
||
+ | endif |
||
+ | endif |
||
+ | |||
+ | ifdef STATIC |
||
+ | LIBSUFFIX=a |
||
+ | else |
||
+ | ifdef MAC |
||
+ | LIBSUFFIX=dylib |
||
+ | else |
||
+ | LIBSUFFIX=so |
||
+ | endif |
||
+ | endif |
||
+ | |||
+ | CC=gcc |
||
+ | LINK=gcc |
||
+ | LINT=splint |
||
+ | LINTFLAGS= '-weak -macrovarprefix "m_"' |
||
+ | <nowiki>##LIBFLAGS=-lsocket</nowiki> |
||
+ | |||
+ | LIBTOOL=ar |
||
+ | <nowiki>#LFLAGS=-v --no-as-needed</nowiki> |
||
+ | LFLAGS=-lm |
||
+ | LPATH=-L$(LBASE) |
||
+ | |||
+ | CEES = $(wildcard *.c) |
||
+ | HEES = $(wildcard *.h) |
||
+ | |||
+ | <nowiki>################ OBJS RULE #############</nowiki> |
||
+ | OBJS = $(patsubst %.c,$(TARGET)/%.o,$(CEES)) |
||
+ | |||
+ | <nowiki>################ DEPS RULE #############</nowiki> |
||
+ | DEPS = $(patsubst %.c,%.D,$(wildcard *.c)) |
||
+ | |||
+ | <nowiki>######################## PLATFORM DEFINITIONS #############</nowiki> |
||
+ | PLATFORM_CPP= |
||
+ | |||
+ | .PHONY: all superclean clean test install uninstall \ |
||
+ | distclean depend lint |
||
+ | |||
+ | <nowiki>######################### MAKE DEPENDENCIES ###############</nowiki> |
||
+ | COMPILE.c= $(CC) $(CFLAGS) $(CPPFLAGS) $(PLATFORM_CPP) \ |
||
+ | $(CINC) $(SUBDIR_CPP) $(TARGET_ARCH) -c |
||
+ | |||
+ | $(TARGET)/%.o: %.c |
||
+ | $(CC) $(CFLAGS) $(CPPFLAGS) $(PLATFORM_CPP) \ |
||
+ | <nowiki>$(CINC) $(SUBDIR_CPP) $(TARGET_ARCH) -c -o $@ $< </nowiki> |
||
+ | |||
+ | <nowiki># Common library rule</nowiki> |
||
+ | |||
+ | $(LBASE)/lib%.a: $(OBJS) |
||
+ | $(LIBTOOL) cr $@ $(OBJS) |
||
+ | ranlib $@ |
||
+ | |||
+ | <nowiki># dependency rule to make temp .D files from .c sources</nowiki> |
||
+ | <nowiki># all the .D files are collected and appended to the</nowiki> |
||
+ | <nowiki># appropriate Makefile when 'make depend' is run</nowiki> |
||
+ | <nowiki># this rule is kept here to make sure it matches COMPILE.c</nowiki> |
||
+ | %.D: %.c |
||
+ | <nowiki>$(CC) -MM -MG -MT $(TARGET)/$(patsubst %.c,%.o,$<) \</nowiki> |
||
+ | -Wall -Wcomment $(CPPFLAGS) $(PLATFORM_CPP) $(CINC) \ |
||
+ | <nowiki>$(SUBDIR_CPP) $(TARGET_ARCH) -c $< > $@</nowiki> |
||
+ | |||
+ | <nowiki>################## MAKE DEPENDENCIES #####################</nowiki> |
||
+ | <nowiki># following depend rule is the GNU version! Other versions TBD</nowiki> |
||
+ | <nowiki># this rule cannot be included by the top level makefile</nowiki> |
||
+ | <nowiki># so platform.profile.cmn was created to allow that Makefile</nowiki> |
||
+ | <nowiki># to define a different 'depend' rule.</nowiki> |
||
+ | depend: dependencies |
||
+ | |||
+ | dependencies: $(DEPS) |
||
+ | <nowiki>@if [ ! -f Makefile ]; then \</nowiki> |
||
+ | echo "Error: Makefile missing!"; \ |
||
+ | exit 1; \ |
||
+ | fi |
||
+ | @rm -f dependencies |
||
+ | @for i in $(DEPS); do \ |
||
+ | <nowiki>if [ -f $$i ] ; then \</nowiki> |
||
+ | (cat $$i >> dependencies; echo "" >> dependencies) ; \ |
||
+ | else \ |
||
+ | (echo "*** Warning: Dependency file $i.D is missing! (Skipping...) ***"; \ |
||
+ | echo "# Warning: Missing file $$i !!!") ; \ |
||
+ | fi; \ |
||
+ | done |
||
+ | @echo "" >> dependencies |
||
+ | <nowiki># delete the .D files to force make depend to rebuild them each time</nowiki> |
||
+ | <nowiki># that target is built</nowiki> |
||
+ | <nowiki>#</nowiki> @rm -f $(DEPS) |
||
+ | |||
+ | <nowiki>################ DEPENDENCIES #########################</nowiki> |
||
+ | <nowiki># depend rule must be included after the 'all' make rule</nowiki> |
||
+ | |||
+ | include ../../netconf/src/platform/platform.profile.depend |
||
+ | |||
+ | test: |
||
+ | |||
+ | install: |
||
+ | mkdir -p $(REAL_INST) |
||
+ | $(SUDO) install $(LIB_INST)/lib$(SUBDIR_NM).$(LIBSUFFIX) $(REAL_INST) |
||
+ | |||
+ | work: |
||
+ | install $(LIB_INST)/lib$(SUBDIR_NM).$(LIBSUFFIX) $(WORK_INST) |
||
+ | |||
+ | sil_lib: $(LIB_INST)/lib$(SUBDIR_NM).$(LIBSUFFIX) |
||
+ | |||
+ | <nowiki># this dummy rule keeps make from deleting the $(OBJS) as</nowiki> |
||
+ | <nowiki># intermediate files</nowiki> |
||
+ | sil_dummy: dependencies $(OBJS) |
||
+ | |||
+ | clean: |
||
+ | rm -f $(OBJS) $(LIB_INST)/lib$(SUBDIR_NM).* |
||
+ | |||
+ | superclean: |
||
+ | rm -f *~ $(DEPS) dependencies $(OBJS) \ |
||
+ | $(LIB_INST)/lib$(SUBDIR_NM).* |
||
+ | |||
+ | $(LIB_INST)/lib$(SUBDIR_NM).so: $(OBJS) |
||
+ | gcc -shared -rdynamic -Wl,-soname,lib$(SUBDIR_NM).so -o $@ $(OBJS) -ldl |
||
+ | |||
+ | <nowiki>#</nowiki> gcc -shared -Wl,-soname,libtoaster.so -o $@ $(OBJS) -lc |
||
+ | |||
+ | $(LBASE)/lib$(SUBDIR_NM).dylib: $(OBJS) |
||
+ | gcc -shared -dynamiclib -std=gnu99 -current_version 1.0 \ |
||
+ | -undefined dynamic_lookup \ |
||
+ | -o $@ -install_name lib$(SUBDIR_NM).dylib $(OBJS) -lxml2 |
||
+ | |||
+ | code: |
||
+ | yangdump format=h indent=4 module=$(SUBDIR_NM) output=$(SUBDIR_NM).h |
||
+ | yangdump format=c indent=4 module=$(SUBDIR_NM) output=$(SUBDIR_NM).c |
||
+ | |||
+ | <nowiki># prevent the make program from choking on all the symbols</nowiki> |
||
+ | <nowiki># that get generated from autogenerated make rules</nowiki> |
||
+ | .NOEXPORT: |
||
+ | |||
+ | include dependencies |
||
+ | |||
+ | == Automation Control == |
||
+ | The YANG language includes many ways to specify conditions for database validity, which traditionally are only documented in DESCRIPTION clauses. The YANG language allows vendors and even data modelers to add new statements to the standard syntax, in a way that allows all tools to skip extension statements that they do not understand. |
||
+ | |||
+ | The '''yangdump''' YANG compiler sames all the non-standard language statements it finds, even those it does not recognize. These are stores in the '''ncx_appinfo_t''' data structure in '''ncx/ncxtypes.h'''.. |
||
+ | |||
+ | There are also SIL access functions defined in '''ncx/ncx_appinfo.h''' that allow these language statements to be accessed. If an argument string was provided, it is saved along with the command name. |
||
+ | |||
+ | Several data structures contains an 'appinfoQ' field to contain all the ncx_appinfo_t stuctures that were generated within the same YANG syntax block (e.g., within a typedef, type, leaf, import statement). |
||
+ | |||
+ | === Built-in YANG Language Extensions === |
||
+ | There are several YANG extensions that are supported by Yuma. They are all defined in the YANG file named '''ncx.yang'''. They are used to 'tag' YANG definitions for some sort of automatic processing by Yuma programs. Extensions are position-sensitive, and if not used in the proper context, they will be ignored. A YANG extension statement must be defined (somewhere) for every extension used in a YANG file, or an error will be occur. |
||
+ | |||
+ | Most of these extensions apply to '''netconfd''' server behavior, but not all of them. For example, the '''ncx:hidden''' extension will prevent '''yangcli''' from displaying help for an object containing this extension. Also, '''yangdump''' will skip this object in HTML output mode. |
||
+ | |||
+ | The following table describes the supported YANG language extensions. All other YANG extension statements will be ignored by Yuma, if encountered in a YANG file: |
||
+ | |||
+ | |||
+ | <center>'''YANG Language Extensions'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | | style="border-top:0.5pt solid #000000;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:none;padding:0.0382in;"| <center>'''extension'''</center> |
||
+ | | style="border:0.5pt solid #000000;padding:0.0382in;"| <center>'''description'''</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:none;padding:0.0382in;"| '''ncx:hidden'''<nowiki>;</nowiki> |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding:0.0382in;"| Declares that the object definition should be hidden from all automatic documentation generation. Help will not be available for the object in '''yangcli'''. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:none;padding:0.0382in;"| '''ncx:metadata ''' “''attr-type attr-name''”; |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding:0.0382in;"| Defines a qualified XML attribute in the module namespace. |
||
+ | |||
+ | Allowed within an RPC input parameter. |
||
+ | |||
+ | '''attr-type''' is a valid type name with optional YANG prefix. |
||
+ | |||
+ | '''attr-name''' is the name of the XML attribute. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:none;padding:0.0382in;"| '''ncx:no-duplicates'''<nowiki>;</nowiki> |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding:0.0382in;"| Declares that the '''ncx:xsdlist''' data type is not allowed to contain duplicate values. The default is to allow duplicate token strings within an '''ncx:xsdlist''' value. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:none;padding:0.0382in;"| '''ncx:password'''<nowiki>;</nowiki> |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding:0.0382in;"| Declares that a string data type is really a password, and will not be displayed or matched by any filter. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:none;padding:0.0382in;"| '''ncx:qname;''' |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding:0.0382in;"| Declares that a string data type is really an XML qualified name. XML prefixes will be properly generated by '''yangcli''' and '''netconfd'''. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:none;padding:0.0382in;"| '''ncx:root'''<nowiki>;</nowiki> |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding:0.0382in;"| <nowiki>Declares that the container parameter is really a NETCONF database root, like <config> in the <edit-config> operations. </nowiki>The child nodes of this container are not specified in the YANG file. Instead, they are allowed to contain any top-level object from any YANG file supported by the server. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:none;padding:0.0382in;"| '''ncx:schema-instance'''<nowiki>;</nowiki> |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding:0.0382in;"| Declares that a string data type is really an special schema instance identifier string. It is the same as an instance-identifier built-in type except the key leaf predicates are optional. For example, missing key values indicate wild cards that will match all values in '''nacm'''<nowiki> <dataRule> expressions.</nowiki> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:none;padding:0.0382in;"| '''ncx:secure;''' |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding:0.0382in;"| Declares that the database object is a secure object. |
||
+ | |||
+ | If the object is an '''rpc''' statement, then only the '''netconfd''' 'superuser' will be allowed to invoke this operation by default. |
||
+ | |||
+ | Otherwise, only read access will be allowed to this object by default, Write access will only be allowed by the 'superuser', by default. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:none;padding:0.0382in;"| '''ncx:very-secure;''' |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding:0.0382in;"| Declares that the database object is a very secure object. |
||
+ | |||
+ | Only the 'superuser' will be allowed to access the object, by default. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:none;padding:0.0382in;"| '''ncx:xsdlist''' “''list-type''”<nowiki>;</nowiki> |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding:0.0382in;"| Declares that a string data type is really an XSD style list. |
||
+ | |||
+ | '''list-type''' is a valid type name with optional YANG prefix. |
||
+ | |||
+ | <nowiki>List processing within <edit-config> will be automatically handled by </nowiki>'''netconfd'''. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:none;padding:0.0382in;"| '''ncx:xpath'''<nowiki>;</nowiki> |
||
+ | | style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding:0.0382in;"| Declares that a string data type is really an XPath expression. XML prefixes and all XPath processing will be done automatically by '''yangcli''' and '''netconfd'''. |
||
+ | |||
+ | |} |
||
+ | === SIL Language Extension Access Functions === |
||
+ | The following table highlights the SIL functions in ncx/ncx_appinfo.h that allow SIL code to examine any of the non-standard language statements that were found in the YANG module: |
||
+ | |||
+ | |||
+ | <center>'''Language Extension Access Functions'''</center> |
||
+ | |||
+ | |||
+ | |||
+ | {| style="border-spacing:0;" |
||
+ | ! <center>Function</center> |
||
+ | ! <center>Description</center> |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ncx_find_appinfo |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Find an '''ncx_appinfo_t '''structure by its prefix and name, in a queue of these entries. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ncx_find_next_appinfo |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Find the next occurrence of the specified '''ncx_appinfo_t''' data structure. |
||
+ | |||
+ | |- |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:none;padding:0.0382in;"| ncx_clone_appinfo |
||
+ | | style="border-top:none;border-bottom:0.05pt solid #000000;border-left:0.05pt solid #000000;border-right:0.05pt solid #000000;padding:0.0382in;"| Clone the specified''' ncx_appinfo_t''' data structure. |
||
+ | |||
+ | |} |
Revision as of 17:33, 22 December 2015
Contents
- 1 Table of Contents
- 2 Legal Statements
- 3 Additional Resources
- 4 Conventions Used in this Document
- 5 Software Overview
- 5.1 Introduction
- 5.2 Yuma Source Files
- 5.3 Server Design
- 5.4 Server Operation
- 5.5 Built-in Server Modules
- 5.5.1 ietf-inet-types.yang
- 5.5.2 ietf-netconf-monitoring.yang
- 5.5.3 ietf-with-defaults.yang
- 5.5.4 ietf-yang-types.yang
- 5.5.5 nc-notifications.yang
- 5.5.6 notifications.yang
- 5.5.7 yuma-app-common.yang
- 5.5.8 yuma-interfaces.yang
- 5.5.9 yuma-mysession.yang
- 5.5.10 yuma-nacm.yang
- 5.5.11 yuma-ncx.yang
- 5.5.12 yuma-netconf.yang
- 5.5.13 yuma-proc.yang
- 5.5.14 yuma-system.yang
- 5.5.15 yuma-time-filter.yang
- 5.5.16 yuma-types.yang
- 6 YANG Objects and Data Nodes
- 7 SIL External Interface
- 8 SIL Callback Interface
- 8.1 RPC Operation Interface
- 8.2 Database Operations
- 8.2.1 Database Template (cfg_template_t)
- 8.2.2 Database Access Functions
- 8.2.3 Database Callback Initialization and Cleanup
- 8.2.4 Example SIL Database Edit Callback Function
- 8.2.5 Database Edit Validate Callback Phase
- 8.2.6 Database Edit Apply Callback Phase
- 8.2.7 Database Edit Commit Callback Phase
- 8.2.8 Database Edit Rollback Callback Phase
- 8.2.9 Database Virtual Node Get Callback Function
- 8.3 Notifications
- 8.4 Periodic Timer Service
- 9 Server Callback Examples
- 10 Development Environment
Table of Contents
1 Preface4
1.1 Legal Statements4
1.2 Additional Resources4
1.2.1 WEB Sites4
1.2.2 Mailing Lists5
1.3 Conventions Used in this Document5
2 Software Overview6
2.1 Introduction6
2.1.1 Intended Audience6
2.1.2 What does Yuma Do?6
2.1.3 What is a Yuma Root?7
2.1.4 Searching Yuma Roots8
2.1.5 What is a SIL?9
2.1.6 Auto-generated SIL Files9
2.1.7 Basic Development Steps10
2.2 Yuma Source Files11
2.2.1 src/ncx Directory11
2.2.2 src/platform Directory13
2.2.3 src/agt Directory13
2.2.4 src/mgr Directory14
2.2.5 src/subsys Directory15
2.2.6 src/netconfd Directory15
2.2.7 src/yangcli Directory15
2.2.8 src/yangdiff Directory16
2.2.9 src/yangdump Directory16
2.3 Server Design17
2.3.1 YANG Native Operation18
2.3.2 YANG Object Tree19
2.3.3 YANG Data Tree20
2.3.4 Service Layering21
2.3.5 Session Control Block22
2.3.6 Server Message Flows22
2.3.7 Main ncxserver Loop24
2.3.8 SIL Callback Functions25
2.4 Server Operation26
2.4.1 Initialization26
2.4.2 Loading Modules and SIL Code27
2.4.3 Core Module Initialization28
2.4.4 Startup Configuration Processing28
2.4.5 Process an Incoming <rpc> Request29
2.4.6 Edit the Database30
2.4.7 Save the Database31
2.5 Built-in Server Modules31
2.5.1 ietf-inet-types.yang32
2.5.2 ietf-netconf-monitoring.yang32
2.5.3 ietf-with-defaults.yang32
2.5.4 ietf-yang-types.yang32
2.5.5 nc-notifications.yang32
2.5.6 notifications.yang32
2.5.7 yuma-app-common.yang33
2.5.8 yuma-interfaces.yang33
2.5.9 yuma-mysession.yang33
2.5.10 yuma-nacm.yang33
2.5.11 yuma-ncx.yang33
2.5.12 yuma-netconf.yang33
2.5.13 yuma-proc.yang33
2.5.14 yuma-system.yang34
2.5.15 yuma-time-filter.yang 34
2.5.16 yuma-types.yang34
3 YANG Objects and Data Nodes34
3.1 Object Definition Tree34
3.1.1 Object Node Types34
3.1.2 Object Node Template (obj_template_t)35
3.1.3 obj_template_t Access Functions37
3.2 Data Tree39
3.2.1 Data Node Types40
3.2.2 Yuma Data Node Edit Variables (val_editvars_t)42
3.2.3 Yuma Data Nodes (val_value_t)43
3.2.4 val_value_t Access Macros46
3.2.5 val_value_t Access Functions47
3.2.6 SIL Utility Functions52
4 SIL External Interface53
4.1 Stage 1 Initialization53
4.2 Stage 2 Initialization56
4.3 Cleanup57
5 SIL Callback Interface58
5.1 RPC Operation Interface59
5.1.1 RPC Callback Initialization59
5.1.2 RPC Message Header59
5.1.3 SIL Support Functions For RPC Operations62
5.1.4 RPC Validate Callback Function63
5.1.5 RPC Invoke Callback Function66
5.1.6 RPC Post Reply Callback Function69
5.2 Database Operations70
5.2.1 Database Template (cfg_template_t)71
5.2.2 Database Access Functions72
5.2.3 Database Callback Initialization and Cleanup73
5.2.4 Example SIL Database Edit Callback Function75
5.2.5 Database Edit Validate Callback Phase77
5.2.6 Database Edit Apply Callback Phase78
5.2.7 Database Edit Commit Callback Phase78
5.2.8 Database Edit Rollback Callback Phase78
5.2.9 Database Virtual Node Get Callback Function79
5.3 Notifications81
5.3.1 Notification Send Function81
5.4 Periodic Timer Service82
5.4.1 Timer Callback Function82
5.4.2 Timer Access Functions83
5.4.3 Example Timer Callback Function84
6 Server Callback Examples84
6.1 YANG84
6.2 Edit Operations85
6.2.1 Create an XPO container85
6.2.2 Create a Profile87
6.2.3 Create a Stream Connection88
6.2.4 Delete an XPO Container91
6.2.5 Delete a Profile93
6.2.6 Delete a Stream Connection94
7 Development Environment94
7.1 Programs and Libraries Needed94
7.2 SIL Makefile95
7.2.1 Target Platforms96
7.2.2 Build Targets96
7.2.3 Command Line Build Options96
7.2.4 Example SIL Makefile97
7.3 Automation Control101
7.3.1 Built-in YANG Language Extensions102
7.3.2 SIL Language Extension Access Functions103= Preface =
Legal Statements
Copyright 2009 – 2012, Andy Bierman, All Rights Reserved.
Additional Resources
This document assumes you have successfully set up the software as described in the printed document:
Yuma Installation Guide
Yuma Quickstart Guide
Other documentation includes:
Yuma User Manual
Yuma netconfd Manual
Yuma yangcli Manual
Yuma yangdiff Manual
To obtain additional support you may join the yuma-users group on sourceforge.net and send email to this e-mail address:
yuma-users@lists.sourceforge.net
The SourceForge.net Support Page for Yuma can be found at this WEB page:
http://sourceforge.net/projects/yuma/support
There are several sources of free information and tools for use with YANG and/or NETCONF.
The following section lists the resources available at this time.
WEB Sites
- Netconf Central
- http://www.netconfcentral.org/
- Yuma Home Page
- Free information on NETCONF and YANG, tutorials, on-line YANG module validation and documentation database
- Yuma SourceFource OpenSource Project
- http://sourceforge.net/projects/yuma/
- Download Yuma source and binaries; project forums and help
- http://sourceforge.net/projects/yuma/
- Yang Central
- http://www.yang-central.org
- Free information and tutorials on YANG, free YANG tools for download
- NETCONF Working Group Wiki Page
- http://trac.tools.ietf.org/wg/netconf/trac/wiki
- Free information on NETCONF standardization activities and NETCONF implementations
- NETCONF WG Status Page
- http://tools.ietf.org/wg/netconf/
- IETF Internet draft status for NETCONF documents
- libsmi Home Page
- http://www.ibr.cs.tu-bs.de/projects/libsmi/
- Free tools such as smidump, to convert SMIv2 to YANG
- YumaWorks
- http://www.yumaworks.com
- Offers support, training, and consulting for Yuma.
- Offers YumaPro, a professional version of Yuma that includes concurrency, external database support, sub-agent support, multiple northbound interfaces, and more. API compatible with Yuma. Availability: September, 2012. Licensed.
Mailing Lists
- NETCONF Working Group
- http://www.ietf.org/html.charters/netconf-charter.html
- Technical issues related to the NETCONF protocol are discussed on the NETCONF WG mailing list. Refer to the instructions on the WEB page for joining the mailing list.
- NETMOD Working Group
- http://www.ietf.org/html.charters/netmod-charter.html
- Technical issues related to the YANG language and YANG data types are discussed on the NETMOD WG mailing list. Refer to the instructions on the WEB page for joining the mailing list.
Conventions Used in this Document
The following formatting conventions are used throughout this document:
--foo | CLI parameter foo |
<foo> | XML parameter foo |
foo | yangcli command or parameter |
$FOO | Environment variable FOO |
$$foo | yangcli global variable foo |
some text | Example command or PDU |
some text | Plain text |
Software Overview
[[Image:]]
Introduction
Refer to section 3 of the Yuma User Manual for a complete introduction to Yuma Tools.
This section focuses on the software development aspects of NETCONF, YANG, and the netconfd server.
Intended Audience
This document is intended for developers of server instrumentation library software, which can be used with the programs in the Yuma suite. It covers the design and operation of the netconfd server, and the development of server instrumentation library code, intended for use with the netconfd server.
What does Yuma Do?
The Yuma Tools suite provides automated support for development and usage of network management information. Refer to the Yuma User Guide for an introduction to the YANG data modeling language and the NETCONF protocol.
This section describes the Yuma development environment and the basic tasks that a software developer needs to perform, in order to integrate YANG module instrumentation into a device.
This manual contains the following information:
- Yuma Development Environment
- Yuma Runtime Environment
- Yuma Source Code Overview
- Yuma Server Instrumentation Library Development Guide
Yuma Tools programs are written in the C programming language, using the 'gnu99' C standard, and should be easily integrated into any operating system or embedded device that supports the Gnu C compiler.
What is a Yuma Root?
[[Image:]]
The Yuma Tools programs will search for some types of files in default locations
- YANG Modules: The 'modules' sub-directory is used as the root of the YANG module library.
- Client Scripts: The yangcli program looks in the 'scripts' sub-directory for user scripts.
- Program Data: The yangcli and netconfd programs look for saved data structures in the 'data' sub-directory.
Searching Yuma Roots
[[Image:]]
1) $HOME Directory
The first Yuma root checked when searching for files is the directory identified by the $HOME environment variable. If a '$HOME/modules', '$HOME/data'. and/or '$HOME/scripts' directory exists, then it will be checked for the specified file(s).
2) The $YUMA_HOME Directory
The second Yuma root checked when searching for files is the directory identified by the $YUMA_HOME environment variable. This is usually set to private work directory, but a shared directory could be used as well. If a '$YUMA_HOME/modules', '$YUMA_HOME/data'. and/or '$YUMA_HOME/scripts' directory exists, then it will be checked for the specified file(s).
3) The $YUMA_INSTALL Directory
The last Yuma root checked when searching for files is the directory identified by the $YUMA_INSTALL environment variable. If it is not set, then the default value of '/usr/share/yuma' is used instead. This is usually set to the public directory where all users should find the default modules. If a '$YUMA_INSTALL/modules', '$YUMA_INSTALL/data'. and/or '$YUMA_INSTALL/scripts' directory exists, then it will be checked for the specified file(s).
What is a SIL?
A SIL is a Server Instrumentation Library. It contains the 'glue code' that binds YANG content (managed by the netconfd server), to your networking device, which implements the specific behavior, as defined by the YANG module statements.
The netconfd server handles all aspects of the NETCONF protocol operation, except data model semantics that are contained in description statements. The server uses YANG files directly, loaded at boot-time or run-time, to manage all NETCONF content, operations, and notifications.
Callback functions are used to hook device and data model specific behavior to database objects and RPC operations. The yangdump program is used to generate the initialization, cleanup, and 'empty' callback functions for a particular YANG module. The callback functions are then completed (by you), as required by the YANG module semantics. This code is then compiled as a shared library and made available to the netconfd server. The 'load' command (via CLI, configuration file, protocol operation) is used (by the operator) to activate the YANG module and its SIL.
Auto-generated SIL Files
The SIL code for a YANG module can be generated with the make_sil_dir script described in the next section. This script can generate 'combined' SIL files or 'split' SIL files (if the –split parameter is present).
A split SIL module for foo.yang would be generated using the following files:
u_foo.c | User SIL | User-provided server instrumentation code for the 'foo' module. |
u_foo.h | User SIL | User-provided external definitions for the 'foo' module. Should not edit! |
y_foo.c | Yuma SIL | Yuma server glue code for the 'foo' module. Do not edit! |
y_foo.h | Yuma SIL | Yuma server external definitions for the 'foo' module. Do not edit! |
A combined SIL module for foo.yang would be generated using the following files:
foo.c | Combined Yuma and User SIL | User-provided server instrumentation code for the 'foo' module. |
foo.h | Combined Yuma and User SIL | User-provided external definitions for the 'foo' module. Should not edit! |
Basic Development Steps
The steps needed to create server instrumentation for use within Yuma are as follows:
- Create the YANG module data model definition, or use an existing YANG module.
-
- Validate the YANG module with the yangdump program and make sure it does not contain any errors. All warnings should also be examined to determine if they indicate data modeling bugs or not.
- Example toaster.yang
- Make sure the $YUMA_HOME environment variable is defined, and pointing to your Yuma development tree.
- Create a SIL development subtree
-
- Generate the directory structure and the Makefile with the make_sil_dir script, installed in the /usr/bin directory. This step will also call yangdump to generate the initial H and C files file the SIL.
- Example: mydir> make_sil_dir –split test
- Use your text editor to fill in the device-specific instrumentation for each object, RPC method, and notification. (In this example, edit test/src/u_test.c) Almost all possible NETCONF-specific code is either handled in the central stack, or generated automatically. so this code is responsible for implementing the semantics of the YANG data model.
- Compile your code
- Use the 'make' command in the SIL 'src' directory. This should generate a library file in the SIL 'lib' directory.
- Example: mydir/test/src> make
- Install the SIL library so it is available to the netconfd server.
- Use the 'make install' command in the SIL 'src' directory.
- Example: mydir/test/src> sudo make install
- Run the netconfd server (or build it again if linking with static libraries)
- Load the new module
- Be sure to add a 'load' command to the configuration file if the module should be loaded upon each reboot.
- yangcli Example: load test
- The netconfd server will load the specified YANG module and the SIL and make it available to all sessions.
Yuma Source Files
This section describes the files that are contained in the yuma-source package.
The important C include files are copied into /usr/include/yuma when the yuma-dev package is installed. The full set of installation sources is installed in /usr/share/yuma/src, if the yuma-source package is installed. Yuma tools will check the $YUMA_HOME/src sub-tree before checking this default installation location. This allows a working copy of the Yuma sources to be used instead of the installation copy, in case it has been modified for a particular embedded system (for example).
This section lists the files that are included within the netconf/src directory.
src/ncx Directory
This directory contains the code that is used to build the libncx.so binary shared library that is used by all Yuma Tools programs. It handles many of the core NETCONF/YANG data structure support, including all of the YANG/YIN, XML, and XPath processing. The following table describes the purpose of each file. Refer to the actual include file (e.g., ncx.h in /usr/include/yuma) for more details on each external function in each C source module.
b64 | Encoding and decoding the YANG binary data type. |
blob | Encoding and decoding the SQL BLOB data type. |
bobhash | Implementation of the BOB hash function. |
cap | NETCONF capability definitions and support functions |
cfg | NETCONF database data structures and configuration locking support. |
cli | CLI parameter parsing data driven by YANG definitions. |
conf | Text .conf file encoding and decoding, data driven by YANG definitions. |
def_reg | Hash-driven definition registry for quick lookup support of some data structures. Contains back-pointers to the actual data. |
dlq | Double linked queue support |
ext | YANG extension data structure support |
grp | YANG grouping data structure support |
help | Automatic help text, data-driven by YANG definitions |
log | System logging support |
ncx_appinfo | Yuma Netconf Extensions (NCX) support |
ncx | YANG module data structure support, and some utilities |
ncx_feature | YANG feature and if-feature statement data structure support |
ncx_list | Support for the ncx_list_t data structure, used for YANG bits and ncx:xsdlist data types. |
ncxmod | File Management: Controls finding and searching for YANG/YIN files, data files, and script files |
ncx_num | Yuma ncx_num_t data structure support. Used for processing value nodes and XPath numbers. |
ncx_str | Yuma string support. |
obj | Yuma object (obj_template_t) data structure access |
obj_help | Automated object help support used with help module |
op | NETCONF operations definitions and support functions |
rpc | NETCONF <rpc> and <rpc-reply> data structures and support functions |
rpc_err | NETCONF <rpc-error> data structures and support functions. |
runstack | Script execution stack support for yangcli scripts |
send_buff | NETCONF send buffer function |
ses | NETCONF session data structures and session access functions |
ses_msg | Message buffering support for NETCONF sessions |
status | Error code definitions and error support functions |
tk | Token chain data structures used for parsing YANG, XPath and other syntaxes. |
top | Top-level XML node registration support. The <rpc> and <hello> elements are registered by the server. The <hello>, <rpc-reply> , and <notification> elements are registered by the client. |
tstamp | Time and date stamp support functions |
typ | YANG typedef data structures and access functions |
val | Yuma value tree data structures and access functions |
val_util | High-level utilities for some common SIL tasks related to the value tree. |
var | User variable support, used by yangcli and (TBD) XPath |
xml_msg | XML message data structures and support functions |
xmlns | XML Namespace registry |
xml_util | XML parse and utility functions |
xml_val | High level support functions for constructing XML-ready val_value_t data structures |
xml_wr | XML output support functions and access-control protected message generation support |
xpath1 | XPath 1.0 implementation |
xpath | XPath data structures and support functions |
xpath_wr | Support for generating XPath expression content within an XML instance document |
xpath_yang | Special YANG XPath construct support, such as path expressions and instance identifiers |
yang | YANG definitions and general support functions |
yang_ext | YANG parsing and validation of the extension statement |
yang_grp | YANG parsing and validation of the grouping statement |
yang_obj | YANG parsing and validation of the rpc, notification, and data definition statements |
yang_parse | Top level YANG parse and validation support |
yang_typ | YANG typedef and type statement support |
yin | YANG to YIN mapping definitions |
yinyang | YIN to YANG translation |
src/platform Directory
This directory contains platform support include files and Makefile support files. It is used by all Yuma C modules to provide an insulating layer between Yuma programs and the hardware platform that is used. For example the m__getMem, m__getObj, and m__freeMem macros are used instead of malloc and free functions directly.
The following table describes the files that are contained in this directory:
curversion.h | File generated during the build process to get the SVNVERSION number |
platform.profile | Included by Makefiles for build support |
platform.profile.cmn | Included by Makefiles for build support |
platform.profile.depend | Included by Makefiles for dependency generation support |
procdefs.h | Platform definitions. Contains basic data types and macros used throughout the Yuma code. All C files include this file before any other Yuma files. |
setversion.sh | Shell script to generate the curversion.h file |
src/agt Directory
This directory contains the NETCONF server implementation and built-in module SIL code. A static library called libagt.a is built and statically linked within the netconfd program.
The following table describes the C modules contained in this directory:
agt_acm | NETCONF access control implementation. Contains the yuma-nacm module SIL callback functions. |
agt | Server initialization and cleanup control points. Also contains the agt_profile_t data structure. |
agt_cap | Server capabilities. Generates the server <capabilities> element content. |
agt_cb | SIL callback support functions. |
agt_cli | Server CLI and .conf file control functions. |
agt_connect | Handles the internal <ncx-connect> message sent from the netconf-subsystem to the netconfd server. |
agt_hello | Handles the incoming client <hello> message and generates the server <hello> message. |
agt_if | Yuma Interfaces module implementation. Contains the yuma-interfaces module SIL callback functions. |
agt_ncx | NETCONF protocol operation implementation. Contains the yuma-netconf module SIL callback functions. |
agt_ncxserver | Implements the ncxserver loop, handling the IO between the server NETCONF sessions and the netconf-subsystem thin client program. |
agt_not | NETCONF Notifications implementation. Contains the notifications and nc-notifications modules SIL callback functions. |
agt_proc | /proc system monitoring implementation. Contains the yuma-proc module SIL callback functions. |
agt_rpc | NETCONF RPC operation handler |
agt_rpcerr | NETCONF <rpc-error> generation |
agt_ses | NETCONF session support and implementation of the Yuma Session extensions. Contains the yuma-mysession module SIL callback functions. |
agt_signal | Server signal handling support |
agt_state | Standard NETCONF monitoring implementation. Contains the ietf-netconf-monitoring SIL callback functions. |
agt_sys | Server system monitoring and notification generation. Contains the yuma-system module SIL callback functions. |
agt_timer | SIL periodic timer callback support functions |
agt_top | Server registration and dispatch of top-level XML messages |
agt_tree | Subtree filtering implementation |
agt_util | SIL callback utilities |
agt_val | Server validation, commit, and rollback support for NETCONF database operations |
agt_val_parse | Incoming <rpc> and <config> content parse and complete YANG constraint validation |
agt_xml | Server XML processing interface to ncx/xml_util functions |
agt_xpath | XPath filtering implementation |
src/mgr Directory
This module contains the NETCONF client support code. It handles all the basic NETCONF details so a simple internal API can be used by NETCONF applications such as yangcli. A static library called libmgr.a is built and statically linked within the yangcli program.
The following table describes the C modules contained in this directory:
mgr | Client initialization and cleanup control points. Also contains manager session control block data structure support functions. |
mgr_cap | Generate the client NETCONF <capabilities> element content |
mgr_hello | Handles the incoming server <hello> message and generates the client <hello> message. |
mgr_io | Handles SSH server IO support for client NETCONF sessions |
mgr_not | Handles incoming server <notification> messages |
mgr_rpc | Generate <rpc> messages going to the NETCONF server and process incoming <rpc-reply> messages from the NETCONF server. |
mgr_ses | Handles all aspects of client NETCONF sessions. |
mgr_signal | Client signal handler |
mgr_top | Client registration and dispatch of top-level XML messages |
mgr_val_parse | Incoming <rpc-reply>, <notification>, and <config> content parse and complete YANG constraint validation. |
mgr_xml | Client XML processing interface to ncx/xml_util functions |
src/subsys Directory
This directory contains the netconf-subsystem program. This is a thin-client application that just transfers input and output between the SSH server and the NETCONF server. It contains one C source module called netconf-subsystem. This is a stand-alone binary that is part of the yuma-server package. It is installed in the /usr/sbin/ directory.
src/netconfd Directory
This directory contains the netconfd program, which implements the NETCONF server. It contains one C module called netconfd, which defines the NETCONF server 'main' function. This is a stand-alone binary that is part of the yuma-server package. It is installed in the /usr/sbin/ directory.
src/yangcli Directory
This directory contains the yangcli program, which is the Yuma NETCONF client program. This is a stand-alone binary that is part of the yuma-client package. It is installed in the /usr/bin/ directory.
The following table describes the C modules contained in this directory:
yangcli | NETCONF client program, provides interactive and script-based CLI, based on YANG modules. |
yangcli_autoload | Uses the server capabilities from the <hello> message to automatically load any missing YANG modules from the server, and apply all features and deviations. |
yang_autolock | Provides protocol exchange support for the high-level get-locks and release-locks commands |
yangcli_cmd | Main local command processor |
yangcli_list | Implements yangcli 'list' command |
yangcli_save | Implements yangcli 'save' command |
yangcli_show | Implements yangcli 'show' command |
yangcli_tab | Implements context-sensitive tab word completion |
yangcli_util | Utilities used by other yangcli C modules |
src/yangdiff Directory
This directory contains the yangdiff program, which is the Yuma YANG module compare program. This is a stand-alone binary that is part of the yuma-client package. It is installed in the /usr/bin/ directory.
The following table describes the C modules contained in this directory:
yangdiff | YANG module semantic compare program |
yangdiff_grp | Implements semantic diff for YANG grouping statement |
yangdiff_obj | Implements semantic diff for YANG data definition statements |
yangdiff_typ | Implements semantic diff for YANG typedef and type statements |
yangdiff_util | Utilities used by the other yangdiff C modules |
src/yangdump Directory
This directory contains the yangdump program, which is the Yuma YANG compiler program. This is a stand-alone binary that is part of the yuma-client package. It is installed in the /usr/bin/ directory.
The following table describes the C modules contained in this directory:
c | Implements SIL C file generation |
c_util | Utilities used for SIL code generation |
h | Implements SIL H file generation |
html | Implements YANG to HTML translation |
sql | Implements SQL generation for YANG module WEB Docs |
xsd | Implements YANG to XSD translation |
xsd_typ | Implements YANG typedef/type statement to XSD simpleType and complexType statements |
xsd_yang | YANG to XSD translation utilities |
yangdump | YANG module compiler |
yangdump_util | Utilities used by all yangdump C modules |
yangyin | Implements YANG to YIN translation |
Server Design
This section describes the basic design used in the netconfd server.
[[Image:]]
Initialization:
The netconfd server will process the YANG modules, CLI parameters, config file parameters, and startup device NETCONF database, then wait for NETCONF sessions.
ncxserver Loop:
The SSH2 server will listen for incoming connections which request the 'netconf' subsystem.
When a new session request is received, the netconf-subsystem program is called, which opens a local connection to the netconfd server, via the ncxserver loop. NETCONF <rpc> requests are processed by the internal NETCONF stack. The module-specific callback functions (blue boxes) can be loaded into the system at build-time or run-time. This is the device instrumentation code, also called a server implementation library (SIL). For example, for libtoaster, this is the code that controls the toaster hardware.
Cleanup:
If the <shutdown> or <reboot> operations are invoked, then the server will cleanup. For a reboot, the init cycle is started again, instead of exiting the program.
YANG Native Operation
[[Image:]]
Yuma uses YANG source modules directly to implement NETCONF protocol operations automatically within the server. The same YANG parser is used by all Yuma programs. It is located in the 'ncx' source directory (libncx.so). There are several different parsing modes, which is set by the application.
In the 'server mode', the descriptive statements, such as 'description' and 'reference' are discarded upon input. Only the machine-readable statements are saved. All possible database validation, filtering, processing, initialization, NV-storage, and error processing is done, based on these machine readable statements.
For example, in order to set the platform-specific default value for some leaf, instead of hard-coded it into the server instrumentation, the default is stored in YANG data instead. The YANG file can be altered, either directly (by editing) or indirectly (via deviation statements), and the new or altered default value specified there.
In addition, range statements, patterns, XPath expressions, and all other machine-readable statements are all processed automatically, so the YANG statements themselves are like server source code.
YANG also allows vendor and platform-specific deviations to be specified, which are like generic patches to the common YANG module for whatever purpose needed. YANG also allows annotations to be defined and added to YANG modules, which are specified with the 'extension' statement. Yuma uses some extensions to control some automation features, but any module can define extensions, and module instrumentation code can access these annotation during server operation, to control device behavior.
There are CLI parameters that can be used to control parser behavior such as warning suppression, and protocol behavior related to the YANG content, such as XML order enforcement and NETCONF protocol operation support. These parameters are stored in the server profile, which can be customized for each platform.
YANG Object Tree
[[Image:]]
The YANG statements found in a module are converted to internal data structures.
For NETCONF and database operations, a single tree of obj_template_t data structures is maintained by the server. This tree represents all the NETCONF data that is supported by the server. It does not represent any actual data structure instances. It just defines the data instances that are allowed to exist on the server.
Raw YANG vs. Cooked YANG:
Some of the nodes in this tree represent the exact YANG statements that the data modeler has used, such as 'augment', 'refine', and 'uses', but these nodes are not used directly in the object tree. They exist in the object tree, but they are processed to produce a final set of YANG data statements, translated into 'cooked' nodes in the object tree. If any deviation statements are used by server implementation of a YANG data node (to change it to match the actual platform implementation of the data node), then these are also 'patched' into the cooked YANG nodes in the object tree.
YANG Data Tree
[[Image:]]
A YANG data tree represents the instances of 1 or more of the objects in the object tree.
Each NETCONF database is a separate data tree. A data tree is constructed for each incoming message as well. The server has automated functions to process the data tree, based on the desired NETCONF operation and the object tree node corresponding to each data node.
Every NETCONF node (including database nodes) are distinguished with XML Qualified Names (QName). The YANG module namespace is used as the XML namespace, and the YANG identifier is used as the XML local name.
Each data node contains a pointer back to its object tree schema node. The value tree is comprised of the val_value_t structure. Only real data is actually stored in the value tree. For example, there are no data tree nodes for choices and cases. These are conceptual layers, not real layers, within the data tree.
The NETCONF server engine accesses individual SIL callback functions through the data tree and object tree. Each data node contains a pointer to its corresponding object node.
Each data node may have several different callback functions stored in the object tree node. Usually, the actual configuration value is stored in the database, However, virtual data nodes are also supported. These are simply placeholder nodes within the data tree, and usually used for non-configuration nodes, such as counters. Instead of using a static value stored in the data node, a callback function is used to retrieve the instrumentation value each time it is accessed.
Service Layering
All of the major server functions are supported by service layers in the 'agt' or 'ncx' libraries:
- Memory management: macros in platform/procdefs.h are used instead of using direct heap functions. The macros m__getMem or m__getObj are used by Yuma code to allocate memory. Both of these functions increment a global counter called malloc_count. The macro m__free is used to delete all malloced memory. This macro increments a global counter called free_count. When a Yuma program exists, it checks if malloc_count equals free_count, and if not, generates an error message. If this occurs, the MEMTRACE=1 parameter can be added to the make command to activate 'mtrace' debugging.
- Queue management: APIs in ncx/dlq.h are used for all double-linked queue management.
- XML namespaces: XML namespaces (including YANG module namespaces) are managed with functions in ncx/xmlns.h. An internal 'namespace ID is used internally instead of the actual URI.
- XML parsing: XML input processing is found in ncx/xml_util.h data structures and functions.
- XML message processing: XML message support is found in ncx/xml_msg.h data structures and functions.
- XML message writing with access control: XML message generation is controlled through API functions located in ncx/xml_wr.h. High level (value tree output) and low-level (individual tag output) XML output functions are provided, which hide all namespace, indentation, and other details. Access control is integrated into XML message output to enforce the configured data access policies uniformly for all RPC operations and notifications. The access control model cannot be bypassed by any dynamically loaded module server instrumentation code.
- XPath Services: All NETCONF XPath filtering, and all YANG XPath-based constraint validation, is handled with common data structures and API functions. The XPath 1.0 implementation is native to the server, and uses the object and value trees directly to generate XPath results for NETCONF and YANG purposes. NETCONF uses XPath differently than XSLT, and libxml2 XPath processing is memory intensive. These functions are located in ncx/xpath.h, ncx/xpath1.h, and ncx/xpath_yang.h. XPath filtered <get> responses are generated in agt/agt_xpath.c.
- Logging service: Encapsulates server output to a log file or to the standard output, filtered by a configurable log level. Located in ncx/log.h. In addition, the macro SET_ERROR() in ncx/status.h is used to report programming errors to the log.
- Session management: All server activity is associated with a session. The session control block and API functions are located in ncx/ses.h. All input, output, access control, and protocol operation support is controlled through the session control block (ses_cb_t).
- Timer service: A periodic timer service is available to SIL modules for performing background maintenance within the main service loop. These functions are located in agt/agt_timer.h.
- Connection management: All TCP connections to the netconfd server are controlled through a main service loop, located in agt/agt_ncxserver.c. It is expected that the 'select' loop in this file will be replaced in embedded systems. The default netconfd server actually listens for local <ncx-connect> connections on an AF_LOCAL socket. The openSSH server listens for connections on port 830 (or other configured TCP ports), and the netconf-subsystem thin client acts as a conduit between the SSH server and the netconfd server.
- Database management: All configuration databases use a common configuration template, defined in ncx/cfg.h. Locking and other generic database functions are handled in this module. The actual manipulation of the value tree is handled by API functions in ncx/val.h, ncx/val_util.h, agt/agt_val_parse.h, and agt/agt_val.h.
- NETCONF operations: All standard NETCONF RPC callback functions are located in agt/agt_ncx.c. All operations are completely automated, so there is no server instrumentation APIs in this file.
- NETCONF request processing: All <rpc> requests and replies use common data structures and APIs, found in ncx/rpc.h and agt/agt_rpc.h. Automated reply generation, automatic filter processing, and message state data is contained in the RPC message control block.
- NETCONF error reporting: All <rpc-error> elements use common data structures defined in ncx/rpc_err,h and agt/agt_rpcerr.h. Most errors are handled automatically, but 'description statement' semantics need to be enforced by the SIL callback functions. These functions use the API functions in agt/agt_util.h (such as agt_record_error) to generate data structures that will be translated to the proper <rpc-error> contents when a reply is sent.
- YANG module library management: All YANG modules are loaded into a common data structure (ncx_module_t) located in ncx/ncxtypes.h. The API functions in ncx/ncxmod.h (such as ncxmod_load_module) are used to locate YANG modules, parse them, and store the internal data structures in a central library. Multiple versions of the same module can be loaded at once, as required by YANG.
Session Control Block
Once a NETCONF session is started, it is assigned a session control block for the life of the session. All NETCONF and system activity in driven through this interface, so the ncxserver loop can be replaced in an embedded system.
Each session control block (ses_scb_t) controls the input and output for one session, which is associated with one SSH user name. Access control (see yuma-nacm.yang) is enforced within the context of a session control block. Unauthorized return data is automatically removed from the response. Unauthorized <rpc> or database write requests are automatically rejected with an 'access-denied' error-tag.
The user preferences for each session are also stored in this data structure. They are initially derived from the server default values, but can be altered with the <set-my-session> operation and retrieved with the <get-my-session> operation.
Server Message Flows
[[Image:]]
The netconfd server provides the following type of components:
- NETCONF session management
- NETCONF/YANG database management
- NETCONF/YANG protocol operations
- Access control configuration and enforcement
- RPC error reporting
- Notification subscription management
- Default data retrieval processing
- Database editing
- Database validation
- Subtree and XPath retrieval filtering
- Dynamic and static capability management
- Conditional object management (if-feature, when)
- Memory management
- Logging management
- Timer services
All NETCONF and YANG protocol operation details are handled automatically within the netconfd server. All database locking and editing is also handled by the server. There are callback functions available at different points of the processing model for your module specific instrumentation code to process each server request, and/or generate notifications. Everything except the 'description statement' semantics are usually handled
The server instrumentation stub files associated with the data model semantics are generated automatically with the yangdump program. The developer fills in server callback functions to activate the networking device behavior represented by each YANG data model.
Main ncxserver Loop
[[Image:]]
The ncxserver loop does very little, and it is designed to be replaced in an embedded server that has its own SSH server:
- A client request to start an SSH session results in an SSH channel being established to an instance of the netconf-subsystem program.
- The netconf-subsystem program will open a local socket (/tmp/ncxserver.sock) and send a proprietary <ncxconnect> message to the netconfd server, which is listening on this local socket with a select loop (in agt_ncxserver.c).
- When a valid <ncxconnect> message is received by netconfd, a new NETCONF session is created.
- After sending the <ncxconnect> message, the netconf-subsystem program goes into 'transfer mode', and simply passes input from the SSH channel to the netconfd server, and passes output from the netconfd server to the SSH server.
- The ncxserver loop simply waits for input on the open connections, with a quick timeout. Each timeout, the server checks if a reboot, shutdown, signal, or other event occurred that needs attention.
- Notifications may also be sent during the timeout check, if any events are queued for processing. The --max-burst configuration parameter controls the number of notifications sent to each notification subscription, during this timeout check.
- Input <rpc> messages are buffered, and when a complete message is received (based on the NETCONF End-of-Message marker), it is processed by the server and any instrumentation module callback functions that are affected by the request.
When the agt_ncxserver_run function in agt/agt_ncxserver.c is replaced within an embedded system, the replacement code must handle the following tasks:
- Call agt_ses_new_session in agt/agt_ses.c when a new NETCONF session starts.
- Call ses_accept_input in ncx/ses.c with the correct session control block when NETCONF data is received.
- Call agt_ses_process_first_ready in agt/agt_ses.c after input is received. This should be called repeatedly until all serialized NETCONF messages have been processed.
- Call agt_ses_kill_session in agt/agt_ses.c when the NETCONF session is terminated.
- The following functions are used for sending NETCONF responses, if responses are buffered instead of sent directly (streamed).
- ses_msg_send_buffs in ncx/ses_msg.c is used to output any queued send buffers.
- The following functions need to be called periodically:
- agt_shutdown_requested in agt/agt_util.c to check if the server should terminate or reboot
- agt_ses_check_timeouts in agt/agt_ses.c to check for idle sessions or sessions stuck waiting for a NETCONF <hello> message.
- agt_timer_handler in agt/agt_timer.c to process server and SIL periodic callback functions.
- send_some_notifications in agt/agt_ncxserver.c to process some outgoing notifications.
SIL Callback Functions
[[Image:]]
- Top Level: The top-level incoming messages are registered, not hard-wired, in the server message processing design. The agt_ncxserver module accepts the <ncxconnect> message from netconf-subsystem. The agt_rpc module accepts the NETCONF <rpc> message. Additional messages can be supported by the server using the top_register_node function.
- All RPC operations are implemented in a data-driven fashion by the server. Each NETCONF operation is handled by a separate function in agt_ncx.c. Any proprietary operation can be automatically supported, using the agt_rpc_register_method function.
- Note: Once the YANG module is loaded into the server, all RPC operations defined in the module are available. If no SIL code is found, these will be dummy 'no-op' functions. This mode can be used to provide some server simulation capability for client applications under development.
- All database operations are performed in a structured manner, using special database access callback functions. Not all database nodes need callback functions. One callback function can be used for each 'phase', or the same function can be used for multiple phases. The agt_cb_register_callback function in agt/agt_cb.c is used by SIL code to hook into NETCONF database operations.
Server Operation
This section briefly describes the server internal behavior for some basic NETCONF operations.
Initialization
The file netconfd/netconfd.c contains the initial 'main' function that is used to start the server.
- The common services support for most core data structures is located in 'libncx.so'. The 'ncx_init' function is called to setup these data structures. This function also calls the bootstrap_cli function in ncx/ncx.c, which processes some key configuration parameters that need to be set right away, such as the logging parameters and the module search path.
- Most of the actual server code is located in the 'agt' directory. The 'agt_init1' function is called to initialize core server functions. The configuration parameters are processed, and the server profile is completed.
- The agt_profile_t data structure in agt/agt.h is used to contain all the vendor-related boot-time options, such as the database target (candidate or running). The init_server_profile function can be edited if the Yuma default values are not desired. This will insure the proper factory defaults for server behavior are used, even if no configuration parameters are provided.
- The function init_server_profile in agt/agt.c is used to set the factory defaults for the server behavior.
The agt_init1 function also loads the core NETCONF protocol, netconfd CLI, and YANG data type modules.
- Note: netconfd uses yuma-netconf.yang, not ietf-netconf.yang to support a data-driven implementation. The only difference is that the yuma version adds some data structures and extensions (such as ncx:root), to automate processing of all NETCONF messages.
After the core definition modules are loaded successfully, the agt_cli_process_input function in agt/agt_cli.c is called to process any command line and/or configuration file parameters that have been entered.
- Note: Any defaults set in the G module definitions will be added to the CLI parameter set. The val_set_by_default function in ncx/val.c can be used to check if the node is set by the server to the YANG default value. If not set, and the node has the YANG default value, then the client set this value explicitly. This is different than the val_is_default function in ncx/val.c, which just checks if the node contains the YANG default value.
All the configuration parameters are saved, and those that can be processed right away are handled. The agt_cli_get_valset function in agt/agt_cli.c can be used to retrieve the entire set of load-time configuration parameters.
Loading Modules and SIL Code
YANG modules and their associated device instrumentation can be loaded dynamically with the --module configuration parameter. Some examples are shown below:
module=foo module=bar module=baz@2009-01-05 module=~/mymodules/myfoo.yang
- The ncxmod_find_sil_file function in ncx/ncxmod.c is used to find the library code associated with the each module name. The following search sequence is followed:
- Check the $YUMA_HOME/target/lib directory
- Check each directory in the $YUMA_RUNPATH environment variable or --runpath configuration variable.
- Check the /usr/lib/yuma directory
- If the module parameter contains any sub-directories or a file extension, then it is treated as a file, and the module search path will not be used. Instead the absolute or relative file specification will be used.
- If the first term starts with an environment variable or the tilde (~) character, and will be expanded first
- If the 'at sign' (@) followed by a revision date is present, then that exact revision will be loaded.
- If no file extension or directories are specified, then the module search path is checked for YANG and YIN files that match. The first match will be used, which may not be the newest, depending on the actual search path sequence.
- The $YUMA_MODPATH environment variable or --modpath configuration parameter can be used to configure one or more directory sub-trees to be searched.
- The $YUMA_HOME environment variable or --yuma-home configuration parameter can be used to specify the Yuma project tree to use if nothing is found in the currect directory or the module search path.
- The $YUMA_INSTALL environment variable or default Yuma install location (/usr/share/yuma/modules) will be used as a last resort to find a YANG or YIN file.
The server processes --module parameters by first checking if a dynamic library can be found which has an 'soname' that matches the module name. If so, then the SIL phase 1 initialization function is called, and that function is expected to call the ncxmod_load_module function.
If no SIL file can be found for the module, then the server will load the YANG module anyway, and support database operations for the module, for provisioning purposes. Any RPC operations defined in the module will also be accepted (depending on access control settings), but the action will not actually be performed. Only the input parameters will be checked, and <or> or some <rpc-error> returned.
Core Module Initialization
The agt_init2 function in agt/agt.c is called after the configuration parameters have been collected.
-
- Initialize the core server code modules
- Static device-specific modules can be added to the agt_init2 function after the core modules have been initialized
- Any 'module' parameters found in the CLI or server configuration file are processed.
- The agt_cap_set_modules function in agt/agt_cap.c is called to set the initial module capabilities for the ietf-netconf-monitoring module
Startup Configuration Processing
After the static and dynamic server modules are loaded, the --startup (or --no-startup) parameter is processed by agt_init2 in agt/agt.c:
- If the --startup parameter is used and includes any sub-directories, it is treated as a file and must be found, as specified.
- Otherwise, the $YUMA_DATAPATH environment variable or --datapath configuration parameter can be used to determine where to find the startup configuration file.
- If neither the --startup or --no-startup configuration parameter is present, then the data search path will be used to find the default startup-cfg.xml
- The $YUMA_HOME environment variable or --yuma-home configuration parameter is checked if no file is found in the data search path. The $YUMA_HOME/data directory is checked if this parameter is set.
- The $YUMA_INSTALL environment variable or default location (/etc/yuma/) is checked next, if the startup configuration is still not found.
It is a fatal error if a startup config is specified and it cannot be found.
As the startup configuration is loaded, any SIL callbacks that have been registered will be invoked for the association data present in the startup configuration file.. The edit operation will be OP_EDITOP_LOAD during this callback.
After the startup configuration is loaded into the running configuration database, all the stage 2 initialization routines are called. These are needed for modules which add read-only data nodes to the tree containing the running configuration. SIL modules may also use their 'init2' function to create factory default configuration nodes (which can be saved for the next reboot).
Process an Incoming <rpc> Request
[[Image:]]
- PARSE Phase: The incoming buffer is converted to a stream of XML nodes, using the xmlTextReader functions from libxml2. The agt_val_parse function is used to convert the stream of XML nodes to a val_value_t structure, representing the incoming request according to the YANG definition for the RPC operation. An rpc_msg_t structure is also built for the request.
- VALIDATE Phase: If a message is parsed correctly, then the incoming message is validated according to the YANG machine-readable constraints. Any description statement constraints need to be checked with a callback function. The agt_rpc_register_method function in agt/agt_rpc.c is used to register callback functions.
- INVOKE Phase: If the message is validated correctly, then the invoke callback is executed. This is usually the only required callback function. Without it, the RPC operation has no affect. This callback will set fields in the rpc_msg_t header that will allow the server to construct or stream the <rpc-reply> message back to the client.
- REPLY Phase: Unless some catastrophic error occurs, the server will generate an <rpc-reply> response. If any <rpc-error> elements are needed, they are generated first. If there is any response data to send, that is generated or streamed (via callback function provided earlier) at this time. Any unauthorized data (according to to the yuma-nacm.yang module configuration) will be silently dropped from the message payload. If there were no errors and no data to send, then an <ok> resonse is generated.
- POST_REPLY Phase: After the response has been sent, a rarely-used callback function can be invoked to cleanup any memory allocation or other data-model related tasks. For example, if the rpc_user1 or rpc_user2 pointers in the message header contain allocated memory then they need to be freed at this time.
Edit the Database
[[Image:]]
- Validate Phase: The server will determine the edit operation and the actual nodes in the target database (candidate or running) that will be affected by the operation. All of the machine-readable YANG statements which apply to the affected node(s) are tested against the incoming PDU and the target database. If there are no errors, the server will search for a SIL validate callback function for the affected node(s). If the SIL code has registered a database callback function for the node or its local ancestors, it will be invoked. This SIL callback function usually checks additional constraints that are contained in the YANG description statements for the database objects.
- Test-Apply and Apply Phase: If the validate phase completes without errors, then the requested changes are applied to the target database. If the target database is the running configuration, or if the edit-config 'test-option' parameter is set to 'test-then-set' (the default if --with-validate=true), then the test-apply phase is executed first. This is essentially the same as the real apply phase, except that changes are made to a copy of the target database. Once all objects have been altered as requested, the entire test database is validated, including all cross-referential integrity tests. If this test completes without any errors, then the procedure is repeated on the real target database.
- Note: This phase is used for the internal data tree manipulation and validation only. It is not used to alter device behavior. Resources may need to be reserved during the SIL apply callback, but the database changes are not activated at this time.
- Commit or Rollback Phase: If the validate and apply phases complete without errors, then then the server will search for SIL commit callback functions for the affected node(s) in the target database. This SIL callback phase is used to apply the changes to the device and/or network. It is only called when a commit procedure is attempted. This can be due to a <commit> operation, or an <edit-config> or <copy-config> operation on the running database.
- Note: If there are errors during the commit phase, then the backup configuration will be applied, and the server will search for a SIL callback to invoke with a 'rollback operation'. The same procedure is used for confirmed commit operations which timeout or canceled by the client.
Save the Database
The following bullets describe how the server saves configuration changes to non-volatile storage:
- If the --with-startup=true parameter is used, then the server will support the :startup capability. In this case, the <copy-config> command needs to be used to cause the running configuration to be saved.
- If the --with-startup=false parameter is used, then the server will not support the :startup capability. In this case, the database will be saved each time the running configuration is changed.
- The <copy-config> or <commit> operations will cause the startup configuration file to be saved, even if nothing has changed. This allows an operator to replace a corrupted or missing startup configuration file at any time.
- The database is saved with the agt_ncx_cfg_save function in agt/agt_ncx.c.
- The with-defaults 'explicit' mode is used during the save operation to filter the database contents.
- Any values that have been set by the client will be saved in NV-storage.
- Any value set by the server to a YANG default value will not be saved in the database.
- If the server create a node that does not have a YANG default value (e.g., containers, lists, keys), then this node will be saved in NV storage.
- If the --startup=filespec parameter is used, then the server will save the database by overwriting that file. The file will be renamed to backup-cfg.xml first.
- If the --no-startup parameter is used, or no startup file is specified and no default is found, then the server will create a file called 'startup-cfg.xml', in the following manner:
- If the $YUMA_HOME variable is set, the configuration will be saved in $YUMA_HOME/data/startup-cfg.xml.
- Otherwise, the configuration will be saved in $HOME/.yuma/startup-cfg.xml.
- The database is saved as an XML instance document, using the <config> element in the NETCONF 'base' namespace as the root element. Each top-level YANG module supported by the server, which contains some explicit configuration data, will be saved as a child node of the <nc:config> element. There is no particular order to the top-level data model elements.
Built-in Server Modules
There are several YANG modules which are implemented within the server, and not loaded at run-time like a dynamic SIL module. Some of them are NETCONF standard modules and some are Yuma extension modules.
ietf-inet-types.yang
This module contains the standard YANG Internet address types. These types are available for commonly used management object types. A YANG module author should check this module first, before creating any new data types with the YANG typedef statement.
There are no accessible objects in this module, so there are no SIL callback functions. The YANG data-types are supported within the Yuma engine core modules, such as ncx/val.c and ncx/xml_wr.c.
ietf-netconf-monitoring.yang
The standard NETCONF Monitoring module is used to examine the capabilities, current state, and statistics related to the NETCONF server. The entire module is supported.
This module is also used to retrieve the actual YANG or YIN files (or URLs for them) that the server is using. Clients can use the <get-schema> RPC operation to retrieve the YANG or YIN files listed in the /netconf-state/schemas subtree. A client will normally check the <hello> message from the server for module capabilities, and use its own local copy of a server YANG module, if it can. If not, then the <get-schema> function can be used to retrieve the YANG module.
The agt/agt_state.c contains the SIL callback functions for this module.
ietf-with-defaults.yang
The standard <with-defaults> extension to some NETCONF operations is defined in this module. This parameter is added to the <get>, <get-config>, and <copy-config> operations to let the client control how 'default leafs' are returned by the server. The Yuma server can be configured to use any of the default handling styles (report-all, trim, or explicit). The filtering of default nodes is handled automatically by the server support functions in agt/agt_util.c, and the XML write functions in ncx/xml_wr.c.
ietf-yang-types.yang
This module contains the standard YANG general user data types. These types are available for commonly used derived types. A YANG module author should check this module first, before creating any new data types with the YANG typedef statement.
There are no accessible objects in this module, so there are no SIL callback functions. The YANG data-types are supported within the Yuma engine core modules, such as ncx/val.c and ncx/xml_wr.c.
nc-notifications.yang
This module is defined in RFC 5277, the NETCONF Notifications specification. It contains the <replayComplete> and <notificationComplete> notification event definitions.
The file agt/agt_not.c contains the SIL support code for this module.
notifications.yang
This module is defined in RFC 5277, the NETCONF Notifications specification. All of this RFC is supported in the server. This module contains the <create-subscription> RPC operation. The notification replay feature is controlled with the --eventlog-size configuration parameter. The <create-subscription> operation is fully supported, including XPath and subtree filters. The yuma-nacm module can be used to control what notification events a user is allowed to receive. The <create-subscription> filter allows the client to select which notification events it wants to receive.
The file agt/agt_not.c contains the SIL callback functions for this modules.
yuma-app-common.yang
This module contains some common groupings of CLI parameters supported by some or all Yuma programs. Each program with CLI parameters defines its own module of CLI parameters (using the ncx:cli extension). The program name is used for the YANG module name as well (e.g., yangdump.yang or netconfd.yang).
The SIL callback functions for the common groupings in this module are found in ncx/val_util.c, such as the val_set_feature_parms function.
yuma-interfaces.yang
This module contains the Yuma interfaces table, which is just a skeleton configuration list, plus some basic interface counters. This module is intended to provide an example for embedded developers to replace this module with their own interfaces table. The Yuma table uses information in some files found in Unix systems which support the /proc/net/dev system file.
The file agt/agt_if.c contains the SIL callback functions for this module.
yuma-mysession.yang
This module provides the Yuma proprietary <get-my-session> and <set-my-session> RPC operations. These are used by the client to set some session output preferences, such as the desired line length, indentation amount, and defaults handling behavior.
The file agt/agt_ses.c contains the SIL callback functions for this module.
yuma-nacm.yang
This module contains the Yuma NETCONF Access Control Model implementation. It provides all user-configurable access control settings and also provides API functions to check if a specific access request should be allowed or not.
The file agt/agt_acm.c contains the SIL callback functions for this module.
yuma-ncx.yang
This module provides the YANG language extension statements that are used by Yuma programs to automate certain parts of the NETCONF protocol, document generation, code generation, etc.
There are no SIL callback functions for this module. There are support functions within the src/ncx directory that include the obj_set_ncx_flags function in ncx/obj.c
yuma-netconf.yang
The NETCONF protocol operations, message structures, and error information are all data-driven, based on the YANG statements in the yuma-netconf.yang module. The ietf-netconf.yang module is not used at this time because it does not contain the complete set of YANG statements needed. The yuma-netconf.yang version is a super-set of the IETF version. Only one YANG module can be associated with an XML namespace in Yuma. In a future version, the extra data structures will be moved to an annotation module.
The file agt/agt_ncx.c contains the SIL callback functions for this module.
This module is not advertised in the server capabilities. It is only used internally within the server.
yuma-proc.yang
This module provides some Unix /proc file-system data, in nested XML format. This module will not load if the files /proc/meminfo and /proc/cpuinfo are not found.
The file agt/agt_proc.c contains the SIL callback functions for this module.
yuma-system.yang
This module contains the Yuma /system data structure, providing basic server information, unix 'uname' data, and all the Yuma proprietary notification event definitions.
The file agt/agt_sys.c contains the SIL callback functions for this module.
yuma-time-filter.yang
This module contains the Yuma last-modified leaf, which extends the standard /netconf-state/datastores/datastore structure in ietf-netconf-monitoring.yang, with the database last-modified timestamp. The standard <get> and <get-config> operations are augmented with the if-modified-since leaf, to allow all-or-none filtering of the configuration, based on its modification timestamp.
The file agt/agt_sys.c contains the SIL callback functions for this module.
yuma-types.yang
This module provides some common data types that are used by other Yuma YANG modules.
There are no SIL callback functions for this module.
YANG Objects and Data Nodes
This section describes the basic design of the YANG object tree and the corresponding data tree that represents instances of various object nodes that the client or the server can create.
Object Definition Tree
The object tree is a tree representation of all the YANG module rpc, data definition, and notification statements. It starts with a 'root' container. This is defined with a YANG container statement which has an ncx:root extension statement within it. The <config> parameter within the <edit-config> operation is an example of an object node which is treated as a root container. Each configuration database maintained by the server (e.g., <candidate> and <running>) has a root container value node as its top-level object.
A root container does not have any child nodes defined in it within the YANG file. However, the Yuma tools will treat this special container as if any top-level YANG data node is allowed to be a child node of the 'root' container type.
Object Node Types
There are 14 different YANG object node types, and a discriminated union of sub-data structures contains fields common to each sub-type. Object templates are defined in ncx/obj.h.
OBJ_TYP_ANYXML | This object represents a YANG anyxml data node. |
OBJ_TYP_CONTAINER | This object represents a YANG presence or non-presence container. |
OBJ_TYP_CONTAINER + ncx:root | If the ncx:root extension is present within a container definition, then the object represents a NETCONF database root. No child nodes |
OBJ_TYP_LEAF | This object represents a YANG leaf data node. |
OBJ_TYP_LEAF_LIST | This object represents a YANG leaf-list data node. |
OBJ_TYP_LIST | This object represents a YANG list data node. |
OBJ_TYP_CHOICE | This object represents a YANG choice schema node. The only children allowed are case objects.
This object does not have instances in the data tree. |
OBJ_TYP_CASE | This object represents a YANG case schema node. This object does not have instances in the data tree. |
OBJ_TYP_USES | This object represents a YANG uses schema node. The contents of the grouping it represents will be expanded into object tree. It is saved in the object tree even during operation, in order for the expanded objects to share common data. This object does not have instances in the data tree. |
OBJ_TYP_REFINE | This object represents a YANG refine statement. It is used to alter the grouping contents during the expansion of a uses statement. This object is only allowed to be a child of a uses statement. It does not have instances in the data tree. |
OBJ_TYP_AUGMENT | This object represents a YANG augment statement. It is used to add additional objects to an existing data structure. This object is only allowed to be a child of a uses statement or a child of a 'root' container. It does not have instances in the data tree, however any children of the augment node will generate object nodes that have instances in the data tree. |
OBJ_TYP_RPC | This object represents a YANG rpc statement. It is used to define new <rpc> operations. This object will only appear as a child of a 'root' container. It does not have instances in the data tree. Only 'rpcio' nodes are allowed to be children of an RPC node. |
OBJ_TYP_RPCIO | This object represents a YANG input or output statement. It is used to define new <rpc> operations. This object will only appear as a child of an RPC node. It does not have instances in the data tree. |
OBJ_TYP_NOTIF | This object represents a YANG notification statement. It is used to define new <notification> event types. This object will only appear as a child of a 'root' container. It does not have instances in the data tree. |
Object Node Template (obj_template_t)
The following typedef is used to represent an object tree node:
/* One YANG data-def-stmt */ typedef struct obj_template_t_ { dlq_hdr_t qhdr; obj_type_t objtype; uint32 flags; /* see OBJ_FL_* definitions */ ncx_error_t tkerr; grp_template_t *grp; /* non-NULL == in a grp.datadefQ */
/* 4 back pointers */ struct obj_template_t_ *parent; struct obj_template_t_ *usesobj; struct obj_template_t_ *augobj; struct xpath_pcb_t_ *when; /* optional when clause */ dlq_hdr_t metadataQ; /* Q of obj_metadata_t */ dlq_hdr_t appinfoQ; /* Q of ncx_appinfo_t */ dlq_hdr_t iffeatureQ; /* Q of ncx_iffeature_t */
/* cbset is agt_rpc_cbset_t for RPC or agt_cb_fnset_t for OBJ */ void *cbset;
/* object namespace ID assigned at runtime * this can be changed over and over as a * uses statement is expanded. The final * expansion into a real object will leave * the correct value in place */ xmlns_id_t nsid;
union def_ { obj_container_t *container; obj_leaf_t *leaf; obj_leaflist_t *leaflist; obj_list_t *list; obj_choice_t *choic; obj_case_t *cas; obj_uses_t *uses; obj_refine_t *refine; obj_augment_t *augment; obj_rpc_t *rpc; obj_rpcio_t *rpcio; obj_notif_t *notif; } def;
} obj_template_t;
The following table highlights the fields within the obj_template_t data structure:
qhdr | Queue header to allow the object template to be stored in a child queue |
objtype | enumeration to identify which variant of the 'def' union is present |
flags | Internal state and properties |
tkerr | Error message information |
grp | back-pointer to parent group if this is a top-level data node within a grouping |
parent | Parent node if any |
usesobj | Back pointer to uses object if this is a top-level data node within an expanded grouping |
augobj | Back pointer to augment object if this is a top-level data node within an expanded augment |
when | XPath structure for YANG when statement |
metadataQ | Queue of obj_template_t for any XML attributes (ncx:metadata) defined for this object node |
appinfoQ | Queue of ncx_appinfo_t for any YANG extensions found defined within the object, that were not collected within a deeper appinfoQ (e.g., within a type statement) |
iffeatureQ | Queue of ncx_iffeature_t for any if-feature statements found within this object node |
cbset | Set of server callback functions for this object node. |
nsid | Object node namespace ID assigned by xmlns.c |
def | Union of object type specific nodes containing the rest of the YANG statements. Note that the server discards all descriptive statements such as description, reference, contact,. |
obj_template_t Access Functions
The file ncx/obj.h contains many API functions so that object properties do not have to be accessed directly. The following table highlights the most commonly used functions. Refer to the H file for a complete definition of each API function.
obj_find_template | Find a top-level object template within a module |
obj_find_child | Find the specified child node within a complex object template . Skips over any nodes without names (augment, uses, etc.) |
obj_first_child | Get the first child node within a complex object template . Skips over any nodes without names. |
obj_next_child | Get the next child node after the current specified child. Skips over any nodes without names. |
obj_first_child_deep | Get the first child node within a complex object template . Skips over any nodes without names, and also any choice and case nodes. |
obj_next_child_deep | Get the next child node after the current specified child. Skips over any nodes without names, and also any choice and case nodes. |
obj_find_case | Find the specified case object child node within the specific complex object node. |
obj_find_type | Check if a typ_template_t in the obj typedefQ hierarchy. |
obj_find_grouping | Check if a grp_template_t in the obj typedefQ hierarchy. |
obj_find_key | Find a specific key component by key leaf identifier name |
obj_first_key | Get the first obj_key_t struct for the specified list object type |
obj_next_key | Get the next obj_key_t struct for the specified list object type |
obj_gen_object_id | Allocate and generate the YANG object ID for an object node |
obj_get_name | Get the object name string |
obj_has_name | Return TRUE if the object has a name field |
obj_has_text_content | Return TRUE if the object has text content |
obj_get_status | Get the YANG status for the object |
obj_get_description | Get the YANG description statement for an object. Note that the server will always return a NULL pointer. |
obj_get_reference | Get the YANG reference statement for an object. Note that the server will always return a NULL pointer. |
obj_get_config_flag | Get the YANG config statement value for an object |
obj_get_typestr | Get the name string for the type of an object |
obj_get_default | Get the YANG default value for an object |
obj_get_default_case | Get the name of the default case for a choice object |
obj_get_typdef | Get the internal type definition for the leaf or leaf-list object |
obj_get_basetype | Get the internal base type enumeration for an object |
obj_get_mod_prefix | Get the module prefix for an object |
obj_get_mod_name | Get the module name containing an object |
obj_get_mod_version | Get the module revision date for the module containing an object. |
obj_get_nsid | Get the internal XML namespace ID for an object |
obj_get_min_elements | Get the YANG min-elements value for a list or leaf-list object |
obj_get_max_elements | Get the YANG max-elements value for a list or leaf-list object |
obj_get_units | Get the YANG units field for a leaf or leaf-list object |
obj_get_parent | Get the parent object node for an object |
obj_get_presence_string | Get the YANG presence statement for a container object |
obj_get_child_count | Get the number of child nodes for a complex object. |
obj_get_fraction_digits | Get the YANG fraction-digits statement for a decimal64 leaf or leaf-list object |
obj_is_leafy | Return TRUE if the object is a leaf or leaf-list type |
obj_is_mandatory | Return TRUE if the object is YANG mandatory |
obj_is_mandatory_when | Return TRUE if the object is YANG mandatory, but first check if any when statements are FALSE first |
obj_is_cloned | Return TRUE if the object is expanded from a grouping or augment statement |
obj_is_data_db | Return TRUE if the object is defined within a YANG database definition |
obj_in_rpc | Return TRUE if the object is defined within an RPC statement |
obj_in_notif | Return TRUE if the object is defined within a notification statement |
obj_is_hidden | Return TRUE if object contains the ncx:hidden extension |
obj_is_root | Return TRUE if object contains the ncx:root extension |
obj_is_password | Return TRUE if object contains the ncx:password extension |
obj_is_cli | Return TRUE if object contains the ncx:cli extension |
obj_is_abstract | Return TRUE if object contains the ncx:abstract extension |
obj_is_xpath_string | Return TRUE if the object is a leaf or leaf-list containing an XPath string |
obj_is_schema_instance_string | Return TRUE if the object is a leaf or leaf-list containing a schema instance identifier string |
obj_is_secure | Return TRUE if object contains the nacm:secure extension |
obj_is_very_secure | Return TRUE if object contains the nacm:very-secure extension |
obj_is_system_ordered | Return TRUE if the list or leaf-list object is system ordered; FALSE if it is user ordered |
obj_is_np_container | Return TRUE if the object is a YANG non presence container |
obj_is_enabled | Return TRUE if the object is enabled; FALSE if any if-feature, when-stmt, or deviation-stmt has removed the object from the system. |
obj_sort_children | Rearrange any child nodes in YANG schema order |
Data Tree
A Yuma data tree is a representation of some subset of all possible object instances that a server is maintaining within a configuration database or other structure.
Each data tree starts with a 'root' container, and any child nodes represent top-level YANG module data nodes that exist within the server.
Each configuration database maintains its own copy (and version) of the data tree. There is only one object tree, however, and all data trees use the same object tree for reference.
Not all object types have a corresponding node within a data tree. Only 'real' data nodes are present. Object nodes that are used as meta-data to organize the object tree (e.g., choice, augment) are not present. The following table lists the object types and whether each one is found in a data tree.
OBJ_TYP_ANYXML | Yes |
OBJ_TYP_CONTAINER | Yes |
OBJ_TYP_CONTAINER (ncx:root) | Yes |
OBJ_TYP_LEAF | Yes |
OBJ_TYP_LEAF_LIST | Yes |
OBJ_TYP_LIST | Yes |
OBJ_TYP_CHOICE | No |
OBJ_TYP_CASE | No |
OBJ_TYP_USES | No |
OBJ_TYP_REFINE | No |
OBJ_TYP_AUGMENT | No |
OBJ_TYP_RPC | No |
OBJ_TYP_RPCIO | No |
OBJ_TYP_NOTIF | No |
Data Node Types
The ncx_btype_t enumeration in ncx/ncxtypes.h is used within each val_value_t to quickly identify which variant of the data node structure is being used.
The following table describes the different enumeration values:
NCX_BT_NONE | No type has been set yet. The val_new_value() function has been called but no specific init function has been called to set the base type. |
NCX_BT_ANY | The node is a YANG 'anyxml' node. When the client or server parses an 'anyxml' object, it will be converted to containers and strings. This type should not be used directly. |
NCX_BT_BITS | YANG 'bits' data type |
NCX_BT_ENUM | YANG 'enumeration' data type |
NCX_BT_EMPTY | YANG 'empty' data type |
NCX_BT_BOOLEAN | YANG 'boolean' data type |
NCX_BT_INT8 | YANG 'int8' data type |
NCX_BT_INT16 | YANG 'int16' data type |
NCX_BT_INT32 | YANG 'int32' data type |
NCX_BT_INT64 | YANG 'int64' data type |
NCX_BT_UINT8 | YANG 'uint8' data type |
NCX_BT_UINT16 | YANG 'uint16' data type |
NCX_BT_UINT32 | YANG 'uint32' data type |
NCX_BT_UINT64 | YANG 'uint64' data type |
NCX_BT_DECIMAL64 | YANG 'decimal64' data type |
NCX_BT_FLOAT64 | Hidden double type, used just for XPath. If the HAS_FLOAT #define is false, then this type will be implemented as a string, not a double. |
NCX_BT_STRING | YANG 'string' type. There are also some Yuma extensions that are used with this data type for special strings. The server needs to know if a string contains XML prefixes or not, and there are several flavors to automatate processing of each one correctly. |
NCX_BT_BINARY | YANG 'binary' data type |
NCX_BT_INSTANCE_ID | YANG 'instance-identifier' data type |
NCX_BT_UNION | YANG 'union' data type. This is a meta-type. When the client or server parses a value, it will resolve the union to one of the data types defined within the union. |
NCX_BT_LEAFREF | YANG 'leafref' data type. This is a meta-type. The client or server will resolve this data type to the type of the actual 'pointed-at' leaf that is being referenced. |
NCX_BT_IDREF | YANG 'identityref' data type |
NCX_BT_SLIST | XSD list data type (ncx:xsdlist extension) |
NCX_BT_CONTAINER | YANG container |
NCX_BT_CHOICE | YANG choice. This is a meta-type and placeholder. It does not appear in the data tree. |
NCX_BT_CASE | YANG case. This is a meta-type and placeholder. It does not appear in the data tree. |
NCX_BT_LIST | YANG list |
NCX_BT_EXTERN | Internal 'external' data type, used in yangcli. It indicates that the content is actually in an external file. |
NCX_BT_INTERN | Internal 'buffer' data type, used in yangcli. The content is actually stored verbatim in an internal buffer. |
Yuma Data Node Edit Variables (val_editvars_t)
There is a temporary data structure which is attached to a data node while editing operations are in progress, called val_editvars_t. This structure is used by the functions in agt/agt_val.c to manipulate the value tree nodes during an <edit-config>, <copy-config>, <load-config>, or <commit> operation.
The SIL callback functions may wish to refer to the fields in this data structure. There is also a SIL cookie field to allow data to be transferred from one callback stage to the later stages. For example, if an edit operation caused the device instrumentation to reserve some memory, then this cookie could store that pointer.
The following typedef is used to define the val_editvars_t structure:
/* one set of edit-in-progress variables for one value node */ typedef struct val_editvars_t_ { /* these fields are only used in modified values before they are * actually added to the config database (TBD: move into struct) * curparent == parent of curnode for merge */ struct val_value_t_ *curparent; op_editop_t editop; /* effective edit operation */ op_insertop_t insertop; /* YANG insert operation */ xmlChar *insertstr; /* saved value or key attr */ struct xpath_pcb_t_ *insertxpcb; /* key attr for insert */ struct val_value_t_ *insertval; /* back-ptr */ boolean iskey; /* T: key, F: value */ boolean operset; /* nc:operation here */ void *pcookie; /* user pointer cookie */ int icookie; /* user integer cookie */ } val_editvars_t;
The following fields within the val_editvars_t are highlighted:
curparent | A 'new' node will use this field to remember the parent of the 'current' value. This is needed to support the YANG insert operation. |
editop | The effective edit operation for this node. |
insertop | The YANG insert operation, if any. |
insertstr | The YANG 'value' or 'key' attribute value string, used to support the YANG insert operation. |
insertxpcb | XPath parser control block for the insert 'key' expression, if needed. Used to support the YANG insert operation. |
insertval | Back pointer to the value node to insert ahead of, or behind, if needed. Used to support the 'before' and 'after' modes of the YANG insert operation. |
iskey | TRUE if this is a key leaf. FALSE otherwise. |
operset | TRUE if there was an nc:operation attribute found in this node; FALSE if the 'editop' is derived from its parent. |
pcookie | SIL user pointer cookie. Not used by the server. Reserved for SIL callback code. |
icookie | SIL user integer cookie. Not used by the server. Reserved for SIL callback code. |
Yuma Data Nodes (val_value_t)
The val_value_t data structure is used to maintain the internal representation of all NETCONF databases, non-configuration data available with the <get> operation, all RPC operation input and output parameters, and all notification contents.
The following typedef is used to define a value node:
/* one value to match one type */ typedef struct val_value_t_ { dlq_hdr_t qhdr;
/* common fields */ struct obj_template_t_ *obj; /* bptr to object def */ typ_def_t *typdef; /* bptr to typdef if leaf */ const xmlChar *name; /* back pointer to elname */ xmlChar *dname; /* AND malloced name if needed */ struct val_value_t_ *parent; /* back-ptr to parent if any */ xmlns_id_t nsid; /* namespace ID for this node */ ncx_btype_t btyp; /* base type of this value */
uint32 flags; /* internal status flags */ ncx_data_class_t dataclass; /* config or state data */
/* YANG does not support user-defined meta-data but NCX does. * The <edit-config>, <get> and <get-config> operations * use attributes in the RPC parameters, the metaQ is still used * * The ncx:metadata extension allows optional attributes * to be added to object nodes for anyxml, leaf, leaf-list, * list, and container nodes. The config property will * be inherited from the object that contains the metadata * * This is used mostly for RPC input parameters * and is strongly discouraged. Full edit-config * support is not provided for metdata */ dlq_hdr_t metaQ; /* Q of val_value_t */
/* value editing variables */ val_editvars_t *editvars; /* edit-in-progress vars */ status_t res; /* validationt result */
/* Used by Agent only: * if this field is non-NULL, then the entire value node * is actually a placeholder for a dynamic read-only object * and all read access is done via this callback function; * the real data type is getcb_fn_t * */ void *getcb;
/* if this field is non-NULL, then a malloced value struct * representing the real value retrieved by * val_get_virtual_value, is cached here for XPath filtering * TBD: add timestamp to reuse cached entries for some time * period */ struct val_value_t_ *virtualval;
/* these fields are used for NCX_BT_LIST */ struct val_index_t_ *index; /* back-ptr/flag in use as index */ dlq_hdr_t indexQ; /* Q of val_index_t or ncx_filptr_t */
/* this field is used for NCX_BT_CHOICE * If set, the object path for this node is really: * $this --> casobj --> casobj.parent --> $this.parent * the OBJ_TYP_CASE and OBJ_TYP_CHOICE nodes are skipped * inside an XML instance document */ struct obj_template_t_ *casobj;
/* these fields are for NCX_BT_LEAFREF * NCX_BT_INSTANCE_ID, or tagged ncx:xpath * value stored in v union as a string */ struct xpath_pcb_t_ *xpathpcb;
/* union of all the NCX-specific sub-types * note that the following invisible constructs should * never show up in this struct: * NCX_BT_CHOICE * NCX_BT_CASE * NCX_BT_UNION */ union v_ { /* complex types have a Q of val_value_t representing * the child nodes with values * NCX_BT_CONTAINER * NCX_BT_LIST */ dlq_hdr_t childQ;
/* Numeric data types: * NCX_BT_INT8, NCX_BT_INT16, * NCX_BT_INT32, NCX_BT_INT64 * NCX_BT_UINT8, NCX_BT_UINT16 * NCX_BT_UINT32, NCX_BT_UINT64 * NCX_BT_DECIMAL64, NCX_BT_FLOAT64 */ ncx_num_t num;
/* String data types: * NCX_BT_STRING * NCX_BT_INSTANCE_ID */
ncx_str_t str; val_idref_t idref; ncx_binary_t binary; /* NCX_BT_BINARY */ ncx_list_t list; /* NCX_BT_BITS, NCX_BT_SLIST */ boolean boo; /* NCX_BT_EMPTY, NCX_BT_BOOLEAN */ ncx_enum_t enu; /* NCX_BT_UNION, NCX_BT_ENUM */ xmlChar *fname; /* NCX_BT_EXTERN */ xmlChar *intbuff; /* NCX_BT_INTERN */ } v; } val_value_t;
The following table highlights the fields in this data structure:
qhdr | Internal queue header to allow a value node to be stored in a queue. A complex node maintains a child queue of val_value_t nodes. |
obj | Back pointer to the object template for this data node |
typdef | Back pointer to the typedef structure if this is a leaf or leaf-list node. |
name | Back pointer to the name string for this node |
dname | Malloced name string if the client or server changed the name of this node, so the object node name is not being used. This is used for anyxml processing (and other things) to allow generic objects (container, string, empty, etc.) to be used to represent the contents of an 'anyxml' node. |
parent | Back pointer to the parent of this node, if any |
nsid | Namespace ID for this node. This may not be the same as the object node namespace ID, e.g., anyxml child node contents will override the generic object namespace. |
btyp | The ncx_btype_t base type enumeration for this node. This is the final resolved value, in the event the object type is not a final resolved base type. |
flags | Internal flags field. Do not access directly. |
dataclass | Internal config or non-config enumeration |
metaQ | Queue of val_value_t structures that represent any meta-variables (XML attributes) found for this data node. For example, the NETCONF filter 'type' and 'select' attributes are defined for the <filter> element in yuma-netconf.yang. |
editvars | Pointer to the malloced edit variables structure for this data node. This node will be freed (and NULL value) when the edit variables are not in use. |
res | Internal validation result status for this node during editing or parsing. |
getcb | Internal server callback function pointer. Used only if this is a 'virtual' node, and the actual value node contents are generated by a SIL callback function instead of being stored in the node itself. |
virtualval | The temporary cached virtual node value, if the getcb pointer is non-NULL. |
indexQ | Queue of internal data structures used during parsing and filtering streamed output. |
casobj | Back pointer to the OBJ_TYP_CASE object node for this data node, if this node is a top-level child of a YANG case statement. |
xpathpcb | XPath parser control block, used if this value contains some sort of XPath string or instance-identifier. For example, the XML namespace ID mappings are stored, so the XML prefix map generated for the <rpc-reply> will contain and reuse the proper namespace attributes, as needed. |
v | Union of different internal fields, depending on the 'btyp' field value. |
v.childQ | Queue of val_value_t child nodes, if this is a complex node. |
v.num | ncx_num_t for all numeric data types |
v.str | Malloced string value for the string data type |
v.idref | Internal data structure for the YANG identityref data type |
v.binary | Internal data structure for the YANG binary data type |
v.list | Internal data structure for YANG bits and NCX xsdlist data types |
v.boo | YANG boolean data type |
v.enu | Internal data structure for YANG enumeration data type |
v.fname | File name for NCX 'external' data type |
v.intbuff | Malloced buffer for 'internal' data type |
val_value_t Access Macros
There are a set of macros defined to access the fields within a val_value_t structure.
These should be used instead of accessing the fields directly. There are also functions defined as well. These macros are provided in addition the the access functions for quick access to the actual node value. These macros must only be used when the base type ('btyp') field has been properly set and known by the SIL code. Some auto-generated SIL code uses these macros.
The following table summarized the val_value_t macros that are defined in ncx/val.h:
VAL_BOOL(V) | Access value for NCX_BT_BOOLEAN |
VAL_EMPTY(V) | Access value for NCX_BT_EMPTY |
VAL_DOUBLE(V) | Access value for NCX_BT_FLOAT64 |
VAL_STRING(V) | Access value for NCX_BT_STRING |
VAL_BINARY(V) | Access value for NCX_BT_BINARY |
VAL_ENU(V) | Access entire ncx_enum_t structure for NCX_BT_ENUM |
VAL_ENUM(V) | Access enumeration integer value for NCX_BT_ENUM |
VAL_ENUM_NAME(V) | Access enumeration name string for NCX_BT_ENUM |
VAL_FLAG(V) | Deprecated: use VAL_BOOL instead |
VAL_LONG(V) | Access NCX_BT_INT64 value |
VAL_INT(V) | Access NCX_BT_INT32 value |
VAL_INT8(V) | Access NCX_BT_INT8 value |
VAL_INT16(V) | Access NCX_BT_INT16 value |
VAL_STR(V) | Deprecated: use VAL_STRING instead |
VAL_INSTANCE_ID(V) | Access NCX_BT_INSTANCE_ID value |
VAL_IDREF(V) | Access entire val_idref_t structure for NCX_BT_IDREF |
VAL_IDREF_NSID(V) | Access the identityref namespace ID for NCX_BT_IDREF |
VAL_IDREF_NAME(V) | Access the identityref name string for NCX_BT_IDREF |
VAL_UINT(V) | Access the NCX_BT_UINT32 value |
VAL_UINT8(V) | Access the NCX_BT_UINT8 value |
VAL_UINT16(V) | Access the NCX_BT_UINT16 value |
VAL_ULONG(V) | Access the NCX_BT_UINT64 value |
VAL_DEC64(V) | Access the ncx_dec64structure for NCX_BT_DEC64 |
VAL_LIST(V) | Access the ncx_list_t structure for NCX_BT_LIST |
VAL_BITS | Access the ncx_list_t structure for NCX_BT_BITS. (Same as VAL_LIST) |
val_value_t Access Functions
The file ncx/val.h contains many API functions so that object properties do not have to be accessed directly. In addition, the file ncx/val_util.h contains more (high-level) utility functions. The following table highlights the most commonly used functions. Refer to the H files for a complete definition of each API function.
val_new_value | Malloc a new value node with type NCX_BT_NONE. |
val_init_complex | Initialize a malloced value node as one of the complex data types. |
val_init_virtual | Initialize a malloced value node as a virtual node (provide a 'get' callback function). |
val_init_from_template | Initialize a malloced value node using an object template. This is the most common form of the init function used by SIL callback functions. |
vaL-free_value | Clean and free a malloced value node. |
val_set_name | Set or replace the value node name. |
val_set_qname | Set or replace the value node namespace ID and name. |
val_string_ok | Check if the string value is valid for the value node object type. |
val_string_ok_errinfo | Check if the string value is valid for the value node object type, and provide the error information to use if it is not OK. |
val_list_ok | Check if the list value is valid for the value node object type. |
val_list_ok_errinfo | Check if the list value is valid for the value node object type, and provide the error information to use if it is not OK. |
val_enum_ok | Check if the enumeration value is valid for the value node object type. |
val_enum_ok_errinfo | Check if the enumeration value is valid for the value node object type, and provide the error information to use if it is not OK. |
val_bit_ok | Check if the bits value is valid for the value node object type. |
val_idref_ok | Check if the identityref value is valid for the value node object type. |
val_parse_idref | Convert a string to an internal QName string into its various parts and find the identity struct that is being referenced (if available). |
val_simval_ok | Check if the smple value is valid for the value node object type. |
val_simval_ok_errinfo | Check if the simple value is valid for the value node object type, and provide the error information to use if it is not OK. |
val_get_first_meta | Get the first meta-variable (XML attribute value) for a value node. |
val_get_next_meta | Get the next meta-variable (XML attribute value) for a value node. |
val_find_meta | Find the specified meta-variable in a value node. |
val_dump_value | Debug function to print the contents of any value node. |
val_dump_value_ex | Debug function to print the contents of any value node, with extended parameters to control the output. |
val_dump_value_max | Debug function to print the contents of any value node, with full control of the output parameters. |
val_set_string | Set a malloced value node as a generic string value. Used instead of val_init_from_template. |
val_set_string2 | Set a malloced value node as a specified string type. Used instead of val_init_from_template. |
val_set_simval | Set a malloced value node as a specified simple type. Used instead of val_init_from_template. |
val_set_simval_str | Set a malloced value node as a specified simple type. Used instead of val_init_from_template. Use a counted string value instead of a zero-terminated string value. |
val_make_string | Create a complete malloced generic string value node. |
val_clone | Clone a value node |
val_clone_test | Clone a value node with a 'test' callback function to prune certain descendant nodes during the clone procedure. |
val_clone_config_data | Clone a value node but skip all the non-configuration descendant nodes. |
val_add_child | Add a child value node to a parent value node. |
val_insert_child | Insert a child value node into a specific spot into a parent value node. |
val_remove_child | Remove a child value node from its parent. |
val_swap_child | Replace a child node within its parent with a different value node. |
val_first_child_match | Match a child node name; Used for partial command completion in yangcli. |
val_next_child_match | Match the next child node name; Used for partial command completion in yangcli. |
val_get_first_child | Get the first child value node. |
val_get_next_child | Get the next child value node. |
val_find_child | Find a specific child value node. |
val_find_next_child | Find the next occurrence of a specified child node. |
val_match_child | Match a potential partial node name against the child node names, and return the first match found, if any. |
val_child_cnt | Get the number of child nodes within a parent node. |
val_liststr_count | Get the number of strings within an NCX_BT_LIST value node. |
val_index_match | Check if 2 value list nodes have the same set of key leaf values. |
val_compare | Compare 2 value nodes |
val_compare_ex | Compare 2 value nodes with extra parameters. |
val_compare_to_string | Compare a value node to a string value instead of another value node. |
val_sprintf_simval_nc | Output the value node as a string into the specified buffer. |
val_make_sprintf_string | Malloc a buffer and fill it with a zero-terminated string representation of the value node. |
val_resolve_scoped_name | Find a descendant node within a value node, from a relative path expression. |
val_has_content | Return TRUE if the value node has any content; FALSE if an empty XML element could represent its value. |
val_has_index | Return TRUE if the value node is a list with a key statement. |
val_get_first_index | Get the first index node for the specified list value node. |
val_get_next_index | Get the next index node for the specified list value node. |
val_set_extern | Set a malloced value node as an NCX_BT_EXTERN internal data type. |
val_set_intern | Set a malloced value node as an NCX_BT_INTERN internal data type. |
val_fit_oneline | Return TRUE if the value node should fit on 1 display line; Sometimes a guess is made instead of determining the exact value. XML namespace declarations generated during XML output can cause this function value to sometimes be wrong. |
val_create_allowed | Return TRUE if the NETCONF create operation is allowed for the specified value node. |
val_delete_allowed | Return TRUE if the NETCONF delete operation is allowed for the specified value node. |
val_is_config_data | Return TRUE if the value node represents configuration data. |
val_get_virtual_value | Get the value for a virtual node from its 'get' callback function. |
val_is_default | Return TRUE if the value node is set to its YANG default value. |
val_is_real | Check if a value node is a real node or one of the abstract node types.
|
val_get_parent_nsid | Get the namespace ID for the parent value node of a specified child node. |
val_instance_count | Get the number of occurrences of the specified child value node within a parent value node. |
val_need_quotes | Return TRUE if the printed string representation of a value node needs quotes (because it contains some whitespace or special characters). |
val_get_dirty_flag | Check if a value node has been altered by an RPC operation, but this edit has not been finalized yet. |
val_get_nest_level | Get the current numeric nest level of the specified value node. |
val_get_mod_name | Get the module name for the specified value node. |
val_get_mod_prefix | Get the module prefix string for the specified value node. |
val_get_nsid | Get the namespace ID for the specified value node. |
val_change_nsid | Change the namespace ID for the specified value node and all of its descendents. |
val_set_pcookie | Set the SIL pointer cookie in the value node editvars structure. |
val_set_icookie | Set the SIL integer cookie in the value node editvars structure. |
val_get_pcookie | Get the SIL pointer cookie in the value node editvars structure. |
val_get_icookie | Get the SIL integer cookie in the value node editvars structure. |
val_get_typdef | Get the typedef structure for a leaf or leaf-list value node. |
val_move_children | Move all the child nodes of one complex value node to another complex value node. |
val_set_canonical_order | Re-order the descendant nodes of a value node so they are in YANG order. Does not change the relative order of system-ordered lists and leaf-lists. |
val_gen_index_chain | Generate the internal key leaf lookup chain for a list value node.. |
val_add_defaults | Generate the leafs that have default values. |
val_instance_check | Check a value node against its template to see if the correct number of descendant nodes are present. |
val_get_choice_first_set | Get the first real node that is present for a conceptual choice statement. |
val_get_choice_next_set | Get the next real node that is present for a conceptual choice statement. |
val_choice_is_set | Return TRUE if some real data node is present for a conceptual choice statement. |
val_new_child_val | Create a child node during an edit operation. Used by the server. SIL code does not need to maintain the value tree. |
val_gen_instance_id | Malloc and generate the YANG instance-identifier string for the value node. |
val_check_obj_when | Check if an object node has any 'when' statements, and if so, evaluate the XPath condition(s) against the value tree to determine if the object should be considered present or not. |
val_check_child_conditional | Check if a child object node has any FALSE 'if-feature' or 'when' statements. |
val_is_mandatory | Check if the child object node is currently mandatory or optional. |
val_get_xpathpcb | Access the XPath parser control block for this value node, if any. |
val_make_simval_obj | Malloc and fill in a value node from an object template and a value string. |
val_set_simval_obj | Fill in a value node from an object template and a value string. |
SIL Utility Functions
There are some high-level SIL callback utilities in agt/agt_util.h. These functions access the lower-level functions in libncx to provide simpler functions for common SIL tasks.
The following table highlights the functions available in this module:
agt_get_cfg_from_parm | For value nodes that represent a NETCONF configuration database name (e.g., empty element named 'running'). The configuration control block for the referenced database is retrieved. |
agt_get_inline_cfg_from_parm | For value nodes that represent inline NETCONF configuration data. The value node for the inline config node is retrieved. |
agt_get_parmval | Get the specified parameter name within the RPC input section, from an RPC message control block. |
agt_record_error | Generate a complete RPC error record to be used when the <rpc-reply> is sent. |
agt_record_error_errinfo | Generate a complete RPC error record to be used when the <rpc-reply> is sent, using the YANG specified error information, not the default error information. |
agt_record_attr_error | Generate a complete RPC error record to be used when the <rpc-reply> is sent for an XML attribute error. |
agt_record_insert_error | Generate a complete RPC error record to be used when the <rpc-reply> is sent for a YANG insert operation error. |
agt_record_unique_error | Generate a complete RPC error record to be used when the <rpc-reply> is sent for a YANG unique statement contraint error. |
agt_check_default | val_nodetest_fn_t Node Test Callback function to filter out default data from streamed replies, according to the server's definition of a default node. |
agt_check_save | val_nodetest_fn_t Node Test Callback function to filter out data nodes that should not be saved to NV-storage. |
agt_enable_feature | Enable the specified YANG feature |
agt_disable_feature | Disable the specified YANG feature |
agt_make_leaf | Create a child value node. |
agt_make_virtual_leaf | Create a virtual value child node. Most device monitoring leafs use this function because the value is retrieved with a device-specific API, not stored in the value tree. |
agt_init_cache | Initialize a cached pointer to a node in a data tree. |
agt_check_cache | Check if a cached pointer to a node in a data tree needs to be updated or set to NULL. |
SIL External Interface
Each SIL has 2 initialization functions and 1 cleanup function that must be present.
- The first initialization callback function is used to set up the configuration related objects.
- The second initialization callback is used to setup up non-configuration objects, after the running configuration has been loaded from the startup file.
- The cleanup callback is used to remove all SIL data structures and unregister all callback functions.
These are the only SIL functions that the server will invoke directly. They are generated by yangdump with the --format=c parameter, and usually do not require any editing by the developer.
Most of the work done by SIL code is through callback functions for specific RPC operations and database objects. These callback functions are registered during the initialization functions.
Stage 1 Initialization
The stage 1 initialization function is the first function called in the library by the server.
If the netconfd configuration parameters include a 'load' command for the module, then this function will be called during server initialization. It can also be called if the <load> operation is invoked during server operation.
This function MUST NOT attempt to access any database. There will not be any configuration databases if this function is called during server initialization. Use the 'init2' function to adjust the running configuration.
This callback function is expected to perform the following functions:
- initialize any module static data
- make sure the requested module name and optional revision date parameters are correct
- load the requested module name and revision with ncxmod_load_module
- setup top-level object cache pointers (if needed)
- register any RPC method callbacks with agt_rpc_register_method
- register any database object callbacks with agt_cb_register_callback
- perform any device-specific and/or module-specific initialization
Name Format:
y_<modname>_init
Input:
- modname == string containing module name to load
- revision == string containing revision date to use == NULL if the operator did not specify a revision.
Returns:
- operation status (0 if success)
Example function generated by yangdump:
/******************************************************************** * FUNCTION y_toaster_init * * initialize the toaster server instrumentation library * * INPUTS: * modname == requested module name * revision == requested version (NULL for any) * * RETURNS: * error status ********************************************************************/ status_t y_toaster_init ( const xmlChar *modname, const xmlChar *revision) { agt_profile_t *agt_profile; status_t res;
y_toaster_init_static_vars();
/* change if custom handling done */ if (xml_strcmp(modname, y_toaster_M_toaster)) { return ERR_NCX_UNKNOWN_MODULE; }
if (revision && xml_strcmp(revision, y_toaster_R_toaster)) { return ERR_NCX_WRONG_VERSION; }
agt_profile = agt_get_profile();
res = ncxmod_load_module( y_toaster_M_toaster, y_toaster_R_toaster, &agt_profile->agt_savedevQ, &toaster_mod); if (res != NO_ERR) { return res; }
toaster_obj = ncx_find_object( toaster_mod, y_toaster_N_toaster); if (toaster_mod == NULL) { return SET_ERROR(ERR_NCX_DEF_NOT_FOUND); }
make_toast_obj = ncx_find_object( toaster_mod, y_toaster_N_make_toast); if (toaster_mod == NULL) { return SET_ERROR(ERR_NCX_DEF_NOT_FOUND); }
cancel_toast_obj = ncx_find_object( toaster_mod, y_toaster_N_cancel_toast); if (toaster_mod == NULL) { return SET_ERROR(ERR_NCX_DEF_NOT_FOUND); }
toastDone_obj = ncx_find_object( toaster_mod, y_toaster_N_toastDone); if (toaster_mod == NULL) { return SET_ERROR(ERR_NCX_DEF_NOT_FOUND); }
res = agt_rpc_register_method( y_toaster_M_toaster, y_toaster_N_make_toast, AGT_RPC_PH_VALIDATE, y_toaster_make_toast_validate); if (res != NO_ERR) { return res; }
res = agt_rpc_register_method( y_toaster_M_toaster, y_toaster_N_make_toast, AGT_RPC_PH_INVOKE, y_toaster_make_toast_invoke); if (res != NO_ERR) { return res; }
res = agt_rpc_register_method( y_toaster_M_toaster, y_toaster_N_cancel_toast, AGT_RPC_PH_VALIDATE, y_toaster_cancel_toast_validate); if (res != NO_ERR) { return res; }
res = agt_rpc_register_method( y_toaster_M_toaster, y_toaster_N_cancel_toast, AGT_RPC_PH_INVOKE, y_toaster_cancel_toast_invoke); if (res != NO_ERR) { return res; }
res = agt_cb_register_callback( y_toaster_M_toaster, (const xmlChar *)"/toaster", (const xmlChar *)"2009-11-20", y_toaster_toaster_edit);
if (res != NO_ERR) { return res; }
/* put your module initialization code here */
return res; } /* y_toaster_init */
Stage 2 Initialization
The stage 2 initialization function is the second function called in the library by the server:
- It will only be called if the stage 1 initialization is called first, and it returns 0 (NO_ERR status).
- This function is used to initialize any needed data structures in the running configuration, such as factory default configuration, read-only counters and status objects.
- It is called after the startup configuration has been loaded into the server.
- If the <load> operation is used during server operation, then this function will be called immediately after the state 1 initialization function.
Note that configuration data structures that are loaded during server initialization (load_running_config) will be handled by the database callback functions registered during phase 1 initialization.
Any server-created configuration nodes should be created during phase 2 initialization (this function), after examining the explicitly-provided configuration data. For example, the top-level /nacm container will be created (by agt_acm.c) if it is not provided in the startup configuration.
This callback function is expected to perform the following functions:
- load non-configuration data structures into the server (if needed)
- initialize top-level data node cache pointers (if needed)
- load factory-default configuration data structures into the server (if needed)
- optionally save a cached pointer to a data tree node (such as the root node for the module). The agt_create_cache function in agt/agt_util.h is used to initialize such a module-static variable.
Name Format:
y_<modname>_init2
Returns:
- operation status (0 if success)
Example function generated by yangdump:
/******************************************************************** * FUNCTION y_toaster_init2 * * SIL init phase 2: non-config data structures * Called after running config is loaded * * RETURNS: * error status ********************************************************************/
status_t y_toaster_init2 (void) { status_t res;
res = NO_ERR;
toaster_val = agt_init_cache( y_toaster_M_toaster, y_toaster_N_toaster, &res); if (res != NO_ERR) { return res; }
/* put your init2 code here */
return res; } /* y_toaster_init2 */
Cleanup
The cleanup function is called during server shutdown. It is only called if the stage 1 initialization function is called. It will be called right away if either the stage 1 or stage 2 initialization functions return a non-zero error status.
This callback function is expected to perform the following functions:
- cleanup any module static data
- free any top-level object cache pointers (if needed)
- unregister any RPC method callbacks with agt_rpc_unregister_method
- unregister any database object callbacks with agt_cb_unregister_callbacks
- perform any device-specific and/or module-specific cleanup
Name Format:
y_<modname>_cleanup
Example function generated by yangdump:
/******************************************************************** * FUNCTION y_toaster_cleanup * cleanup the server instrumentation library * ********************************************************************/ void y_toaster_cleanup (void) { agt_rpc_unregister_method( y_toaster_M_toaster, y_toaster_N_make_toast);
agt_rpc_unregister_method( y_toaster_M_toaster, y_toaster_N_cancel_toast);
agt_cb_unregister_callbacks( y_toaster_M_toaster, (const xmlChar *)"/toaster");
/* put your cleanup code here */
} /* y_toaster_cleanup */
SIL Callback Interface
This section briefly describes the SIL code that a developer will need to create to handle the data-model specific details. SIL functions access internal server data structures, either directly or through utility functions. Database mechanics and XML processing are done by the server engine, not the SIL code. A more complete reference can be found in section 5.
When a <rpc> request is received, the NETCONF server engine will perform the following tasks before calling any SIL:
- parse the RPC operation element, and find its associated YANG rpc template
- if found, check if the session is allowed to invoke this RPC operation
- if the RPC is allowed, parse the rest of the XML message, using the rpc_template_t for the RPC operation to determine if the basic structure is valid.
- if the basic structure is valid, construct an rpc_msg_t data structure for the incoming message.
- check all YANG machine-readable constraints, such as must, when, if-feature, min-elements, etc.
- if the incoming message is completely 'YANG valid', then the server will check for an RPC validate function, and call it if found. This SIL code is only needed if there are additional system constraints to check. For example:
- need to check if a configuration name such as <candidate/> is supported
- need to check if a configuration database is locked by another session
- need to check description statement constraints not covered by machine-readable constraints
- need to check if a specific capability or feature is enabled
- If the validate function returns a NO_ERR status value, then the server will call the SIL invoke callback, if it is present. This SIL code should always be present, otherwise the RPC operation will have no real affect on the system.
- At this point, an <rpc-reply> is generated, based on the data in the rpc_msg_t.
- Errors are recorded in a queue when they are detected.
- The server will handle the error reply generation for all errors it detects.
- For SIL detected errors, the agt_record_error function in agt/agt_util.h is usually used to save the error details.
- Reply data can be generated by the SIL invoke callback function and stored in the rpc_msg_t structure.
- Replay data can be streamed by the SIL code via reply callback functions. For example, the <get> and <get-config> operations use callback functions to deal with filters, and stream the reply by walking the target data tree.
- After the <rpc-reply> is sent, the server will check for an RPC post reply callback function. This is only needed if the SIL code allocated some per-message data structures. For example, the rpc_msg_t contains 2 SIL controlled pointers (rpc_user1 and rpc_user2). The post reply callback is used by the SIL code to free these pointers, if needed.
The database edit SIL callbacks are only used for database operations that alter the database. The validate and invoke callback functions for these operations will in turn invoke the data-model specific SIL callback functions, depending on the success or failure of the edit request.
RPC Operation Interface
All RPC operations are data-driven within the server, using the YANG rpc statement for the operation and SIL callback functions.
Any new protocol operation can be added by defining a new YANG rpc statement in a module, and providing the proper SIL code.
RPC Callback Initialization
The agt_rpc_register_method function in agt/agt_rpc.h is used to provide a callback function for a specific callback phase. The same function can be used for multiple phases if desired.
/* Template for RPC server callbacks * The same template is used for all RPC callback phases */ typedef status_t (*agt_rpc_method_t) (ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode);
extern status_t agt_rpc_register_method (const xmlChar *module, const xmlChar *method_name, agt_rpc_phase_t phase, agt_rpc_method_t method);
module | The name of the module that contains the rpc statement |
method_name | The identifier for the rpc statement |
phase | AGT_PH_VALIDATE(0): validate phaseAGT_PH_INVOKE(1): invoke phaseAGT_PH_POST_REPLY(2): post-reply phase |
method | The address of the callback function to register |
RPC Message Header
The NETCONF server will parse the incoming XML message and construct an RPC message header, which is used to maintain state and any other message-specific data during the processing of an incoming <rpc> request.
The rpc_msg_t data structure in ncx/rpc.h is used for this purpose. The following table summarizes the fields:
qhdr | dlq_hdr_t | none | Queue header to store RPC messages in a queue (within the session header) |
mhdr | xml_msg_hdr_t | none | XML message prefix map and other data used to parse the request and generate the reply. |
rpc_in_attrs | xml_attrs_t * | readwrite | Queue of xml_attr_t representing any XML attributes that were present in the <rpc> element. A callback function may add xml_attr_t structs to this queue to send in the reply. |
rpc_method | obj_template_t * | read | Back-pointer to the object template for this RPC operation. |
rpc_agt_state | int | read | Enum value (0, 1, 2) for the current RPC callback phase. |
rpc_err_option | op_errop_t | read | Enum value for the <error-option> parameter. This is only set if the <edit-config> operation is in progress. |
rpc_top_editop | op_editop_t | read | Enum value for the <default-operation> parameter. This is only set if the <edit-config> operation is in progress. |
rpc_input | val_value_t * | read | Value tree representing the container of 'input' parameters for this RPC operation. |
rpc_user1 | void * | readwrite | Void pointer that can be used by the SIL functions to store their own message-specific data. |
rpc_user2 | void * | readwrite | Void pointer that can be used by the SIL functions to store their own message-specific data. |
rpc_returncode | uint32 | none | Internal return code used to control nested callbacks. |
rpc_data_type | rpc_data_t | write | For RPC operations that return data, this enumeration is set to indicate which type of data is desired.
RPC_DATA_STD: A <data> container will be used to encapsulate any returned data, within the <rpc-reply> element. RPC_DATA_YANG: The <rpc-reply> element will be the only container encapsulated any returned data. |
rpc_datacb | void * | write | For operations that return streamed data, this pointer is set to the desired callback function to use for generated the data portion of the <rpc-reply> XML response.
The template for this callback is agt_rpc_data_cb_t, found in agt_rpc.h |
rpc_dataQ | dlq_hdr_t | write | For operations that return stored data, this queue of val_value_t structures can be used to provide the response data. Each val_value_t structure will be encoded as one of the corresponding RPC output parameters. |
rpc_filter | op_filter_t | none | Internal structure for optimizing subtree and XPath retrieval operations. |
rpc_need_undo | boolean | none | Internal flag to indicate if rollback-on-error is in effect dusing an <edit-config> operation. |
rpc_undoQ | dlq_hdr_t | none | Queue of rpc_undo_rec_t structures, used to undo edits if rollback-on-error is in affect during an <edit-config> operation. |
rpc_auditQ | dlq_hdr_t | none | Queue of rpc_audit_rec_t structures used internally to generate database alteration notifications and audit log entries. |
The following C code represents the rpc_msg_t data structure:
/* NETCONF Server and Client RPC Request/Reply Message Header */ typedef struct rpc_msg_t_ { dlq_hdr_t qhdr;
/* generic XML message header */ xml_msg_hdr_t mhdr;
/* incoming: top-level rpc element data */ xml_attrs_t *rpc_in_attrs; /* borrowed from <rpc> elem */
/* incoming: * 2nd-level method name element data, used in agt_output_filter * to check get or get-config */ struct obj_template_t_ *rpc_method;
/* incoming: SERVER RPC processing state */ int rpc_agt_state; /* agt_rpc_phase_t */ op_errop_t rpc_err_option; op_editop_t rpc_top_editop; val_value_t *rpc_input;
/* incoming: * hooks for method routines to save context or whatever */ void *rpc_user1; void *rpc_user2; uint32 rpc_returncode; /* for nested callbacks */
/* incoming: get method reply handling builtin * If the rpc_datacb is non-NULL then it will be used as a * callback to generate the rpc-reply inline, instead of * buffering the output. * The rpc_data and rpc_filter parameters are optionally used * by the rpc_datacb function to generate a reply. */ rpc_data_t rpc_data_type; /* type of data reply */
void *rpc_datacb; /* agt_rpc_data_cb_t */ dlq_hdr_t rpc_dataQ; /* data reply: Q of val_value_t */ op_filter_t rpc_filter; /* backptrs for get* methods */
/* incoming: rollback or commit phase support builtin * As an edit-config (or other RPC) is processed, a * queue of 'undo records' is collected. * If the apply phase succeeds then it is discarded, * otherwise if rollback-on-error is requested, * it is used to undo each change that did succeed (if any) * before an error occured in the apply phase. */ boolean rpc_need_undo; /* set by edit_config_validate */ dlq_hdr_t rpc_undoQ; /* Q of rpc_undo_rec_t */ dlq_hdr_t rpc_auditQ; /* Q of rpc_audit_rec_t */
} rpc_msg_t;
SIL Support Functions For RPC Operations
The file agt/agt_rpc.c contains some functions that are used by SIL callback functions.
The following table highlights the functions that may be useful to SIL developers:
agt_rpc_register_method | Register a SIL RPC operation callback function for 1 callback phase. |
agt_rpc_support_method | Tell the server that an RPC operation is supported by the system.. |
agt_rpc_unsupport_method | Tell the server that an RPC operation is not supported by the system.. |
agt_rpc_unregister_method | Remove all the SIL RPC operation callback functions for 1 RPC operation. |
RPC Validate Callback Function
[[Image:]]
The RPC validate callback function is optional to use. Its purpose is to validate any aspects of an RPC operation, beyond the constraints checked by the server engine. Only 1 function can register for each YANG rpc statement. The standard NETCONF operations are reserved by the server engine. There is usually zero or one of these callback functions for every 'rpc' statement in the YANG module associated with the SIL code.
It is enabled with the agt_rpc_register_method function, within the phase 1 initialization callback function.
The yangdump code generator will create this SIL callback function by default. There will C comments in the code to indicate where your additional C code should be added.
The val_find_child function is commonly used to find particular parameters within the RPC input section, which is encoded as a val_value_t tree.
The agt_record_error function is commonly used to record any parameter or other errors. In the libtoaster example, there are internal state variables (toaster_enabled and toaster_toasting), maintained by the SIL code, which are checked in addition to any provided parameters.
Example SIL Function Registration
res = agt_rpc_register_method( y_toaster_M_toaster, y_toaster_N_make_toast, AGT_RPC_PH_VALIDATE, y_toaster_make_toast_validate); if (res != NO_ERR) { return res; }
Example SIL Function:
/******************************************************************** * FUNCTION y_toaster_make_toast_validate * * RPC validation phase * All YANG constraints have passed at this point. * Add description-stmt checks in this function. * * INPUTS: * see agt/agt_rpc.h for details * * RETURNS: * error status ********************************************************************/ static status_t y_toaster_make_toast_validate ( ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode) { status_t res; val_value_t *errorval; const xmlChar *errorstr; val_value_t *toasterDoneness_val; val_value_t *toasterToastType_val; uint32 toasterDoneness; val_idref_t *toasterToastType;
res = NO_ERR; errorval = NULL; errorstr = NULL;
toasterDoneness_val = val_find_child( msg->rpc_input, y_toaster_M_toaster, y_toaster_N_toasterDoneness); if (toasterDoneness_val != NULL && toasterDoneness_val->res == NO_ERR) { toasterDoneness = VAL_UINT(toasterDoneness_val); }
toasterToastType_val = val_find_child( msg->rpc_input, y_toaster_M_toaster, y_toaster_N_toasterToastType); if (toasterToastType_val != NULL && toasterToastType_val->res == NO_ERR) { toasterToastType = VAL_IDREF(toasterToastType_val); }
/* added code starts here */ if (toaster_enabled) { /* toaster service enabled, check if in use */
if (toaster_toasting) { res = ERR_NCX_IN_USE; } else { /* this is where a check on bread inventory would go */
/* this is where a check on toaster HW ready would go */ } } else { /* toaster service disabled */ res = ERR_NCX_RESOURCE_DENIED; } /* added code ends here */
/* if error: set the res, errorstr, and errorval parms */ if (res != NO_ERR) { agt_record_error( scb, &msg->mhdr, NCX_LAYER_OPERATION, res, methnode, NCX_NT_STRING, errorstr, NCX_NT_VAL, errorval); }
return res;
} /* y_toaster_make_toast_validate */
RPC Invoke Callback Function
[[Image:]]
The RPC invoke callback function is used to perform the operation requested by the client session. Only 1 function can register for each YANG rpc statement. The standard NETCONF operations are reserved by the server engine. There is usually one of these callback functions for every 'rpc' statement in the YANG module associated with the SIL code.
The RPC invoke callback function is optional to use, although if no invoke callback is provided, then the operation will have no affect. Normally, this is only the case if the module is be tested by an application developer, using netconfd as a server simulator.
It is enabled with the agt_rpc_register_method function, within the phase 1 initialization callback function.
The yangdump code generator will create this SIL callback function by default. There will C comments in the code to indicate where your additional C code should be added.
The val_find_child function is commonly used to retrieve particular parameters within the RPC input section, which is encoded as a val_value_t tree. The rpc_user1 and rpc_user2 cache pointers in the rpc_msg_t structure can also be used to store data in the validation phase, so it can be immediately available in the invoke phase.
The agt_record_error function is commonly used to record any internal or platform-specific errors. In the libtoaster example, if the request to create a timer callback control block fails, then an error is recorded.
For RPC operations that return either an <ok> or <rpc-error> response, there is nothing more required of the RPC invoke callback function.
For operations which return some data or <rpc-error>, the SIL code must do 1 of 2 additional tasks:
- add a val_value_t structure to the rpc_dataQ queue in the rpc_msg_t for each parameter listed in the YANG rpc 'output' section.
- set the rpc_datacb pointer in the rpc_msg_t structure to the address of your data reply callback function. See the agt_rpc_data_cb_t definition in agt/agt_rpc.h for more details.
Example SIL Function Registration
res = agt_rpc_register_method( y_toaster_M_toaster, y_toaster_N_make_toast, AGT_RPC_PH_INVOKE, y_toaster_make_toast_invoke); if (res != NO_ERR) { return res; }
Example SIL Function:
/******************************************************************** * FUNCTION y_toaster_make_toast_invoke * * RPC invocation phase * All constraints have passed at this point. * Call device instrumentation code in this function. * * INPUTS: * see agt/agt_rpc.h for details * * RETURNS: * error status ********************************************************************/ static status_t y_toaster_make_toast_invoke ( ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode) { status_t res; val_value_t *toasterDoneness_val; val_value_t *toasterToastType_val; uint32 toasterDoneness; val_idref_t *toasterToastType;
res = NO_ERR; toasterDoneness = 0;
toasterDoneness_val = val_find_child( msg->rpc_input, y_toaster_M_toaster, y_toaster_N_toasterDoneness); if (toasterDoneness_val != NULL && toasterDoneness_val->res == NO_ERR) { toasterDoneness = VAL_UINT(toasterDoneness_val); }
toasterToastType_val = val_find_child( msg->rpc_input, y_toaster_M_toaster, y_toaster_N_toasterToastType); if (toasterToastType_val != NULL && toasterToastType_val->res == NO_ERR) { toasterToastType = VAL_IDREF(toasterToastType_val); }
/* invoke your device instrumentation code here */
/* make sure the toasterDoneness value is set */ if (toasterDoneness_val == NULL) { toasterDoneness = 5; /* set the default */ }
/* arbitrary formula to convert toaster doneness to the * number of seconds the toaster should be on */ toaster_duration = toasterDoneness * 12;
/* this is where the code would go to adjust the duration * based on the bread type */
if (LOGDEBUG) { log_debug("\ntoaster: starting toaster for %u seconds", toaster_duration); }
/* this is where the code would go to start the toaster * heater element */
/* start a timer to toast for the specified time interval */ res = agt_timer_create(toaster_duration, FALSE, toaster_timer_fn, NULL, &toaster_timer_id); if (res == NO_ERR) { toaster_toasting = TRUE; } else { agt_record_error( scb, &msg->mhdr, NCX_LAYER_OPERATION, res, methnode, NCX_NT_NONE, NULL, NCX_NT_NONE, NULL); } /* added code ends here */
return res;
} /* y_toaster_make_toast_invoke */
RPC Post Reply Callback Function
[[Image:]]
The RPC post-reply callback function is used to clean up after a message has been processed. Only 1 function can register for each YANG rpc statement. The standard NETCONF operations are reserved by the server engine. This callback is not needed unless the SIL validate or invoke callback allocated some memory that needs to deleted after the <rpc-reply> is sent.
The RPC post reply callback function is optional to use. It is enabled with the agt_rpc_register_method function, within the phase 1 initialization callback function.
The yangdump code generator will not create this SIL callback function by default.
Example SIL Function Registration
res = agt_rpc_register_method( y_foo_M_foo, y_foo_N_command, AGT_RPC_PH_POST_REPLY, y_foo_command_post); if (res != NO_ERR) { return res; }
Example SIL Function:
/******************************************************************** * FUNCTION y_foo_command_post * * RPC post reply phase * * INPUTS: * see agt/agt_rpc.h for details * * RETURNS: * error status ********************************************************************/ static status_t y_foo_command_post ( ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode) { (void)scb; (void)methnode; if (msg->rpc_user1 != NULL) { m__free(msg->rpc_user1); msg->rpc_user1 = NULL; } return NO_ERR; } /* y_foo_command_post */
Database Operations
The server database is designed so that the SIL callback functions do not need to really know which database model is being used by the server (e.g., target is candidate vs. running configuration).
There are three SIL database edit callback phases:
- Validate: Check the parameters no matter what database is the target
- Apply: The server will manipulate the database nodes as needed. The SIL usually has nothing to do in this phase unless internal resources need to be reserved.
- Commit or Rollback: Depending on the result of the previous phases, either the commit or the rollback callback phase will be invoked, if and when the changes are going to be finalized in the running configuration.
The SIL code is not responsible for maintaining the value tree for any database. This is done by the server.
The SIL database edit callback code is responsible for the following tasks:
- Perform any data-model specific validation that is not already covered by a machine-readable statement, during the validation phase.
- Reserve any data-model specific resources for the proposed new configuration content, during the apply phase.
- Activate any data-model behavior changes based on the new configuration content, during the commit phase.
- Release any reserved resources that were previously allocated in the apply phase, during the rollback phase.
Database Template (cfg_template_t)
Every NETCONF database has a common template control block, and common set of access functions.
NETCONF databases are not separate entities like separate SQL databases. Each NETCONF database is conceptually the same database, but in different states:
- candidate: A complete configuration that may contain changes that have not been applied yet. This is only available if the :candidate capability is advertised by the server. The value tree for this database contains only configuration data nodes.
- running: The complete current server configuration. This is available on every NETCONF server. The value tree for this database contains configuration data nodes and non-configuration nodes created and maintained by the server. The server will maintain read-only nodes when <edit-config>, <copy-config>, or <commit> operations are performed on the running configuration. SIL code should not alter the data nodes within a configuration directly. This work is handled by the server. SIL callback code should only alter its own data structures, if needed.
- startup: A complete configuration that will be used upon the next reboot of the device. This is only available if the :startup capability is advertised by the server. The value tree for this database contains only configuration data nodes.
NETCONF also recognized external files via the <url> parameter, if the :url capability is advertised by the server. These databases will be supported in a future release of the server. The NETCONF standard does not require that these external databases support the same set of protocol operations as the standard databases, listed above. A client application can reliably copy from and to an external database, but editing and filtered retrieval may not be supported.
The following typedef is used to define a NETCONF database template:
/* struct representing 1 configuration database */ typedef struct cfg_template_t_ { dlq_hdr_t qhdr; ncx_cfg_t cfg_id; cfg_location_t cfg_loc; cfg_state_t cfg_state; xmlChar *name; xmlChar *src_url; xmlChar *load_time; xmlChar *lock_time; xmlChar *last_ch_time; uint32 flags; ses_id_t locked_by; cfg_source_t lock_src; dlq_hdr_t load_errQ; /* Q of rpc_err_rec_t */ val_value_t *root; /* btyp == container */ } cfg_template_t;
The following table highlights the fields in the cfg_template_t data structure:
qhdr | Queue header to allow the object template to be stored in a queue. |
cfg_id | Internal configuration ID assigned to this configuration. |
cfg_loc | Enumeration identifying the configuration source location. |
cfg_state | Current internal configuration state. |
name | Name string for this configuration. |
src_url | URL for use with 'cfg_loc' to identify the configuration source. |
load_time | Date and time string when the configuration was loaded. |
lock_time | Date and time string when the configuration was last locked. |
last_ch_time | Date and time string when the configuration was last changed. |
flags | Internal configuration flags. Do not use directly. |
locked_by | Session ID that owns the global configuration lock, if the database is currently locked. |
lock_src | If the database is locked, identifies the protocol or other source that currently caused the database to be locked. |
load_errQ | Queue of rpc_err_rec_t structures that represent any <rpc-error> records that were generated when the configuration was loaded, if any. |
root | The root of the value tree representing the entire database. |
Database Access Functions
The file ncx/cfg.h contains some high-level database access functions that may be of interest to SIL callback functions for custom RPC operations. All database access details are handled by the server if the database edit callback functions are used (associated with a particular object node supported by the server)..The following table highlights the most commonly used functions. Refer to the H file for a complete definition of each API function.
cfg_new_template | Create a new configuration database. |
cfg_free_template | Free a configuration database. |
cfg_get_state | Get the current internal database state. |
cfg_get_config | Get a configuration database template pointer, from a configuration name string. |
cfg_get_config_id | Get a configuration database template pointer, from a configuration ID. |
cfg_fill_candidate_from_inline | Fill the candidate database from an internal value tree data structure. |
cfg_get_dirty_flag | Returns TRUE if the database has changes in it that have not been saved yet. This applies to the candidate and running databases at this time. |
cfg_ok_to_lock | Check if the database could be successfully locked by a specific session. |
cfg_ok_to_unlock | Check if the database could be successfully unlocked by a specific session. |
cfg_ok_to_read | Check if the database is in a state where read operations are allowed. |
cfg_ok_to_write | Check if the database could be successfully written by a specific session. Checks the global configuration lock, if any is set. |
cfg_is_global_locked | Returns TRUE if the database is locked right now with a global lock. |
cfg_get_global_lock_info | Get some information about the current global lock on the database. |
cfg_lock | Get a global lock on the database. |
cfg_unlock | Release the global lock on the database. |
cfg_release_locks | Release all locks on all databases |
Database Callback Initialization and Cleanup
The file agt/agt_cb.h contains functions that a SIL developer needs to register and unregister database edit callback functions. The same callback function can be used for different phases, if desired.
The following function template definition is used for all SIL database edit callback functions:
/* Callback function for agent object handler * Used to provide a callback sub-mode for * a specific named object * * INPUTS: * scb == session control block making the request * msg == incoming rpc_msg_t in progress * cbtyp == reason for the callback * editop == the parent edit-config operation type, which * is also used for all other callbacks * that operate on objects * newval == container object holding the proposed changes to * apply to the current config, depending on * the editop value. Will not be NULL. * curval == current container values from the <running> * or <candidate> configuration, if any. Could be NULL * for create and other operations. * * RETURNS: * status: */ typedef status_t (*agt_cb_fn_t) (ses_cb_t *scb, rpc_msg_t *msg, agt_cbtyp_t cbtyp, op_editop_t editop, val_value_t *newval, val_value_t *curval);
scb | The session control block making the edit request. The SIL callback code should not need this parameter except to pass to functions that need the SCB. |
msg | Incoming RPC message in progress. The server uses some fields in this structure, and there are 2 SIL fields for the RPC callback functions. The SIL callback code should not need this parameter except to pass to functions that need the message header. |
cbtyp | Enumeration for the callback phase in progress.. |
editop | The edit operation in effect as this node is being processed. |
newval | Value node containing the new value for a create, merge, replace, or insert operation. The 'newval' parm may be NULL and should be ignored for a delete operation. In that case, the 'curval' pointer contains the node being deleted. |
curval | Value node containing the current database node that corresponds to the 'newval' node, if any is available. |
A SIL database edit callback function is hooked into the server with the agt_cb_register_callback or agt_cb_register_callbacks functions, described below. The SIL code generated by yangdump uses the first function to register a single callback function for all callback phases.
extern status_t agt_cb_register_callback (const xmlChar *modname, const xmlChar *defpath, const xmlChar *version, const agt_cb_fn_t cbfn);
modname | Module name string that defines this object node. |
defpath | Absolute path expression string indicating which node the callback function is for. |
version | If non-NULL, indicates the exact module version expected. |
cbfn | The callback function address. This function will be used for all callback phases. |
extern status_t agt_cb_register_callbacks (const xmlChar *modname, const xmlChar *defpath, const xmlChar *version, const agt_cb_fnset_t *cbfnset);
modname | Module name string that defines this object node. |
defpath | Absolute path expression string indicating which node the callback function is for. |
version | If non-NULL, indicates the exact module version expected. |
cbfnset | The callback function set structure, fillied in with the addesses of all desired callback phases. Any NULL slots will cause that phase to be skipped. |
The agt_cb_unregister_callbacks function is called during the module cleanup. It is generated by yangdump automatically for all RPC operations.
extern void agt_cb_unregister_callbacks (const xmlChar *modname, const xmlChar *defpath);
modname | Module name string that defines this object node. |
defpath | Absolute path expression string indicating which node the callback function is for. |
Example SIL Database Edit Callback Function
The following example code is from the libtoaster source code, available in yuma-dev and yuma-source packages.
/******************************************************************** * FUNCTION y_toaster_toaster_edit * * Edit database object callback * Path: /toaster * Add object instrumentation in COMMIT phase. * * INPUTS: * see agt/agt_cb.h for details * * RETURNS: * error status ********************************************************************/
static status_t y_toaster_toaster_edit ( ses_cb_t *scb, rpc_msg_t *msg, agt_cbtyp_t cbtyp, op_editop_t editop, val_value_t *newval, val_value_t *curval) { status_t res; val_value_t *errorval; const xmlChar *errorstr;
res = NO_ERR; errorval = NULL; errorstr = NULL;
switch (cbtyp) { case AGT_CB_VALIDATE: /* description-stmt validation here */ break; case AGT_CB_APPLY: /* database manipulation done here */ break; case AGT_CB_COMMIT: /* device instrumentation done here */ switch (editop) { case OP_EDITOP_LOAD: toaster_enabled = TRUE; toaster_toasting = FALSE; break; case OP_EDITOP_MERGE: break; case OP_EDITOP_REPLACE: break; case OP_EDITOP_CREATE: toaster_enabled = TRUE; toaster_toasting = FALSE; break; case OP_EDITOP_DELETE: toaster_enabled = FALSE; if (toaster_toasting) { agt_timer_delete(toaster_timer_id); toaster_timer_id = 0; toaster_toasting = FALSE; y_toaster_toastDone_send((const xmlChar *)"error"); } break; default: res = SET_ERROR(ERR_INTERNAL_VAL); }
if (res == NO_ERR) { res = agt_check_cache( &toaster_val, newval, curval, editop); }
if (res == NO_ERR && (editop == OP_EDITOP_LOAD || editop == OP_EDITOP_CREATE)){ res = y_toaster_toaster_mro(newval); } break; case AGT_CB_ROLLBACK: /* undo device instrumentation here */ break; default: res = SET_ERROR(ERR_INTERNAL_VAL); }
/* if error: set the res, errorstr, and errorval parms */ if (res != NO_ERR) { agt_record_error( scb, &msg->mhdr, NCX_LAYER_CONTENT, res, NULL, NCX_NT_STRING, errorstr, NCX_NT_VAL, errorval); }
return res;
} /* y_toaster_toaster_edit */
Database Edit Validate Callback Phase
[[Image:]]
A SIL database validation phase callback function is responsible for checking all the 'description statement' sort of data model requirements that are not covered by any of the YANG machine-readable statements.
For example, if a 'user name' parameter needed to match an existing user name in /etc/passwd, then the SIL validation callback would call the system APIs needed to check if the 'newval' string value matched a valid user name. The server will make sure the user name is well-formed and could be a valid user name.
Database Edit Apply Callback Phase
The callback function for this phase is called when database edits are being applied to the running configuration. The resources needed for the requested operation may be reserved at this time, if needed.
Database Edit Commit Callback Phase
This callback function for this phase is called when database edits are being committed to the running configuration. The SIL callback function is expected to finalize and apply any data-model dependent system behavior at this time.
Database Edit Rollback Callback Phase
This callback function for this phase is called when database edits are being undone, after some apply phase or commit phase callback function returned an error, or a confirmed commit operation timed out.
The SIL callback function is expected to release any resources it allocated during the apply or commit phases. Usually only the commit or the rollback function will be called for a given SIL callback, but it is possible for both to be called. For example, if the 'rollback-on-error' option is in effect, and some SIL commit callback fails after your SIL commit callback succeeds, then your SIL rollback callback may be called as well.
Database Virtual Node Get Callback Function
A common SIL callback function to use is a virtual node 'get' function. A virtual node can be either a configuration or non-configuration node, but is more likely to be a non-configuration node, such as a counter or hardware status object.
The function agt_make_virtual_leaf in agt/agt_util.h is a common API used for creating a virtual leaf within an existing parent container.
The following typedef defines the getcb_fn_t template, used by all virtual callback functions. This function is responsible for filling in a value node with the current instance value. The status NO_ERR is returned if this is done successfully.
/* getcb_fn_t * * Callback function for agent node get handler * * INPUTS: * scb == session that issued the get (may be NULL) * can be used for access control purposes * cbmode == reason for the callback * virval == place-holder node in the data model for * this virtual value node * dstval == pointer to value output struct * * OUTPUTS: * *fil may be adjusted depending on callback reason * *dstval should be filled in, depending on the callback reason * * RETURNS: * status: */ typedef status_t (*getcb_fn_t) (ses_cb_t *scb, getcb_mode_t cbmode, const val_value_t *virval, val_value_t *dstval);
The following table describes the parameters.
scb | This is the session control block making the request, if available. This pointer may be NULL, so in the rare event this parameter is needed by the SIL callback function, it should be checked first. |
cbmode | The callback type. The only supported enumeration at this time is GETCB_GET_VALUE. Other values may be used in the future for different retrieval modes. |
virval | The virtual value node in the data tree that is being referenced, The val_get_virtual_value function was called for this value node. |
dstval | The destination value node that needs to be filled in. This is just an empty value node that has been malloced and then initialized with the val_init_from_template function. The SIL callback function needs to set the value properly. The val_set_simval and val_set_simval_obj functions are two API functions that can be used for this purpose. |
The following example from agt/agt_ses.c shows a SIL get callback function for the ietf-netconf-monitoring data model, which returns the 'in-sessions' counter value:
/******************************************************************** * FUNCTION agt_ses_get_inSessions * * <get> operation handler for the inSessions counter * * INPUTS: * see ncx/getcb.h getcb_fn_t for details * * RETURNS: * status *********************************************************************/ status_t agt_ses_get_inSessions (ses_cb_t *scb, getcb_mode_t cbmode, const val_value_t *virval, val_value_t *dstval) { (void)scb; (void)virval;
if (cbmode == GETCB_GET_VALUE) { VAL_UINT(dstval) = agttotals->inSessions; return NO_ERR; } else { return ERR_NCX_OPERATION_NOT_SUPPORTED; }
} /* agt_ses_get_inSessions */
The following example from agt/agt_state.c shows a complex get callback function for the same data model, which returns the entire <capabilities> element when it is requested. This is done by simply cloning the 'official copy' of the server capabilities that is maintained by the agt/agt_caps.c module.
/******************************************************************** * FUNCTION get_caps
* * <get> operation handler for the capabilities NP container * * INPUTS: * see ncx/getcb.h getcb_fn_t for details * * RETURNS: * status *********************************************************************/ static status_t get_caps (ses_cb_t *scb, getcb_mode_t cbmode, val_value_t *virval, val_value_t *dstval) { val_value_t *capsval; status_t res;
(void)scb; (void)virval; res = NO_ERR;
if (cbmode == GETCB_GET_VALUE) { capsval = val_clone(agt_cap_get_capsval()); if (!capsval) { return ERR_INTERNAL_MEM; } else { /* change the namespace to this module, * and get rid of the netconf NSID */ val_change_nsid(capsval, statemod->nsid); val_move_children(capsval, dstval); val_free_value(capsval); } } else { res = ERR_NCX_OPERATION_NOT_SUPPORTED; } return res;
} /* get_caps */
Notifications
The yangdump program will automatically generate functions to queue a specific notification type for processing. It is up to the SIL callback code to invoke this function when the notification event needs to be generated. The SIL code is expected to provide the value nodes that are needed for any notification payload objects.
Notification Send Function
The function to generate a notification control block and queue it for notification replay and delivery is generated by the yangdump program. A function parameter will exist for each top-level data node defined in the YANG notification definition.
In the example below, the 'toastDone' notification event contains just one leaf, called the 'toastStatus'. There is SIL timer callback code which calls this function, and provides the final toast status, after the <make-toast> operation has been completed or canceled.
/******************************************************************** * FUNCTION y_toaster_toastDone_send * * Send a y_toaster_toastDone notification * Called by your code when notification event occurs * ********************************************************************/ void y_toaster_toastDone_send ( const xmlChar *toastStatus) { agt_not_msg_t *notif; val_value_t *parmval; status_t res;
res = NO_ERR;
if (LOGDEBUG) { log_debug("\nGenerating <toastDone> notification"); }
notif = agt_not_new_notification(toastDone_obj); if (notif == NULL) { log_error("\nError: malloc failed, cannot send <toastDone> notification"); return; }
/* add toastStatus to payload */ parmval = agt_make_leaf( toastDone_obj, y_toaster_N_toastStatus, toastStatus, &res); if (parmval == NULL) { log_error( "\nError: make leaf failed (%s), cannot send <toastDone> notification", get_error_string(res)); } else { agt_not_add_to_payload(notif, parmval); }
agt_not_queue_notification(notif);
} /* y_toaster_toastDone_send */
Periodic Timer Service
Some SIL code may need to be called at periodic intervals to check system status, update counters, and/or perhaps send notifications.
The file agt/agt_timer.h contains the timer access function declarations.
This section provides a brief overview of the SIL timer service.
Timer Callback Function
The timer callback function is expected to do a short amount of work, and not block the running process. The function returns zero for a normal exit, and -1 if there was an error and the timer should be destroyed.
The agt_timer_fn_t template in agt/agt_timer.h is used to define the SIL timer callback function prototype. This typedef defines the callback function template expected by the server for use with the timer service:
/* timer callback function * * Process the timer expired event * * INPUTS: * timer_id == timer identifier * cookie == context pointer, such as a session control block, * passed to agt_timer_set function (may be NULL) * * RETURNS: * 0 == normal exit * -1 == error exit, delete timer upon return */ typedef int (*agt_timer_fn_t) (uint32 timer_id, void *cookie);
The following table describes the parameters for this callback function:
timer_id | The timer ID that was returned when the agt_timer_create function was called. |
cookie | The cookie parameter value that was passed to the server when the agt_timer_create function was called. |
Timer Access Functions
A SIL timer can be set up as a periodic timer or a one-time event.
The timer interval (in seconds) and the SIL timer callback function are provided when the timer is created. A timer can also be restarted if it is running, and the time interval can be changed as well.
The following table highlights the SIL timer access functions in agt/agt_timer.h:
agt_timer_create | Create a SIL timer. |
agt_timer_restart | Restart a SIL timer |
agt_timer_delete | Delete a SIL timer |
Example Timer Callback Function
The following example from toaster.c simply completes the toast when the timer expires and calls the auto-generated 'toastDone' send notification function:
/******************************************************************** * FUNCTION toaster_timer_fn * * Added timeout function for toaster function * * INPUTS: * see agt/agt_timer.h * * RETURNS: * 0 for OK; -1 to kill periodic timer ********************************************************************/ static int toaster_timer_fn (uint32 timer_id, void *cookie) { (void)timer_id; (void)cookie;
/* toast is finished */ toaster_toasting = FALSE; toaster_timer_id = 0; if (LOGDEBUG2) { log_debug2("\ntoast is finished"); } y_toaster_toastDone_send((const xmlChar *)"done"); return 0;
} /* toaster_timer_fn */
Server Callback Examples
This section was written by Mark Pashley for the Yuma Integration Test Suite.
It is included here because it explains the details of SIL callback for several message flow examples.
This document details the SIL callbacks that are made when Yuma processes NETCONF edit queries when configured to use the candidate database configuration (--target=candidate).
YANG
The following YANG defines the configuration that is used for all of the examples within this document.
container xpo { presence "Indicates that the Device Test API is available."; description "Top-level container for all configuration and status objects.";
//////////////////////////////////// // Start of main configuration block //////////////////////////////////// grouping connectionItem { description "Connection container.";
leaf sourceId { description "The ID of the item providing the input to the connection."; type uint32; }
leaf bitrate { description "The maximum expected bitrate over this connection."; type uint32; units "bps"; } }
list profile { key id; description "Profile container.";
leaf id { description "Unique ID for this profile."; type uint32; }
list streamConnection { description "Connection between two streams."; key id;
leaf id { description "Connection identifier."; type uint32; }
uses connectionItem; } }
leaf activeProfile { description "The number of the active profile."; type uint32; } }
Edit Operations
The following sections identify the messages sent by the Netconf Client and the SIL callbacks that will be made. The message sequence charts do not show operations for locking and unlocking of the running and candidate configurations.
Create an XPO container
The message sequence chart below shows the expected SIL callbacks for a create xpo container operation.
[[Image:]]
- The client issues an rpc edit-config to create an xpo container:
<?xml version="1.0" encoding="UTF-8"?> <rpc message-id="4" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <target> <candidate/> </target> <default-operation>merge</default-operation> <config> <xpo xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="create" xmlns="http://www.ericsson.com/television/ns/xpo3/base"/> </config> </edit-config> </rpc>
- Netconf executes the xpo_edit<validate> callback to validate the change to the candidate configuration.
- Netconf executes the xpo_edit<apply> callback to apply the change to the candidate configuration.
- The client receives an rpc-reply indicating success.
- The client issues an rpc commit to commit the change to the running configuration.
- Netconf executes the xpo_edit<validate> callback to validate the change to the running configuration.
- Netconf executes the xpo_edit<commit create> callback to perform a create operation change to the candidate configuration.
- The client receives an rpc-reply indicating success.
Create a Profile
The message sequence chart below shows the expected SIL callbacks for a create profile operation.
[[Image:]]
- The client issues an rpc edit-config to create a profile:
<?xml version="1.0" encoding="UTF-8"?> <rpc message-id="5" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <target> <candidate/> </target> <default-operation>merge</default-operation> <config> <xpo xmlns="http://www.ericsson.com/television/ns/xpo3/base"> <profile xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="create"><id>1</id></profile></xpo> </config> </edit-config> </rpc>
- Netconf executes the profile_edit<validate> callback for the candidate configuration.
- Netconf executes the profile_id_edit<validate> callback for the candidate configuration.
- Netconf executes the profile_edit<apply> callback for the candidate configuration.
- Netconf executes the profile_id_edit<apply> callback for the candidate configuration.
- The client receives an rpc-reply indicating success.
- The client issues an rpc commit to commit the change to the running configuration.
- Netconf executes the profile_edit<apply> callback for the running configuration.
- Netconf executes the profile_id_edit<apply> callback for the running configuration.
- Netconf executes the profile_edit<commit create> callback for the running configuration.
- Netconf executes the profile_id_edit< commit create > callback for the running configuration.
- The client receives an rpc-reply indicating success.
Create a Stream Connection
The message sequence chart below shows the expected SIL callbacks for a create profile stream connection operation. In this scenario the XPO container is empty prior to step 1.
[[Image:]]
- The client issues an rpc edit-config to create a profile stream connection. (Note the profile has not previously been created)
<?xml version="1.0" encoding="UTF-8"?> <rpc message-id="5" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <target> <candidate/> </target> <default-operation>merge</default-operation> <config> <xpo xmlns="http://www.ericsson.com/television/ns/xpo3/base"> <profile><id>1</id> <streamConnection xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="create"><id>1</id> <sourceId>100</sourceId> <bitrate>500</bitrate> </streamConnection> </profile></xpo> </config> </edit-config> </rpc>
- Netconf executes the profile_edit<validate> callback for the candidate configuration.
- Netconf executes the profile_id_edit<validate> callback for the candidate configuration.
- Netconf executes the profile_streamConnection_edit<validate> callback for the candidate configuration.
- Netconf executes the profile_streamConnection_id_edit<validate> callback for the candidate configuration.
- Netconf executes the profile_streamConnection_sourceId_edit<validate> callback for the candidate configuration.
- Netconf executes the profile_streamConnection_bitrate_edit<validate> callback for the candidate configuration.
- Netconf executes the profile_edit<apply> callback for the candidate configuration.
- Netconf executes the profile_id_edit<apply> callback for the candidate configuration.
- Netconf executes the profile_streamConnection_edit<apply> callback for the candidate configuration.
- Netconf executes the profile_streamConnection_id_edit<apply> callback for the candidate configuration.
- Netconf executes the profile_streamConnection_sourceId_edit<apply> callback for the candidate configuration.
- Netconf executes the profile_streamConnection_bitrate_edit<apply> callback for the candidate configuration.
- The client receives an rpc-reply indicating success.
- The client issues an rpc commit to commit the change to the running configuration.
- Netconf executes the profile_edit<apply> callback for the running configuration.
- Netconf executes the profile_id_edit<apply> callback for the running configuration.
- Netconf executes the profile_streamConnection_edit<apply> callback for the running configuration.
- Netconf executes the profile_streamConnection_id_edit<apply> callback for the running configuration.
- Netconf executes the profile_streamConnection_sourceId_edit<apply> callback for the running configuration.
- Netconf executes the profile_streamConnection_bitrate_edit<apply> callback for the running configuration.
- Netconf executes the profile_edit<commit create> callback for the running configuration.
- Netconf executes the profile_id_edit<commit create> callback for the running configuration.
- Netconf executes the profile_streamConnection_edit<commit create> callback for the running configuration.
- Netconf executes the profile_streamConnection_id_edit<commit create> callback for the running configuration.
- Netconf executes the profile_streamConnection_sourceId_edit<commit create> callback for the running configuration.
- Netconf executes the profile_streamConnection_bitrate_edit<commit create> callback for the running configuration.
- The client receives an rpc-reply indicating success.
Delete an XPO Container
The message sequence chart below shows the expected SIL callbacks for a delete xpo container operation. In this scenario the XPO container is populated with at last one profile prior to step 1.
[[Image:]]
- The client issues an rpc edit-config to delete an xpo container:
<?xml version="1.0" encoding="UTF-8"?> <rpc message-id="10" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <target> <candidate/> </target> <default-operation>merge</default-operation> <config> <xpo xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete" xmlns="http://www.ericsson.com/television/ns/xpo3/base"/> </config> </edit-config> </rpc>
- Netconf executes the xpo_edit<validate> callback to validate the change to the candidate configuration.
- Netconf executes the xpo_edit<apply> callback to apply the change to the candidate configuration.
- The client receives an rpc-reply indicating success.
- The client issues an rpc commit to commit the change to the running configuration.
- Netconf executes the xpo_edit<validate> callback to validate the change to the running configuration.
- Netconf executes the xpo_edit<commit delete> callback to perform a create operation change to the candidate configuration.
- The client receives an rpc-reply indicating success.
Delete a Profile
The message sequence chart below shows the expected SIL callbacks for a delete xpo profile operation. In this scenario the XPO container is populated with at last one profile prior to step 1.
[[Image:]]
- The client issues an rpc edit-config to delete a profile:
<?xml version="1.0" encoding="UTF-8"?> <rpc message-id="10" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <target> <candidate/> </target> <default-operation>merge</default-operation> <config> <xpo xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <profile xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete"><id>1</id></profile></xpo> </config> </edit-config> </rpc>
- Netconf executes the xpo_profile_edit<validate> callback to validate the change to the candidate configuration.
- Netconf executes the xpo_ profile_edit<apply> callback to apply the change to the candidate configuration.
- The client receives an rpc-reply indicating success.
- The client issues an rpc commit to commit the change to the running configuration.
- Netconf executes the xpo_ profile_edit<validate> callback to validate the change to the running configuration.
- Netconf executes the xpo_ profile_edit<commit delete> callback to perform a create operation change to the candidate configuration.
- The client receives an rpc-reply indicating success.
Delete a Stream Connection
Deleting a stream connection is no different to deleting a profile. For delete operations SIL callbacks are only made for the highest level node that is being deleted.
Development Environment
This section describes the Yuma Tools development environment used to produce the Linux binaries.
Programs and Libraries Needed
There are several components used in the Yuma software development environment:
- gcc compiler and linker
- ldconfig and install programs
- GNU make program
- shell program, such as bash
- Yuma development tree: the source tree containing Yuma code, specified with the $YUMA_HOME environment variable.
- SIL development tree: the source tree containing server instrumentation code
The following external program is used by Yuma, and needs to be pre-installed:
- opensshd (needed by netconfd)
- The SSH2 server code does not link with netconfd. Instead, the netconf-subsystem program is invoked, and local connections are made to the netconfd server from this SSH2 subsystem.
The following program is part of Yuma Tools, and needs to be installed:
- netconf-subsystem (needed by netconfd)
- The thin client sub-program that is called by sshd when a new SSH2 connection to the 'netconf' sub-system is attempted.
- This program will use an AF_LOCAL socket, using a proprietary <ncxconnect> message, to communicate with the netconfd server..
- After establishing a connection with the netconfd server, this program simply transfers SSH2 NETCONF channel data between sshd and netconfd.
- The thin client sub-program that is called by sshd when a new SSH2 connection to the 'netconf' sub-system is attempted.
The following program is part of Yuma Tools, and usually found within the Yuma development tree:
- netconfd
- The NETCONF server that processes all protocol operations.
- The agt_ncxserver component will listen for <ncxconnect> messages on the designated socket (/tmp/ncxserver.sock). If an invalid message is received, the connection will be dropped. Otherwise, the netconf-subsystem will begin passing NETCONF channel data to the netconfd server. The first message is expected to be a valid NETCONF <hello> PDU. If
- The NETCONF server that processes all protocol operations.
The following external libraries are used by Yuma, and need to be pre-installed:
- ncurses (needed by yangcli)
- character processing library needed by libtecla; used within yangcli
- libc (or glibc, needed by all applications)
- unix system library
- libssh2 (needed by yangcli)
- SSH2 client library, used by yangcli
- libxml2 (needed by all applications)
- xmlTextReader XML parser
- pattern support
SIL Makefile
The SIL Makefile is based on the Makefile for Yuma sources. The automake program is not used at this time. There is no ./configure script to run. There are 2 basic build steps:
- make
- [sudo] make install
The installation step may require root access via the sudo program, depending on the system.
Target Platforms
The following target platforms are supported:
- Fedora and Ubuntu: These are the default targets and no special command line options are needed.
Build Targets
The following table describes the build targets that are supported:
all | Make everything. This is the default if not target is specified. |
depend | Make the dependencies files. |
clean | Remove the target files. |
superclean | Remove all the dependencies and the target files. |
distclean | Remove all the distribution files that make be installed, all the dependencies and the target files. |
test | Make any test code. |
lint | Run a lint program on the source files. |
install | Install the components into the system. |
uninstall | Remove the components from the system. |
Command Line Build Options
There are several command line options that can be used when making the Yuma source code. These may have an impact on building and linking the SIL source code. The following table describes these options:
CYGWIN=1 | Build for the Windows Cygwin target environment. |
DEBUG=1 | Generate debug symbols for gdb debugging, and do not generate optimized binary code. The default is not to generate symbols, and instead use -O2 optimization. |
ETC_PREFIX | Build 'etc' install directory to use (default /etc) |
LIB64=1 | Build so that SIL libraries are installed in the 'lib64' directory |
MAC=1 | Build the software for the Mac OS X platform. |
MEMTRACE=1 | Enabled 'mtrace' memory leak debugging to identify the exact nodes which were malloced but never freed. |
NOFLOAT=1 | Defining this make flag will force the server to implement XPath numbers with a string representation instead of using the 'double' data type from the floating point library. This will impact the correctness of XPath expression evaluation, so this should not be done unless the <math.h> library support is not available. (Required for CYGWIN=1) |
PREFIX=string | Build Root path to use (default /usr) |
RELEASE=n | Builds release 'n' (version-release) for Ubuntu or RPM package distribution |
STATIC=1 | Build static libraries instead of dynamic libraries, where needed. This sometimes makes debugging simpler and faster. Embedded systems without dynamic library support need to use this make option.(Required for CYGWIN=1) |
STATIC_SERVER | Defining this make flag forces the server not to require or use the 'dylib' functions to dynamically load SIL libraries at run-time, without requiring ldconfig. Instead, the server will assume the server code has been modified so these SIL libraries are initialized and cleaned up statically. |
Example SIL Makefile
The script /usr/bin/make_sil_dir is used to automatically create a SIL work sub-directory tree. Support files are located in the /usr/share/yuma/util directory.
The following Makefile is for the libtoaster library, supporting the toaster.yang module:
# SIL Makefile for Yuma Server Instrumentation Library #
############### SOURCE PROFILE ##############################
SUBDIR_NM=toaster
SUBDIR_CPP=
############### TARGET PROFILE ##############################
TARGET=../bin
LIB_INST=../lib
WORK_INST=$(YUMA_HOME)/target/lib
REAL_INST=$(DESTDIR)/usr/lib/yuma
#################### MAKE RULES ########################
all: sil_dummy sil_lib
#################### PLATFORM DEFINITIONS ############
ifdef YUMA_HOME CINC = -I. \ -I$(YUMA_HOME)/src/platform \ -I$(YUMA_HOME)/src/ncx \ -I$(YUMA_HOME)/src/agt \ -I/usr/include \ -I/usr/include/libxml2 \ -I/usr/include/libxml2/libxml else ifdef YUMA_INSTALL CINC = -I. \ -I$(YUMA_INSTALL)/src/platform \ -I$(YUMA_INSTALL)/src/ncx \ -I$(YUMA_INSTALL)/src/agt \ -I/usr/include \ -I/usr/include/libxml2 \ -I/usr/include/libxml2/libxml else CINC = -I. \ -I/usr/share/yuma/src/netconf/src/platform \ -I/usr/share/yuma/src/netconf/src/ncx \ -I/usr/share/yuma/src/netconf/src/agt \ -I/usr/include \ -I/usr/include/libxml2 \ -I/usr/include/libxml2/libxml endif endif
# added /sw/include for MacOSX ifdef MAC # MACOSX version CINC +=-I/sw/include CFLAGS += -DMACOSX=1 endif
LBASE=../lib
ifdef DESTDIR OWNER= else ifdef MAC OWNER=-oroot else OWNER= --owner=root endif endif
### GCC + [LINUX or MACOSX]
CWARN=-Wall -Wno-long-long -Wformat-y2k -Winit-self \ -Wmissing-include-dirs -Wswitch-default -Wunused-parameter \ -Wextra -Wundef -Wshadow -Wpointer-arith \ -Wwrite-strings -Wbad-function-cast -Wcast-qual -Wcast-align \ -Waggregate-return -Wstrict-prototypes -Wold-style-definition \ -Wmissing-prototypes -Wmissing-declarations \ -Wpacked -Winvalid-pch \ -Wredundant-decls -Wnested-externs -Winline -std=gnu99 -Werror
# -Wunreachable-code removed due to -O3 # -O3 changed to -O2 due to code bloat from inline functions
CDEFS=-DDEBUG -DLINUX -DGCC
ifndef NOFLOAT CDEFS += -DHAS_FLOAT endif
CFLAGS=$(CDEFS) $(CWARN) -fPIC
# production (0) or debug (1) build ifdef DEBUG CFLAGS += -ggdb3 else CFLAGS += -O2 endif
# memory leak debugging mode ifdef MEMTRACE CFLAGS += -DMEMORY_DEBUG=1 endif
# free or SDK version ifdef FREE CFLAGS += -DFREE_VERSION endif
ifdef RELEASE CFLAGS += -DRELEASE=$(RELEASE) endif
ifdef MAC GRP= else ifdef DESTDIR GRP= else GRP=--group=root endif endif
ifdef STATIC LIBSUFFIX=a else ifdef MAC LIBSUFFIX=dylib else LIBSUFFIX=so endif endif
CC=gcc LINK=gcc LINT=splint LINTFLAGS= '-weak -macrovarprefix "m_"' ##LIBFLAGS=-lsocket
LIBTOOL=ar #LFLAGS=-v --no-as-needed LFLAGS=-lm LPATH=-L$(LBASE)
CEES = $(wildcard *.c) HEES = $(wildcard *.h)
################ OBJS RULE ############# OBJS = $(patsubst %.c,$(TARGET)/%.o,$(CEES))
################ DEPS RULE ############# DEPS = $(patsubst %.c,%.D,$(wildcard *.c))
######################## PLATFORM DEFINITIONS ############# PLATFORM_CPP=
.PHONY: all superclean clean test install uninstall \ distclean depend lint
######################### MAKE DEPENDENCIES ############### COMPILE.c= $(CC) $(CFLAGS) $(CPPFLAGS) $(PLATFORM_CPP) \ $(CINC) $(SUBDIR_CPP) $(TARGET_ARCH) -c
$(TARGET)/%.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) $(PLATFORM_CPP) \ $(CINC) $(SUBDIR_CPP) $(TARGET_ARCH) -c -o $@ $<
# Common library rule
$(LBASE)/lib%.a: $(OBJS) $(LIBTOOL) cr $@ $(OBJS) ranlib $@
# dependency rule to make temp .D files from .c sources # all the .D files are collected and appended to the # appropriate Makefile when 'make depend' is run # this rule is kept here to make sure it matches COMPILE.c %.D: %.c $(CC) -MM -MG -MT $(TARGET)/$(patsubst %.c,%.o,$<) \ -Wall -Wcomment $(CPPFLAGS) $(PLATFORM_CPP) $(CINC) \ $(SUBDIR_CPP) $(TARGET_ARCH) -c $< > $@
################## MAKE DEPENDENCIES ##################### # following depend rule is the GNU version! Other versions TBD # this rule cannot be included by the top level makefile # so platform.profile.cmn was created to allow that Makefile # to define a different 'depend' rule. depend: dependencies
dependencies: $(DEPS) @if [ ! -f Makefile ]; then \ echo "Error: Makefile missing!"; \ exit 1; \ fi @rm -f dependencies @for i in $(DEPS); do \ if [ -f $$i ] ; then \ (cat $$i >> dependencies; echo "" >> dependencies) ; \ else \ (echo "*** Warning: Dependency file $i.D is missing! (Skipping...) ***"; \ echo "# Warning: Missing file $$i !!!") ; \ fi; \ done @echo "" >> dependencies # delete the .D files to force make depend to rebuild them each time # that target is built # @rm -f $(DEPS)
################ DEPENDENCIES ######################### # depend rule must be included after the 'all' make rule
include ../../netconf/src/platform/platform.profile.depend
test:
install: mkdir -p $(REAL_INST) $(SUDO) install $(LIB_INST)/lib$(SUBDIR_NM).$(LIBSUFFIX) $(REAL_INST)
work: install $(LIB_INST)/lib$(SUBDIR_NM).$(LIBSUFFIX) $(WORK_INST)
sil_lib: $(LIB_INST)/lib$(SUBDIR_NM).$(LIBSUFFIX)
# this dummy rule keeps make from deleting the $(OBJS) as # intermediate files sil_dummy: dependencies $(OBJS)
clean: rm -f $(OBJS) $(LIB_INST)/lib$(SUBDIR_NM).*
superclean: rm -f *~ $(DEPS) dependencies $(OBJS) \ $(LIB_INST)/lib$(SUBDIR_NM).*
$(LIB_INST)/lib$(SUBDIR_NM).so: $(OBJS) gcc -shared -rdynamic -Wl,-soname,lib$(SUBDIR_NM).so -o $@ $(OBJS) -ldl
# gcc -shared -Wl,-soname,libtoaster.so -o $@ $(OBJS) -lc
$(LBASE)/lib$(SUBDIR_NM).dylib: $(OBJS) gcc -shared -dynamiclib -std=gnu99 -current_version 1.0 \ -undefined dynamic_lookup \ -o $@ -install_name lib$(SUBDIR_NM).dylib $(OBJS) -lxml2
code: yangdump format=h indent=4 module=$(SUBDIR_NM) output=$(SUBDIR_NM).h yangdump format=c indent=4 module=$(SUBDIR_NM) output=$(SUBDIR_NM).c
# prevent the make program from choking on all the symbols # that get generated from autogenerated make rules .NOEXPORT:
include dependencies
Automation Control
The YANG language includes many ways to specify conditions for database validity, which traditionally are only documented in DESCRIPTION clauses. The YANG language allows vendors and even data modelers to add new statements to the standard syntax, in a way that allows all tools to skip extension statements that they do not understand.
The yangdump YANG compiler sames all the non-standard language statements it finds, even those it does not recognize. These are stores in the ncx_appinfo_t data structure in ncx/ncxtypes.h..
There are also SIL access functions defined in ncx/ncx_appinfo.h that allow these language statements to be accessed. If an argument string was provided, it is saved along with the command name.
Several data structures contains an 'appinfoQ' field to contain all the ncx_appinfo_t stuctures that were generated within the same YANG syntax block (e.g., within a typedef, type, leaf, import statement).
Built-in YANG Language Extensions
There are several YANG extensions that are supported by Yuma. They are all defined in the YANG file named ncx.yang. They are used to 'tag' YANG definitions for some sort of automatic processing by Yuma programs. Extensions are position-sensitive, and if not used in the proper context, they will be ignored. A YANG extension statement must be defined (somewhere) for every extension used in a YANG file, or an error will be occur.
Most of these extensions apply to netconfd server behavior, but not all of them. For example, the ncx:hidden extension will prevent yangcli from displaying help for an object containing this extension. Also, yangdump will skip this object in HTML output mode.
The following table describes the supported YANG language extensions. All other YANG extension statements will be ignored by Yuma, if encountered in a YANG file:
ncx:hidden; | Declares that the object definition should be hidden from all automatic documentation generation. Help will not be available for the object in yangcli. |
ncx:metadata “attr-type attr-name”; | Defines a qualified XML attribute in the module namespace.
Allowed within an RPC input parameter. attr-type is a valid type name with optional YANG prefix. attr-name is the name of the XML attribute. |
ncx:no-duplicates; | Declares that the ncx:xsdlist data type is not allowed to contain duplicate values. The default is to allow duplicate token strings within an ncx:xsdlist value. |
ncx:password; | Declares that a string data type is really a password, and will not be displayed or matched by any filter. |
ncx:qname; | Declares that a string data type is really an XML qualified name. XML prefixes will be properly generated by yangcli and netconfd. |
ncx:root; | Declares that the container parameter is really a NETCONF database root, like <config> in the <edit-config> operations. The child nodes of this container are not specified in the YANG file. Instead, they are allowed to contain any top-level object from any YANG file supported by the server. |
ncx:schema-instance; | Declares that a string data type is really an special schema instance identifier string. It is the same as an instance-identifier built-in type except the key leaf predicates are optional. For example, missing key values indicate wild cards that will match all values in nacm <dataRule> expressions. |
ncx:secure; | Declares that the database object is a secure object.
If the object is an rpc statement, then only the netconfd 'superuser' will be allowed to invoke this operation by default. Otherwise, only read access will be allowed to this object by default, Write access will only be allowed by the 'superuser', by default. |
ncx:very-secure; | Declares that the database object is a very secure object.
Only the 'superuser' will be allowed to access the object, by default. |
ncx:xsdlist “list-type”; | Declares that a string data type is really an XSD style list.
list-type is a valid type name with optional YANG prefix. List processing within <edit-config> will be automatically handled by netconfd. |
ncx:xpath; | Declares that a string data type is really an XPath expression. XML prefixes and all XPath processing will be done automatically by yangcli and netconfd. |
SIL Language Extension Access Functions
The following table highlights the SIL functions in ncx/ncx_appinfo.h that allow SIL code to examine any of the non-standard language statements that were found in the YANG module:
ncx_find_appinfo | Find an ncx_appinfo_t structure by its prefix and name, in a queue of these entries. |
ncx_find_next_appinfo | Find the next occurrence of the specified ncx_appinfo_t data structure. |
ncx_clone_appinfo | Clone the specified ncx_appinfo_t data structure. |