Fixed [xml bind yang error in xml_bind_yang_rpc_reply #175](https://github.com/clicon/clixon/issues/175)

This commit is contained in:
Olof hagsand 2021-02-16 17:21:33 +01:00
parent a129756c6c
commit dee4e87edf
5 changed files with 56 additions and 12 deletions

View file

@ -112,6 +112,7 @@ Developers may need to change their code
### Corrected Bugs ### Corrected Bugs
* Fixed [xml bind yang error in xml_bind_yang_rpc_reply #175](https://github.com/clicon/clixon/issues/175)
* Fixed: [Is there an error with plugin's ca_interrupt setting ? #173](https://github.com/clicon/clixon/issues/173) * Fixed: [Is there an error with plugin's ca_interrupt setting ? #173](https://github.com/clicon/clixon/issues/173)
* Fixed: unknown nodes (for extenstions) did not work when placed directly under a grouping clause * Fixed: unknown nodes (for extenstions) did not work when placed directly under a grouping clause
* Fixed: [Behaviour of Empty LIST Input in RESTCONF JSON #166](https://github.com/clicon/clixon/issues/166) * Fixed: [Behaviour of Empty LIST Input in RESTCONF JSON #166](https://github.com/clicon/clixon/issues/166)

View file

@ -216,6 +216,9 @@ module clixon-example {
leaf uk{ leaf uk{
type string; type string;
} }
leaf val{
type string;
}
} }
} }
} }

View file

@ -309,7 +309,7 @@ example_rpc(clicon_handle h, /* Clicon handle */
cprintf(cbret, "<rpc-reply xmlns=\"%s\"", NETCONF_BASE_NAMESPACE); cprintf(cbret, "<rpc-reply xmlns=\"%s\"", NETCONF_BASE_NAMESPACE);
if ((xp = xml_parent(xe)) != NULL && if ((xp = xml_parent(xe)) != NULL &&
(msgid = xml_find_value(xp, "message-id"))){ (msgid = xml_find_value(xp, "message-id"))){
cprintf(cbret, " message-id=\"%s\">", msgid); cprintf(cbret, " message-id=\"%s\"", msgid);
} }
cprintf(cbret, ">"); cprintf(cbret, ">");
if (!xml_child_nr_type(xe, CX_ELMNT)) if (!xml_child_nr_type(xe, CX_ELMNT))

View file

@ -323,6 +323,8 @@ clicon_rpc_netconf(clicon_handle h,
* @param[in] xml XML netconf tree * @param[in] xml XML netconf tree
* @param[out] xret Return XML netconf tree, error or OK * @param[out] xret Return XML netconf tree, error or OK
* @param[out] sp Socket pointer for notification, otherwise NULL * @param[out] sp Socket pointer for notification, otherwise NULL
* @retval 0 OK
* @retval -1 Error
* @code * @code
* cxobj *xret = NULL; * cxobj *xret = NULL;
* int s; * int s;
@ -345,6 +347,8 @@ clicon_rpc_netconf_xml(clicon_handle h,
char *rpcname; char *rpcname;
cxobj *xreply; cxobj *xreply;
yang_stmt *yspec; yang_stmt *yspec;
cxobj *xerr = NULL;
int ret;
if ((cb = cbuf_new()) == NULL){ if ((cb = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new"); clicon_err(OE_XML, errno, "cbuf_new");
@ -363,11 +367,24 @@ clicon_rpc_netconf_xml(clicon_handle h,
xml_find_type(xreply, NULL, "rpc-error", CX_ELMNT) == NULL){ xml_find_type(xreply, NULL, "rpc-error", CX_ELMNT) == NULL){
yspec = clicon_dbspec_yang(h); yspec = clicon_dbspec_yang(h);
/* Here use rpc name to bind to yang */ /* Here use rpc name to bind to yang */
if (xml_bind_yang_rpc_reply(xreply, rpcname, yspec, NULL) < 0) if ((ret = xml_bind_yang_rpc_reply(xreply, rpcname, yspec, &xerr)) < 0)
goto done; goto done;
if (ret == 0){
/* Replace reply with error */
if (*xret) {
cxobj *xc;
if ((xc = xml_child_i(*xret, 0)) != NULL)
xml_purge(xc);
if (xml_addsub(*xret, xerr) < 0)
goto done;
xerr = NULL;
}
}
} }
retval = 0; retval = 0;
done: done:
if (xerr)
xml_free(xerr);
if (cb) if (cb)
cbuf_free(cb); cbuf_free(cb);
return retval; return retval;

View file

@ -613,9 +613,9 @@ xml_bind_yang_rpc(cxobj *xrpc,
/*! Find yang spec association of XML node for outgoing RPC starting with <rpc-reply> /*! Find yang spec association of XML node for outgoing RPC starting with <rpc-reply>
* *
* Incoming RPC has an "input" structure that is not taken care of by xml_bind_yang * Outgoing RPC has an "output" structure that is not taken care of by xml_bind_yang
* @param[in] xrpc XML rpc node * @param[in] xrpc XML rpc node
* @param[in] name Name of RPC (not seen in output/reply) * @param[in] name Name of RPC (not seen in output/reply)
* @param[in] yspec Yang spec * @param[in] yspec Yang spec
* @param[out] xerr Reason for failure, or NULL * @param[out] xerr Reason for failure, or NULL
* @retval 1 OK yang assignment made * @retval 1 OK yang assignment made
@ -640,10 +640,20 @@ xml_bind_yang_rpc_reply(cxobj *xrpc,
yang_stmt *yo = NULL; /* output */ yang_stmt *yo = NULL; /* output */
cxobj *x; cxobj *x;
int ret; int ret;
cxobj *xerr1 = NULL;
char *opname;
cbuf *cberr = NULL;
if (strcmp(xml_name(xrpc), "rpc-reply")){ opname = xml_name(xrpc);
clicon_err(OE_UNIX, EINVAL, "rpc-reply expected"); if (strcmp(opname, "rpc-reply")){
goto done; if ((cberr = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
cprintf(cberr, "Internal error, unrecognized netconf operation in backend reply, expected rpc-reply but received: %s", opname);
if (xerr && netconf_operation_failed_xml(xerr, "application", cbuf_get(cberr)) < 0)
goto done;
goto fail;
} }
x = NULL; x = NULL;
while ((x = xml_child_each(xrpc, x, CX_ELMNT)) != NULL) { while ((x = xml_child_each(xrpc, x, CX_ELMNT)) != NULL) {
@ -663,18 +673,31 @@ xml_bind_yang_rpc_reply(cxobj *xrpc,
} }
if (yo != NULL){ if (yo != NULL){
xml_spec_set(xrpc, yo); xml_spec_set(xrpc, yo);
if ((ret = xml_bind_yang(xrpc, YB_MODULE, yspec, xerr)) < 0) /* Use a temporary xml error tree since it is stringified in the original error on error */
if ((ret = xml_bind_yang(xrpc, YB_PARENT, NULL, &xerr1)) < 0)
goto done; goto done;
if (ret == 0) if (ret == 0){
if ((cberr = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
cprintf(cberr, "Internal error in backend reply: ");
if (netconf_err2cb(xerr1, cberr) < 0)
goto done;
if (xerr && netconf_operation_failed_xml(xerr, "application", cbuf_get(cberr)) < 0)
goto done;
goto fail; goto fail;
}
} }
retval = 1; retval = 1;
done: done:
if (cberr)
cbuf_free(cberr);
if (xerr1)
xml_free(xerr1);
return retval; return retval;
fail: fail:
retval = 0; retval = 0;
goto done; goto done;
} }