Sysrepo Integration Internals

This section describes the internal processing model used by the Sysrepo Integration feature and the APIs available when SIL code needs to cooperate with sysrepo-managed processing.

Sysrepo Integration Server Initialization

When Sysrepo Integration is enabled, netconfd-pro performs its normal server startup sequence and then initializes the sysrepo integration layer.

The initialization flow is divided into two main phases.

During INIT Phase 1:

  • connect to sysrepo

  • create the required sysrepo connection and session context

  • load Sysrepo supported modules into the netconfd-pro server

During INIT Phase 2:

  • load the initial datastore contents from sysrepo

  • register the internal Global callback for EDIT, GET2, RPC, and Action processing

  • finalize the internal integration state used for runtime operation

After the initialization sequence is complete, the sysrepo connection and session remain active so they can be reused during normal request processing.

If sysrepo initialization does not complete successfully, the server log should be checked for connection, module loading, or datastore initialization errors.

Automatic Handling for Sysrepo-Managed Modules

The Sysrepo Integration feature does not require SIL code or auto-generated SIL code for YANG modules that are managed through Sysrepo.

When a YANG module is installed in Sysrepo and the same module is also loaded by netconfd-pro, the server automatically enables the internal Global Callbacks APIs handling for that module.

In this mode, netconfd-pro does not require module-specific SIL callbacks to process configuration edits, retrieval requests, RPCs, or Actions. Instead, the server automatically invokes its internal Sysrepo Integration for the relevant operations and communicates with Sysrepo as needed.

This design allows a YANG module to be managed through Sysrepo with minimal server-side integration work, provided that the module is present in the Sysrepo repository and available to netconfd-pro at startup.

From an internal processing perspective, the server uses its own integration logic to translate the corresponding netconfd-pro callback activity into Sysrepo operations. The module therefore participates in normal server processing while Sysrepo provides datastore access, subscriber dispatch, and backend integration.

Using SIL Together with Sysrepo Integration

Even though netconfd-pro does not require SIL code for communication with sysrepo, combined SIL and Sysrepo Integration support is still possible for the same YANG module when deployment-specific processing is needed.

In this model, Sysrepo Integration remains responsible for the Sysrepo interaction path, while SIL code can invoke dedicated Sysrepo Integration APIs to cooperate with that path. This makes it possible to extend or customize behavior for a sysrepo-managed module without requiring the module to be handled entirely outside the Sysrepo Integration framework.

The following sections describe the APIs available for this purpose.

Sysrepo SIL EDIT APIs

The EDIT APIs are used when SIL code needs to cooperate with Sysrepo during configuration edit processing. These APIs are intended for use from EDIT3 Callback, where the standard netconfd-pro edit phases map cleanly to Sysrepo update, apply, and rollback behavior.

A typical Phase mapping is:

  • Validate phase: perform module-specific validation

  • Apply phase: stage the corresponding Sysrepo edits

  • Commit phase: apply the pending Sysrepo changes

  • Rollback phase: discard the pending Sysrepo changes if needed

Note

The Sysrepo Integration feature uses the EDIT3 Callback Function callback model for edit synchronization with Sysrepo. The EDIT APIs described in this section are therefore intended for EDIT3 callbacks only.

The following example shows a typical EDIT3 callback structure:

   /*
    * @brief Edit database object callback (agt_edit3_fn_t)\n
    *
    * @param editcb Edit Control Block that contains
    * EDIT3 callback information
    *
    * @return return status for the phase.
    */
   static status_t
       sample_edit3_callback (agt_editcb_t *editcb)
   {
       status_t res = NO_ERR;
       agt_cbtyp_t cbtyp = editcb->cbtyp;
       ses_cb_t *scb = editcb->scb;
       rpc_msg_t *msg = editcb->msg;
       op_editop_t editop = editcb->editop;
       val_value_t *newval = editcb->newval;
       val_value_t *curval = editcb->curval;
       val_value_t *errorval = (curval) ? curval : newval;

       if (LOGDEBUG) {
           log_debug("\n (%s) Enter EDIT-3 sysrepo callback"
                     "\n ------PHASE:%s;EDITOP: %s"
                     "\n ------Instance ID: %s\n",
                     errorval ? VAL_NAME(errorval) : NCX_NT_NONE,
                     agt_cbtype_name(cbtyp),
                     op_editop_name(editop),
                     editcb->instance_id);
       }

       switch (cbtyp) {
       case AGT_CB_VALIDATE:
           /* description-stmt validation here */
           break;
       case AGT_CB_APPLY:
           /* database manipulation are performed by the server here */
           if (op_editop_is_delete(editop)) {
               /* Delete all data from the device */
               res = agt_sysrepo_delete_item(errorval);
           } else {
               /* Use update value to update your device data
                *
                * The technique here is to replace the existing data
                * with this composite Update value.
                */
               res =
                   agt_sysrepo_update_items(editcb->txcb,
                                            newval,
                                            curval,
                                            editop);
           }
           break;
       case AGT_CB_COMMIT:
           /* Apply changes now to finish the write to sysrepo datastore. */
           res = agt_sysrepo_apply_changes();
           break;
       case AGT_CB_ROLLBACK:
           /* In case of failure do the discard changes */
           agt_sysrepo_discard_changes();
           break;
       default:
           FLAG_INT_ERROR;
           res = ERR_INTERNAL_VAL;
       }

       if (res != NO_ERR) {
           record_val_error(scb, &msg->mhdr, res, errorval);
       }

       return res;

   } /* sample_edit3_callback */

The following EDIT APIs are available:

Delete a single node from the Sysrepo datastore. This function is typically used in the APPLY phase when the current edit operation is a delete.

status_t agt_sysrepo_delete_item(val_value_t *useval)

Delete a single node in the sysrepo datastore.

Can be used in the SIL callback in the Apply Phase Only one edit is done for the provided node.

Parameters:

useval -- to use to delete an item in the Sysrepo datastore

Returns:

return status of the operation

Stage an update for the current node in the Sysrepo datastore. This function is typically used in the APPLY phase for create, merge, replace, or update processing. The function operates at the current level only. Child processing is expected to be handled by the corresponding lower-level EDIT3 callbacks.

status_t agt_sysrepo_update_items(agt_cfg_transaction_t *txcb, val_value_t *newval, val_value_t *curval, op_editop_t editop)

Update a complex node in the sysrepo datastore.

Can be used in the SIL callback in the Apply Phase

Only one level edits are done, no complex children are processed in this function.

Parameters:
  • txcb -- transaction control block in progress

  • newval -- to use for the edit

  • curval -- to use for the edit

  • editop -- current edit operation

Returns:

return status of the operation

Apply the sysrepo changes that were staged during the APPLY phase. This function is intended for use in the COMMIT phase.

status_t agt_sysrepo_apply_changes(void)

Apply changes to sysrepo datastore made in the Apply Phase.

Must be called in the Commit Phase

Returns:

return status of the operation

Discard any pending sysrepo changes. This function is intended for use in the ROLLBACK phase.

void agt_sysrepo_discard_changes(void)

Discard changes made in the Commit/Apply Phase.

Must be called in the Rollback Phase

Sysrepo SIL GET2 APIs

The GET2 APIs are used when SIL code needs to retrieve operational data through sysrepo.

For sysrepo-managed retrieval, the recommended pattern is to register a single top-level GET2 callback for the subtree being served. That callback can delegate retrieval to the Sysrepo Integration API.

Note

For Sysrepo Integration, only one top-level GET2 callback should be registered for the subtree handled through Sysrepo. The top-level callback retrieves the complete subtree from Sysrepo and returns it using the All In One GET2 Callback processing model. Additional deeper GET2 callbacks for descendants in the same subtree should be omitted.

Example:

   /* GET2 TEST
    *
    * see ncx/getcb.h (getcb_fn2_t)
    */
   static status_t
       sample_get2_callback (ses_cb_t *scb,
                             xml_msg_hdr_t *msg,
                             getcb_get2_t *get2cb)
   {
       obj_template_t *obj = GETCB_GET2_OBJ(get2cb);
       if (!obj) {
           return ERR_INTERNAL_VAL;
       }

       if (LOGDEBUG) {
           log_debug("\n\nEnter GET2 sysrepo callback for '%s:%s'",
                     obj_get_mod_name(obj),
                     obj_get_name(obj));
       }

       if (LOGDEBUG3) {
           getcb_dump_get2cb(get2cb);
       }

       status_t res =
           agt_sysrepo_handle_get2(scb, msg, get2cb);

       return res;

   }  /* sample_get2_callback */

The following GET2 API is available:

Handle GET2 processing by retrieving data from sysrepo for the current GET2 request.

status_t agt_sysrepo_handle_get2(ses_cb_t *scb, xml_msg_hdr_t *msg, getcb_get2_t *get2cb)

Sysrepo SIL RPC APIs

The RPC APIs are used when SIL code needs to cooperate with Sysrepo during RPC validation and invocation processing.

A typical pattern is to use one callback for the Validation Phase and a second callback for the Invocation Phase. The validation callback checks that the RPC is backed by an active Sysrepo subscriber. The invocation callback then forwards the RPC input to Sysrepo and handles the output returned by Sysrepo.

Example RPC validate callback:

   /*
    * Validation phase callback for RPC
    */
   static status_t
       sample_rpc_validate (ses_cb_t *scb,
                            rpc_msg_t *msg,
                            xml_node_t *methnode)
   {
       /* YANG module found for this node */
       const xmlChar *modname = methnode->module;

       /* qualified name of element */
       const xmlChar *qname = methnode->qname;

       /* element name without any prefix */
       const xmlChar *elname = methnode->elname;

       /* Invoke Global RPC callbacks only for module with a name sample */
       if (LOGDEBUG) {
           log_debug("\n\nEnter RPC VALIDATE sysrepo callback"
                     "\n modname=%s"
                     "\n RPC Qualified Name=%s"
                     "\n RPC Name=%s\n",
                     modname,
                     qname ? qname : NCX_NT_NONE,
                     elname ? elname : NCX_NT_NONE);
       }

       /* Check RPC input to ensure it is required */
       val_value_t *inputval = agt_get_rpc_input(msg);
       if (inputval == NULL) {
           return ERR_NCX_OPERATION_FAILED;
       }

       /* Check if the RPC even registered in Sysrepo meaning:
        * Sysrepo has RPC/action subscribers registered for
        * provided RPC operation.
        */
       status_t res = agt_sysrepo_validate_rpc(methnode);

       if (res != NO_ERR) {
           agt_record_error(scb,
                            &msg->mhdr,
                            NCX_LAYER_OPERATION,
                            res,
                            methnode,
                            (inputval) ? NCX_NT_VAL : NCX_NT_NONE,
                            inputval,
                            (inputval) ? NCX_NT_VAL : NCX_NT_NONE,
                            inputval);
       }
       return res;

   } /* sample_rpc_validate */

Example RPC invoke callback:

   /*
    * @brief Invocation phase callback for RPC
    */
   static status_t
       sample_rpc_invoke (ses_cb_t *scb,
                          rpc_msg_t *msg,
                          xml_node_t *methnode)
   {
       status_t res = NO_ERR;

       /* YANG module found for this node */
       const xmlChar *modname = methnode->module;

       /* qualified name of element */
       const xmlChar *qname = methnode->qname;

       /* element name without any prefix */
       const xmlChar *elname = methnode->elname;

       /* Invoke Global RPC callbacks only for module with a name sample */
       if (LOGDEBUG) {
           log_debug("\n\nEnter GLOBAL RPC INVOKE sysrepo callback"
                     "\n modname=%s"
                     "\n RPC Qualified Name=%s"
                     "\n RPC Name=%s\n",
                     modname,
                     qname ? qname : NCX_NT_NONE,
                     elname ? elname : NCX_NT_NONE);
       }

       res =
           agt_sysrepo_invoke_rpc(scb,
                                  msg,
                                  methnode);
       return res;

   } /* sample_rpc_invoke */

The following RPC APIs are available:

Check whether the target RPC has an active Sysrepo subscriber registration. This function is typically used during the Validation phase. An error is returned if there is no matching subscriber.

status_t agt_sysrepo_validate_rpc(xml_node_t *methnode)

Check if the RPC even registered in Sysrepo process.

Meaning: Checks if Sysrepo has an RPC/action subscriber(s) registered for provided RPC operation. Error reported if there are no any subscribers to the RPC in the Sysrepo.

Parameters:

methnode -- XML node for the operation

Returns:

return status of the validation.

Invoke the RPC through Sysrepo. This function builds the Sysrepo input, sends the RPC to Sysrepo, and processes the returned output.

status_t agt_sysrepo_invoke_rpc(ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode)

Process RPC Invoke Phase.

  • Build the input values for the sysrepo handling

  • Send the RPC operation to sysrepo process

  • Handle output

Parameters:
  • scb -- session invoking the RPC operation.

  • msg -- message in progress for this <rpc> request.

  • methnode -- XML node for the operation

Returns:

return status of the validation.

Sysrepo SIL Action APIs

The Action APIs are used when SIL code needs to cooperate with sysrepo during YANG 1.1 Action Validation and invocation processing.

The processing model is similar to the RPC path, but action execution is node-instance specific. The Validation callback checks that the target Action is backed by an active Sysrepo subscriber for the selected data node instance. The Invocation callback then forwards the Action input to Sysrepo and processes the returned output.

Example action validate callback:

   /*
    * @brief YANG 1.1 global action validate callback.
    */
   static status_t
       sample_action_validate (ses_cb_t *scb,
                               rpc_msg_t *msg,
                               xml_node_t *methnode,
                               val_value_t *actionval)
   {
       status_t res = NO_ERR;

       /* YANG module found for this node */
       const xmlChar *modname = methnode->module;

       /* qualified name of element */
       const xmlChar *qname = methnode->qname;

       /* element name without any prefix */
       const xmlChar *elname = methnode->elname;

       /* Invoke Action callbacks only for module with a name sample */
       if (LOGDEBUG) {
           log_debug("\n\nEnter ACTION VALIDATE sysrepo callback"
                     "\n modname=%s"
                     "\n Action Qualified Name=%s"
                     "\n Action Name=%s",
                     modname,
                     qname ? qname : NCX_NT_NONE,
                     elname ? elname : NCX_NT_NONE);
       }

       /* Check RPC input to ensure it is required */
       val_value_t *inputval = agt_get_rpc_input(msg);
       if (inputval == NULL) {
           return ERR_NCX_OPERATION_FAILED;
       }

       /* Assign an error value in case any errors occur */
       val_value_t *errorval = inputval;

       /* Check if the Action even registered in Sysrepo meaning:
        * Sysrepo has RPC/action subscribers registered for
        * provided Action operation.
        */
       res =
           agt_sysrepo_validate_action(methnode, actionval);

       if (res != NO_ERR) {
           agt_record_error(scb,
                            &msg->mhdr,
                            NCX_LAYER_OPERATION,
                            res,
                            methnode,
                            (errorval) ? NCX_NT_VAL : NCX_NT_NONE,
                            errorval,
                            (errorval) ? NCX_NT_VAL : NCX_NT_NONE,
                            errorval);
       }
       return res;

   } /* sample_action_validate */

Example action invoke callback:

   /*
    * @brief YANG 1.1 global action invoke callback.
    */
   static status_t
       sample_action_invoke (ses_cb_t *scb,
                             rpc_msg_t *msg,
                             xml_node_t *methnode,
                             val_value_t *actionval)
   {
       status_t res = NO_ERR;

       /* YANG module found for this node */
       const xmlChar *modname = methnode->module;

       /* qualified name of element */
       const xmlChar *qname = methnode->qname;

       /* element name without any prefix */
       const xmlChar *elname = methnode->elname;

       /* Invoke Action callbacks only for module with a name sample */
       if (LOGDEBUG) {
           log_debug("\n\nEnter ACTION INVOKE sysrepo callback"
                     "\n modname=%s"
                     "\n Action Qualified Name=%s"
                     "\n Action Name=%s",
                     modname,
                     qname ? qname : NCX_NT_NONE,
                     elname ? elname : NCX_NT_NONE);
       }

       res =
           agt_sysrepo_invoke_action(scb,
                                     msg,
                                     methnode,
                                     actionval);

       return res;

   } /* sample_action_invoke */

The following Action APIs are available:

Check whether the target action has an active Sysrepo subscriber registration. This function is typically used during the validation phase. An error is returned if there is no matching subscriber.

status_t agt_sysrepo_validate_action(xml_node_t *methnode, val_value_t *actionval)

Check if the Action even registered in Sysrepo process.

Meaning: Checks if Sysrepo has an Action subscriber(s) registered for provided Action operation. Error reported if there are no any subscribers to the Action in the Sysrepo.

Parameters:
  • methnode -- XML node for the operation

  • actionval -- the nested 'action-method-name' node that was parsed within the topval subtree, in the RPC "<action>" request.

Returns:

return status of the validation.

Invoke the action through Sysrepo. This function builds the Sysrepo input, sends the action request to Sysrepo, and processes the returned output.

status_t agt_sysrepo_invoke_action(ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode, val_value_t *actionval)

Process Action Invoke Phase.

  • Build the input values for the sysrepo handling

  • Send the RPC operation to sysrepo process

  • Handle output

Parameters:
  • scb -- session invoking the RPC operation.

  • msg -- message in progress for this <rpc> request.

  • methnode -- XML node for the operation

  • actionval -- the nested 'action-method-name' node that was parsed within the topval subtree, in the RPC "<action>" request.

Returns:

return status of the validation.