diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 12bf047a..c1aee865 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -3,7 +3,8 @@ ***** BEGIN LICENSE BLOCK ***** Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren - Copyright (C) 2017-2020 Olof Hagsand + Copyright (C) 2017-2019 Olof Hagsand + Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC This file is part of CLIXON. @@ -168,22 +169,28 @@ client_get_capabilities(clicon_handle h, char *xpath, cxobj **xret) { - int retval = -1; - cxobj *xrstate = NULL; /* xml restconf-state node */ - cxobj *xcap = NULL; /* xml capabilities node */ - + int retval = -1; + cxobj *xrstate = NULL; /* xml restconf-state node */ + cbuf *cb = NULL; + if ((xrstate = xpath_first(*xret, NULL, "restconf-state")) == NULL){ clicon_err(OE_YANG, ENOENT, "restconf-state not found in config node"); goto done; } - if ((xcap = xml_new("capabilities", xrstate, yspec)) == NULL) + if ((cb = cbuf_new()) == NULL){ + clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; - if (xml_parse_va(&xcap, yspec, "urn:ietf:params:restconf:capability:defaults:1.0?basic-mode=explicit") < 0) - goto done; - if (xml_parse_va(&xcap, yspec, "urn:ietf:params:restconf:capability:depth:1.0") < 0) + } + cprintf(cb, ""); + cprintf(cb, "urn:ietf:params:restconf:capability:defaults:1.0?basic-mode=explicit"); + cprintf(cb, "urn:ietf:params:restconf:capability:depth:1.0"); + cprintf(cb, ""); + if (xml_parse_string2(cbuf_get(cb), YB_PARENT, NULL, &xrstate, NULL) < 0) goto done; retval = 0; done: + if (cb) + cbuf_free(cb); return retval; } @@ -217,10 +224,10 @@ client_get_streams(clicon_handle h, goto done; } if ((cb = cbuf_new()) == NULL){ - clicon_err(OE_UNIX, 0, "clicon buffer"); + clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; } - cprintf(cb,"<%s xmlns=\"%s\">", top, yang_argument_get(yns)); + cprintf(cb, "<%s xmlns=\"%s\">", top, yang_argument_get(yns)); /* Second argument is a hack to have the same function for the * RFC5277 and 8040 stream cases */ @@ -271,11 +278,16 @@ client_statedata(clicon_handle h, yang_stmt *ymod; int ret; char *namespace; + cbuf *cb = NULL; if ((yspec = clicon_dbspec_yang(h)) == NULL){ clicon_err(OE_YANG, ENOENT, "No yang spec"); goto done; } + if ((cb = cbuf_new()) == NULL){ + clicon_err(OE_UNIX, errno, "cbuf_new"); + goto done; + } if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277")){ if ((ymod = yang_find_module_by_name(yspec, "clixon-rfc5277")) == NULL){ clicon_err(OE_YANG, ENOENT, "yang module clixon-rfc5277 not found"); @@ -285,7 +297,9 @@ client_statedata(clicon_handle h, clicon_err(OE_YANG, ENOENT, "clixon-rfc5277 namespace not found"); goto done; } - if (xml_parse_va(xret, yspec, "", namespace) < 0) + + cprintf(cb, "", namespace); + if (xml_parse_string2(cbuf_get(cb), YB_TOP, yspec, xret, NULL) < 0) goto done; if ((ret = client_get_streams(h, yspec, xpath, ymod, "netconf", xret)) < 0) goto done; @@ -301,7 +315,9 @@ client_statedata(clicon_handle h, clicon_err(OE_YANG, ENOENT, "ietf-restconf-monitoring namespace not found"); goto done; } - if (xml_parse_va(xret, yspec, "", namespace) < 0) + cbuf_reset(cb); + cprintf(cb, "", namespace); + if (xml_parse_string2(cbuf_get(cb), YB_TOP, yspec, xret, NULL) < 0) goto done; if ((ret = client_get_streams(h, yspec, xpath, ymod, "restconf-state", xret)) < 0) goto done; @@ -323,6 +339,8 @@ client_statedata(clicon_handle h, retval = 1; /* OK */ done: clicon_debug(1, "%s %d", __FUNCTION__, retval); + if (cb) + cbuf_free(cb); return retval; fail: retval = 0; @@ -574,7 +592,7 @@ from_client_edit_config(clicon_handle h, xml_spec_set(xc, NULL); /* Populate XML with Yang spec (why not do this in parser?) */ - if (xml_apply(xc, CX_ELMNT, xml_spec_populate, yspec) < 0) + if (xml_spec_populate(xc, yspec, NULL) < 0) goto done; /* Maybe validate xml here as in text_modify_top? */ if (xml_apply(xc, CX_ELMNT, xml_non_config_data, &non_config) < 0) @@ -980,15 +998,22 @@ from_client_get(clicon_handle h, } /* If not only-state, then read running config * Note xret can be pruned by nacm below and change name and - * metrged with state data, so zero-copy cant be used + * merged with state data, so zero-copy cant be used * Also, must use external namespace context here due to ", yspec, &xt) < 0) + if (xml_parse_file(fd, yspec, &xt) < 0) goto done; if (xt == NULL){ clicon_err(OE_XML, 0, "No xml tree in %s", filename); @@ -748,6 +749,10 @@ main(int argc, if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") && yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0) goto done; + /* Load yang YANG module state */ + if (clicon_option_bool(h, "CLICON_XMLDB_MODSTATE") && + yang_spec_parse_module(h, "ietf-yang-library", NULL, yspec)< 0) + goto done; /* Here all modules are loaded * Compute and set canonical namespace context */ diff --git a/apps/backend/backend_plugin.c b/apps/backend/backend_plugin.c index edfe51c8..f2c28e66 100644 --- a/apps/backend/backend_plugin.c +++ b/apps/backend/backend_plugin.c @@ -133,7 +133,7 @@ clixon_plugin_statedata(clicon_handle h, cbuf_free(ccc); } #endif - if (xml_apply(x, CX_ELMNT, xml_spec_populate, yspec) < 0) + if (xml_spec_populate(x, yspec, NULL) < 0) goto done; if ((ret = netconf_trymerge(x, yspec, xret)) < 0) goto done; diff --git a/apps/backend/backend_startup.c b/apps/backend/backend_startup.c index 55c0aa1c..5ef7e9cd 100644 --- a/apps/backend/backend_startup.c +++ b/apps/backend/backend_startup.c @@ -176,7 +176,7 @@ load_extraxml(clicon_handle h, goto done; } yspec = clicon_dbspec_yang(h); - if (xml_parse_file(fd, "", yspec, &xt) < 0) + if (xml_parse_file(fd, yspec, &xt) < 0) goto done; /* Replace parent w first child */ if (xml_rootchild(xt, 0, &xt) < 0) diff --git a/apps/cli/cli_common.c b/apps/cli/cli_common.c index c55e7358..d3bf9d05 100644 --- a/apps/cli/cli_common.c +++ b/apps/cli/cli_common.c @@ -796,7 +796,7 @@ load_config_file(clicon_handle h, clicon_err(OE_UNIX, errno, "open(%s)", filename); goto done; } - if (xml_parse_file(fd, "", NULL, &xt) < 0) + if (xml_parse_file(fd, NULL, &xt) < 0) goto done; if (xt == NULL) goto done; diff --git a/apps/cli/cli_main.c b/apps/cli/cli_main.c index 66786725..4885ba0c 100644 --- a/apps/cli/cli_main.c +++ b/apps/cli/cli_main.c @@ -541,7 +541,7 @@ main(int argc, char **argv) cligen_tree_add(cli_cligen(h), treeref, pt); if (printgen) - cligen_print(stdout, pt, 1); /* pt_print */ + pt_print(stdout, pt, 1); /* pt_print */ } /* Initialize cli syntax */ diff --git a/apps/cli/cli_show.c b/apps/cli/cli_show.c index b9a3bd46..6eb7dbb6 100644 --- a/apps/cli/cli_show.c +++ b/apps/cli/cli_show.c @@ -2,7 +2,9 @@ * ***** BEGIN LICENSE BLOCK ***** - Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren + Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren + Copyright (C) 2017-2019 Olof Hagsand + Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC This file is part of CLIXON. @@ -431,6 +433,7 @@ cli_show_config1(clicon_handle h, cvec *argv) { int retval = -1; + int ret; char *db; char *formatstr; char *xpath; @@ -450,6 +453,10 @@ cli_show_config1(clicon_handle h, goto done; } + if ((yspec = clicon_dbspec_yang(h)) == NULL){ + clicon_err(OE_FATAL, 0, "No DB_SPEC"); + goto done; + } /* First argv argument: Database */ db = cv_string_get(cvec_i(argv, 0)); /* Second argv argument: Format */ @@ -489,13 +496,13 @@ cli_show_config1(clicon_handle h, clicon_rpc_generate_error(xerr, "Get configuration", NULL); goto done; } - if ((yspec = clicon_dbspec_yang(h)) == NULL){ - clicon_err(OE_FATAL, 0, "No DB_SPEC"); + /* Some formats (eg cli) require yang */ + if ((ret = xml_spec_populate(xt, yspec, &xerr)) < 0) + goto done; + if (ret == 0){ + clicon_rpc_generate_error(xerr, "Get configuration", NULL); goto done; } - /* Some formats (eg cli) require yang */ - if (xml_apply(xt, CX_ELMNT, xml_spec_populate, yspec) < 0) - goto done; /* Print configuration according to format */ switch (format){ case FORMAT_XML: @@ -681,6 +688,7 @@ cli_show_auto1(clicon_handle h, cvec *argv) { int retval = 1; + int ret; yang_stmt *yspec; char *api_path_fmt; /* xml key format */ // char *api_path = NULL; /* xml key */ @@ -740,6 +748,13 @@ cli_show_auto1(clicon_handle h, clicon_rpc_generate_error(xerr, "Get configuration", NULL); goto done; } + /* Some formats (eg cli) require yang */ + if ((ret = xml_spec_populate(xt, yspec, &xerr)) < 0) + goto done; + if (ret == 0){ + clicon_rpc_generate_error(xerr, "Get configuration", NULL); + goto done; + } if ((xp = xpath_first(xt, nsc, "%s", xpath)) != NULL) /* Print configuration according to format */ switch (format){ diff --git a/apps/netconf/netconf_main.c b/apps/netconf/netconf_main.c index a540628e..c92ac114 100644 --- a/apps/netconf/netconf_main.c +++ b/apps/netconf/netconf_main.c @@ -103,7 +103,6 @@ netconf_hello_dispatch(cxobj *xn) return retval; } - /*! Process incoming packet * @param[in] h Clicon handle * @param[in] cb Packet buffer @@ -149,7 +148,7 @@ netconf_input_packet(clicon_handle h, free(str0); if ((xrpc=xpath_first(xreq, NULL, "//rpc")) != NULL){ isrpc++; - if (xml_spec_populate_rpc_input(h, xrpc, yspec) < 0) + if (xml_spec_populate_rpc(xrpc, yspec, NULL) < 0) goto done; if ((ret = xml_yang_validate_rpc(h, xrpc, &xret)) < 0) goto done; diff --git a/apps/netconf/netconf_rpc.c b/apps/netconf/netconf_rpc.c index 8f3315f5..74d3f3ee 100644 --- a/apps/netconf/netconf_rpc.c +++ b/apps/netconf/netconf_rpc.c @@ -2,7 +2,9 @@ * ***** BEGIN LICENSE BLOCK ***** - Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren + Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren + Copyright (C) 2017-2019 Olof Hagsand + Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC This file is part of CLIXON. @@ -157,9 +159,11 @@ netconf_get_config(clicon_handle h, cxobj *xn, cxobj **xret) { - cxobj *xfilter; /* filter */ - int retval = -1; - char *ftype = NULL; + int retval = -1; + cxobj *xfilter; /* filter */ + char *ftype = NULL; + cxobj *xdata; + yang_stmt *yspec; /* ie ... */ if ((xfilter = xpath_first(xn, NULL, "filter")) != NULL) @@ -354,9 +358,11 @@ netconf_get(clicon_handle h, cxobj *xn, cxobj **xret) { - cxobj *xfilter; /* filter */ - int retval = -1; - char *ftype = NULL; + int retval = -1; + cxobj *xfilter; /* filter */ + char *ftype = NULL; + cxobj *xdata; + yang_stmt *yspec; /* ie ... */ if ((xfilter = xpath_first(xn, NULL, "filter")) != NULL) @@ -471,7 +477,6 @@ netconf_notification_cb(int s, } /* - RESULT # If not present, events in the default NETCONF stream will be sent. @@ -586,7 +591,7 @@ netconf_application_rpc(clicon_handle h, /* 1. Check xn arguments with input statement. */ if ((yinput = yang_find(yrpc, Y_INPUT, NULL)) != NULL){ xml_spec_set(xn, yinput); /* needed for xml_spec_populate */ - if (xml_apply(xn, CX_ELMNT, xml_spec_populate, yspec) < 0) + if (xml_spec_populate(xn, yspec, NULL) < 0) goto done; if ((ret = xml_yang_validate_all_top(h, xn, &xerr)) < 0) goto done; @@ -618,9 +623,8 @@ netconf_application_rpc(clicon_handle h, if ((youtput = yang_find(yrpc, Y_OUTPUT, NULL)) != NULL){ xoutput=xpath_first(*xret, NULL, "/"); xml_spec_set(xoutput, youtput); /* needed for xml_spec_populate */ - if (xml_apply(xoutput, CX_ELMNT, xml_spec_populate, yspec) < 0) + if (xml_spec_populate(xoutput, yspec, NULL) < 0) goto done; - if ((ret = xml_yang_validate_all_top(h, xoutput, &xerr)) < 0) goto done; if (ret > 0 && (ret = xml_yang_validate_add(h, xoutput, &xerr)) < 0) diff --git a/apps/restconf/README.md b/apps/restconf/README.md index 35afad43..78c7a67b 100644 --- a/apps/restconf/README.md +++ b/apps/restconf/README.md @@ -217,7 +217,7 @@ You can also run restconf in a debugger. sudo gdb /www-data/clixon_restconf (gdb) run -D 1 -f /usr/local/etc/example.xml ``` -but you need to ensure /www-data/fastcgi_restconf.sock has the following access: +but you need to ensure /www-data/fastcgi_restconf.sock has the following access (may need to be done after restconf has started) ``` rwxr-xr-x 1 www-data www-data 0 sep 22 11:46 /www-data/fastcgi_restconf.sock ``` diff --git a/apps/restconf/restconf_main.c b/apps/restconf/restconf_main.c index ad3fd10e..297a09fa 100644 --- a/apps/restconf/restconf_main.c +++ b/apps/restconf/restconf_main.c @@ -3,6 +3,7 @@ ***** BEGIN LICENSE BLOCK ***** Copyright (C) 2009-2019 Olof Hagsand + Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC This file is part of CLIXON. @@ -233,7 +234,7 @@ api_root(clicon_handle h, if (xml_parse_string("2016-06-21", NULL, &xt) < 0) goto done; - if (xml_apply(xt, CX_ELMNT, xml_spec_populate, yspec) < 0) + if (xml_spec_populate(xt, yspec, NULL) < 0) goto done; if ((cb = cbuf_new()) == NULL){ clicon_err(OE_XML, errno, "cbuf_new"); @@ -548,15 +549,15 @@ usage(clicon_handle h, { fprintf(stderr, "usage:%s [options]\n" "where options are\n" - "\t-h \t\tHelp\n" - "\t-D \tDebug level\n" - "\t-f \tConfiguration file (mandatory)\n" - "\t-l > \tLog on (s)yslog, (f)ile (syslog is default)\n" - "\t-p \tYang directory path (see CLICON_YANG_DIR)\n" - "\t-d \tSpecify restconf plugin directory dir (default: %s)\n" - "\t-y \tLoad yang spec file (override yang main module)\n" + "\t-h \t\t Help\n" + "\t-D \t Debug level\n" + "\t-f \t Configuration file (mandatory)\n" + "\t-l > \t Log on (s)yslog, (f)ile (syslog is default)\n" + "\t-p \t Yang directory path (see CLICON_YANG_DIR)\n" + "\t-d \t Specify restconf plugin directory dir (default: %s)\n" + "\t-y \t Load yang spec file (override yang main module)\n" "\t-a UNIX|IPv4|IPv6 Internal backend socket family\n" - "\t-u \tInternal socket domain path or IP addr (see -a)\n" + "\t-u \t Internal socket domain path or IP addr (see -a)\n" "\t-o \"