Controlling SIL Invocation
There are several extensions and API functions that control how the server will invoke the SIL code and process data in edit requests.
SIL Priority
Warning
Use of SIL Priority is not recommended!
Use Commit Completeness callbacks if possible to apply and commit system resources after the phase is complete, so edit callback order does not matter.
It is possible for the client to send several edits within a single <edit-config> or <copy-config> request.
Sometimes it is useful to make sure certain data structures are validated and processed before other data structures.
Note
SIL priority is represented as an integer from 1 to 255
Callbacks with lower values are invoked before higher values
The default SIL priority is 255
The SIL callbacks for an "edit" within the server may not correspond exactly to an edit request from the client. For example, a "replace" operation on a container or list may result in some child nodes to be created and other child nodes to be deleted.
The server constructs an edit list based on the client request:
Each top-level edit results in an "undo" record
Each "undo" record may have nested SIL callbacks. For example, an edit for a container that has multiple child nodes.
Each descendant container or list within the "undo" record will result in a nested SIL callback.
The leafy child nodes of each container or list are called "child edits". For EDIT2 callbacks, the child edits are gathered together and done all at once (for each parent).
The server orders SIL invocations by sorting the internal edits:
If the
agt_silcall_delete_first
field in the agent profile is set to 'true' then delete operations will be sorted before non-delete operations. If set to 'false' then the edit operation is ignored for the sorting.An edit "undo" record is considered to be a delete if:
The undo->editop is a delete (or remove) operation
The undo->editop is a "merge" and any child_edits contain a delete operation.
SIL callbacks at the same level (sibling nodes) are also sorted
For delete operations, the SIL priority may be reversed (see below). If this behavior is configured, and delete operations will be sorted in reverse (highest to lowest). Otherwise they are sorted in the normal fashion (same as non-delete operations).
For non-delete operations the SIL callback is sorted from lowest to highest values.
Reverse SIL priority for Delete Operations
The configuration parameter --sil-prio-reverse-for-deletes controls whether SIL priority is reversed for delete operations.
If set to "true" the SIL priority for DELETE operations will be reversed.
If 'false' then the SIL priority for delete operations will not be reversed. The default is "false".
This parameter has no affect on non-delete operations (starting in 21.10-17).
Starting from version 21.10-17, the server introduces a refined process for handling undo records to determine the SIL priority and undo record order. This update also applies to nested silcalls within undo records, ensuring consistency in the execution flow.
The procedure includes the following key points:
Deletes before non-deletes: Delete operations are prioritized and processed before any non-delete operations.
EDIT2 merge rule: In cases of EDIT2 merges, the undo record for this EDIT2 operation is treated as a delete if any child edits has a delete operation.
EDIT2 Simultaneous child edits: All child edits within an EDIT2 undo record are invoked at the same time.
Ordered execution: Child edits are executed with deletes first, followed by non-deletes.
SIL priority separation: SIL priority is applied independently to delete and non-delete operations.
sil-prio-reverse-for-deletes: This configuration applies only to delete operations, affecting their execution order.
Non-reversed SIL priority for non-deletes: The SIL priority for non-deletes remains as is, without any reversal in order.
These changes streamline the processing of undo records and ensure precise adherence to SIL priority rules, enhancing the system's reliability and consistency in managing operations.
Setting SIL Priority for YANG Objects
The ywx:sil-priority extension can be used to control the order that edits are processed. The SIL priority settings are usually done with an --annotation YANG module, since the client does not need this information.
Suppress leafref Validation
Leafref validation involves searching all the “pointed at” leaf instances to make sure that the leafref leaf being validated contains one of the values actually in use. An instance is required to exist for the leafref to be valid.
YANG 1.0 does not support the “require-instance” sub-statement for a leafref definition. In order to force the server to skip this validation step, use the 'agt_cb_skip_leafref_validation' API function.
-
status_t agt_cb_skip_leafref_validation(const xmlChar *defpath)
Set a previously registered callback as a node that the server should skip leafref validation in order to save processing time.
- Parameters:
defpath -- Xpath with default (or no) prefixes
- Returns:
status
In the following example, the path
/t641-1:B/t641-1:BB/t641-1:fd-mode
represents a leafref leaf that will be treated as if the “require-instance false”
statement was present in the YANG definition:
Inside SIL init function:
res = agt_cb_register_callback(
y_test_fd641_1_M_test_fd641_1,
(const xmlChar *)"/t641-1:B/t641-1:BB/t641-1:fd-mode",
y_test_fd641_1_R_test_fd641_1,
test_fd641_1_B_BB_fd_mode_edit);
if (res != NO_ERR) {
return res;
}
res = agt_cb_skip_leafref_validation(
(const xmlChar *)"/t641-1:B/t641-1:BB/t641-1:fd-mode");
if (res != NO_ERR) {
return res;
}
SIL Priority Invocation Examples
In this section, we provide an example of how SIL priority is invoked and enforced in specific scenarios.
By demonstrating the interaction of different SIL priority levels within a YANG model structure, you can understand how operations are handled and ordered during configuration changes.
Mixed Operations Example
The following example uses different values for the sil-prio-reverse-for-deletes parameter to show how delete and create operations are processed when SIL priority is applied.
Below is a YANG tree structure from the testModel1 module, showing various containers and lists with their assigned SIL priorities.
YANG Tree Example:
module: testModel1
+--rw CONT1 [sil-priority 170]
+--rw leaf1? uint32
+--rw leaf2? string
+--rw leaf3? string
+--rw resource* string
+--rw LIST1* [name] [sil-priority 170]
| +--rw name string
| +--rw leaf1? uint32
| +--rw leaf2? string
| +--rw leaf3? string
| +--rw resource* string
+--rw LIST2* [name] [sil-priority 180]
| +--rw name string
| +--rw leaf1? uint32
| +--rw leaf2? enumeration
| +--rw leaf3? string
| +--rw resource* string
+--rw CONT1_1 [sil-priority 210]
| +--rw leaf1? uint32
| +--rw leaf2? string
| +--rw leaf3? string
| +--rw resource* string
+--rw CONT1_2 [sil-priority 220]
+--rw leaf1? uint32
+--rw leaf2? string
+--rw leaf3? string
+--rw resource* string
Pre-requisite Configuration
The following configuration is retrieved from the running datastore before making any changes:
> sget-config source=running /CONT1
RPC Data Reply 2 for session 1 [default]:
{
"yuma-netconf:rpc-reply": {
"data": {
"testModel1:CONT1": {
"leaf1":5,
"LIST1": [
{
"name":"1",
"leaf1":100,
"leaf2":"test1"
}
],
"LIST2": [
{
"name":"1",
"leaf1":200,
"leaf2":"success",
"leaf3":"test2"
}
],
"CONT1_1": {
"leaf1":300,
"leaf2":"test3"
},
"CONT1_2": {
"leaf1":400,
"leaf2":"test4"
}
}
}
}
}
Example RPC Call
The following RPC is sent to modify the configuration, replacing LIST1 within CONT1:
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="7">
<edit-config>
<target>
<running/>
</target>
<default-operation>merge</default-operation>
<test-option>test-then-set</test-option>
<config>
<CONT1 xmlns="http://test.com/ns/yang/testModel1" nc:operation="replace">
<LIST1>
<name>2</name>
<leaf1>500</leaf1>
<leaf2>test5</leaf2>
</LIST1>
</CONT1>
</config>
</edit-config>
</rpc>
SIL Priority Enforcement and Expected Outcomes
With sil-prio-reverse-for-deletes == true:
When the reverse priority for deletes is enabled, delete operations are processed first, in descending order of priority.
undo for replace op on testModel1:CONT1
silcall for testModel1:CONT1 [Level:1] [Prio:170] [op:replace] (val: testModel1:CONT1 [Prio:255])
silcall for testModel1:CONT1_2 [Level:2] [Prio:220] [op:delete] (val: testModel1:CONT1_2 [Prio:0])
silcall for testModel1:CONT1_1 [Level:2] [Prio:210] [op:delete] (val: testModel1:CONT1_1 [Prio:0])
silcall for testModel1:LIST2 [Level:2] [Prio:180] [op:delete] (val: testModel1:LIST2 [Prio:0])
silcall for testModel1:LIST1 [Level:2] [Prio:170] [op:delete] (val: testModel1:LIST1 [Prio:0])
silcall for testModel1:LIST1 [Level:2] [Prio:170] [op:create] (val: testModel1:LIST1 [Prio:0])
With sil-prio-reverse-for-deletes == false:
When the reverse priority for deletes is disabled, delete operations are processed in ascending priority, starting with the lowest priority.
undo for replace op on testModel1:CONT1
silcall for testModel1:CONT1 [Level:1] [Prio:170] [op:replace] (val: testModel1:CONT1 [Prio:255])
silcall for testModel1:LIST1 [Level:2] [Prio:170] [op:delete] (val: testModel1:LIST1 [Prio:0])
silcall for testModel1:LIST2 [Level:2] [Prio:180] [op:delete] (val: testModel1:LIST2 [Prio:0])
silcall for testModel1:CONT1_1 [Level:2] [Prio:210] [op:delete] (val: testModel1:CONT1_1 [Prio:0])
silcall for testModel1:CONT1_2 [Level:2] [Prio:220] [op:delete] (val: testModel1:CONT1_2 [Prio:0])
silcall for testModel1:LIST1 [Level:2] [Prio:170] [op:create] (val: testModel1:LIST1 [Prio:0])
In this example, SIL priority controls the order of operations for both deletes and creates, and the sil-prio-reverse-for-deletes parameter alters the order of delete operations, ensuring flexible handling based on configuration requirements.