* Restconf with startup feature will now copy all edit changes to startup db (as it should according to RFC 8040)

* See [Restconf does not handle startup datastore according to the RFC](https://github.com/clicon/clixon/issues/74)
* Netconf Startup feature is no longer hardcoded, you need to explicitly enable it (See RFC 6241, Section 8.7)
  * Enable in config file with: `<CLICON_FEATURE>ietf-netconf:startup</CLICON_FEATURE>`, or use `*:*`
This commit is contained in:
Olof hagsand 2019-04-26 12:12:55 +02:00
parent 161ef9c7b0
commit 6bf2a74e24
26 changed files with 270 additions and 128 deletions

View file

@ -214,104 +214,6 @@ clicon_conf_xml_set(clicon_handle h,
return 0;
}
#ifdef XXX
/*! Get xmldb datastore plugin handle, as used by dlopen/dlsym/dlclose */
plghndl_t
clicon_xmldb_plugin_get(clicon_handle h)
{
clicon_hash_t *cdat = clicon_data(h);
size_t len;
void *p;
if ((p = hash_value(cdat, "xmldb_plugin", &len)) != NULL)
return *(plghndl_t*)p;
return NULL;
}
/*! Set xmldb datastore plugin handle, as used by dlopen/dlsym/dlclose */
int
clicon_xmldb_plugin_set(clicon_handle h,
plghndl_t handle)
{
clicon_hash_t *cdat = clicon_data(h);
if (hash_add(cdat, "xmldb_plugin", &handle, sizeof(void*)) == NULL)
return -1;
return 0;
}
/*! Get XMLDB API struct pointer
* @param[in] h Clicon handle
* @retval xa XMLDB API struct
* @note xa is really of type struct xmldb_api*
*/
void *
clicon_xmldb_api_get(clicon_handle h)
{
clicon_hash_t *cdat = clicon_data(h);
size_t len;
void *xa;
if ((xa = hash_value(cdat, "xmldb_api", &len)) != NULL)
return *(void**)xa;
return NULL;
}
/*! Set or reset XMLDB API struct pointer
* @param[in] h Clicon handle
* @param[in] xa XMLDB API struct
* @note xa is really of type struct xmldb_api*
*/
int
clicon_xmldb_api_set(clicon_handle h,
void *xa)
{
clicon_hash_t *cdat = clicon_data(h);
/* It is the pointer to xa_api that should be copied by hash,
so we send a ptr to the ptr to indicate what to copy.
*/
if (hash_add(cdat, "xmldb_api", &xa, sizeof(void*)) == NULL)
return -1;
return 0;
}
/*! Get XMLDB storage handle
* @param[in] h Clicon handle
* @retval xh XMLDB storage handle. If not connected return NULL
*/
void *
clicon_xmldb_handle_get(clicon_handle h)
{
clicon_hash_t *cdat = clicon_data(h);
size_t len;
void *xh;
if ((xh = hash_value(cdat, "xmldb_handle", &len)) != NULL)
return *(void**)xh;
return NULL;
}
/*! Set or reset XMLDB storage handle
* @param[in] h Clicon handle
* @param[in] xh XMLDB storage handle. If NULL reset it
* @note Just keep note of it, dont allocate it or so.
*/
int
clicon_xmldb_handle_set(clicon_handle h,
void *xh)
{
clicon_hash_t *cdat = clicon_data(h);
if (hash_add(cdat, "xmldb_handle", &xh, sizeof(void*)) == NULL)
return -1;
return 0;
}
#endif /* XXX */
/*! Get authorized user name
* @param[in] h Clicon handle
* @retval xh XMLDB storage handle. If not connected return NULL

View file

@ -1030,14 +1030,8 @@ netconf_module_load(clicon_handle h)
goto done;
if (xml_parse_string("<CLICON_FEATURE>ietf-netconf:validate</CLICON_FEATURE>", yspec, &xc) < 0)
goto done;
if (xml_parse_string("<CLICON_FEATURE>ietf-netconf:startup</CLICON_FEATURE>", yspec, &xc) < 0)
goto done;
if (xml_parse_string("<CLICON_FEATURE>ietf-netconf:xpath</CLICON_FEATURE>", yspec, &xc) < 0)
goto done;
#ifdef NYI
if (xml_parse_string("<CLICON_FEATURE>ietf-netconf:confirmed-commit</CLICON_FEATURE>", yspec, &xc) < 0)
goto done;
#endif
/* Load yang spec */
if (yang_spec_parse_module(h, "ietf-netconf", NULL, yspec)< 0)
goto done;

View file

@ -1591,6 +1591,33 @@ ys_populate_identity(yang_stmt *ys,
return retval;
}
/*! Return 1 if feature is enabled, 0 if not using the populated yang tree
*
* @param[in] yspec yang specification
* @param[in] module Name of module
* @param[in] feature Name of feature
* @retval 0 Not found or not set
* @retval 1 Found and set
* XXX: should the in-param be h, ymod, or yspec?
*/
int
if_feature(yang_stmt *yspec,
char *module,
char *feature)
{
yang_stmt *ym; /* module */
yang_stmt *yf; /* feature */
cg_var *cv;
if ((ym = yang_find_module_by_name(yspec, module)) == NULL)
return 0;
if ((yf = yang_find(ym, Y_FEATURE, feature)) == NULL)
return 0;
if ((cv = yang_cv_get(yf)) == NULL)
return 0;
return cv_bool_get(cv);
}
/*! Populate yang feature statement - set cv to 1 if enabled
*
* @param[in] ys Feature yang statement to populate.
@ -1608,6 +1635,8 @@ ys_populate_feature(clicon_handle h,
char *module;
char *feature;
cxobj *xc;
char *m;
char *f;
/* get clicon config file in xml form */
if ((x = clicon_conf_xml(h)) == NULL)
@ -1620,11 +1649,12 @@ ys_populate_feature(clicon_handle h,
feature = ys->ys_argument;
xc = NULL;
while ((xc = xml_child_each(x, xc, CX_ELMNT)) != NULL && found == 0) {
char *m = NULL;
char *f = NULL;
m = NULL;
f = NULL;
if (strcmp(xml_name(xc), "CLICON_FEATURE") != 0)
continue;
/* get m and f from configuration feature rules */
/* CLICON_FEATURE is on the form <module>:<feature>.
* Split on colon to get module(m) and feature(f) respectively */
if (nodeid_split(xml_body(xc), &m, &f) < 0)
goto done;
if (m && f &&