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>