Added clicon_data_init API, and yang_mount_get API

Moved dynamic options from options to data API
This commit is contained in:
Olof hagsand 2023-03-12 20:53:48 +01:00
parent 5822c1a72a
commit 1e136bc9df
11 changed files with 174 additions and 43 deletions

View file

@ -177,7 +177,7 @@ startup_common(clicon_handle h,
if (clicon_option_bool(h, "CLICON_XMLDB_MODSTATE")) if (clicon_option_bool(h, "CLICON_XMLDB_MODSTATE"))
if ((msdiff = modstate_diff_new()) == NULL) if ((msdiff = modstate_diff_new()) == NULL)
goto done; goto done;
clicon_debug(1, "Reading startup config from %s", db); clicon_debug(1, "Reading initial config from %s", db);
/* Get the startup datastore WITHOUT binding to YANG, sorting and default setting. /* Get the startup datastore WITHOUT binding to YANG, sorting and default setting.
* It is done below, later in this function * It is done below, later in this function
*/ */
@ -202,6 +202,7 @@ startup_common(clicon_handle h,
if (xmldb_get0(h, db, YB_NONE, NULL, "/", 0, 0, &xt, msdiff, &xerr) < 0) if (xmldb_get0(h, db, YB_NONE, NULL, "/", 0, 0, &xt, msdiff, &xerr) < 0)
goto done; goto done;
} }
clicon_debug_xml(CLIXON_DBG_DETAIL, xt, "startup");
if (msdiff && msdiff->md_status == 0){ // Possibly check for CLICON_XMLDB_MODSTATE if (msdiff && msdiff->md_status == 0){ // Possibly check for CLICON_XMLDB_MODSTATE
clicon_log(LOG_WARNING, "Modstate expected in startup datastore but not found\n" clicon_log(LOG_WARNING, "Modstate expected in startup datastore but not found\n"
"This may indicate that the datastore is not initialized corrrectly, such as copy/pasted.\n" "This may indicate that the datastore is not initialized corrrectly, such as copy/pasted.\n"
@ -439,6 +440,7 @@ startup_commit(clicon_handle h,
* edit-config * edit-config
*/ */
xml_name_set(td->td_target, NETCONF_INPUT_CONFIG); xml_name_set(td->td_target, NETCONF_INPUT_CONFIG);
if ((ret = xmldb_put(h, "running", OP_REPLACE, td->td_target, if ((ret = xmldb_put(h, "running", OP_REPLACE, td->td_target,
clicon_username_get(h), cbret)) < 0) clicon_username_get(h), cbret)) < 0)
goto done; goto done;

View file

@ -73,7 +73,7 @@ struct client_entry{
uint32_t ce_out_rpc_errors; /* <rpc-error> messages*/ uint32_t ce_out_rpc_errors; /* <rpc-error> messages*/
uint32_t ce_out_notifications; /* Outgoing notifications */ uint32_t ce_out_notifications; /* Outgoing notifications */
}; };
typedef struct client_entry client_entry;
/* /*
* Prototypes * Prototypes

View file

@ -171,7 +171,7 @@ netconf_hello_msg(clicon_handle h,
else if (strncmp(body, NETCONF_BASE_CAPABILITY_1_1, strlen(NETCONF_BASE_CAPABILITY_1_1)) == 0 && else if (strncmp(body, NETCONF_BASE_CAPABILITY_1_1, strlen(NETCONF_BASE_CAPABILITY_1_1)) == 0 &&
clicon_option_int(h, "CLICON_NETCONF_BASE_CAPABILITY") > 0){ /* RFC 6241 */ clicon_option_int(h, "CLICON_NETCONF_BASE_CAPABILITY") > 0){ /* RFC 6241 */
foundbase_11++; foundbase_11++;
clicon_option_int_set(h, "netconf-framing", NETCONF_SSH_CHUNKED); /* enable chunked enc */ clicon_data_int_set(h, "netconf-framing", NETCONF_SSH_CHUNKED); /* enable chunked enc */
} }
} }
} }
@ -208,7 +208,7 @@ netconf_rpc_message(clicon_handle h,
cxobj *xc; cxobj *xc;
netconf_framing_type framing; netconf_framing_type framing;
framing = clicon_option_int(h, "netconf-framing"); framing = clicon_data_int_get(h, "netconf-framing");
if (_netconf_hello_nr == 0 && if (_netconf_hello_nr == 0 &&
clicon_option_bool(h, "CLICON_NETCONF_HELLO_OPTIONAL") == 0){ clicon_option_bool(h, "CLICON_NETCONF_HELLO_OPTIONAL") == 0){
if (netconf_operation_failed_xml(&xret, "rpc", "Client must send an hello element before any RPC")< 0) if (netconf_operation_failed_xml(&xret, "rpc", "Client must send an hello element before any RPC")< 0)
@ -321,7 +321,7 @@ netconf_input_packet(clicon_handle h,
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(1, "%s", __FUNCTION__);
rpcname = xml_name(xreq); rpcname = xml_name(xreq);
rpcprefix = xml_prefix(xreq); rpcprefix = xml_prefix(xreq);
framing = clicon_option_int(h, "netconf-framing"); framing = clicon_data_int_get(h, "netconf-framing");
if (xml2ns(xreq, rpcprefix, &namespace) < 0) if (xml2ns(xreq, rpcprefix, &namespace) < 0)
goto done; goto done;
if (strcmp(rpcname, "rpc") == 0){ if (strcmp(rpcname, "rpc") == 0){
@ -406,7 +406,7 @@ netconf_input_frame(clicon_handle h,
clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__); clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
clicon_debug(CLIXON_DBG_MSG, "Recv ext: %s", cbuf_get(cb)); clicon_debug(CLIXON_DBG_MSG, "Recv ext: %s", cbuf_get(cb));
framing = clicon_option_int(h, "netconf-framing"); framing = clicon_data_int_get(h, "netconf-framing");
yspec = clicon_dbspec_yang(h); yspec = clicon_dbspec_yang(h);
if ((str = strdup(cbuf_get(cb))) == NULL){ if ((str = strdup(cbuf_get(cb))) == NULL){
clicon_err(OE_UNIX, errno, "strdup"); clicon_err(OE_UNIX, errno, "strdup");
@ -582,7 +582,7 @@ netconf_input_cb(int s,
for (i=0; i<len; i++){ for (i=0; i<len; i++){
if (buf[i] == 0) if (buf[i] == 0)
continue; /* Skip NULL chars (eg from terminals) */ continue; /* Skip NULL chars (eg from terminals) */
if (clicon_option_int(h, "netconf-framing") == NETCONF_SSH_CHUNKED){ if (clicon_data_int_get(h, "netconf-framing") == NETCONF_SSH_CHUNKED){
/* Track chunked framing defined in RFC6242 */ /* Track chunked framing defined in RFC6242 */
if ((ret = netconf_input_chunked_framing(buf[i], &frame_state, &frame_size)) < 0) if ((ret = netconf_input_chunked_framing(buf[i], &frame_state, &frame_size)) < 0)
goto done; goto done;
@ -663,7 +663,7 @@ send_hello(clicon_handle h,
} }
if (netconf_hello_server(h, cb, id) < 0) if (netconf_hello_server(h, cb, id) < 0)
goto done; goto done;
framing = clicon_option_int(h, "netconf-framing"); framing = clicon_data_int_get(h, "netconf-framing");
if (netconf_output_encap(framing, cb) < 0) if (netconf_output_encap(framing, cb) < 0)
goto done; goto done;
if (netconf_output(s, cb, "hello") < 0) if (netconf_output(s, cb, "hello") < 0)

View file

@ -37,7 +37,7 @@
* Access functions for clixon data. * Access functions for clixon data.
* Free-typed values for runtime getting and setting. * Free-typed values for runtime getting and setting.
* Accessed with clicon_data(h). * Accessed with clicon_data(h).
* @see clixon_option.[ch] for clixon options * @see clixon_option.[ch] for clixon options from Clixon configuration file
*/ */
#ifndef _CLIXON_DATA_H_ #ifndef _CLIXON_DATA_H_
@ -76,6 +76,11 @@ cvec *clicon_data_cvec_get(clicon_handle h, const char *name);
int clicon_data_cvec_set(clicon_handle h, const char *name, cvec *cvv); int clicon_data_cvec_set(clicon_handle h, const char *name, cvec *cvv);
int clicon_data_cvec_del(clicon_handle h, const char *name); int clicon_data_cvec_del(clicon_handle h, const char *name);
/* String options, default NULL */
int clicon_data_int_get(clicon_handle h, const char *name);
int clicon_data_int_set(clicon_handle h, const char *name, int val);
int clicon_data_int_del(clicon_handle h, const char *name);
yang_stmt * clicon_dbspec_yang(clicon_handle h); yang_stmt * clicon_dbspec_yang(clicon_handle h);
int clicon_dbspec_yang_set(clicon_handle h, yang_stmt *ys); int clicon_dbspec_yang_set(clicon_handle h, yang_stmt *ys);

View file

@ -54,6 +54,9 @@
* Prototypes * Prototypes
*/ */
int yang_schema_mount_point(yang_stmt *y); int yang_schema_mount_point(yang_stmt *y);
int yang_mount_get(yang_stmt *yu, char *xpath, yang_stmt **yspec);
int yang_mount_set(yang_stmt *yu, char *xpath, yang_stmt *yspec);
int xml_yang_mount_get(clicon_handle h, cxobj *x, validate_level *vl, yang_stmt **yspec); int xml_yang_mount_get(clicon_handle h, cxobj *x, validate_level *vl, yang_stmt **yspec);
int xml_yang_mount_set(cxobj *x, yang_stmt *yspec); int xml_yang_mount_set(cxobj *x, yang_stmt *yspec);
int xml_yang_mount_freeall(cvec *cvv); int xml_yang_mount_freeall(cvec *cvv);

View file

@ -250,6 +250,65 @@ clicon_data_cvec_del(clicon_handle h,
return clicon_ptr_del(h, name); return clicon_ptr_del(h, name);
} }
/*! Get data option as integer but store as string
*
* @param[in] h clicon_handle
* @param[in] name option name
* @retval int An integer as a result of atoi
* @retval -1 If option does not exist
* Note that -1 can be both error and value.
* @see clicon_option_int for values in clixon config file
*/
int
clicon_data_int_get(clicon_handle h,
const char *name)
{
clicon_hash_t *cdat = clicon_data(h);
char *s;
if (clicon_hash_lookup(cdat, (char*)name) == NULL)
return -1;
s = clicon_hash_value(cdat, (char*)name, NULL);
return atoi(s);
}
/*! Set a single string data via handle
*
* @param[in] h clicon_handle
* @param[in] name option name
* @param[in] val option value, must be null-terminated string
* @retval 0 OK
* @retval -1 Error
*/
int
clicon_data_int_set(clicon_handle h,
const char *name,
int val)
{
clicon_hash_t *cdat = clicon_data(h);
char s[64];
if (snprintf(s, sizeof(s)-1, "%u", val) < 0)
return -1;
return clicon_hash_add(cdat, (char*)name, s, strlen(s)+1)==NULL?-1:0;
}
/*! Delete single int data via handle
*
* @param[in] h clicon_handle
* @param[in] name option name
* @retval 0 OK
* @retval -1 Error
*/
int
clicon_data_int_del(clicon_handle h,
const char *name)
{
clicon_hash_t *cdat = clicon_data(h);
return clicon_hash_del(cdat, (char*)name);
}
/*! Get data yangspec, yspec /*! Get data yangspec, yspec
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @retval yspec Yang spec * @retval yspec Yang spec

View file

@ -495,6 +495,7 @@ xmldb_readfile(clicon_handle h,
clicon_err(OE_CFG, ENOENT, "No CLICON_XMLDB_FORMAT"); clicon_err(OE_CFG, ENOENT, "No CLICON_XMLDB_FORMAT");
goto done; goto done;
} }
clicon_debug(CLIXON_DBG_DEFAULT, "Reading datastore %s using %s", dbfile, format);
/* Parse file into internal XML tree from different formats */ /* Parse file into internal XML tree from different formats */
if ((fp = fopen(dbfile, "r")) == NULL) { if ((fp = fopen(dbfile, "r")) == NULL) {
clicon_err(OE_UNIX, errno, "open(%s)", dbfile); clicon_err(OE_UNIX, errno, "open(%s)", dbfile);
@ -686,7 +687,6 @@ xmldb_get_nocache(clicon_handle h,
cxobj **xerr) cxobj **xerr)
{ {
int retval = -1; int retval = -1;
char *dbfile = NULL;
yang_stmt *yspec; yang_stmt *yspec;
cxobj *xt = NULL; cxobj *xt = NULL;
cxobj *x; cxobj *x;
@ -805,8 +805,6 @@ xmldb_get_nocache(clicon_handle h,
done: done:
if (xt) if (xt)
xml_free(xt); xml_free(xt);
if (dbfile)
free(dbfile);
if (xvec) if (xvec)
free(xvec); free(xvec);
if (fd != -1) if (fd != -1)

View file

@ -1631,10 +1631,10 @@ netconf_module_load(clicon_handle h)
* But start with default: RFC 4741 EOM ]]>]]> * But start with default: RFC 4741 EOM ]]>]]>
* For now this only applies to external protocol * For now this only applies to external protocol
*/ */
clicon_option_int_set(h, "netconf-framing", NETCONF_SSH_EOM); clicon_data_int_set(h, "netconf-framing", NETCONF_SSH_EOM);
if (clicon_option_bool(h, "CLICON_NETCONF_HELLO_OPTIONAL")){ if (clicon_option_bool(h, "CLICON_NETCONF_HELLO_OPTIONAL")){
if (clicon_option_int(h, "CLICON_NETCONF_BASE_CAPABILITY") > 0) /* RFC 6241 */ if (clicon_option_int(h, "CLICON_NETCONF_BASE_CAPABILITY") > 0) /* RFC 6241 */
clicon_option_int_set(h, "netconf-framing", NETCONF_SSH_CHUNKED); clicon_data_int_set(h, "netconf-framing", NETCONF_SSH_CHUNKED);
} }
retval = 0; retval = 0;
done: done:

View file

@ -129,6 +129,7 @@ static const map_str2int yang_regexp_map[] = {
}; };
/*! Print registry on file. For debugging. /*! Print registry on file. For debugging.
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @param[in] dbglevel Debug level * @param[in] dbglevel Debug level
* @retval 0 OK * @retval 0 OK
@ -190,6 +191,7 @@ clicon_option_dump(clicon_handle h,
} }
/*! Open and parse single config file /*! Open and parse single config file
*
* @param[in] filename * @param[in] filename
* @param[in] yspec * @param[in] yspec
* @param[out] xconfig Pointer to xml config tree. Should be freed by caller * @param[out] xconfig Pointer to xml config tree. Should be freed by caller
@ -426,6 +428,7 @@ parse_configfile(clicon_handle h,
} }
/*! Add configuration option overriding file setting /*! Add configuration option overriding file setting
*
* Add to clicon_options hash, and to clicon_conf_xml tree * Add to clicon_options hash, and to clicon_conf_xml tree
* Assumes clicon_conf_xml_set has been called * Assumes clicon_conf_xml_set has been called
* @param[in] h Clicon handle * @param[in] h Clicon handle
@ -579,6 +582,7 @@ clicon_options_main(clicon_handle h)
} }
/*! Check if a clicon option has a value /*! Check if a clicon option has a value
*
* @param[in] h clicon_handle * @param[in] h clicon_handle
* @param[in] name option name * @param[in] name option name
* @retval !=0 option exists * @retval !=0 option exists
@ -597,8 +601,8 @@ clicon_option_exists(clicon_handle h,
* *
* @param[in] h clicon_handle * @param[in] h clicon_handle
* @param[in] name option name * @param[in] name option name
* @retval NULL If option not found, or value of option is NULL
* @retval string value of option if found * @retval string value of option if found
* @retval NULL If option not found, or value of option is NULL
* clicon options should be strings. * clicon options should be strings.
* @note To differentiate the two reasons why NULL may be returned, use function * @note To differentiate the two reasons why NULL may be returned, use function
* clicon_option_exists() before the call * clicon_option_exists() before the call
@ -615,6 +619,7 @@ clicon_option_str(clicon_handle h,
} }
/*! Set a single string option via handle /*! Set a single string option via handle
*
* @param[in] h clicon_handle * @param[in] h clicon_handle
* @param[in] name option name * @param[in] name option name
* @param[in] val option value, must be null-terminated string * @param[in] val option value, must be null-terminated string
@ -646,6 +651,7 @@ clicon_option_str_set(clicon_handle h,
* Note that -1 can be both error and value. * Note that -1 can be both error and value.
* This means that it should be used together with clicon_option_exists() and * This means that it should be used together with clicon_option_exists() and
* supply a default value as shown in the example. * supply a default value as shown in the example.
* @see clicon_data_int_get for transient values (not clixon config file)
*/ */
int int
clicon_option_int(clicon_handle h, clicon_option_int(clicon_handle h,
@ -659,6 +665,7 @@ clicon_option_int(clicon_handle h,
} }
/*! Set option given as int. /*! Set option given as int.
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @param[in] name Name of option to set * @param[in] name Name of option to set
* @param[in] val Integer value * @param[in] val Integer value
@ -707,6 +714,7 @@ clicon_option_bool(clicon_handle h,
} }
/*! Set option given as bool /*! Set option given as bool
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @param[in] name Name of option to set * @param[in] name Name of option to set
* @param[in] val Boolean value, 0 or 1 * @param[in] val Boolean value, 0 or 1
@ -730,6 +738,7 @@ clicon_option_bool_set(clicon_handle h,
} }
/*! Delete option /*! Delete option
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @param[in] name Name of option to delete * @param[in] name Name of option to delete
*/ */
@ -754,6 +763,7 @@ clicon_option_del(clicon_handle h,
*-----------------------------------------------------------------*/ *-----------------------------------------------------------------*/
/*! Get "do not include keys in cvec" in cli vars callbacks /*! Get "do not include keys in cvec" in cli vars callbacks
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @retval flag If set, get only vars * @retval flag If set, get only vars
* @see clixon-config@<date>.yang CLICON_CLI_VARONLY * @see clixon-config@<date>.yang CLICON_CLI_VARONLY
@ -770,6 +780,7 @@ clicon_cli_varonly(clicon_handle h)
} }
/*! Get family of backend socket: AF_UNIX, AF_INET or AF_INET6 /*! Get family of backend socket: AF_UNIX, AF_INET or AF_INET6
*
* @see clixon-config@<date>.yang CLICON_SOCK_FAMILY * @see clixon-config@<date>.yang CLICON_SOCK_FAMILY
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @retval fam Socket family * @retval fam Socket family
@ -792,6 +803,7 @@ clicon_sock_family(clicon_handle h)
} }
/*! Get port for backend socket in case of AF_INET or AF_INET6 /*! Get port for backend socket in case of AF_INET or AF_INET6
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @retval port Socket port * @retval port Socket port
* @see clixon-config@<date>.yang CLICON_SOCK_PORT * @see clixon-config@<date>.yang CLICON_SOCK_PORT
@ -807,6 +819,7 @@ clicon_sock_port(clicon_handle h)
} }
/*! Set if all configuration changes are committed automatically /*! Set if all configuration changes are committed automatically
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @retval flag Autocommit (or not) * @retval flag Autocommit (or not)
*/ */
@ -822,6 +835,7 @@ clicon_autocommit(clicon_handle h)
} }
/*! Which method to boot/start clicon backend /*! Which method to boot/start clicon backend
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @retval mode Startup mode * @retval mode Startup mode
*/ */
@ -836,6 +850,7 @@ clicon_startup_mode(clicon_handle h)
} }
/*! Which privileges drop method to use for backend /*! Which privileges drop method to use for backend
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @retval mode Privileges mode * @retval mode Privileges mode
*/ */
@ -850,6 +865,7 @@ clicon_backend_privileges_mode(clicon_handle h)
} }
/*! Which privileges drop method to use for restconf /*! Which privileges drop method to use for restconf
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @retval mode Privileges mode * @retval mode Privileges mode
*/ */
@ -864,6 +880,7 @@ clicon_restconf_privileges_mode(clicon_handle h)
} }
/*! Which privileges drop method to use /*! Which privileges drop method to use
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @retval mode Privileges mode * @retval mode Privileges mode
*/ */
@ -878,6 +895,7 @@ clicon_nacm_credentials(clicon_handle h)
} }
/*! Which datastore cache method to use /*! Which datastore cache method to use
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @retval method Datastore cache method * @retval method Datastore cache method
* @see clixon-config@<date>.yang CLICON_DATASTORE_CACHE * @see clixon-config@<date>.yang CLICON_DATASTORE_CACHE
@ -894,6 +912,7 @@ clicon_datastore_cache(clicon_handle h)
} }
/*! Which Yang regexp/pattern engine to use /*! Which Yang regexp/pattern engine to use
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @retval mode Regexp engine to use * @retval mode Regexp engine to use
* @see clixon-config@<date>.yang CLICON_YANG_REGEXP * @see clixon-config@<date>.yang CLICON_YANG_REGEXP
@ -916,6 +935,7 @@ clicon_yang_regexp(clicon_handle h)
*--------------------------------------------------------------------*/ *--------------------------------------------------------------------*/
/*! Get quiet mode eg -q option, do not print notifications on stdout /*! Get quiet mode eg -q option, do not print notifications on stdout
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @retval flag quiet mode on or off * @retval flag quiet mode on or off
*/ */
@ -929,6 +949,7 @@ clicon_quiet_mode(clicon_handle h)
} }
/*! Set quiet mode /*! Set quiet mode
*
* @param[in] h Clicon handle * @param[in] h Clicon handle
* @param[in] val Flag value * @param[in] val Flag value
*/ */
@ -938,4 +959,3 @@ clicon_quiet_mode_set(clicon_handle h,
{ {
return clicon_option_int_set(h, "CLICON_QUIET", val); return clicon_option_int_set(h, "CLICON_QUIET", val);
} }

View file

@ -445,6 +445,8 @@ xp_yang_eval(xp_yang_ctx *xy,
* @param[in] ys YANG referring node * @param[in] ys YANG referring node
* @param[in] path_arg path-arg * @param[in] path_arg path-arg
* @param[out] yref YANG referred node * @param[out] yref YANG referred node
* @retval 0 OK
* @retval -1 Error
* @note this function uses XPATH parser, which is (much too) general * @note this function uses XPATH parser, which is (much too) general
* @code * @code
* yang_stmt *ys; // source / referring node * yang_stmt *ys; // source / referring node

View file

@ -131,6 +131,65 @@ yang_schema_mount_point(yang_stmt *y)
goto done; goto done;
} }
/*! Get yangspec mount-point
*
* @param[in] yu Yang unknown node to save the yspecs
* @param[in] xpath Key for yspec on yu
* @param[out] yspec YANG stmt spec
* @retval 0 OK
* @retval -1 Error
*/
int
yang_mount_get(yang_stmt *yu,
char *xpath,
yang_stmt **yspec)
{
cvec *cvv = NULL;
cg_var *cv;
/* Special value in yang unknown node for mount-points: mapping from xpath->mounted yspec */
if ((cvv = yang_cvec_get(yu)) != NULL &&
(cv = cvec_find(cvv, xpath)) != NULL &&
yspec)
*yspec = cv_void_get(cv);
return 0;
}
/*! Set yangspec mount-point on yang unknwon node
*
* Stored in a separate structure (not in XML config tree)
* @param[in] yu Yang unknown node to save the yspecs
* @param[in] xpath Key for yspec on yu
* @param[in] yspec Yangspec for this mount-point (consumed)
* @retval 0 OK
* @retval -1 Error
*/
int
yang_mount_set(yang_stmt *yu,
char *xpath,
yang_stmt *yspec)
{
int retval = -1;
yang_stmt *yspec0;
cvec *cvv;
cg_var *cv;
if ((cvv = yang_cvec_get(yu)) != NULL &&
(cv = cvec_find(cvv, xpath)) != NULL &&
(yspec0 = cv_void_get(cv)) != NULL){
#if 0 /* Problematic to free yang specs here, upper layers should handle it? */
ys_free(yspec0);
#endif
cv_void_set(cv, NULL);
}
else if ((cv = yang_cvec_add(yu, CGV_VOID, xpath)) == NULL)
goto done;
cv_void_set(cv, yspec);
retval = 0;
done:
return retval;
}
/*! Get yangspec mount-point /*! Get yangspec mount-point
* *
* @param[in] h Clixon handle * @param[in] h Clixon handle
@ -148,8 +207,6 @@ xml_yang_mount_get(clicon_handle h,
yang_stmt **yspec) yang_stmt **yspec)
{ {
int retval = -1; int retval = -1;
cvec *cvv = NULL;
cg_var *cv;
yang_stmt *y; yang_stmt *y;
yang_stmt *yu; yang_stmt *yu;
char *xpath = NULL; // XXX free it char *xpath = NULL; // XXX free it
@ -162,21 +219,15 @@ xml_yang_mount_get(clicon_handle h,
if (ret == 0) if (ret == 0)
goto fail; goto fail;
/* Check validate level */ /* Check validate level */
if (clixon_plugin_yang_mount_all(h, xt, NULL, vl, NULL) < 0) if (vl && clixon_plugin_yang_mount_all(h, xt, NULL, vl, NULL) < 0)
goto done; goto done;
// XXX hardcoded prefix: yangmnt // XXX hardcoded prefix: yangmnt
if ((yu = yang_find(y, Y_UNKNOWN, "yangmnt:mount-point")) == NULL) if ((yu = yang_find(y, Y_UNKNOWN, "yangmnt:mount-point")) == NULL)
goto ok; goto ok;
if (xml2xpath(xt, NULL, 1, &xpath) < 0) if (xml2xpath(xt, NULL, 1, &xpath) < 0)
goto done; goto done;
/* Special value in yang unknown node for mount-points: mapping from xpath->mounted yspec */ if (yang_mount_get(yu, xpath, yspec) < 0)
if ((cvv = yang_cvec_get(yu)) == NULL) goto done;
goto ok;
if ((cv = cvec_find(cvv, xpath)) == NULL)
goto ok;
if (yspec)
*yspec = cv_void_get(cv);
ok: ok:
retval = 1; retval = 1;
done: done:
@ -188,7 +239,8 @@ xml_yang_mount_get(clicon_handle h,
goto done; goto done;
} }
/*! Set yangspec mount-point
/*! Set yangspec mount-point via XML mount-point node
* *
* Stored in a separate structure (not in XML config tree) * Stored in a separate structure (not in XML config tree)
* @param[in] x XML moint-point node * @param[in] x XML moint-point node
@ -200,12 +252,10 @@ int
xml_yang_mount_set(cxobj *x, xml_yang_mount_set(cxobj *x,
yang_stmt *yspec) yang_stmt *yspec)
{ {
cg_var *cv; int retval = -1;
yang_stmt *y; yang_stmt *y;
yang_stmt *yu; yang_stmt *yu;
yang_stmt *yspec0;
char *xpath = NULL; char *xpath = NULL;
cvec *cvv;
if ((y = xml_spec(x)) == NULL || if ((y = xml_spec(x)) == NULL ||
(yu = yang_find(y, Y_UNKNOWN, "yangmnt:mount-point")) == NULL){ (yu = yang_find(y, Y_UNKNOWN, "yangmnt:mount-point")) == NULL){
@ -213,21 +263,13 @@ xml_yang_mount_set(cxobj *x,
} }
if (xml2xpath(x, NULL, 1, &xpath) < 0) if (xml2xpath(x, NULL, 1, &xpath) < 0)
goto done; goto done;
if ((cvv = yang_cvec_get(yu)) != NULL && if (yang_mount_set(yu, xpath, yspec) < 0)
(cv = cvec_find(cvv, xpath)) != NULL && goto done;
(yspec0 = cv_void_get(cv)) != NULL){ retval = 0;
#if 0 /* Problematic to free yang specs here, upper layers should handle it? */
ys_free(yspec0);
#endif
cv_void_set(cv, NULL);
}
else if ((cv = yang_cvec_add(yu, CGV_VOID, xpath)) == NULL)
return -1;
cv_void_set(cv, yspec);
done: done:
if (xpath) if (xpath)
free(xpath); free(xpath);
return 0; return retval;
} }
/*! Free all yspec yang-mounts /*! Free all yspec yang-mounts