This example shows the build steps and run-time message flows for a custom RPC operation.
Example YANG Module
module myrpc { namespace "http://www.netconfcentral.org/ns/yang/myrpc"; prefix "m"; revision "2020-02-04"; rpc myrpc { description "Example RPC returns <ok>"; input { leaf parm1 { type string; description "example input parameter"; } } } }
1) Generate the SIL-SA Library
- Copy the YANG module myrpc.yang to a directory where the client and server can find it, like $HOME/modules/ directory
- Make sure the SDK tools are properly installed
- Use the make_sil_sa_dir script to generate the 'myrpc' source tree
> make_sil_sa_dir myrpc Example: andy@andy-i7-dev:~/X$ make_sil_sa_dir myrpc modparms = Add --sil-get2 because --sil-sa present (GET1 not supported) *** /home/andy/modules/myrpc.yang *** 0 Errors, 0 Warnings Add --sil-get2 because --sil-sa present (GET1 not supported) *** /home/andy/modules/myrpc.yang *** 0 Errors, 0 Warnings andy@andy-i7-dev:~/X$
2) Build and Install the SIL-SA Library
- The stub code generated by yangdump-sdk supports the new RPC operation without any modification.
- The empty stub code does not implement the RPC in the system. You have to add this code.
- There are some C compiler warnings generated in the stub code because the variables are not used yet. You should fill in the stub code and these warnings should go away.
- Verify the SIL-SA library is installed in the /usr/lib/yumapro directory
- Note that the library name contains the string "_sa". This prevents netconfd-pro from loading the library and enables sil-sa-app to load the library instead.
> cd myrpc > make > sudo make install > ls -l /usr/lib/yumapro/libmyrpc_sa.so Example: andy@andy-i7-dev:~/X$ cd myrpc/ andy@andy-i7-dev:~/X/myrpc$ make for dir in src; do\ cd $dir && make && cd ..;\ done make[1]: Entering directory '/home/andy/X/myrpc/src' Makefile:322: dependencies: No such file or directory cc -MM -MG -MT ../bin/myrpc.o \ -Wall -Wcomment -I. -I/usr/include/yumapro/platform -I/usr/include/yumapro/ncx -I/usr/include/yumapro/agt -I/usr/include/yumapro/sil-sa -I/usr/include/yumapro/ycontrol -I/usr/include -I/usr/include/libxml2 -I/usr/include/libxml2/libxml \ -c myrpc.c > myrpc.D cc -O2 -DDEBUG=1 -DLINUX=1 -DGCC=1 -DHAS_FLOAT=1 -Wall -Wno-long-long -Wformat-y2k -Winit-self -Wswitch-default -Wextra -Wundef -Wshadow -Wpointer-arith -Wwrite-strings -Wbad-function-cast -Wcast-qual -Waggregate-return -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Winvalid-pch -Wredundant-decls -Wnested-externs -Winline -std=gnu99 -Werror=incompatible-pointer-types -fPIC \ -I. -I/usr/include/yumapro/platform -I/usr/include/yumapro/ncx -I/usr/include/yumapro/agt -I/usr/include/yumapro/sil-sa -I/usr/include/yumapro/ycontrol -I/usr/include -I/usr/include/libxml2 -I/usr/include/libxml2/libxml -c -o ../bin/myrpc.o myrpc.c myrpc.c: In function ‘y_myrpc_myrpc_validate’: myrpc.c:110:20: warning: variable ‘v_parm1’ set but not used [-Wunused-but-set-variable] const xmlChar *v_parm1; ^~~~~~~ myrpc.c: In function ‘y_myrpc_myrpc_invoke’: myrpc.c:165:20: warning: variable ‘v_parm1’ set but not used [-Wunused-but-set-variable] const xmlChar *v_parm1; ^~~~~~~ cc -O2 -DDEBUG=1 -DLINUX=1 -DGCC=1 -DHAS_FLOAT=1 -Wall -Wno-long-long -Wformat-y2k -Winit-self -Wswitch-default -Wextra -Wundef -Wshadow -Wpointer-arith -Wwrite-strings -Wbad-function-cast -Wcast-qual -Waggregate-return -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Winvalid-pch -Wredundant-decls -Wnested-externs -Winline -std=gnu99 -Werror=incompatible-pointer-types -fPIC -shared -rdynamic -Wl,-soname,libmyrpc.so -o ../lib/libmyrpc.so ../bin/myrpc.o make[1]: Leaving directory '/home/andy/X/myrpc/src' andy@andy-i7-dev:~/X/myrpc$ sudo make install for dir in src; do\ cd $dir && make install && cd ..;\ done make[1]: Entering directory '/home/andy/X/myrpc/src' mkdir -p /usr/lib/yumapro install ../lib/libmyrpc.so \ /usr/lib/yumapro/libmyrpc_sa.so make[1]: Leaving directory '/home/andy/X/myrpc/src' andy@andy-i7-dev:~/X/myrpc$ sudo make install for dir in src; do\ cd $dir && make install && cd ..;\ done make[1]: Entering directory '/home/andy/X/myrpc/src' mkdir -p /usr/lib/yumapro install ../lib/libmyrpc.so \ /usr/lib/yumapro/libmyrpc_sa.so make[1]: Leaving directory '/home/andy/X/myrpc/src' andy@andy-i7-dev:~/X/myrpc$ andy@andy-i7-dev:~/X/myrpc$ ls -l /usr/lib/yumapro/libmyrpc_sa.so -rwxr-xr-x 1 root root 8336 Feb 4 10:01 /usr/lib/yumapro/libmyrpc_sa.so andy@andy-i7-dev:~/X/myrpc$
3) Start the Server and sil-sa-app
- Start the netconfd-pro server and sil-sa-app program. They can be started in any order.
> netconfd-pro --log-level=debug2 --module=myrpc In another terminal window: > sil-sa-app --log-level=debug2
The server and sil-sa-app process will send YControl messages back and forth.
The sil-sa-app will register with the server to handle the myrpc operation
The following example from the server log file shows this register-request message
<?xml version="1.0" encoding="UTF-8"?> <ycontrol xmlns="http://yumaworks.com/ns/yumaworks-ycontrol"> <message-id>2</message-id> <message-type>subsys-request</message-type> <server-id>server1</server-id> <subsys-id>subsys1</subsys-id> <service-id>sil-sa</service-id> <payload> <sil-sa xmlns="http://yumaworks.com/ns/yumaworks-sil-sa"> <register-request> <register> <module>myrpc</module> <rpc-name>myrpc</rpc-name> </register> </register-request> </sil-sa> </payload> </ycontrol>
4) Send the RPC request to the server
- Use yangcli-pro or another client program to send an RPC request to the server
<?xml version="1.0" encoding="UTF-8"?> <rpc message-id="3" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <myrpc xmlns="http://www.netconfcentral.org/ns/yang/myrpc"> <parm1>test1</parm1> </myrpc> </rpc>
5) Server sends RPC Request to the Subsystem
The server will send an <rpc-request> message to the sil-sa-app subsystem
<?xml version="1.0" encoding="UTF-8"?> <ycontrol xmlns:ya="http://yumaworks.com/ns/yumaworks-attrs" xmlns="http://yumaworks.com/ns/yumaworks-ycontrol"> <message-id>2</message-id> <message-type>server-request</message-type> <server-id>server1</server-id> <subsys-id>subsys1</subsys-id> <service-id>sil-sa</service-id> <payload> <sil-sa xmlns="http://yumaworks.com/ns/yumaworks-sil-sa"> <rpc-request> <transaction-id>R2</transaction-id> <user-id>andy</user-id> <client-addr>127.0.0.1</client-addr> <rpc-module>myrpc</rpc-module> <rpc-name>myrpc</rpc-name> <rpc-input ya:datapath="/m:myrpc/m:input"> <parm1 xmlns="http://www.netconfcentral.org/ns/yang/myrpc">test1</parm1> </rpc-input> </rpc-request> </sil-sa> </payload> </ycontrol>
6) Subsystem Processes the RPC Request
The sil-sa-app will process the RPC request and invoke the validate and invoke callbacks in myrpc.c.
yc_parse: Overriding datapath obj 'rpc-input' with '/m:myrpc/m:input' ycontrol: dispatch message to service 'sil-sa' Start SIL validate rpc <myrpc> from module myrpc Start SIL invoke rpc <myrpc> from module myrpc ycontrol_msg: sending subsys-response # 2 for sil-sa ses_msg: reused out buff 0x55ae82dab130 for s 1 ses_msg: free msg 0x55ae82dda020 for session 1 ses got send request on session 1 ses_msg: send 1.1 buff:521 for s:1
7) Subsystem Sends an RPC Response to the Server
The sil-sa-app will send an <rpc-response> message to the server
<?xml version="1.0" encoding="UTF-8"?> <ycontrol xmlns:ya="http://yumaworks.com/ns/yumaworks-attrs" xmlns="http://yumaworks.com/ns/yumaworks-ycontrol"> <message-id>2</message-id> <message-type>subsys-response</message-type> <server-id>server1</server-id> <subsys-id>subsys1</subsys-id> <service-id>sil-sa</service-id> <payload> <sil-sa xmlns="http://yumaworks.com/ns/yumaworks-sil-sa"> <rpc-response> <transaction-id>R2</transaction-id> <rpc-ok/> </rpc-response> </sil-sa> </payload> </ycontrol>
8) Server Processes the Subsystem Response and Sends Reply to Client
The server will then process this message and send an <rpc-reply> message to the client
agt_sil: adding data response 2 for subsys subsys1 agt_top: end dispatch yumaworks-ycontrol:ycontrol ses_msg: free msg 0x5579c9a9b880 for session 3 ycontrol_mode_done for TXID 'R2' agt_rpc: start results for 'subsys1' (ok) agt_rpc: Got rpc-ok from subsys 'subsys1' agt_rpc: sending ok <rpc-reply> for ses 4 msg '3' <?xml version="1.0" encoding="UTF-8"?> <rpc-reply message-id="3" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <ok/> </rpc-reply>