* Proper RFC 6241 Netconf error handling

* New functions added in clixon_netconf_lib.[ch]
  * Datastore code modified for RFC 6241
  * Remaining: validate, generic restconf and netconf code
This commit is contained in:
Olof hagsand 2018-03-18 18:06:02 +00:00
parent 52e510cfdf
commit efa72e9e6f
26 changed files with 1196 additions and 475 deletions

View file

@ -180,7 +180,7 @@ backend_client_rm(clicon_handle h,
return backend_client_delete(h, ce); /* actually purge it */
}
/*! FInd target/source in netconf request. Assume sanity made so not finding is error */
/*! Find target/source in netconf request. Assume sanity- not finding is error */
static char*
netconf_db_find(cxobj *xn,
char *name)
@ -214,31 +214,28 @@ from_client_get_config(clicon_handle h,
cxobj *xfilter;
char *selector = "/";
cxobj *xret = NULL;
cbuf *cbx = NULL; /* Assist cbuf */
if ((db = netconf_db_find(xe, "source")) == NULL){
clicon_err(OE_XML, 0, "db not found");
goto done;
}
if (xmldb_validate_db(db) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>No such database: %s</error-message>"
"</rpc-error></rpc-reply>", db);
if ((cbx = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
cprintf(cbx, "No such database: %s", db);
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
goto done;
goto ok;
}
if ((xfilter = xml_find(xe, "filter")) != NULL)
if ((selector = xml_find_value(xfilter, "select"))==NULL)
selector="/";
if (xmldb_get(h, db, selector, 1, &xret) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>application</error-type>"
"<error-severity>error</error-severity>"
"<error-info>read-registry</error-info>"
"</rpc-error></rpc-reply>");
if (netconf_operation_failed(cbret, "application", "read registry")< 0)
goto done;
goto ok;
}
cprintf(cbret, "<rpc-reply>");
@ -254,6 +251,8 @@ from_client_get_config(clicon_handle h,
ok:
retval = 0;
done:
if (cbx)
cbuf_free(cbx);
if (xret)
xml_free(xret);
return retval;
@ -276,18 +275,15 @@ from_client_get(clicon_handle h,
char *selector = "/";
cxobj *xret = NULL;
int ret;
cbuf *cbx = NULL; /* Assist cbuf */
if ((xfilter = xml_find(xe, "filter")) != NULL)
if ((selector = xml_find_value(xfilter, "select"))==NULL)
selector="/";
/* Get config */
if (xmldb_get(h, "running", selector, 0, &xret) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>application</error-type>"
"<error-severity>error</error-severity>"
"<error-info>read-registry</error-info>"
"</rpc-error></rpc-reply>");
if (netconf_operation_failed(cbret, "application", "read registry")< 0)
goto done;
goto ok;
}
/* Get state data from plugins as defined by plugin_statedata(), if any */
@ -308,23 +304,25 @@ from_client_get(clicon_handle h,
cprintf(cbret, "</rpc-reply>");
}
else { /* 1 Error from callback */
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>rpc</error-type>"
"<error-severity>error</error-severity>"
"<error-message>Internal error:%s</error-message>"
"</rpc-error></rpc-reply>", clicon_err_reason);
if ((cbx = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
cprintf(cbx, "Internal error:%s", clicon_err_reason);
if (netconf_operation_failed(cbret, "rpc", cbuf_get(cbx))< 0)
goto done;
clicon_log(LOG_NOTICE, "%s Error in backend_statedata_call:%s", __FUNCTION__, xml_name(xe));
}
ok:
retval = 0;
done:
if (cbx)
cbuf_free(cbx);
if (xret)
xml_free(xret);
return retval;
}
/*! Internal message: edit-config
*
* @param[in] h Clicon handle
@ -340,14 +338,13 @@ from_client_edit_config(clicon_handle h,
{
int retval = -1;
char *target;
cbuf *cb = NULL;
cxobj *xret = NULL;
cxobj *xc;
cxobj *x;
enum operation_type operation = OP_MERGE;
int piddb;
int non_config = 0;
yang_spec *yspec;
cbuf *cbx = NULL; /* Assist cbuf */
if ((yspec = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_YANG, ENOENT, "No yang spec");
@ -357,50 +354,44 @@ from_client_edit_config(clicon_handle h,
clicon_err(OE_XML, 0, "db not found");
goto done;
}
if ((cbx = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
if (xmldb_validate_db(target) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>No such database: %s</error-message>"
"</rpc-error></rpc-reply>", target);
cprintf(cbx, "No such database: %s", target);
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
goto done;
goto ok;
}
/* Check if target locked by other client */
piddb = xmldb_islocked(h, target);
if (piddb && mypid != piddb){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>lock-denied</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>Operation failed, lock is already held</error-message>"
"<error-info><session-id>%d</session-id></error-info>"
"</rpc-error></rpc-reply>",
piddb);
cprintf(cbx, "<session-id>%d</session-id>", piddb);
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
goto done;
goto ok;
}
if ((x = xpath_first(xn, "default-operation")) != NULL){
if (xml_operation(xml_body(x), &operation) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"</rpc-error></rpc-reply>");
if (netconf_invalid_value(cbret, "protocol", "Wrong operation")< 0)
goto done;
goto ok;
}
}
if ((xc = xpath_first(xn, "config")) != NULL){
if ((xc = xpath_first(xn, "config")) == NULL){
if (netconf_missing_element(cbret, "protocol", "<bad-element>config</bad-element>", NULL) < 0)
goto done;
goto ok;
}
else{
if (xml_apply(xc, CX_ELMNT, xml_spec_populate, yspec) < 0)
goto done;
if (xml_apply(xc, CX_ELMNT, xml_non_config_data, &non_config) < 0)
goto done;
if (non_config){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>state data not allowed</error-message>"
"</rpc-error></rpc-reply>");
if (netconf_invalid_value(cbret, "protocol", "State data not allowed")< 0)
goto done;
goto ok;
}
/* Cant do this earlier since we dont have a yang spec to
@ -408,35 +399,23 @@ from_client_edit_config(clicon_handle h,
*/
if (xml_child_sort && xml_apply0(xc, CX_ELMNT, xml_sort, NULL) < 0)
goto done;
if (xmldb_put(h, target, operation, xc) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>%s</error-message>"
"</rpc-error></rpc-reply>", clicon_err_reason);
if (xmldb_put(h, target, operation, xc, cbret) < 0){
clicon_debug(1, "%s ERROR PUT", __FUNCTION__);
if (netconf_operation_failed(cbret, "protocol", clicon_err_reason)< 0)
goto done;
goto ok;
}
}
else{
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-info><bad-element>config</bad-element></error-info>"
"</rpc-error></rpc-reply>");
goto ok;
}
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
ok:
if (!cbuf_len(cbret))
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
retval = 0;
done:
if (xret)
xml_free(xret);
if (cb)
cbuf_free(cb);
if (cbx)
cbuf_free(cbx);
clicon_debug(1, "%s done cbret:%s", __FUNCTION__, cbuf_get(cbret));
return retval;
}
} /* from_client_edit_config */
/*! Internal message: Lock database
*
@ -454,26 +433,23 @@ from_client_lock(clicon_handle h,
int retval = -1;
char *db;
int piddb;
cbuf *cbx = NULL; /* Assist cbuf */
if ((db = netconf_db_find(xe, "target")) == NULL){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-info><bad-element>target</bad-element></error-info>"
"</rpc-error></rpc-reply>");
if (netconf_missing_element(cbret, "protocol", "<bad-element>target</bad-element>", NULL) < 0)
goto done;
goto ok;
}
if ((cbx = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
if (xmldb_validate_db(db) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>No such database: %s</error-message>"
"</rpc-error></rpc-reply>", db);
cprintf(cbx, "No such database: %s", db);
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
goto done;
goto ok;
}
/*
* A lock MUST not be granted if either of the following conditions is true:
* 1) A lock is already held by any NETCONF session or another entity.
@ -482,23 +458,21 @@ from_client_lock(clicon_handle h,
*/
piddb = xmldb_islocked(h, db);
if (piddb){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>lock-denied</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>Lock failed, lock is already held</error-message>"
"<error-info><session-id>%d</session-id></error-info>"
"</rpc-error></rpc-reply>",
piddb);
cprintf(cbx, "<session-id>%d</session-id>", piddb);
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
goto done;
goto ok;
}
else{
xmldb_lock(h, db, pid);
if (xmldb_lock(h, db, pid) < 0)
goto done;
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
}
ok:
retval = 0;
// done:
done:
if (cbx)
cbuf_free(cbx);
return retval;
}
@ -518,23 +492,21 @@ from_client_unlock(clicon_handle h,
int retval = -1;
char *db;
int piddb;
cbuf *cbx = NULL; /* Assist cbuf */
if ((db = netconf_db_find(xe, "target")) == NULL){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-info><bad-element>target</bad-element></error-info>"
"</rpc-error></rpc-reply>");
if (netconf_missing_element(cbret, "protocol", "<bad-element>target</bad-element>", NULL) < 0)
goto done;
goto ok;
}
if ((cbx = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
if (xmldb_validate_db(db) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>No such database: %s</error-message>"
"</rpc-error></rpc-reply>", db);
cprintf(cbx, "No such database: %s", db);
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
goto done;
goto ok;
}
piddb = xmldb_islocked(h, db);
@ -546,14 +518,9 @@ from_client_unlock(clicon_handle h,
* session that obtained the lock
*/
if (piddb==0 || piddb != pid){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>lock-denied</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>Unlock failed, lock is already held</error-message>"
"<error-info><session-id>pid=%d piddb=%d</session-id></error-info>"
"</rpc-error></rpc-reply>",
pid, piddb);
cprintf(cbx, "<session-id>pid=%d piddb=%d</session-id>", pid, piddb);
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Unlock failed, lock is already held") < 0)
goto done;
goto ok;
}
else{
@ -585,15 +552,11 @@ from_client_kill_session(clicon_handle h,
struct client_entry *ce;
char *db = "running"; /* XXX */
cxobj *x;
if ((x = xml_find(xe, "session-id")) == NULL ||
(str = xml_find_value(x, "body")) == NULL){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-info><bad-element>session-id</bad-element></error-info>"
"</rpc-error></rpc-reply>");
if (netconf_missing_element(cbret, "protocol", "<bad-element>session-id</bad-element>", NULL) < 0)
goto done;
goto ok;
}
pid = atoi(str);
@ -618,18 +581,14 @@ from_client_kill_session(clicon_handle h,
xmldb_unlock(h, db);
}
else{ /* failed to kill client */
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>application</error-type>"
"<error-severity>error</error-severity>"
"<error-message>Faile to kill session</error-message>"
"</rpc-error></rpc-reply>");
if (netconf_operation_failed(cbret, "application", "Failed to kill session")< 0)
goto done;
goto ok;
}
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
ok:
retval = 0;
// done:
done:
return retval;
}
@ -647,74 +606,57 @@ from_client_copy_config(clicon_handle h,
int mypid,
cbuf *cbret)
{
char *source;
char *target;
int retval = -1;
int piddb;
char *source;
char *target;
int retval = -1;
int piddb;
cbuf *cbx = NULL; /* Assist cbuf */
if ((source = netconf_db_find(xe, "source")) == NULL){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-info><bad-element>source</bad-element></error-info>"
"</rpc-error></rpc-reply>");
if (netconf_missing_element(cbret, "protocol", "<bad-element>source</bad-element>", NULL) < 0)
goto done;
goto ok;
}
if ((cbx = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
if (xmldb_validate_db(source) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>No such database: %s</error-message>"
"</rpc-error></rpc-reply>", source);
cprintf(cbx, "No such database: %s", source);
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
goto done;
goto ok;
}
if ((target = netconf_db_find(xe, "target")) == NULL){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-info><bad-element>target</bad-element></error-info>"
"</rpc-error></rpc-reply>");
if (netconf_missing_element(cbret, "protocol", "<bad-element>target</bad-element>", NULL) < 0)
goto done;
goto ok;
}
if (xmldb_validate_db(target) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>No such database: %s</error-message>"
"</rpc-error></rpc-reply>", target);
cprintf(cbx, "No such database: %s", target);
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
goto done;
goto ok;
}
/* Check if target locked by other client */
piddb = xmldb_islocked(h, target);
if (piddb && mypid != piddb){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>lock-denied</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>Operation failed, lock is already held</error-message>"
"<error-info><session-id>%d</session-id></error-info>"
"</rpc-error></rpc-reply>",
piddb);
cprintf(cbx, "<session-id>%d</session-id>", piddb);
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Copy failed, lock is already held") < 0)
goto done;
goto ok;
}
if (xmldb_copy(h, source, target) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>application</error-type>"
"<error-severity>error</error-severity>"
"<error-info>read-registry</error-info>"
"</rpc-error></rpc-reply>");
if (netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
goto done;
goto ok;
}
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
ok:
retval = 0;
// done:
done:
if (cbx)
cbuf_free(cbx);
return retval;
}
@ -732,67 +674,51 @@ from_client_delete_config(clicon_handle h,
int mypid,
cbuf *cbret)
{
int retval = -1;
char *target;
int piddb;
int retval = -1;
char *target;
int piddb;
cbuf *cbx = NULL; /* Assist cbuf */
if ((target = netconf_db_find(xe, "target")) == NULL||
strcmp(target, "running")==0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-info><bad-element>target</bad-element></error-info>"
"</rpc-error></rpc-reply>");
if (netconf_missing_element(cbret, "protocol", "<bad-element>target</bad-element>", NULL) < 0)
goto done;
goto ok;
}
if ((cbx = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
if (xmldb_validate_db(target) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>No such database: %s</error-message>"
"</rpc-error></rpc-reply>", target);
cprintf(cbx, "No such database: %s", target);
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
goto done;
goto ok;
}
/* Check if target locked by other client */
piddb = xmldb_islocked(h, target);
if (piddb && mypid != piddb){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>lock-denied</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-message>Operation failed, lock is already held</error-message>"
"<error-info><session-id>%d</session-id></error-info>"
"</rpc-error></rpc-reply>",
piddb);
cprintf(cbx, "<session-id>%d</session-id>", piddb);
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
goto done;
goto ok;
}
if (xmldb_delete(h, target) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-info>Internal error</error-info>"
"<error-message>%s</error-message>"
"</rpc-error></rpc-reply>", clicon_err_reason);
if (netconf_operation_failed(cbret, "protocol", clicon_err_reason)< 0)
goto done;
goto ok;
}
if (xmldb_create(h, target) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-info>Internal error</error-info>"
"<error-message>%s</error-message>"
"</rpc-error></rpc-reply>", clicon_err_reason);
if (netconf_operation_failed(cbret, "protocol", clicon_err_reason)< 0)
goto done;
goto ok;
}
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
ok:
retval = 0;
// done:
done:
if (cbx)
cbuf_free(cbx);
return retval;
}
@ -829,13 +755,8 @@ from_client_create_subscription(clicon_handle h,
if ((ftype = xml_find_value(x, "type")) != NULL){
/* Only accept xpath as filter type */
if (strcmp(ftype, "xpath") != 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>application</error-type>"
"<error-severity>error</error-severity>"
"<error-message>only xpath filter type supported</error-message>"
"<error-info>type</error-info>"
"</rpc-error></rpc-reply>");
if (netconf_operation_failed(cbret, "application", "Only xpath filter type supported")< 0)
goto done;
goto ok;
}
}
@ -866,12 +787,8 @@ from_client_debug(clicon_handle h,
char *valstr;
if ((valstr = xml_find_body(xe, "level")) == NULL){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-info><bad-element>level</bad-element></error-info>"
"</rpc-error></rpc-reply>");
if (netconf_missing_element(cbret, "application", "<bad-element>level</bad-element>", NULL) < 0)
goto done;
goto ok;
}
level = atoi(valstr);
@ -882,7 +799,7 @@ from_client_debug(clicon_handle h,
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
ok:
retval = 0;
//done:
done:
return retval;
}
@ -917,23 +834,13 @@ from_client_msg(clicon_handle h,
goto done;
}
if (clicon_msg_decode(msg, &xt) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>rpc</error-type>"
"<error-severity>error</error-severity>"
"<error-message>rpc expected</error-message>"
"<error-info>Not recognized</error-info>"
"</rpc-error></rpc-reply>");
if (netconf_malformed_message(cbret, "Not recognized, rpc expected")< 0)
goto done;
goto reply;
}
if ((x = xpath_first(xt, "/rpc")) == NULL){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>rpc</error-type>"
"<error-severity>error</error-severity>"
"<error-message>rpc expected</error-message>"
"<error-info>Not recognized</error-info>"
"</rpc-error></rpc-reply>");
if (netconf_malformed_message(cbret, "Not recognized, rpc expected")< 0)
goto done;
goto reply;
}
xe = NULL;
@ -977,12 +884,8 @@ from_client_msg(clicon_handle h,
}
else if (strcmp(name, "validate") == 0){
if ((db = netconf_db_find(xe, "source")) == NULL){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>missing-element</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"<error-info><bad-element>source</bad-element></error-info>"
"</rpc-error></rpc-reply>");
if (netconf_missing_element(cbret, "protocol", "<bad-element>source</bad-element>", NULL) < 0)
goto done;
goto reply;
}
if (from_client_validate(h, db, cbret) < 0)
@ -1007,34 +910,22 @@ from_client_msg(clicon_handle h,
else{
clicon_err_reset();
if ((ret = backend_rpc_cb_call(h, xe, ce, cbret)) < 0){
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>rpc</error-type>"
"<error-severity>error</error-severity>"
"<error-message>Internal error:%s</error-message>"
"</rpc-error></rpc-reply>", clicon_err_reason);
if (netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
goto done;
clicon_log(LOG_NOTICE, "%s Error in backend_rpc_call:%s", __FUNCTION__, xml_name(xe));
goto reply; /* Dont quit here on user callbacks */
}
if (ret == 0) /* not handled by callback */
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>rpc</error-type>"
"<error-severity>error</error-severity>"
"<error-message>%s</error-message>"
"<error-info>Not recognized</error-info>"
"</rpc-error></rpc-reply>",
name);
if (ret == 0){ /* not handled by callback */
if (netconf_operation_failed(cbret, "application", "Callback not recognized")< 0)
goto done;
goto reply;
}
}
}
reply:
if (cbuf_len(cbret) == 0)
cprintf(cbret, "<rpc-reply><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>rpc</error-type>"
"<error-severity>error</error-severity>"
"<error-message>Internal error %s</error-message>"
"</rpc-error></rpc-reply>",clicon_err_reason);
if (netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
goto done;
clicon_debug(1, "%s cbret:%s", __FUNCTION__, cbuf_get(cbret));
if (send_msg_reply(ce->ce_s, cbuf_get(cbret), cbuf_len(cbret)+1) < 0){
switch (errno){
@ -1055,7 +946,7 @@ from_client_msg(clicon_handle h,
}
// ok:
retval = 0;
done:
done:
if (xt)
xml_free(xt);
if (cbret)