experimental netconf yang spec
This commit is contained in:
parent
822aac18a1
commit
056b5c97dd
16 changed files with 250 additions and 147 deletions
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
## 3.4.0 (Upcoming)
|
## 3.4.0 (Upcoming)
|
||||||
|
|
||||||
|
* experimental netconf yang rpc
|
||||||
|
|
||||||
* datastore/keyvalue/Makefile is left behind on make distclean. Fixed by conditional configure. Thanks renato@netgate.com.
|
* datastore/keyvalue/Makefile is left behind on make distclean. Fixed by conditional configure. Thanks renato@netgate.com.
|
||||||
|
|
||||||
* Better semantic versioning, eg MAJOR/MINOR/PATCH, where increment in PATCH does not change API.
|
* Better semantic versioning, eg MAJOR/MINOR/PATCH, where increment in PATCH does not change API.
|
||||||
|
|
|
||||||
|
|
@ -74,9 +74,9 @@
|
||||||
|
|
||||||
/* Command line options to be passed to getopt(3) */
|
/* Command line options to be passed to getopt(3) */
|
||||||
#ifdef BACKEND_STARTUP_COMPAT
|
#ifdef BACKEND_STARTUP_COMPAT
|
||||||
#define BACKEND_OPTS "hD:f:d:b:Fzu:P:1s:c:IRCrg:py:x:" /* substitute s: for IRCc:r */
|
#define BACKEND_OPTS "hD:f:d:b:Fzu:P:1s:c:IRCrg:y:x:" /* substitute s: for IRCc:r */
|
||||||
#else
|
#else
|
||||||
#define BACKEND_OPTS "hD:f:d:b:Fzu:P:1s:c:g:py:x:" /* substitute s: for IRCc:r */
|
#define BACKEND_OPTS "hD:f:d:b:Fzu:P:1s:c:g:y:x:" /* substitute s: for IRCc:r */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! Terminate. Cannot use h after this */
|
/*! Terminate. Cannot use h after this */
|
||||||
|
|
@ -148,7 +148,6 @@ usage(char *argv0, clicon_handle h)
|
||||||
" -C\t\tCall plugin_reset() in plugins to reset system state in candidate db (use with -I)\n"
|
" -C\t\tCall plugin_reset() in plugins to reset system state in candidate db (use with -I)\n"
|
||||||
" -r\t\tReload running database\n"
|
" -r\t\tReload running database\n"
|
||||||
#endif /* BACKEND_STARTUP_COMPAT */
|
#endif /* BACKEND_STARTUP_COMPAT */
|
||||||
" -p \t\tPrint database yang specification\n"
|
|
||||||
" -g <group>\tClient membership required to this group (default: %s)\n"
|
" -g <group>\tClient membership required to this group (default: %s)\n"
|
||||||
" -y <file>\tOverride yang spec file (dont include .yang suffix)\n"
|
" -y <file>\tOverride yang spec file (dont include .yang suffix)\n"
|
||||||
" -x <plugin>\tXMLDB plugin\n",
|
" -x <plugin>\tXMLDB plugin\n",
|
||||||
|
|
@ -611,7 +610,6 @@ main(int argc, char **argv)
|
||||||
struct stat st;
|
struct stat st;
|
||||||
clicon_handle h;
|
clicon_handle h;
|
||||||
int help = 0;
|
int help = 0;
|
||||||
int printspec = 0;
|
|
||||||
int pid;
|
int pid;
|
||||||
char *pidfile;
|
char *pidfile;
|
||||||
char *sock;
|
char *sock;
|
||||||
|
|
@ -736,9 +734,6 @@ main(int argc, char **argv)
|
||||||
case 'g': /* config socket group */
|
case 'g': /* config socket group */
|
||||||
clicon_option_str_set(h, "CLICON_SOCK_GROUP", optarg);
|
clicon_option_str_set(h, "CLICON_SOCK_GROUP", optarg);
|
||||||
break;
|
break;
|
||||||
case 'p' : /* Print spec */
|
|
||||||
printspec++;
|
|
||||||
break;
|
|
||||||
case 'y' :{ /* Override yang module or absolute filename */
|
case 'y' :{ /* Override yang module or absolute filename */
|
||||||
clicon_option_str_set(h, "CLICON_YANG_MODULE_MAIN", optarg);
|
clicon_option_str_set(h, "CLICON_YANG_MODULE_MAIN", optarg);
|
||||||
break;
|
break;
|
||||||
|
|
@ -823,7 +818,7 @@ main(int argc, char **argv)
|
||||||
if (xmldb_connect(h) < 0)
|
if (xmldb_connect(h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Parse db spec file */
|
/* Parse db spec file */
|
||||||
if (yang_spec_main(h, stdout, printspec) < 0)
|
if (yang_spec_main(h) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Set options: database dir and yangspec (could be hidden in connect?)*/
|
/* Set options: database dir and yangspec (could be hidden in connect?)*/
|
||||||
|
|
|
||||||
|
|
@ -242,9 +242,9 @@ main(int argc, char **argv)
|
||||||
int logdst = CLICON_LOG_STDERR;
|
int logdst = CLICON_LOG_STDERR;
|
||||||
char *restarg = NULL; /* what remains after options */
|
char *restarg = NULL; /* what remains after options */
|
||||||
int dump_configfile_xml = 0;
|
int dump_configfile_xml = 0;
|
||||||
|
yang_spec *yspec;
|
||||||
|
|
||||||
/* Defaults */
|
/* Defaults */
|
||||||
|
|
||||||
/* In the startup, logs to stderr & debug flag set later */
|
/* In the startup, logs to stderr & debug flag set later */
|
||||||
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
|
||||||
/* Initiate CLICON handle */
|
/* Initiate CLICON handle */
|
||||||
|
|
@ -397,20 +397,17 @@ main(int argc, char **argv)
|
||||||
cv_exclude_keys(clicon_cli_varonly(h));
|
cv_exclude_keys(clicon_cli_varonly(h));
|
||||||
|
|
||||||
/* Parse db specification as cli*/
|
/* Parse db specification as cli*/
|
||||||
if (yang_spec_main(h, stdout, printspec) < 0)
|
if ((yspec = yang_spec_main(h)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
if (printspec)
|
||||||
|
yang_print(stdout, (yang_node*)yspec);
|
||||||
|
|
||||||
/* Create tree generated from dataspec. If no other trees exists, this is
|
/* Create tree generated from dataspec. If no other trees exists, this is
|
||||||
* the only one.
|
* the only one.
|
||||||
*/
|
*/
|
||||||
if (clicon_cli_genmodel(h)){
|
if (clicon_cli_genmodel(h)){
|
||||||
yang_spec *yspec; /* yang spec */
|
|
||||||
parse_tree pt = {0,}; /* cli parse tree */
|
parse_tree pt = {0,}; /* cli parse tree */
|
||||||
|
|
||||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
|
||||||
clicon_err(OE_FATAL, 0, "No YANG DB_SPEC");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
/* Create cli command tree from dbspec */
|
/* Create cli command tree from dbspec */
|
||||||
if (yang2cli(h, yspec, &pt, clicon_cli_genmodel_type(h)) < 0)
|
if (yang2cli(h, yspec, &pt, clicon_cli_genmodel_type(h)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -114,9 +114,8 @@ process_incoming_packet(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
free(str0);
|
free(str0);
|
||||||
if ((xrpc=xpath_first(xreq, "//rpc")) != NULL){
|
if ((xrpc=xpath_first(xreq, "//rpc")) != NULL)
|
||||||
isrpc++;
|
isrpc++;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
if (xpath_first(xreq, "//hello") != NULL)
|
if (xpath_first(xreq, "//hello") != NULL)
|
||||||
;
|
;
|
||||||
|
|
@ -215,9 +214,10 @@ netconf_input_cb(int s,
|
||||||
buf[i],
|
buf[i],
|
||||||
&xml_state)) {
|
&xml_state)) {
|
||||||
/* OK, we have an xml string from a client */
|
/* OK, we have an xml string from a client */
|
||||||
if (process_incoming_packet(h, cb) < 0){
|
/* Remove trailer */
|
||||||
|
*(((char*)cbuf_get(cb)) + cbuf_len(cb) - strlen("]]>]]>")) = '\0';
|
||||||
|
if (process_incoming_packet(h, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
if (cc_closed)
|
if (cc_closed)
|
||||||
break;
|
break;
|
||||||
cbuf_reset(cb);
|
cbuf_reset(cb);
|
||||||
|
|
@ -268,7 +268,6 @@ netconf_terminate(clicon_handle h)
|
||||||
{
|
{
|
||||||
yang_spec *yspec;
|
yang_spec *yspec;
|
||||||
|
|
||||||
|
|
||||||
clicon_rpc_close_session(h);
|
clicon_rpc_close_session(h);
|
||||||
if ((yspec = clicon_dbspec_yang(h)) != NULL)
|
if ((yspec = clicon_dbspec_yang(h)) != NULL)
|
||||||
yspec_free(yspec);
|
yspec_free(yspec);
|
||||||
|
|
@ -302,7 +301,8 @@ usage(clicon_handle h,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc,
|
||||||
|
char **argv)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
@ -337,7 +337,6 @@ main(int argc, char **argv)
|
||||||
use_syslog = 1;
|
use_syslog = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Logs, error and debug to stderr or syslog, set debug level
|
* Logs, error and debug to stderr or syslog, set debug level
|
||||||
*/
|
*/
|
||||||
|
|
@ -379,12 +378,17 @@ main(int argc, char **argv)
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
/* Parse yang database spec file */
|
/* Parse yang database spec file */
|
||||||
if (yang_spec_main(h, stdout, 0) < 0)
|
if (yang_spec_main(h) == NULL)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* Parse netconf yang spec file */
|
||||||
|
if (yang_spec_netconf(h) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Initialize plugins group */
|
/* Initialize plugins group */
|
||||||
if (netconf_plugin_load(h) < 0)
|
if (netconf_plugin_load(h) < 0)
|
||||||
return -1;
|
goto done;
|
||||||
|
|
||||||
|
|
||||||
/* Call start function is all plugins before we go interactive */
|
/* Call start function is all plugins before we go interactive */
|
||||||
tmp = *(argv-1);
|
tmp = *(argv-1);
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,6 @@ catch:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! See if there is any callback registered for this tag
|
/*! See if there is any callback registered for this tag
|
||||||
*
|
*
|
||||||
* @param[in] h clicon handle
|
* @param[in] h clicon handle
|
||||||
|
|
@ -215,7 +214,7 @@ netconf_plugin_callbacks(clicon_handle h,
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
netconf_reg_t *nreg;
|
netconf_reg_t *nreg;
|
||||||
yang_spec *yspec;
|
yang_spec *yspec = NULL; /* application yspec */
|
||||||
yang_stmt *yrpc;
|
yang_stmt *yrpc;
|
||||||
yang_stmt *yinput;
|
yang_stmt *yinput;
|
||||||
yang_stmt *youtput;
|
yang_stmt *youtput;
|
||||||
|
|
@ -234,19 +233,32 @@ netconf_plugin_callbacks(clicon_handle h,
|
||||||
nreg = NEXTQ(netconf_reg_t *, nreg);
|
nreg = NEXTQ(netconf_reg_t *, nreg);
|
||||||
} while (nreg != deps);
|
} while (nreg != deps);
|
||||||
}
|
}
|
||||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
/* First check system / netconf RPC:s */
|
||||||
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if ((cb = cbuf_new()) == NULL){
|
if ((cb = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_UNIX, 0, "cbuf_new");
|
clicon_err(OE_UNIX, 0, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* create absolute path */
|
/* create absolute path */
|
||||||
|
if (xml_namespace(xn))
|
||||||
cprintf(cb, "/%s:%s", xml_namespace(xn), xml_name(xn));
|
cprintf(cb, "/%s:%s", xml_namespace(xn), xml_name(xn));
|
||||||
|
else
|
||||||
|
cprintf(cb, "/nc:%s", xml_name(xn)); /* Hardcoded for netconf */
|
||||||
|
/* Find yang rpc statement, return yang rpc statement if found */
|
||||||
|
if (yrpc == NULL){
|
||||||
|
/* Then check application RPC */
|
||||||
|
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||||
|
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cbuf_reset(cb);
|
||||||
|
if (xml_namespace(xn))
|
||||||
|
cprintf(cb, "/%s:%s", xml_namespace(xn), xml_name(xn));
|
||||||
|
else
|
||||||
|
cprintf(cb, "/%s", xml_name(xn)); /* XXX not accepdted by below */
|
||||||
/* Find yang rpc statement, return yang rpc statement if found */
|
/* Find yang rpc statement, return yang rpc statement if found */
|
||||||
if (yang_abs_schema_nodeid(yspec, cbuf_get(cb), &yrpc) < 0)
|
if (yang_abs_schema_nodeid(yspec, cbuf_get(cb), &yrpc) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
/* Check if found */
|
/* Check if found */
|
||||||
if (yrpc != NULL){
|
if (yrpc != NULL){
|
||||||
if ((yinput = yang_find((yang_node*)yrpc, Y_INPUT, NULL)) != NULL){
|
if ((yinput = yang_find((yang_node*)yrpc, Y_INPUT, NULL)) != NULL){
|
||||||
|
|
|
||||||
|
|
@ -856,51 +856,85 @@ netconf_create_subscription(clicon_handle h,
|
||||||
* @param[in] h clicon handle
|
* @param[in] h clicon handle
|
||||||
* @param[in] xn Sub-tree (under xorig) at <rpc>...</rpc> level.
|
* @param[in] xn Sub-tree (under xorig) at <rpc>...</rpc> level.
|
||||||
* @param[out] xret Return XML, error or OK
|
* @param[out] xret Return XML, error or OK
|
||||||
|
* @retval 0 OK, can also be netconf error
|
||||||
|
* @retval -1 Error, fatal
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
netconf_rpc_dispatch(clicon_handle h,
|
netconf_rpc_dispatch(clicon_handle h,
|
||||||
cxobj *xn,
|
cxobj *xn,
|
||||||
cxobj **xret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
|
int retval = -1;
|
||||||
cxobj *xe;
|
cxobj *xe;
|
||||||
int ret = 0;
|
yang_spec *yspec = NULL;
|
||||||
|
|
||||||
|
/* Check incoming RPC against system / netconf RPC:s */
|
||||||
|
if ((yspec = clicon_netconf_yang(h)) == NULL){
|
||||||
|
clicon_err(OE_YANG, ENOENT, "No netconf yang spec");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
xe = NULL;
|
xe = NULL;
|
||||||
while ((xe = xml_child_each(xn, xe, CX_ELMNT)) != NULL) {
|
while ((xe = xml_child_each(xn, xe, CX_ELMNT)) != NULL) {
|
||||||
if (strcmp(xml_name(xe), "get-config") == 0)
|
if (strcmp(xml_name(xe), "get-config") == 0){
|
||||||
return netconf_get_config(h, xe, xret);
|
if (netconf_get_config(h, xe, xret) < 0)
|
||||||
else if (strcmp(xml_name(xe), "edit-config") == 0)
|
goto done;
|
||||||
return netconf_edit_config(h, xe, xret);
|
}
|
||||||
else if (strcmp(xml_name(xe), "copy-config") == 0)
|
else if (strcmp(xml_name(xe), "edit-config") == 0){
|
||||||
return netconf_copy_config(h, xe, xret);
|
if (netconf_edit_config(h, xe, xret) < 0)
|
||||||
else if (strcmp(xml_name(xe), "delete-config") == 0)
|
goto done;
|
||||||
return netconf_delete_config(h, xe, xret);
|
}
|
||||||
else if (strcmp(xml_name(xe), "lock") == 0)
|
else if (strcmp(xml_name(xe), "copy-config") == 0){
|
||||||
return netconf_lock(h, xe, xret);
|
if (netconf_copy_config(h, xe, xret) < 0)
|
||||||
else if (strcmp(xml_name(xe), "unlock") == 0)
|
goto done;
|
||||||
return netconf_unlock(h, xe, xret);
|
}
|
||||||
else if (strcmp(xml_name(xe), "get") == 0)
|
else if (strcmp(xml_name(xe), "delete-config") == 0){
|
||||||
return netconf_get(h, xe, xret);
|
if (netconf_delete_config(h, xe, xret) < 0)
|
||||||
else if (strcmp(xml_name(xe), "close-session") == 0)
|
goto done;
|
||||||
return netconf_close_session(h, xe, xret);
|
}
|
||||||
else if (strcmp(xml_name(xe), "kill-session") == 0)
|
else if (strcmp(xml_name(xe), "lock") == 0) {
|
||||||
return netconf_kill_session(h, xe, xret);
|
if (netconf_lock(h, xe, xret) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
else if (strcmp(xml_name(xe), "unlock") == 0){
|
||||||
|
if (netconf_unlock(h, xe, xret) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
else if (strcmp(xml_name(xe), "get") == 0){
|
||||||
|
if (netconf_get(h, xe, xret) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
else if (strcmp(xml_name(xe), "close-session") == 0){
|
||||||
|
if (netconf_close_session(h, xe, xret) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
else if (strcmp(xml_name(xe), "kill-session") == 0) {
|
||||||
|
if (netconf_kill_session(h, xe, xret) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
/* Validate capability :validate */
|
/* Validate capability :validate */
|
||||||
else if (strcmp(xml_name(xe), "validate") == 0)
|
else if (strcmp(xml_name(xe), "validate") == 0){
|
||||||
return netconf_validate(h, xe, xret);
|
if (netconf_validate(h, xe, xret) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
/* Candidate configuration capability :candidate */
|
/* Candidate configuration capability :candidate */
|
||||||
else if (strcmp(xml_name(xe), "commit") == 0)
|
else if (strcmp(xml_name(xe), "commit") == 0){
|
||||||
return netconf_commit(h, xe, xret);
|
if (netconf_commit(h, xe, xret) < 0)
|
||||||
else if (strcmp(xml_name(xe), "discard-changes") == 0)
|
goto done;
|
||||||
return netconf_discard_changes(h, xe, xret);
|
}
|
||||||
|
else if (strcmp(xml_name(xe), "discard-changes") == 0){
|
||||||
|
if (netconf_discard_changes(h, xe, xret) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
/* RFC 5277 :notification */
|
/* RFC 5277 :notification */
|
||||||
else if (strcmp(xml_name(xe), "create-subscription") == 0)
|
else if (strcmp(xml_name(xe), "create-subscription") == 0){
|
||||||
return netconf_create_subscription(h, xe, xret);
|
if (netconf_create_subscription(h, xe, xret) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
/* Others */
|
/* Others */
|
||||||
else{
|
else {
|
||||||
if ((ret = netconf_plugin_callbacks(h, xe, xret)) < 0)
|
if ((retval = netconf_plugin_callbacks(h, xe, xret)) < 0)
|
||||||
return -1;
|
goto done;
|
||||||
if (ret == 0){ /* not handled by callback */
|
if (retval == 0){ /* not handled by callback */
|
||||||
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
|
clicon_xml_parse(xret, NULL, "<rpc-reply><rpc-error>"
|
||||||
"<error-tag>operation-failed</error-tag>"
|
"<error-tag>operation-failed</error-tag>"
|
||||||
"<error-type>rpc</error-type>"
|
"<error-type>rpc</error-type>"
|
||||||
|
|
@ -908,10 +942,11 @@ netconf_rpc_dispatch(clicon_handle h,
|
||||||
"<error-message>%s</error-message>"
|
"<error-message>%s</error-message>"
|
||||||
"<error-info>Not recognized</error-info>"
|
"<error-info>Not recognized</error-info>"
|
||||||
"</rpc-error></rpc-reply>", xml_name(xe));
|
"</rpc-error></rpc-reply>", xml_name(xe));
|
||||||
return 0;
|
goto done;
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -357,7 +357,7 @@ main(int argc,
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Parse yang database spec file */
|
/* Parse yang database spec file */
|
||||||
if (yang_spec_main(h, NULL, 0) < 0)
|
if (yang_spec_main(h) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if ((sockpath = clicon_option_str(h, "CLICON_RESTCONF_PATH")) == NULL){
|
if ((sockpath = clicon_option_str(h, "CLICON_RESTCONF_PATH")) == NULL){
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,9 @@ int clicon_dbspec_yang_set(clicon_handle h, struct yang_spec *ys);
|
||||||
char *clicon_dbspec_name(clicon_handle h);
|
char *clicon_dbspec_name(clicon_handle h);
|
||||||
int clicon_dbspec_name_set(clicon_handle h, char *name);
|
int clicon_dbspec_name_set(clicon_handle h, char *name);
|
||||||
|
|
||||||
|
yang_spec *clicon_netconf_yang(clicon_handle h);
|
||||||
|
int clicon_netconf_yang_set(clicon_handle h, struct yang_spec *ys);
|
||||||
|
|
||||||
plghndl_t clicon_xmldb_plugin_get(clicon_handle h);
|
plghndl_t clicon_xmldb_plugin_get(clicon_handle h);
|
||||||
int clicon_xmldb_plugin_set(clicon_handle h, plghndl_t handle);
|
int clicon_xmldb_plugin_set(clicon_handle h, plghndl_t handle);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,8 @@ cg_var *ys_parse(yang_stmt *ys, enum cv_type cvtype);
|
||||||
int ys_parse_sub(yang_stmt *ys);
|
int ys_parse_sub(yang_stmt *ys);
|
||||||
int yang_mandatory(yang_stmt *ys);
|
int yang_mandatory(yang_stmt *ys);
|
||||||
int yang_config(yang_stmt *ys);
|
int yang_config(yang_stmt *ys);
|
||||||
int yang_spec_main(clicon_handle h, FILE *f, int printspec);
|
yang_spec *yang_spec_netconf(clicon_handle h);
|
||||||
|
yang_spec *yang_spec_main(clicon_handle h);
|
||||||
cvec *yang_arg2cvec(yang_stmt *ys, char *delimi);
|
cvec *yang_arg2cvec(yang_stmt *ys, char *delimi);
|
||||||
int yang_key_match(yang_node *yn, char *name);
|
int yang_key_match(yang_node *yn, char *name);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -382,8 +382,6 @@ clicon_options_main(clicon_handle h)
|
||||||
/* Read configfile */
|
/* Read configfile */
|
||||||
if (clicon_option_readfile_xml(copt, configfile, yspec) < 0)
|
if (clicon_option_readfile_xml(copt, configfile, yspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (yspec)
|
|
||||||
yspec_free(yspec);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
|
|
@ -402,6 +400,9 @@ clicon_options_main(clicon_handle h)
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (yspec) /* The clixon yang-spec is not used after this */
|
||||||
|
yspec_free(yspec);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -704,7 +705,7 @@ clicon_quiet_mode_set(clicon_handle h, int val)
|
||||||
return clicon_option_int_set(h, "CLICON_QUIET", val);
|
return clicon_option_int_set(h, "CLICON_QUIET", val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Get YANG specification
|
/*! Get YANG specification for application
|
||||||
* Must use hash functions directly since they are not strings.
|
* Must use hash functions directly since they are not strings.
|
||||||
*/
|
*/
|
||||||
yang_spec *
|
yang_spec *
|
||||||
|
|
@ -719,7 +720,7 @@ clicon_dbspec_yang(clicon_handle h)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Set yang database specification
|
/*! Set yang specification for application
|
||||||
* ys must be a malloced pointer
|
* ys must be a malloced pointer
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
|
@ -736,6 +737,39 @@ clicon_dbspec_yang_set(clicon_handle h,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Get YANG NETCONF specification
|
||||||
|
* Must use hash functions directly since they are not strings.
|
||||||
|
*/
|
||||||
|
yang_spec *
|
||||||
|
clicon_netconf_yang(clicon_handle h)
|
||||||
|
{
|
||||||
|
clicon_hash_t *cdat = clicon_data(h);
|
||||||
|
size_t len;
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
if ((p = hash_value(cdat, "netconf_yang", &len)) != NULL)
|
||||||
|
return *(yang_spec **)p;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Set yang netconf specification
|
||||||
|
* ys must be a malloced pointer
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clicon_netconf_yang_set(clicon_handle h,
|
||||||
|
struct yang_spec *ys)
|
||||||
|
{
|
||||||
|
clicon_hash_t *cdat = clicon_data(h);
|
||||||
|
|
||||||
|
/* It is the pointer to ys that should be copied by hash,
|
||||||
|
so we send a ptr to the ptr to indicate what to copy.
|
||||||
|
*/
|
||||||
|
if (hash_add(cdat, "netconf_yang", &ys, sizeof(ys)) == NULL)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Get dbspec name as read from spec. Can be used in CLI '@' syntax.
|
/*! Get dbspec name as read from spec. Can be used in CLI '@' syntax.
|
||||||
* XXX: this we muśt change,...
|
* XXX: this we muśt change,...
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ xml_parse_qname(struct xml_parse_yacc_arg *ya,
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
yang_stmt *y=NULL; /* yang node */
|
yang_stmt *y = NULL; /* yang node */
|
||||||
cxobj *xp; /* xml parent */
|
cxobj *xp; /* xml parent */
|
||||||
|
|
||||||
xp = ya->ya_xparent;
|
xp = ya->ya_xparent;
|
||||||
|
|
|
||||||
|
|
@ -1527,7 +1527,7 @@ yang_parse_recurse(clicon_handle h,
|
||||||
if ((nr = yang_parse_find_match(h, yang_dir, module, fbuf)) < 0)
|
if ((nr = yang_parse_find_match(h, yang_dir, module, fbuf)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (nr == 0){
|
if (nr == 0){
|
||||||
clicon_err(OE_YANG, errno, "No matching %s yang files found (expected modulenameor absolute filename)", module);
|
clicon_err(OE_YANG, errno, "No matching %s yang files found (expected module name or absolute filename)", module);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1820,7 +1820,6 @@ yang_abs_schema_nodeid(yang_spec *yspec,
|
||||||
yang_stmt *ymod;
|
yang_stmt *ymod;
|
||||||
char *id;
|
char *id;
|
||||||
char *prefix = NULL;
|
char *prefix = NULL;
|
||||||
|
|
||||||
yang_stmt *yprefix;
|
yang_stmt *yprefix;
|
||||||
|
|
||||||
/* check absolute schema_nodeid */
|
/* check absolute schema_nodeid */
|
||||||
|
|
@ -2024,24 +2023,36 @@ yang_config(yang_stmt *ys)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Utility function for handling yang parsing and translation to key format
|
/*! Parse netconf yang spec, used by netconf client and as internal protocol */
|
||||||
|
yang_spec *
|
||||||
|
yang_spec_netconf(clicon_handle h)
|
||||||
|
{
|
||||||
|
yang_spec *yspec = NULL;
|
||||||
|
|
||||||
|
if ((yspec = yspec_new()) == NULL)
|
||||||
|
goto done;
|
||||||
|
if (yang_parse(h, CLIXON_DATADIR, "ietf-netconf", NULL, yspec) < 0){
|
||||||
|
yspec_free(yspec); yspec = NULL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
clicon_netconf_yang_set(h, yspec);
|
||||||
|
done:
|
||||||
|
return yspec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Read, parse and save application yang specification as option
|
||||||
* @param h clicon handle
|
* @param h clicon handle
|
||||||
* @param f file to print to (if printspec enabled)
|
* @param f file to print to (if printspec enabled)
|
||||||
* @param printspec print database (YANG) specification as read from file
|
* @param printspec print database (YANG) specification as read from file
|
||||||
*/
|
*/
|
||||||
int
|
yang_spec*
|
||||||
yang_spec_main(clicon_handle h,
|
yang_spec_main(clicon_handle h)
|
||||||
FILE *f,
|
|
||||||
int printspec)
|
|
||||||
{
|
{
|
||||||
yang_spec *yspec;
|
yang_spec *yspec = NULL;
|
||||||
char *yang_dir;
|
char *yang_dir;
|
||||||
char *yang_module;
|
char *yang_module;
|
||||||
char *yang_revision;
|
char *yang_revision;
|
||||||
int retval = -1;
|
|
||||||
|
|
||||||
if ((yspec = yspec_new()) == NULL)
|
|
||||||
goto done;
|
|
||||||
if ((yang_dir = clicon_yang_dir(h)) == NULL){
|
if ((yang_dir = clicon_yang_dir(h)) == NULL){
|
||||||
clicon_err(OE_FATAL, 0, "CLICON_YANG_DIR option not set");
|
clicon_err(OE_FATAL, 0, "CLICON_YANG_DIR option not set");
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -2052,14 +2063,15 @@ yang_spec_main(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
yang_revision = clicon_yang_module_revision(h);
|
yang_revision = clicon_yang_module_revision(h);
|
||||||
if (yang_parse(h, yang_dir, yang_module, yang_revision, yspec) < 0)
|
if ((yspec = yspec_new()) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
if (yang_parse(h, yang_dir, yang_module, yang_revision, yspec) < 0){
|
||||||
|
yspec_free(yspec); yspec = NULL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
clicon_dbspec_yang_set(h, yspec);
|
clicon_dbspec_yang_set(h, yspec);
|
||||||
if (printspec)
|
|
||||||
yang_print(f, (yang_node*)yspec);
|
|
||||||
retval = 0;
|
|
||||||
done:
|
done:
|
||||||
return retval;
|
return yspec;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Given a yang node, translate the argument string to a cv vector
|
/*! Given a yang node, translate the argument string to a cv vector
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,8 @@ clicon_yang_debug(int d)
|
||||||
also called from yacc generated code *
|
also called from yacc generated code *
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
clixon_yang_parseerror(void *_yy, char *s)
|
clixon_yang_parseerror(void *_yy,
|
||||||
|
char *s)
|
||||||
{
|
{
|
||||||
clicon_err(OE_YANG, 0, "%s on line %d: %s at or before: '%s'",
|
clicon_err(OE_YANG, 0, "%s on line %d: %s at or before: '%s'",
|
||||||
_YY->yy_name,
|
_YY->yy_name,
|
||||||
|
|
@ -195,7 +196,8 @@ clixon_yang_parseerror(void *_yy, char *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
yang_parse_init(struct clicon_yang_yacc_arg *yy, yang_spec *ysp)
|
yang_parse_init(struct clicon_yang_yacc_arg *yy,
|
||||||
|
yang_spec *ysp)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -219,7 +221,8 @@ ystack_pop(struct clicon_yang_yacc_arg *yy)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ys_stack *
|
struct ys_stack *
|
||||||
ystack_push(struct clicon_yang_yacc_arg *yy, yang_node *yn)
|
ystack_push(struct clicon_yang_yacc_arg *yy,
|
||||||
|
yang_node *yn)
|
||||||
{
|
{
|
||||||
struct ys_stack *ystack;
|
struct ys_stack *ystack;
|
||||||
|
|
||||||
|
|
@ -272,7 +275,9 @@ ysp_add(struct clicon_yang_yacc_arg *yy,
|
||||||
|
|
||||||
/*! combination of ysp_add and ysp_push for sub-modules */
|
/*! combination of ysp_add and ysp_push for sub-modules */
|
||||||
static yang_stmt *
|
static yang_stmt *
|
||||||
ysp_add_push(struct clicon_yang_yacc_arg *yy, int keyword, char *argument)
|
ysp_add_push(struct clicon_yang_yacc_arg *yy,
|
||||||
|
int keyword,
|
||||||
|
char *argument)
|
||||||
{
|
{
|
||||||
yang_stmt *ys;
|
yang_stmt *ys;
|
||||||
|
|
||||||
|
|
@ -286,7 +291,8 @@ ysp_add_push(struct clicon_yang_yacc_arg *yy, int keyword, char *argument)
|
||||||
/* identifier-ref-arg-str has a [prefix :] id and prefix_id joins the id with an
|
/* identifier-ref-arg-str has a [prefix :] id and prefix_id joins the id with an
|
||||||
optional prefix into a single string */
|
optional prefix into a single string */
|
||||||
static char*
|
static char*
|
||||||
prefix_id_join(char *prefix, char *id)
|
prefix_id_join(char *prefix,
|
||||||
|
char *id)
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
int len;
|
int len;
|
||||||
|
|
@ -333,7 +339,7 @@ module_stmt : K_MODULE id_arg_str
|
||||||
}
|
}
|
||||||
'{' module_substmts '}'
|
'{' module_substmts '}'
|
||||||
{ if (ystack_pop(_yy) < 0) _YYERROR("2");
|
{ if (ystack_pop(_yy) < 0) _YYERROR("2");
|
||||||
clicon_debug(2,"module -> id-arg-str { module-substmts }");}
|
clicon_debug(2,"module_stmt -> id-arg-str { module-substmts }");}
|
||||||
;
|
;
|
||||||
|
|
||||||
module_substmts : module_substmts module_substmt
|
module_substmts : module_substmts module_substmt
|
||||||
|
|
@ -693,7 +699,7 @@ anyxml_substmt : when_stmt { clicon_debug(2,"anyxml-substmt -> when-st
|
||||||
| status_stmt { clicon_debug(2,"anyxml-substmt -> status-stmt"); }
|
| status_stmt { clicon_debug(2,"anyxml-substmt -> status-stmt"); }
|
||||||
| description_stmt { clicon_debug(2,"anyxml-substmt -> description-stmt"); }
|
| description_stmt { clicon_debug(2,"anyxml-substmt -> description-stmt"); }
|
||||||
| reference_stmt { clicon_debug(2,"anyxml-substmt -> reference-stmt"); }
|
| reference_stmt { clicon_debug(2,"anyxml-substmt -> reference-stmt"); }
|
||||||
| ustring ':' ustring ';' { clicon_debug(2,"anyxml-substmt -> anyxml extension"); }
|
| ustring ':' ustring ';' { free($1); free($3); clicon_debug(2,"anyxml-substmt -> anyxml extension"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* uses */
|
/* uses */
|
||||||
|
|
|
||||||
|
|
@ -3,136 +3,137 @@
|
||||||
|
|
||||||
# include err() and new() functions
|
# include err() and new() functions
|
||||||
. ./lib.sh
|
. ./lib.sh
|
||||||
|
clixon_cf="-f /usr/local/etc/routing.xml"
|
||||||
|
|
||||||
# For memcheck
|
# For memcheck
|
||||||
# clixon_netconf="valgrind --leak-check=full --show-leak-kinds=all clixon_netconf"
|
#clixon_netconf="valgrind --leak-check=full --show-leak-kinds=all clixon_netconf"
|
||||||
clixon_netconf=clixon_netconf
|
clixon_netconf=clixon_netconf
|
||||||
|
|
||||||
|
echo "clixon_backend -z $clixon_cf"
|
||||||
# kill old backend (if any)
|
# kill old backend (if any)
|
||||||
new "kill old backend"
|
new "kill old backend"
|
||||||
sudo clixon_backend -zf $clixon_cf
|
sudo clixon_backend -z $clixon_cf
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
err
|
err
|
||||||
fi
|
fi
|
||||||
new "start backend"
|
new "start backend"
|
||||||
# start new backend
|
# start new backend
|
||||||
sudo clixon_backend -s init -f $clixon_cf
|
sudo clixon_backend -s init $clixon_cf
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
err
|
err
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "netconf tests"
|
new "netconf tests"
|
||||||
|
|
||||||
new "netconf get empty config"
|
expecteof "$clixon_netconf -q $clixon_cf" '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
|
||||||
|
|
||||||
new "Add subtree eth/0/0 using none which should not change anything"
|
new "Add subtree eth/0/0 using none which should not change anything"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><edit-config><default-operation>none</default-operation><target><candidate/></target><config><interfaces><interface><name>eth/0/0</name></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><edit-config><default-operation>none</default-operation><target><candidate/></target><config><interfaces><interface><name>eth/0/0</name></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Check nothing added"
|
new "Check nothing added"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -q $clixon_cf" '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "Add subtree eth/0/0 using none and create which should add eth/0/0"
|
new "Add subtree eth/0/0 using none and create which should add eth/0/0"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="create"><name>eth/0/0</name><type>eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="create"><name>eth/0/0</name><type>eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Check eth/0/0 added using xpath"
|
new "Check eth/0/0 added using xpath"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/interfaces/interface[name=eth/0/0]"/></get-config></rpc>]]>]]>' "^<rpc-reply><data><interfaces><interface><name>eth/0/0</name><type>eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/interfaces/interface[name=eth/0/0]"/></get-config></rpc>]]>]]>' "^<rpc-reply><data><interfaces><interface><name>eth/0/0</name><type>eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Re-create same eth/0/0 which should generate error"
|
new "Re-create same eth/0/0 which should generate error"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="create"><name>eth/0/0</name><type>eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><rpc-error>"
|
expecteof "$clixon_netconf -q $clixon_cf" '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="create"><name>eth/0/0</name><type>eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><rpc-error>"
|
||||||
|
|
||||||
new "Delete eth/0/0 using none config"
|
new "Delete eth/0/0 using none config"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="delete"><name>eth/0/0</name><type>eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="delete"><name>eth/0/0</name><type>eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Check deleted eth/0/0 (non-presence container)"
|
new "Check deleted eth/0/0 (non-presence container)"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -q $clixon_cf" '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "Re-Delete eth/0/0 using none should generate error"
|
new "Re-Delete eth/0/0 using none should generate error"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="delete"><name>eth/0/0</name><type>eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><rpc-error>"
|
expecteof "$clixon_netconf -q $clixon_cf" '<rpc><edit-config><target><candidate/></target><config><interfaces><interface operation="delete"><name>eth/0/0</name><type>eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><rpc-error>"
|
||||||
|
|
||||||
new "netconf edit config"
|
new "netconf edit config"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth/0/0</name></interface><interface><name>eth1</name><enabled>true</enabled><ipv4><address><ip>9.2.3.4</ip><prefix-length>24</prefix-length></address></ipv4></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth/0/0</name></interface><interface><name>eth1</name><enabled>true</enabled><ipv4><address><ip>9.2.3.4</ip><prefix-length>24</prefix-length></address></ipv4></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get config xpath"
|
new "netconf get config xpath"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/interfaces/interface[name=eth1]/enabled"/></get-config></rpc>]]>]]>' "^<rpc-reply><data><interfaces><interface><name>eth1</name><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/interfaces/interface[name=eth1]/enabled"/></get-config></rpc>]]>]]>' "^<rpc-reply><data><interfaces><interface><name>eth1</name><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get config xpath parent"
|
new "netconf get config xpath parent"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/interfaces/interface[name=eth1]/enabled/../.."/></get-config></rpc>]]>]]>' "^<rpc-reply><data><interfaces><interface><name>eth/0/0</name><enabled>true</enabled></interface><interface><name>eth1</name><enabled>true</enabled><ipv4><enabled>true</enabled><forwarding>false</forwarding><address><ip>9.2.3.4</ip><prefix-length>24</prefix-length></address></ipv4></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" '<rpc><get-config><source><candidate/></source><filter type="xpath" select="/interfaces/interface[name=eth1]/enabled/../.."/></get-config></rpc>]]>]]>' "^<rpc-reply><data><interfaces><interface><name>eth/0/0</name><enabled>true</enabled></interface><interface><name>eth1</name><enabled>true</enabled><ipv4><enabled>true</enabled><forwarding>false</forwarding><address><ip>9.2.3.4</ip><prefix-length>24</prefix-length></address></ipv4></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate missing type"
|
new "netconf validate missing type"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get empty config2"
|
new "netconf get empty config2"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf edit extra xml"
|
new "netconf edit extra xml"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><edit-config><target><candidate/></target><config><interfaces><extra/></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><edit-config><target><candidate/></target><config><interfaces><extra/></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf edit config eth1"
|
new "netconf edit config eth1"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth1</name><type>eth</type></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth1</name><type>eth</type></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf edit config replace XXX is merge?"
|
new "netconf edit config replace XXX is merge?"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth2</name><type>eth</type></interface></interfaces></config><default-operation>merge</default-operation></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth2</name><type>eth</type></interface></interfaces></config><default-operation>merge</default-operation></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get replaced config"
|
new "netconf get replaced config"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><interfaces><interface><name>eth1</name><type>eth</type><enabled>true</enabled></interface><interface><name>eth2</name><type>eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><interfaces><interface><name>eth1</name><type>eth</type><enabled>true</enabled></interface><interface><name>eth2</name><type>eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf edit state operation should fail"
|
new "netconf edit state operation should fail"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><edit-config><target><candidate/></target><config><interfaces-state><interface><name>eth1</name><type>eth</type></interface></interfaces-state></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>invalid-value</error-tag>"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><edit-config><target><candidate/></target><config><interfaces-state><interface><name>eth1</name><type>eth</type></interface></interfaces-state></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-tag>invalid-value</error-tag>"
|
||||||
|
|
||||||
new "netconf get state operation"
|
new "netconf get state operation"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><get><filter type=\"xpath\" select=\"/interfaces-state\"/></get></rpc>]]>]]>" "^<rpc-reply><data><interfaces-state><interface><name>eth0</name><type>eth</type><if-index>42</if-index></interface></interfaces-state></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><get><filter type=\"xpath\" select=\"/interfaces-state\"/></get></rpc>]]>]]>" "^<rpc-reply><data><interfaces-state><interface><name>eth0</name><type>eth</type><if-index>42</if-index></interface></interfaces-state></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf lock/unlock"
|
new "netconf lock/unlock"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]><rpc><unlock><target><candidate/></target></unlock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]><rpc><unlock><target><candidate/></target></unlock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf lock/lock"
|
new "netconf lock/lock"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf lock"
|
new "netconf lock"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><lock><target><candidate/></target></lock></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "close-session"
|
new "close-session"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><close-session/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><close-session/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "kill-session"
|
new "kill-session"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><kill-session><session-id>44</session-id></kill-session></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><kill-session><session-id>44</session-id></kill-session></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "copy startup"
|
new "copy startup"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><copy-config><target><startup/></target><source><candidate/></source></copy-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><copy-config><target><startup/></target><source><candidate/></source></copy-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get startup"
|
new "netconf get startup"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><interfaces><interface><name>eth1</name><type>eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><interfaces><interface><name>eth1</name><type>eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf delete startup"
|
new "netconf delete startup"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><delete-config><target><startup/></target></delete-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><delete-config><target><startup/></target></delete-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf check empty startup"
|
new "netconf check empty startup"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf rpc"
|
new "netconf rpc"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><rt:fib-route><routing-instance-name>ipv4</routing-instance-name><destination-address><address-family>ipv4</address-family></destination-address></rt:fib-route></rpc>]]>]]>" "^<rpc-reply><route><address-family>ipv4</address-family><next-hop><next-hop-list>"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><rt:fib-route><routing-instance-name>ipv4</routing-instance-name><destination-address><address-family>ipv4</address-family></destination-address></rt:fib-route></rpc>]]>]]>" "^<rpc-reply><route><address-family>ipv4</address-family><next-hop><next-hop-list>"
|
||||||
|
|
||||||
new "netconf rpc w/o namespace"
|
new "netconf rpc w/o namespace"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><fib-route><routing-instance-name>ipv4</routing-instance-name><destination-address><address-family>ipv4</address-family></destination-address></fib-route></rpc>]]>]]>" "^<rpc-reply><route><address-family>ipv4</address-family><next-hop><next-hop-list>"
|
expecteof "$clixon_netconf -q $clixon_cf" "<rpc><fib-route><routing-instance-name>ipv4</routing-instance-name><destination-address><address-family>ipv4</address-family></destination-address></fib-route></rpc>]]>]]>" "^<rpc-reply><route><address-family>ipv4</address-family><next-hop><next-hop-list>"
|
||||||
|
|
||||||
new "netconf subscription"
|
new "netconf subscription"
|
||||||
expectwait "$clixon_netconf -qf $clixon_cf" "<rpc><create-subscription><stream>ROUTING</stream></create-subscription></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><notification><event>Routing notification</event></notification>]]>]]>$" 30
|
expectwait "$clixon_netconf -q $clixon_cf" "<rpc><create-subscription><stream>ROUTING</stream></create-subscription></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><notification><event>Routing notification</event></notification>]]>]]>$" 30
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if still alive
|
# Check if still alive
|
||||||
|
|
@ -141,7 +142,7 @@ if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err "backend already dead"
|
||||||
fi
|
fi
|
||||||
# kill backend
|
# kill backend
|
||||||
sudo clixon_backend -zf $clixon_cf
|
sudo clixon_backend -z $clixon_cf
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
err "kill backend"
|
err "kill backend"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ clixon_cli=clixon_cli
|
||||||
|
|
||||||
cat <<EOF > /tmp/conf_yang.xml
|
cat <<EOF > /tmp/conf_yang.xml
|
||||||
<config>
|
<config>
|
||||||
<CLICON_CONFIGFILE>/tmp/test_yang.xml</CLICON_CONFIGFILE>
|
<CLICON_CONFIGFILE>/tmp/conf_yang.xml</CLICON_CONFIGFILE>
|
||||||
<CLICON_YANG_DIR>/usr/local/share/routing/yang</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>/usr/local/share/routing/yang</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>
|
<CLICON_YANG_MODULE_MAIN>example</CLICON_YANG_MODULE_MAIN>
|
||||||
<CLICON_CLISPEC_DIR>/usr/local/lib/routing/clispec</CLICON_CLISPEC_DIR>
|
<CLICON_CLISPEC_DIR>/usr/local/lib/routing/clispec</CLICON_CLISPEC_DIR>
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ datarootdir = @datarootdir@
|
||||||
|
|
||||||
YANGSPECS = clixon-config@2017-12-03.yang
|
YANGSPECS = clixon-config@2017-12-03.yang
|
||||||
YANGSPECS += ietf-netconf@2011-06-01.yang
|
YANGSPECS += ietf-netconf@2011-06-01.yang
|
||||||
|
YANGSPECS += ietf-inet-types@2013-07-15.yang
|
||||||
|
|
||||||
APPNAME = clixon # subdir ehere these files are installed
|
APPNAME = clixon # subdir ehere these files are installed
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue