* Netconf as default namespace has been disabled by default.

* Only requests on the form: `<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><edit-config>...` will be accepted
  * All replies will be on the form: `<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">...`
  * Requests such as: `<rpc><edit-config>...` will not  be accepted.
  * You can revert this behaviour (to clixon pre-4.6 behaviour) by enabling `CLICON_NAMESPACE_NETCONF_DEFAULT`
  * This API change is a consequence of: [copy-config's RPC cxobj parameter does not contain namespace #131](https://github.com/clicon/clixon/issues/131)
This commit is contained in:
Olof hagsand 2020-09-02 15:40:35 +02:00
parent a01fe04613
commit 81fc7f742b
81 changed files with 976 additions and 830 deletions

View file

@ -430,7 +430,7 @@ client_get_config_only(clicon_handle h,
if (nacm_datanode_read(h, xret, xvec, xlen, username, xnacm) < 0)
goto done;
}
cprintf(cbret, "<rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\">", NETCONF_BASE_NAMESPACE);
if (xret==NULL)
cprintf(cbret, "<data/>");
else{
@ -693,7 +693,7 @@ from_client_edit_config(clicon_handle h,
}
}
assert(cbuf_len(cbret) == 0);
cprintf(cbret, "<rpc-reply><ok");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok", NETCONF_BASE_NAMESPACE);
if (clicon_data_get(h, "objectexisted", &val) == 0)
cprintf(cbret, " objectexisted=\"%s\"", val);
cprintf(cbret, "/></rpc-reply>");
@ -777,7 +777,7 @@ from_client_copy_config(clicon_handle h,
goto ok;
}
xmldb_modified_set(h, target, 1); /* mark as dirty */
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
ok:
retval = 0;
done:
@ -844,7 +844,7 @@ from_client_delete_config(clicon_handle h,
goto ok;
}
xmldb_modified_set(h, target, 1); /* mark as dirty */
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
ok:
retval = 0;
done:
@ -914,7 +914,7 @@ from_client_lock(clicon_handle h,
}
if (xmldb_lock(h, db, id) < 0)
goto done;
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
ok:
retval = 0;
done:
@ -985,7 +985,7 @@ from_client_unlock(clicon_handle h,
}
else{
xmldb_unlock(h, db);
if (cprintf(cbret, "<rpc-reply><ok/></rpc-reply>") < 0)
if (cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE) < 0)
goto done;
}
ok:
@ -1178,7 +1178,7 @@ from_client_get(clicon_handle h,
if (nacm_datanode_read(h, xret, xvec, xlen, username, xnacm) < 0)
goto done;
}
cprintf(cbret, "<rpc-reply>"); /* OK */
cprintf(cbret, "<rpc-reply xmlns=\"%s\">", NETCONF_BASE_NAMESPACE); /* OK */
if (xret==NULL)
cprintf(cbret, "<data/>");
else{
@ -1227,7 +1227,7 @@ from_client_close_session(clicon_handle h,
xmldb_unlock_all(h, id);
stream_ss_delete_all(h, ce_event_cb, (void*)ce);
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
return 0;
}
@ -1279,7 +1279,7 @@ from_client_kill_session(clicon_handle h,
}
if (xmldb_islocked(h, db) == id)
xmldb_unlock(h, db);
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
ok:
retval = 0;
done:
@ -1377,7 +1377,7 @@ from_client_create_subscription(clicon_handle h,
if (stream_replay_trigger(h, stream, ce_event_cb, (void*)ce) < 0)
goto done;
}
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
ok:
retval = 0;
done:
@ -1416,7 +1416,7 @@ from_client_debug(clicon_handle h,
clicon_debug_init(level, NULL); /* 0: dont debug, 1:debug */
setlogmask(LOG_UPTO(level?LOG_DEBUG:LOG_INFO)); /* for syslog */
clicon_log(LOG_NOTICE, "%s debug:%d", __FUNCTION__, clicon_debug_get());
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
ok:
retval = 0;
done:
@ -1439,7 +1439,7 @@ from_client_ping(clicon_handle h,
void *arg,
void *regarg)
{
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
return 0;
}
@ -1462,7 +1462,7 @@ from_client_stats(clicon_handle h,
int retval = -1;
uint64_t nr;
cprintf(cbret, "<rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\">", NETCONF_BASE_NAMESPACE);
nr=0;
xml_stats_global(&nr);
cprintf(cbret, "<global><xmlnr>%" PRIu64 "</xmlnr></global>", nr);
@ -1516,7 +1516,7 @@ from_client_restart_plugin(clicon_handle h,
if (ret == 0)
goto ok; /* cbret set */
}
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
ok:
retval = 0;
done:
@ -1525,7 +1525,6 @@ from_client_restart_plugin(clicon_handle h,
return retval;
}
/*!
* @retval 0 OK
* @retval -1 Error
@ -1546,7 +1545,8 @@ from_client_hello(clicon_handle h,
}
id++;
clicon_session_id_set(h, id);
cprintf(cbret, "<hello><session-id>%u</session-id></hello>", id);
cprintf(cbret, "<hello xmlns=\"%s\"><session-id>%u</session-id></hello>",
NETCONF_BASE_NAMESPACE, id);
retval = 0;
done:
return retval;

View file

@ -680,7 +680,7 @@ from_client_commit(clicon_handle h,
goto ok;
}
if (ret == 1)
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
ok:
retval = 0;
done:
@ -732,7 +732,7 @@ from_client_discard_changes(clicon_handle h,
goto ok;
}
xmldb_modified_set(h, "candidate", 0); /* reset dirty bit */
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
ok:
retval = 0;
done:
@ -829,7 +829,7 @@ from_client_validate(clicon_handle h,
goto done;
goto ok;
}
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
/* Call plugin transaction end callbacks */
plugin_transaction_end_all(h, td);
ok:

View file

@ -697,6 +697,7 @@ main(int argc,
clicon_configfile(h));
goto done;
}
/* Treat unknown XML as anydata */
if (clicon_option_bool(h, "CLICON_YANG_UNKNOWN_ANYDATA") == 1)
xml_bind_yang_unknown_anydata(1);
@ -712,6 +713,9 @@ main(int argc,
if (xmldb_connect(h) < 0)
goto done;
/* Set default namespace according to CLICON_NAMESPACE_NETCONF_DEFAULT */
xml_nsctx_namespace_netconf_default(h);
/* Add (hardcoded) netconf features in case ietf-netconf loaded here
* Otherwise it is loaded in netconf_module_load below
*/

View file

@ -595,6 +595,9 @@ main(int argc,
if (netconf_module_features(h) < 0)
goto done;
/* Set default namespace according to CLICON_NAMESPACE_NETCONF_DEFAULT */
xml_nsctx_namespace_netconf_default(h);
/* Treat unknwon XML as anydata */
if (clicon_option_bool(h, "CLICON_YANG_UNKNOWN_ANYDATA") == 1)
xml_bind_yang_unknown_anydata(1);

View file

@ -525,7 +525,8 @@ cli_show_config1(clicon_handle h,
xml2cli_cb(stdout, xc, prefix, gt, cligen_output); /* cli syntax */
break;
case FORMAT_NETCONF:
cligen_output(stdout, "<rpc><edit-config><target><candidate/></target><config>\n");
cligen_output(stdout, "<rpc xmlns=\"%s\"><edit-config><target><candidate/></target><config>\n",
NETCONF_BASE_NAMESPACE);
xc = NULL; /* Dont print xt itself */
while ((xc = xml_child_each(xt, xc, -1)) != NULL)
clicon_xml2file_cb(stdout, xc, 2, 1, cligen_output);
@ -774,7 +775,8 @@ cli_show_auto1(clicon_handle h,
xml2cli_cb(stdout, xp, prefix, gt, cligen_output); /* cli syntax */
break;
case FORMAT_NETCONF:
fprintf(stdout, "<rpc><edit-config><target><candidate/></target><config>\n");
fprintf(stdout, "<rpc xmlns=\"%s\"><edit-config><target><candidate/></target><config>\n",
NETCONF_BASE_NAMESPACE);
clicon_xml2file(stdout, xp, 2, 1);
fprintf(stdout, "</config></edit-config></rpc>]]>]]>\n");
break;

View file

@ -192,6 +192,9 @@ netconf_input_packet(clicon_handle h,
* includes any "xmlns" attributes.
*/
while ((xa = xml_child_each(xrpc, xa, CX_ATTR)) != NULL){
/* If attribute already exists, dont copy it */
if (xml_find_type(xc, NULL, xml_name(xa), CX_ATTR) != NULL)
continue;
if ((xa2 = xml_dup(xa)) ==NULL)
goto done;
if (xml_addsub(xc, xa2) < 0)
@ -522,12 +525,15 @@ main(int argc,
cligen_bufthreshold = clicon_option_int(h, "CLICON_CLI_BUF_THRESHOLD");
cbuf_alloc_set(cligen_buflen, cligen_bufthreshold);
/* Set default namespace according to CLICON_NAMESPACE_NETCONF_DEFAULT */
xml_nsctx_namespace_netconf_default(h);
/* Add (hardcoded) netconf features in case ietf-netconf loaded here
* Otherwise it is loaded in netconf_module_load below
*/
if (netconf_module_features(h) < 0)
goto done;
/* Create top-level yang spec and store as option */
if ((yspec = yspec_new()) == NULL)
goto done;

View file

@ -93,12 +93,14 @@ netconf_get_config_subtree(clicon_handle h,
if ((xdata = xpath_first(*xret, NULL, "/rpc-reply/data")) == NULL)
goto ok;
if (xml_filter(xfilter, xdata) < 0){
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply><rpc-error>"
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply xmlns=\"%s\"><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>applicatio</error-type>"
"<error-type>application</error-type>"
"<error-severity>error</error-severity>"
"<error-info>filtering</error-info>"
"</rpc-error></rpc-reply>");
"</rpc-error></rpc-reply>",
NETCONF_BASE_NAMESPACE
);
}
ok:
retval = 0;
@ -180,13 +182,14 @@ netconf_get_config(clicon_handle h,
goto done;
}
else{
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply><rpc-error>"
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply xmlns=\"%s\"><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>applicatio</error-type>"
"<error-severity>error</error-severity>"
"<error-message>filter type not supported</error-message>"
"<error-info>type</error-info>"
"</rpc-error></rpc-reply>");
"</rpc-error></rpc-reply>",
NETCONF_BASE_NAMESPACE);
}
retval = 0;
done:
@ -245,11 +248,12 @@ get_edit_opts(cxobj *xn,
retval = 1; /* hunky dory */
return retval;
parerr: /* parameter error, xret set */
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply><rpc-error>"
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply xmlns=\"%s\"><rpc-error>"
"<error-tag>invalid-value</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"</rpc-error></rpc-reply>");
"</rpc-error></rpc-reply>",
NETCONF_BASE_NAMESPACE);
return 0;
}
@ -322,11 +326,12 @@ netconf_edit_config(clicon_handle h,
* (implement the features before removing these checks)
*/
if (testopt!=TEST_THEN_SET || erropt!=STOP_ON_ERROR){
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply><rpc-error>"
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply xmlns=\"%s\"><rpc-error>"
"<error-tag>operation-not-supported</error-tag>"
"<error-type>protocol</error-type>"
"<error-severity>error</error-severity>"
"</rpc-error></rpc-reply>");
"</rpc-error></rpc-reply>",
NETCONF_BASE_NAMESPACE);
goto ok;
}
if (clicon_rpc_netconf_xml(h, xml_parent(xn), xret, NULL) < 0)
@ -377,13 +382,14 @@ netconf_get(clicon_handle h,
goto done;
}
else{
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply><rpc-error>"
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply xmlns=\"%s\"><rpc-error>"
"<error-tag>operation-failed</error-tag>"
"<error-type>applicatio</error-type>"
"<error-severity>error</error-severity>"
"<error-message>filter type not supported</error-message>"
"<error-info>type</error-info>"
"</rpc-error></rpc-reply>");
"</rpc-error></rpc-reply>",
NETCONF_BASE_NAMESPACE);
}
retval = 0;
done:
@ -505,13 +511,14 @@ netconf_create_subscription(clicon_handle h,
if ((xfilter = xpath_first(xn, NULL, "//filter")) != NULL){
if ((ftype = xml_find_value(xfilter, "type")) != NULL){
if (strcmp(ftype, "xpath") != 0){
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply><rpc-error>"
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply xmlns=\"%s\"><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>");
"</rpc-error></rpc-reply>",
NETCONF_BASE_NAMESPACE);
goto ok;
}
}
@ -580,13 +587,14 @@ netconf_application_rpc(clicon_handle h,
if (ys_module_by_xml(yspec, xn, &ymod) < 0)
goto done;
if (ymod == NULL){
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply><rpc-error>"
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply xmlns=\"%s\"><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 module</error-info>"
"</rpc-error></rpc-reply>", xml_name(xn));
"</rpc-error></rpc-reply>",
NETCONF_BASE_NAMESPACE, xml_name(xn));
goto ok;
}
yrpc = yang_find(ymod, Y_RPC, xml_name(xn));
@ -717,13 +725,14 @@ netconf_rpc_dispatch(clicon_handle h,
if ((retval = netconf_application_rpc(h, xe, xret)) < 0)
goto done;
if (retval == 0){ /* not handled by callback */
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply><rpc-error>"
clixon_xml_parse_va(YB_NONE, NULL, xret, NULL, "<rpc-reply xmlns=\"%s\"><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>", xml_name(xe));
"</rpc-error></rpc-reply>",
NETCONF_BASE_NAMESPACE, xml_name(xe));
goto done;
}
}

View file

@ -763,6 +763,9 @@ main(int argc,
clicon_err(OE_DAEMON, EINVAL, "Restconf bind port is 0");
goto done;
}
/* Set default namespace according to CLICON_NAMESPACE_NETCONF_DEFAULT */
xml_nsctx_namespace_netconf_default(h);
/* Check server ssl certs */
if (use_ssl){
/* Init evhtp ssl config struct */

View file

@ -325,6 +325,8 @@ main(int argc,
cligen_bufthreshold = clicon_option_int(h, "CLICON_CLI_BUF_THRESHOLD");
cbuf_alloc_set(cligen_buflen, cligen_bufthreshold);
/* Set default namespace according to CLICON_NAMESPACE_NETCONF_DEFAULT */
xml_nsctx_namespace_netconf_default(h);
/* Add (hardcoded) netconf features in case ietf-netconf loaded here
* Otherwise it is loaded in netconf_module_load below

View file

@ -570,12 +570,18 @@ api_data_write(clicon_handle h,
goto done;
/* If we already have that default namespace, remove it in child */
if ((xa = xml_find_type(xdata, NULL, "xmlns", CX_ATTR)) != NULL){
if (xml2ns(xparent, NULL, &namespace) < 0)
if (xml2ns(xparent, NULL, &namespace) < 0){
clicon_debug(1, "%s G done", __FUNCTION__);
goto done;
}
if (namespace == NULL){
clicon_log_xml(LOG_DEBUG, xparent, "%s xparent:", __FUNCTION__);
/* XXX */
}
/* Set xmlns="" default namespace attribute (if diff from default) */
if (strcmp(namespace, xml_value(xa))==0)
if (namespace && strcmp(namespace, xml_value(xa))==0)
xml_purge(xa);
}
}
}
/* For internal XML protocol: add username attribute for access control
*/
@ -583,7 +589,8 @@ api_data_write(clicon_handle h,
/* Create text buffer for transfer to backend */
if ((cbx = cbuf_new()) == NULL)
goto done;
cprintf(cbx, "<rpc username=\"%s\" xmlns:%s=\"%s\">",
cprintf(cbx, "<rpc xmlns=\"%s\" username=\"%s\" xmlns:%s=\"%s\">",
NETCONF_BASE_NAMESPACE,
username?username:"",
NETCONF_BASE_PREFIX,
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */
@ -819,7 +826,8 @@ api_data_delete(clicon_handle h,
/* For internal XML protocol: add username attribute for access control
*/
username = clicon_username_get(h);
cprintf(cbx, "<rpc username=\"%s\" xmlns:%s=\"%s\">",
cprintf(cbx, "<rpc xmlns=\"%s\" username=\"%s\" xmlns:%s=\"%s\">",
NETCONF_BASE_NAMESPACE,
username?username:"",
NETCONF_BASE_PREFIX,
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */

View file

@ -369,7 +369,8 @@ api_data_post(clicon_handle h,
/* For internal XML protocol: add username attribute for access control
*/
username = clicon_username_get(h);
cprintf(cbx, "<rpc username=\"%s\" xmlns:%s=\"%s\">",
cprintf(cbx, "<rpc xmlns=\"%s\" username=\"%s\" xmlns:%s=\"%s\">",
NETCONF_BASE_NAMESPACE,
username?username:"",
NETCONF_BASE_PREFIX,
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */
@ -632,6 +633,10 @@ api_operations_post_output(clicon_handle h,
if (clicon_debug_get())
clicon_log_xml(LOG_DEBUG, xoutput, "%s xoutput:", __FUNCTION__);
#endif
/* Remove original netconf default namespace. Somewhat unsure what "output" belongs to? */
if ((xa = xml_find_type(xoutput, NULL, "xmlns", CX_ATTR)) != NULL)
if (xml_purge(xa) < 0)
goto done;
/* Sanity check of outgoing XML
* For now, skip outgoing checks.

View file

@ -266,8 +266,8 @@ restconf_stream(clicon_handle h,
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
cprintf(cb, "<rpc><create-subscription xmlns=\"%s\"><stream>%s</stream>",
EVENT_RFC5277_NAMESPACE, name);
cprintf(cb, "<rpc xmlns=\"%s\"><create-subscription xmlns=\"%s\"><stream>%s</stream>",
NETCONF_BASE_NAMESPACE, EVENT_RFC5277_NAMESPACE, name);
/* Print all fields */
for (i=0; i<cvec_len(qvec); i++){
cv = cvec_i(qvec, i);